57bf6a3b336623ff21204d37b6cd15772f01cd7e
[laas.git] / src / workflow / tests / test_steps.py
1 ##############################################################################
2 # Copyright (c) 2018 Parker Berberian, Sawyer Bergeron, and others.
3 #
4 # All rights reserved. This program and the accompanying materials
5 # are made available under the terms of the Apache License, Version 2.0
6 # which accompanies this distribution, and is available at
7 # http://www.apache.org/licenses/LICENSE-2.0
8 ##############################################################################
9
10 """
11 This file tests basic functionality of each step class.
12
13 More in depth case coverage of WorkflowStep.post() must happen elsewhere.
14 """
15
16 import json
17 from unittest import SkipTest, mock
18
19 from django.test import TestCase, RequestFactory
20 from dashboard.testing_utils import make_lab, make_user, make_os,\
21     make_complete_host_profile, make_opnfv_role, make_image, make_grb,\
22     make_config_bundle, make_host, make_user_profile, make_generic_host
23 from workflow import resource_bundle_workflow
24 from workflow import booking_workflow
25 from workflow import sw_bundle_workflow
26 from workflow.models import Repository
27 from workflow.tests import test_fixtures
28
29
30 class TestConfig:
31     """
32     Basic class to instantiate and hold reference.
33
34     to models we will need often
35     """
36
37     def __init__(self, usr=None):
38         self.lab = make_lab()
39         self.user = usr or make_user()
40         self.os = make_os()
41         self.host_prof = make_complete_host_profile(self.lab)
42         self.host = make_host(self.host_prof, self.lab, name="host1")
43
44         # pod description as required by testing lib
45         self.topology = {
46             "host1": {
47                 "type": self.host_prof,
48                 "role": make_opnfv_role(),
49                 "image": make_image(self.lab, 3, self.user, self.os, self.host_prof),
50                 "nets": [
51                     [{"name": "public", "tagged": True, "public": True}]
52                 ]
53             }
54         }
55         self.grb = make_grb(self.topology, self.user, self.lab)[0]
56         self.generic_host = make_generic_host(self.grb, self.host_prof, "host1")
57
58
59 class StepTestCase(TestCase):
60
61     # after setUp is called, this should be an instance of a step
62     step = None
63
64     post_data = {}  # subclasses will set this
65
66     @classmethod
67     def setUpTestData(cls):
68         super().setUpTestData()
69         cls.factory = RequestFactory()
70         cls.user_prof = make_user_profile()
71         cls.user = cls.user_prof.user
72
73     def setUp(self):
74         super().setUp()
75         if self.step is None:
76             raise SkipTest("Step instance not given")
77         repo = Repository()
78         self.add_to_repo(repo)
79         self.step = self.step(1, repo)
80
81     def assertCorrectPostBehavior(self, post_data):
82         """
83         Stub for validating step behavior on POST request.
84
85         allows subclasses to override and make assertions about
86         the side effects of self.step.post()
87         post_data is the data passed into post()
88         """
89         return
90
91     def add_to_repo(self, repo):
92         """
93         Stub for modifying the step's repo.
94
95         This method is a hook that allows subclasses to modify
96         the contents of the repo before the step is created.
97         """
98         return
99
100     def assertValidHtml(self, html_str):
101         """
102         Assert that html_str is a valid html fragment.
103
104         However, I know of no good way of doing this in python
105         """
106         self.assertTrue(isinstance(html_str, str))
107         self.assertGreater(len(html_str), 0)
108
109     def test_render_to_string(self):
110         request = self.factory.get("/workflow/manager/")
111         request.user = self.user
112         response_html = self.step.render_to_string(request)
113         self.assertValidHtml(response_html)
114
115     def test_post(self, data=None):
116         post_data = data or self.post_data
117         self.step.post(post_data, self.user)
118         self.assertCorrectPostBehavior(data)
119
120
121 class SelectStepTestCase(StepTestCase):
122     # ID of model to be sent to the step's form
123     # can be an int or a list of ints
124     obj_id = -1
125
126     def setUp(self):
127         super().setUp()
128
129         try:
130             iter(self.obj_id)
131         except TypeError:
132             self.obj_id = [self.obj_id]
133
134         field_data = json.dumps(self.obj_id)
135         self.post_data = {
136             "searchable_select": [field_data]
137         }
138
139
140 class DefineHardwareTestCase(StepTestCase):
141     step = resource_bundle_workflow.Define_Hardware
142     post_data = {
143         "filter_field": {
144             "lab": {
145                 "lab_35": {"selected": True, "id": 35}},
146             "host": {
147                 "host_1": {"selected": True, "id": 1}}
148         }
149     }
150
151
152 class DefineNetworkTestCase(StepTestCase):
153     step = resource_bundle_workflow.Define_Nets
154     post_data = {"xml": test_fixtures.MX_GRAPH_MODEL}
155
156
157 class ResourceMetaTestCase(StepTestCase):
158     step = resource_bundle_workflow.Resource_Meta_Info
159     post_data = {
160         "bundle_name": "my_bundle",
161         "bundle_description": "My Bundle"
162     }
163
164
165 class BookingResourceTestCase(SelectStepTestCase):
166     step = booking_workflow.Booking_Resource_Select
167
168     def add_to_repo(self, repo):
169         repo.el[repo.SESSION_USER] = self.user
170
171     @classmethod
172     def setUpTestData(cls):
173         super().setUpTestData()
174         conf = TestConfig(usr=cls.user)
175         cls.obj_id = conf.grb.id
176
177
178 class SoftwareSelectTestCase(SelectStepTestCase):
179     step = booking_workflow.SWConfig_Select
180
181     def add_to_repo(self, repo):
182         repo.el[repo.SESSION_USER] = self.user
183         repo.el[repo.SELECTED_RESOURCE_TEMPLATE] = self.conf.grb
184
185     @classmethod
186     def setUpTestData(cls):
187         super().setUpTestData()
188         cls.conf = TestConfig(usr=cls.user)
189         host_map = {"host1": cls.conf.generic_host}
190         config_bundle = make_config_bundle(cls.conf.grb, cls.conf.user, cls.conf.topology, host_map)[0]
191         cls.obj_id = config_bundle.id
192
193
194 class OPNFVSelectTestCase(SelectStepTestCase):
195     step = booking_workflow.OPNFV_Select
196
197     def add_to_repo(self, repo):
198         repo.el[repo.SELECTED_CONFIG_BUNDLE] = self.config_bundle
199
200     @classmethod
201     def setUpTestData(cls):
202         super().setUpTestData()
203         conf = TestConfig(usr=cls.user)
204         host_map = {"host1": conf.generic_host}
205         cls.config_bundle, opnfv_config = make_config_bundle(conf.grb, conf.user, conf.topology, host_map)
206         cls.obj_id = opnfv_config.id
207
208
209 class BookingMetaTestCase(StepTestCase):
210     step = booking_workflow.Booking_Meta
211     post_data = {
212         "length": 14,
213         "purpose": "Testing",
214         "project": "Lab as a Service",
215         "users": ["[-1]"]
216     }
217
218     def add_to_repo(self, repo):
219         repo.el[repo.SESSION_MANAGER] = mock.MagicMock()
220
221     @classmethod
222     def setUpTestData(cls):
223         super().setUpTestData()
224         new_user = make_user(username="collaborator", email="different@mail.com")
225         new_user_prof = make_user_profile(user=new_user)
226         data = "[" + str(new_user_prof.id) + "]"  # list of IDs
227         cls.post_data['users'] = [data]
228
229
230 class ConfigResourceSelectTestCase(SelectStepTestCase):
231     step = sw_bundle_workflow.SWConf_Resource_Select
232
233     def add_to_repo(self, repo):
234         repo.el[repo.SESSION_USER] = self.user
235
236     @classmethod
237     def setUpTestData(cls):
238         super().setUpTestData()
239         conf = TestConfig(usr=cls.user)
240         cls.obj_id = conf.grb.id
241
242
243 class DefineSoftwareTestCase(StepTestCase):
244     step = sw_bundle_workflow.Define_Software
245     post_data = {
246         "form-0-image": 1,
247         "headnode": 1,
248         "form-0-headnode": "",
249         "form-TOTAL_FORMS": 1,
250         "form-INITIAL_FORMS": 1,
251         "form-MIN_NUM_FORMS": 0,
252         "form-MAX_NUM_FORMS": 1000,
253     }
254
255     def add_to_repo(self, repo):
256         repo.el[repo.SELECTED_RESOURCE_TEMPLATE] = self.conf.grb
257
258     @classmethod
259     def setUpTestData(cls):
260         super().setUpTestData()
261         cls.conf = TestConfig(usr=cls.user)
262
263
264 class ConfigSoftwareTestCase(StepTestCase):
265     step = sw_bundle_workflow.Config_Software
266     post_data = {
267         "name": "config_bundle",
268         "description": "My Config Bundle"
269     }