aboutsummaryrefslogtreecommitdiffstats
path: root/src/workflow/tests
diff options
context:
space:
mode:
Diffstat (limited to 'src/workflow/tests')
-rw-r--r--src/workflow/tests/__init__.py8
-rw-r--r--src/workflow/tests/constants.py198
-rw-r--r--src/workflow/tests/test_steps.py281
-rw-r--r--src/workflow/tests/test_steps_render.py43
-rw-r--r--src/workflow/tests/test_workflows.py100
5 files changed, 630 insertions, 0 deletions
diff --git a/src/workflow/tests/__init__.py b/src/workflow/tests/__init__.py
new file mode 100644
index 0000000..4f0437d
--- /dev/null
+++ b/src/workflow/tests/__init__.py
@@ -0,0 +1,8 @@
+##############################################################################
+# Copyright (c) 2018 Parker Berberian, Sawyer Bergeron and others.
+#
+# All rights reserved. This program and the accompanying materials
+# are made available under the terms of the Apache License, Version 2.0
+# which accompanies this distribution, and is available at
+# http://www.apache.org/licenses/LICENSE-2.0
+##############################################################################
diff --git a/src/workflow/tests/constants.py b/src/workflow/tests/constants.py
new file mode 100644
index 0000000..f94a949
--- /dev/null
+++ b/src/workflow/tests/constants.py
@@ -0,0 +1,198 @@
+##############################################################################
+# Copyright (c) 2018 Parker Berberian, Sawyer Bergeron, and others.
+#
+# All rights reserved. This program and the accompanying materials
+# are made available under the terms of the Apache License, Version 2.0
+# which accompanies this distribution, and is available at
+# http://www.apache.org/licenses/LICENSE-2.0
+##############################################################################
+POD_XML = """<mxGraphModel>
+<root>
+<mxCell id="0"/>
+<mxCell id="1" parent="0"/>
+<mxCell id="host_null" value="Test profile 0" style="editable=0" vertex="1" connectable="0" parent="1">
+<mxGeometry x="75" y="150" width="110" height="90" as="geometry"/>
+</mxCell>
+<mxCell id="2" value="eno0" style="fillColor=blue;editable=0" vertex="1" parent="host_null">
+<mxGeometry x="90" y="5" width="20" height="20" as="geometry"/>
+</mxCell>
+<mxCell id="3" value="eno1" style="fillColor=blue;editable=0" vertex="1" parent="host_null">
+<mxGeometry x="90" y="30" width="20" height="20" as="geometry"/>
+</mxCell>
+<mxCell id="4" value="eno2" style="fillColor=blue;editable=0" vertex="1" parent="host_null">
+<mxGeometry x="90" y="55" width="20" height="20" as="geometry"/>
+</mxCell>
+<mxCell id="5" value="Test profile 3" style="editable=0" vertex="1" connectable="0" parent="1">
+<mxGeometry x="75" y="290" width="110" height="90" as="geometry"/>
+</mxCell>
+<mxCell id="6" value="eno0" style="fillColor=blue;editable=0" vertex="1" parent="5">
+<mxGeometry x="90" y="5" width="20" height="20" as="geometry"/>
+</mxCell>
+<mxCell id="7" value="eno1" style="fillColor=blue;editable=0" vertex="1" parent="5">
+<mxGeometry x="90" y="30" width="20" height="20" as="geometry"/>
+</mxCell>
+<mxCell id="8" value="eno2" style="fillColor=blue;editable=0" vertex="1" parent="5">
+<mxGeometry x="90" y="55" width="20" height="20" as="geometry"/>
+</mxCell>
+<mxCell id="network_0" value="{&quot;vlan_id&quot;:&quot;500&quot;,&quot;name&quot;:&quot;net&quot;}" style="fillColor=red" vertex="1" parent="1">
+<mxGeometry x="400" y="-20" width="10" height="2000" as="geometry"/>
+</mxCell>
+<mxCell id="9" value="" style="fillColor=black;opacity=0" vertex="1" parent="network_0">
+<mxGeometry width="10" height="40" relative="1" as="geometry"/>
+</mxCell>
+<mxCell id="10" value="" style="fillColor=black;opacity=0" vertex="1" parent="network_0">
+<mxGeometry y="0.02" width="10" height="40" relative="1" as="geometry"/>
+</mxCell>
+<mxCell id="11" value="" style="fillColor=black;opacity=0" vertex="1" parent="network_0">
+<mxGeometry y="0.04" width="10" height="40" relative="1" as="geometry"/>
+</mxCell>
+<mxCell id="12" value="" style="fillColor=black;opacity=0" vertex="1" parent="network_0">
+<mxGeometry y="0.06" width="10" height="40" relative="1" as="geometry"/>
+</mxCell>
+<mxCell id="13" value="" style="fillColor=black;opacity=0" vertex="1" parent="network_0">
+<mxGeometry y="0.08" width="10" height="40" relative="1" as="geometry"/>
+</mxCell>
+<mxCell id="14" value="" style="fillColor=black;opacity=0" vertex="1" parent="network_0">
+<mxGeometry y="0.1" width="10" height="40" relative="1" as="geometry"/>
+</mxCell>
+<mxCell id="15" value="" style="fillColor=black;opacity=0" vertex="1" parent="network_0">
+<mxGeometry y="0.12" width="10" height="40" relative="1" as="geometry"/>
+</mxCell>
+<mxCell id="16" value="" style="fillColor=black;opacity=0" vertex="1" parent="network_0">
+<mxGeometry y="0.14" width="10" height="40" relative="1" as="geometry"/>
+</mxCell>
+<mxCell id="17" value="" style="fillColor=black;opacity=0" vertex="1" parent="network_0">
+<mxGeometry y="0.16" width="10" height="40" relative="1" as="geometry"/>
+</mxCell>
+<mxCell id="18" value="" style="fillColor=black;opacity=0" vertex="1" parent="network_0">
+<mxGeometry y="0.18" width="10" height="40" relative="1" as="geometry"/>
+</mxCell>
+<mxCell id="19" value="" style="fillColor=black;opacity=0" vertex="1" parent="network_0">
+<mxGeometry y="0.2" width="10" height="40" relative="1" as="geometry"/>
+</mxCell>
+<mxCell id="20" value="" style="fillColor=black;opacity=0" vertex="1" parent="network_0">
+<mxGeometry y="0.22" width="10" height="40" relative="1" as="geometry"/>
+</mxCell>
+<mxCell id="21" value="" style="fillColor=black;opacity=0" vertex="1" parent="network_0">
+<mxGeometry y="0.24" width="10" height="40" relative="1" as="geometry"/>
+</mxCell>
+<mxCell id="22" value="" style="fillColor=black;opacity=0" vertex="1" parent="network_0">
+<mxGeometry y="0.26" width="10" height="40" relative="1" as="geometry"/>
+</mxCell>
+<mxCell id="23" value="" style="fillColor=black;opacity=0" vertex="1" parent="network_0">
+<mxGeometry y="0.28" width="10" height="40" relative="1" as="geometry"/>
+</mxCell>
+<mxCell id="24" value="" style="fillColor=black;opacity=0" vertex="1" parent="network_0">
+<mxGeometry y="0.3" width="10" height="40" relative="1" as="geometry"/>
+</mxCell>
+<mxCell id="25" value="" style="fillColor=black;opacity=0" vertex="1" parent="network_0">
+<mxGeometry y="0.32" width="10" height="40" relative="1" as="geometry"/>
+</mxCell>
+<mxCell id="26" value="" style="fillColor=black;opacity=0" vertex="1" parent="network_0">
+<mxGeometry y="0.34" width="10" height="40" relative="1" as="geometry"/>
+</mxCell>
+<mxCell id="27" value="" style="fillColor=black;opacity=0" vertex="1" parent="network_0">
+<mxGeometry y="0.36" width="10" height="40" relative="1" as="geometry"/>
+</mxCell>
+<mxCell id="28" value="" style="fillColor=black;opacity=0" vertex="1" parent="network_0">
+<mxGeometry y="0.38" width="10" height="40" relative="1" as="geometry"/>
+</mxCell>
+<mxCell id="29" value="" style="fillColor=black;opacity=0" vertex="1" parent="network_0">
+<mxGeometry y="0.4" width="10" height="40" relative="1" as="geometry"/>
+</mxCell>
+<mxCell id="30" value="" style="fillColor=black;opacity=0" vertex="1" parent="network_0">
+<mxGeometry y="0.42" width="10" height="40" relative="1" as="geometry"/>
+</mxCell>
+<mxCell id="31" value="" style="fillColor=black;opacity=0" vertex="1" parent="network_0">
+<mxGeometry y="0.44" width="10" height="40" relative="1" as="geometry"/>
+</mxCell>
+<mxCell id="32" value="" style="fillColor=black;opacity=0" vertex="1" parent="network_0">
+<mxGeometry y="0.46" width="10" height="40" relative="1" as="geometry"/>
+</mxCell>
+<mxCell id="33" value="" style="fillColor=black;opacity=0" vertex="1" parent="network_0">
+<mxGeometry y="0.48" width="10" height="40" relative="1" as="geometry"/>
+</mxCell>
+<mxCell id="34" value="" style="fillColor=black;opacity=0" vertex="1" parent="network_0">
+<mxGeometry y="0.5" width="10" height="40" relative="1" as="geometry"/>
+</mxCell>
+<mxCell id="35" value="" style="fillColor=black;opacity=0" vertex="1" parent="network_0">
+<mxGeometry y="0.52" width="10" height="40" relative="1" as="geometry"/>
+</mxCell>
+<mxCell id="36" value="" style="fillColor=black;opacity=0" vertex="1" parent="network_0">
+<mxGeometry y="0.54" width="10" height="40" relative="1" as="geometry"/>
+</mxCell>
+<mxCell id="37" value="" style="fillColor=black;opacity=0" vertex="1" parent="network_0">
+<mxGeometry y="0.56" width="10" height="40" relative="1" as="geometry"/>
+</mxCell>
+<mxCell id="38" value="" style="fillColor=black;opacity=0" vertex="1" parent="network_0">
+<mxGeometry y="0.58" width="10" height="40" relative="1" as="geometry"/>
+</mxCell>
+<mxCell id="39" value="" style="fillColor=black;opacity=0" vertex="1" parent="network_0">
+<mxGeometry y="0.6" width="10" height="40" relative="1" as="geometry"/>
+</mxCell>
+<mxCell id="40" value="" style="fillColor=black;opacity=0" vertex="1" parent="network_0">
+<mxGeometry y="0.62" width="10" height="40" relative="1" as="geometry"/>
+</mxCell>
+<mxCell id="41" value="" style="fillColor=black;opacity=0" vertex="1" parent="network_0">
+<mxGeometry y="0.64" width="10" height="40" relative="1" as="geometry"/>
+</mxCell>
+<mxCell id="42" value="" style="fillColor=black;opacity=0" vertex="1" parent="network_0">
+<mxGeometry y="0.66" width="10" height="40" relative="1" as="geometry"/>
+</mxCell>
+<mxCell id="43" value="" style="fillColor=black;opacity=0" vertex="1" parent="network_0">
+<mxGeometry y="0.68" width="10" height="40" relative="1" as="geometry"/>
+</mxCell>
+<mxCell id="44" value="" style="fillColor=black;opacity=0" vertex="1" parent="network_0">
+<mxGeometry y="0.7000000000000001" width="10" height="40" relative="1" as="geometry"/>
+</mxCell>
+<mxCell id="45" value="" style="fillColor=black;opacity=0" vertex="1" parent="network_0">
+<mxGeometry y="0.72" width="10" height="40" relative="1" as="geometry"/>
+</mxCell>
+<mxCell id="46" value="" style="fillColor=black;opacity=0" vertex="1" parent="network_0">
+<mxGeometry y="0.74" width="10" height="40" relative="1" as="geometry"/>
+</mxCell>
+<mxCell id="47" value="" style="fillColor=black;opacity=0" vertex="1" parent="network_0">
+<mxGeometry y="0.76" width="10" height="40" relative="1" as="geometry"/>
+</mxCell>
+<mxCell id="48" value="" style="fillColor=black;opacity=0" vertex="1" parent="network_0">
+<mxGeometry y="0.78" width="10" height="40" relative="1" as="geometry"/>
+</mxCell>
+<mxCell id="49" value="" style="fillColor=black;opacity=0" vertex="1" parent="network_0">
+<mxGeometry y="0.8" width="10" height="40" relative="1" as="geometry"/>
+</mxCell>
+<mxCell id="50" value="" style="fillColor=black;opacity=0" vertex="1" parent="network_0">
+<mxGeometry y="0.8200000000000001" width="10" height="40" relative="1" as="geometry"/>
+</mxCell>
+<mxCell id="51" value="" style="fillColor=black;opacity=0" vertex="1" parent="network_0">
+<mxGeometry y="0.84" width="10" height="40" relative="1" as="geometry"/>
+</mxCell>
+<mxCell id="52" value="" style="fillColor=black;opacity=0" vertex="1" parent="network_0">
+<mxGeometry y="0.86" width="10" height="40" relative="1" as="geometry"/>
+</mxCell>
+<mxCell id="53" value="" style="fillColor=black;opacity=0" vertex="1" parent="network_0">
+<mxGeometry y="0.88" width="10" height="40" relative="1" as="geometry"/>
+</mxCell>
+<mxCell id="54" value="" style="fillColor=black;opacity=0" vertex="1" parent="network_0">
+<mxGeometry y="0.9" width="10" height="40" relative="1" as="geometry"/>
+</mxCell>
+<mxCell id="55" value="" style="fillColor=black;opacity=0" vertex="1" parent="network_0">
+<mxGeometry y="0.92" width="10" height="40" relative="1" as="geometry"/>
+</mxCell>
+<mxCell id="56" value="" style="fillColor=black;opacity=0" vertex="1" parent="network_0">
+<mxGeometry y="0.9400000000000001" width="10" height="40" relative="1" as="geometry"/>
+</mxCell>
+<mxCell id="57" value="" style="fillColor=black;opacity=0" vertex="1" parent="network_0">
+<mxGeometry y="0.96" width="10" height="40" relative="1" as="geometry"/>
+</mxCell>
+<mxCell id="58" value="" style="fillColor=black;opacity=0" vertex="1" parent="network_0">
+<mxGeometry y="0.98" width="10" height="40" relative="1" as="geometry"/>
+</mxCell>
+<mxCell id="59" value="{&quot;tagged&quot;:true}" style="strokeColor=red" edge="1" parent="1" source="2" target="13">
+<mxGeometry relative="1" as="geometry"/>
+</mxCell>
+<mxCell id="60" value="{&quot;tagged&quot;:false}" style="strokeColor=red" edge="1" parent="1" source="7" target="17">
+<mxGeometry relative="1" as="geometry"/>
+</mxCell>
+</root>
+</mxGraphModel>
+"""
diff --git a/src/workflow/tests/test_steps.py b/src/workflow/tests/test_steps.py
new file mode 100644
index 0000000..380102a
--- /dev/null
+++ b/src/workflow/tests/test_steps.py
@@ -0,0 +1,281 @@
+##############################################################################
+# Copyright (c) 2018 Parker Berberian, Sawyer Bergeron, and others.
+#
+# All rights reserved. This program and the accompanying materials
+# are made available under the terms of the Apache License, Version 2.0
+# which accompanies this distribution, and is available at
+# http://www.apache.org/licenses/LICENSE-2.0
+##############################################################################
+
+from django.test import TestCase
+from dashboard.populate_db import Populator
+from workflow.tests import constants
+from workflow.workflow_factory import WorkflowFactory
+from workflow.models import Repository
+from workflow.resource_bundle_workflow import Define_Hardware, Define_Nets, Resource_Meta_Info, Host_Meta_Info
+from workflow.sw_bundle_workflow import SWConf_Resource_Select, Define_Software, Config_Software
+from workflow.booking_workflow import Booking_Resource_Select, SWConfig_Select, Booking_Meta
+from django.http import QueryDict, HttpRequest
+from django.contrib.auth.models import User
+from resource_inventory.models import (
+ Scenario,
+ Installer,
+ OPNFVRole,
+ Image,
+ GenericResourceBundle,
+ GenericHost,
+ HostProfile,
+ GenericResource,
+ ConfigBundle
+)
+
+
+class BaseStepTestCase(TestCase):
+
+ @classmethod
+ def setUpTestData(cls):
+ Populator().populate()
+
+ def makeRepo(self):
+ repo = Repository()
+ repo.el[repo.SESSION_USER] = User.objects.filter(username="user 1").first()
+ return repo
+
+ def step_test(self, step_type, data):
+ step = WorkflowFactory().make_step(step_type, self.makeRepo())
+ formData = QueryDict(mutable=True)
+ formData.update(data)
+ request = HttpRequest()
+ request.POST = formData
+ response = step.post_render(request)
+ context = step.get_context()
+ return response, context
+
+
+class BookingResourceSelectTestCase(BaseStepTestCase):
+
+ def test_step_with_good_data(self):
+ grb_model = GenericResourceBundle.objects.filter(owner__username="user 1").first()
+ grb = [{"small_name": grb_model.name, "expanded_name": "user 1", "id": grb_model.id, "string": ""}]
+ grb = str(grb).replace("'", '"')
+ data = {"generic_resource_bundle": grb}
+ response, context = self.step_test(Booking_Resource_Select, data)
+ self.assertTrue(True)
+
+ def test_step_with_bad_data(self): # TODO
+ data = {}
+ response, context = self.step_test(Booking_Resource_Select, data)
+
+ def test_step_with_empty_data(self):
+ data = {}
+ response, context = self.step_test(SWConfig_Select, data)
+
+
+class SoftwareConfigSelectTestCase(BaseStepTestCase):
+
+ def test_step_with_good_data(self):
+ config_model = ConfigBundle.objects.filter(owner__username="user 1").first()
+ config = [{"expanded_name": "user 1", "small_name": config_model.name, "id": config_model.id, "string": ""}]
+ config = str(config).replace("'", '"')
+ data = {"software_bundle": config}
+ response, context = self.step_test(SWConfig_Select, data)
+
+ def test_step_with_bad_data(self): # TODO
+ data = {}
+ response, context = self.step_test(SWConfig_Select, data)
+
+ def test_step_with_empty_data(self):
+ data = {}
+ response, context = self.step_test(SWConfig_Select, data)
+
+
+class BookingMetaTestCase(BaseStepTestCase):
+
+ def test_step_with_good_data(self):
+ data = {"length": 7, "project": "LaaS", "purpose": "testing"}
+ user2 = User.objects.get(username="user 2")
+ john = User.objects.get(username="johnsmith")
+ users = [
+ {"expanded_name": "", "id": user2.id, "small_name": user2.username, "string": user2.email},
+ {"expanded_name": "", "id": john.id, "small_name": john.username, "string": john.email}
+ ]
+ users = str(users).replace("'", '"')
+ data['users'] = users
+ response, context = self.step_test(Booking_Meta, data)
+
+ def test_step_with_bad_data(self): # TODO
+ data = {}
+ response, context = self.step_test(Booking_Meta, data)
+
+ def test_step_with_empty_data(self):
+ data = {}
+ response, context = self.step_test(Booking_Meta, data)
+
+
+class DefineHardwareTestCase(BaseStepTestCase):
+
+ def test_step_with_good_data(self):
+ hosts = {"host_4": 1, "host_1": 1}
+ labs = {"lab_1": "true"}
+ data = {"hosts": hosts, "labs": labs}
+ response, context = self.step_test(Define_Hardware, data)
+
+ def test_step_with_bad_data(self): # TODO
+ data = {}
+ response, context = self.step_test(Define_Hardware, data)
+
+ def test_step_with_empty_data(self):
+ data = {}
+ response, context = self.step_test(Define_Hardware, data)
+
+
+class HostMetaInfoTestCase(BaseStepTestCase):
+
+ def makeRepo(self):
+ """
+ override to provide step with needed host info
+ """
+ repo = super(HostMetaInfoTestCase, self).makeRepo()
+ # get models
+ models = {}
+ models['bundle'] = GenericResourceBundle()
+ # make generic hosts
+ gres1 = GenericResource(bundle=models['bundle'])
+ prof1 = HostProfile.objects.get(name="Test profile 0")
+ ghost1 = GenericHost(profile=prof1, resource=gres1)
+
+ gres2 = GenericResource(bundle=models['bundle'])
+ prof2 = HostProfile.objects.get(name="Test profile 3")
+ ghost2 = GenericHost(profile=prof2, resource=gres2)
+ models['hosts'] = [ghost1, ghost2]
+ repo.el[repo.GRESOURCE_BUNDLE_MODELS] = models
+ return repo
+
+ def test_step_with_good_data(self):
+ data = {"form-INITIAL_FORMS": 2, "form-MAX_NUM_FORMS": 1000}
+ data["form-MIN_NUM_FORMS"] = 0
+ data["form-TOTAL_FORMS"] = 2
+ data['form-0-host_name'] = "first host"
+ data['form-1-host_name'] = "second host"
+ response, context = self.step_test(Host_Meta_Info, data)
+
+ def test_step_with_bad_data(self): # TODO
+ data = {"form-INITIAL_FORMS": 0, "form-MAX_NUM_FORMS": 1000}
+ data["form-MIN_NUM_FORMS"] = 0
+ data["form-TOTAL_FORMS"] = 0
+ response, context = self.step_test(Host_Meta_Info, data)
+
+ def test_step_with_empty_data(self):
+ data = {"form-INITIAL_FORMS": 0, "form-MAX_NUM_FORMS": 1000}
+ data["form-MIN_NUM_FORMS"] = 0
+ data["form-TOTAL_FORMS"] = 0
+ response, context = self.step_test(Host_Meta_Info, data)
+
+
+class DefineNetsTestCase(BaseStepTestCase):
+
+ def test_step_with_good_data(self):
+ xml = constants.POD_XML
+ data = {"xml": xml}
+ response, context = self.step_test(Define_Nets, data)
+
+ def test_step_with_bad_data(self): # TODO
+ data = {}
+ response, context = self.step_test(Define_Nets, data)
+
+ def test_step_with_empty_data(self):
+ data = {}
+ response, context = self.step_test(Define_Nets, data)
+
+
+class ResourceMetaInfoTestCase(BaseStepTestCase):
+
+ def test_step_with_good_data(self):
+ data = {"bundle_description": "description", "bundle_name": "my testing bundle"}
+ response, context = self.step_test(Resource_Meta_Info, data)
+
+ def test_step_with_bad_data(self): # TODO
+ data = {}
+ response, context = self.step_test(Resource_Meta_Info, data)
+
+ def test_step_with_empty_data(self):
+ data = {}
+ response, context = self.step_test(Resource_Meta_Info, data)
+
+
+class SWConfResourceSelectTestCase(BaseStepTestCase):
+
+ def test_step_with_good_data(self):
+ grb_model = GenericResourceBundle.objects.filter(owner__username="user 1").first()
+ grb = [{"small_name": grb_model.name, "expanded_name": "user 1", "id": grb_model.id, "string": ""}]
+ grb = str(grb).replace("'", '"')
+ data = {"generic_resource_bundle": grb}
+ response, context = self.step_test(SWConf_Resource_Select, data)
+
+ def test_step_with_bad_data(self): # TODO
+ data = {}
+ response, context = self.step_test(SWConf_Resource_Select, data)
+
+ def test_step_with_empty_data(self):
+ data = {}
+ response, context = self.step_test(SWConf_Resource_Select, data)
+
+
+class DefineSoftwareTestCase(BaseStepTestCase):
+
+ def makeRepo(self):
+ """
+ put selected grb in repo for step
+ """
+ repo = super(DefineSoftwareTestCase, self).makeRepo()
+ grb = GenericResourceBundle.objects.filter(owner__username="user 1").first()
+ repo.el[repo.SWCONF_SELECTED_GRB] = grb
+ return repo
+
+ def test_step_with_good_data(self):
+ data = {"form-INITIAL_FORMS": 3, "form-MAX_NUM_FORMS": 1000}
+ data["form-MIN_NUM_FORMS"] = 0
+ data["form-TOTAL_FORMS"] = 3
+ an_image_id = Image.objects.get(name="a host image").id
+ another_image_id = Image.objects.get(name="another host image").id
+ control = OPNFVRole.objects.get(name="Controller")
+ compute = OPNFVRole.objects.get(name="Compute")
+ jumphost = OPNFVRole.objects.get(name="Jumphost")
+ data['form-0-image'] = an_image_id
+ data['form-1-image'] = an_image_id
+ data['form-2-image'] = another_image_id
+ data['form-0-role'] = compute.id
+ data['form-1-role'] = control.id
+ data['form-2-role'] = jumphost.id
+ response, context = self.step_test(Define_Software, data)
+
+ def test_step_with_bad_data(self): # TODO
+ data = {"form-INITIAL_FORMS": 0, "form-MAX_NUM_FORMS": 1000}
+ data["form-MIN_NUM_FORMS"] = 0
+ data["form-TOTAL_FORMS"] = 0
+ response, context = self.step_test(Define_Software, data)
+
+ def test_step_with_empty_data(self):
+ data = {"form-INITIAL_FORMS": 0, "form-MAX_NUM_FORMS": 1000}
+ data["form-MIN_NUM_FORMS"] = 0
+ data["form-TOTAL_FORMS"] = 0
+ response, context = self.step_test(Define_Software, data)
+
+
+class ConfigSoftwareTestCase(BaseStepTestCase):
+
+ def test_step_with_good_data(self):
+ data = {"description": "description", "name": "namey"}
+ installer = Installer.objects.get(name="Fuel")
+ scenario = Scenario.objects.get(name="os-nosdn-nofeature-noha")
+ data['installer'] = installer.id
+ data['scenario'] = scenario.id
+ response, context = self.step_test(Config_Software, data)
+
+ def test_step_with_bad_data(self): # TODO
+ data = {}
+ response, context = self.step_test(Config_Software, data)
+
+ def test_step_with_empty_data(self):
+ data = {}
+ response, context = self.step_test(Config_Software, data)
diff --git a/src/workflow/tests/test_steps_render.py b/src/workflow/tests/test_steps_render.py
new file mode 100644
index 0000000..f3df8f2
--- /dev/null
+++ b/src/workflow/tests/test_steps_render.py
@@ -0,0 +1,43 @@
+##############################################################################
+# Copyright (c) 2018 Parker Berberian, Sawyer Bergeron, and others.
+#
+# All rights reserved. This program and the accompanying materials
+# are made available under the terms of the Apache License, Version 2.0
+# which accompanies this distribution, and is available at
+# http://www.apache.org/licenses/LICENSE-2.0
+##############################################################################
+
+from django.test import TestCase, Client
+
+
+class SuperViewTestCase(TestCase):
+ url = "/"
+ client = Client()
+
+ def test_get(self):
+ response = self.client.get(self.url)
+ self.assertLess(response.status_code, 300)
+
+
+class DefineHardwareViewTestCase(SuperViewTestCase):
+ url = "/wf/workflow/step/define_hardware"
+
+
+class DefineNetworkViewTestCase(SuperViewTestCase):
+ url = "/wf/workflow/step/define_net"
+
+
+class ResourceMetaViewTestCase(SuperViewTestCase):
+ url = "/wf/workflow/step/resource_meta"
+
+
+class BookingMetaViewTestCase(SuperViewTestCase):
+ url = "/wf/workflow/step/booking_meta"
+
+
+class SoftwareSelectViewTestCase(SuperViewTestCase):
+ url = "/wf/workflow/step/software_select"
+
+
+class ResourceSelectViewTestCase(SuperViewTestCase):
+ url = "/wf/workflow/step/resource_select"
diff --git a/src/workflow/tests/test_workflows.py b/src/workflow/tests/test_workflows.py
new file mode 100644
index 0000000..7a53521
--- /dev/null
+++ b/src/workflow/tests/test_workflows.py
@@ -0,0 +1,100 @@
+##############################################################################
+# Copyright (c) 2018 Parker Berberian, Sawyer Bergeron, and others.
+#
+# All rights reserved. This program and the accompanying materials
+# are made available under the terms of the Apache License, Version 2.0
+# which accompanies this distribution, and is available at
+# http://www.apache.org/licenses/LICENSE-2.0
+##############################################################################
+
+from django.test import TestCase
+from workflow.workflow_factory import WorkflowFactory
+from dashboard.populate_db import Populator
+
+
+"""
+To start a workflow:
+ POST to /wf/workflow {"add": <wf_type_int>
+
+ types:
+ 0 - Booking
+ 1 - Resource
+ 2 - Config
+
+To remove a workflow:
+ POST to /wf/workflow {"cancel": ""}
+"""
+
+
+class WorkflowTestCase(TestCase):
+
+ @classmethod
+ def setUpTestData(cls):
+ Populator().populate()
+
+ def setUp(self):
+ self.clear_workflow()
+ self.create_workflow(self.wf_type)
+
+ def create_workflow(self, wf_type):
+ self.clear_workflow()
+
+ # creates workflow on backend
+ self.client.post("/", {"create": int(wf_type)}) # TODO: verify content type, etc
+
+ def clear_workflow(self):
+ session = self.client.session
+ for k in session.keys():
+ del session[k]
+ session.save()
+
+ def render_steps(self):
+ """
+ retrieves each step individually at /wf/workflow/step=<index>
+ """
+ for i in range(self.step_count):
+ # renders the step itself, not in an iframe
+ exception = None
+ try:
+ response = self.client.get("/wf/workflow/", {"step": str(i)})
+ self.assertLess(response.status_code, 300)
+ except Exception as e:
+ exception = e
+
+ self.assertIsNone(exception)
+
+
+class BookingWorkflowTestCase(WorkflowTestCase):
+
+ @classmethod
+ def setUpClass(cls):
+ super(BookingWorkflowTestCase, cls).setUpClass()
+ cls.step_count = len(WorkflowFactory.booking_steps)
+ cls.wf_type = 0
+
+ def test_steps_render(self):
+ super(BookingWorkflowTestCase, self).render_steps()
+
+
+class ResourceWorkflowTestCase(WorkflowTestCase):
+
+ @classmethod
+ def setUpClass(cls):
+ super(ResourceWorkflowTestCase, cls).setUpClass()
+ cls.step_count = len(WorkflowFactory.resource_steps)
+ cls.wf_type = 1
+
+ def test_steps_render(self):
+ super(ResourceWorkflowTestCase, self).render_steps()
+
+
+class ConfigWorkflowTestCase(WorkflowTestCase):
+
+ @classmethod
+ def setUpClass(cls):
+ super(ConfigWorkflowTestCase, cls).setUpClass()
+ cls.step_count = len(WorkflowFactory.config_steps)
+ cls.wf_type = 2
+
+ def test_steps_render(self):
+ super(ConfigWorkflowTestCase, self).render_steps()