update installer under scenario
[releng.git] / utils / test / testapi / opnfv_testapi / tests / unit / resources / test_scenario.py
1 import functools
2 import httplib
3 import json
4 import os
5
6 from datetime import datetime
7
8 from opnfv_testapi.common import message
9 import opnfv_testapi.resources.scenario_models as models
10 from opnfv_testapi.tests.unit.resources import test_base as base
11
12
13 def _none_default(check, default):
14     return check if check else default
15
16
17 class TestScenarioBase(base.TestBase):
18     def setUp(self):
19         super(TestScenarioBase, self).setUp()
20         self.get_res = models.Scenario
21         self.list_res = models.Scenarios
22         self.basePath = '/api/v1/scenarios'
23         self.req_d = self._load_request('scenario-c1.json')
24         self.req_2 = self._load_request('scenario-c2.json')
25
26     def tearDown(self):
27         pass
28
29     def assert_body(self, project, req=None):
30         pass
31
32     @staticmethod
33     def _load_request(f_req):
34         abs_file = os.path.join(os.path.dirname(__file__), f_req)
35         with open(abs_file, 'r') as f:
36             loader = json.load(f)
37             f.close()
38         return loader
39
40     def create_return_name(self, req):
41         _, res = self.create(req)
42         return res.href.split('/')[-1]
43
44     def assert_res(self, code, scenario, req=None):
45         self.assertEqual(code, httplib.OK)
46         if req is None:
47             req = self.req_d
48         self.assertIsNotNone(scenario._id)
49         self.assertIsNotNone(scenario.creation_date)
50         self.assertEqual(scenario, models.Scenario.from_dict(req))
51
52     @staticmethod
53     def set_query(*args):
54         uri = ''
55         for arg in args:
56             uri += arg + '&'
57         return uri[0: -1]
58
59     def get_and_assert(self, name):
60         code, body = self.get(name)
61         self.assert_res(code, body, self.req_d)
62
63
64 class TestScenarioCreate(TestScenarioBase):
65     def test_withoutBody(self):
66         (code, body) = self.create()
67         self.assertEqual(code, httplib.BAD_REQUEST)
68
69     def test_emptyName(self):
70         req_empty = models.ScenarioCreateRequest('')
71         (code, body) = self.create(req_empty)
72         self.assertEqual(code, httplib.BAD_REQUEST)
73         self.assertIn(message.missing('name'), body)
74
75     def test_noneName(self):
76         req_none = models.ScenarioCreateRequest(None)
77         (code, body) = self.create(req_none)
78         self.assertEqual(code, httplib.BAD_REQUEST)
79         self.assertIn(message.missing('name'), body)
80
81     def test_success(self):
82         (code, body) = self.create_d()
83         self.assertEqual(code, httplib.OK)
84         self.assert_create_body(body)
85
86     def test_alreadyExist(self):
87         self.create_d()
88         (code, body) = self.create_d()
89         self.assertEqual(code, httplib.FORBIDDEN)
90         self.assertIn(message.exist_base, body)
91
92
93 class TestScenarioGet(TestScenarioBase):
94     def setUp(self):
95         super(TestScenarioGet, self).setUp()
96         self.scenario_1 = self.create_return_name(self.req_d)
97         self.scenario_2 = self.create_return_name(self.req_2)
98
99     def test_getByName(self):
100         self.get_and_assert(self.scenario_1)
101
102     def test_getAll(self):
103         self._query_and_assert(query=None, reqs=[self.req_d, self.req_2])
104
105     def test_queryName(self):
106         query = self.set_query('name=nosdn-nofeature-ha')
107         self._query_and_assert(query, reqs=[self.req_d])
108
109     def test_queryInstaller(self):
110         query = self.set_query('installer=apex')
111         self._query_and_assert(query, reqs=[self.req_d])
112
113     def test_queryVersion(self):
114         query = self.set_query('version=master')
115         self._query_and_assert(query, reqs=[self.req_d])
116
117     def test_queryProject(self):
118         query = self.set_query('project=functest')
119         self._query_and_assert(query, reqs=[self.req_d, self.req_2])
120
121     # close due to random fail, open again after solve it in another patch
122     # def test_queryCombination(self):
123     #     query = self._set_query('name=nosdn-nofeature-ha',
124     #                             'installer=apex',
125     #                             'version=master',
126     #                             'project=functest')
127     #
128     #     self._query_and_assert(query, reqs=[self.req_d])
129
130     def _query_and_assert(self, query, found=True, reqs=None):
131         code, body = self.query(query)
132         if not found:
133             self.assertEqual(code, httplib.OK)
134             self.assertEqual(0, len(body.scenarios))
135         else:
136             self.assertEqual(len(reqs), len(body.scenarios))
137             for req in reqs:
138                 for scenario in body.scenarios:
139                     if req['name'] == scenario.name:
140                         self.assert_res(code, scenario, req)
141
142
143 class TestScenarioDelete(TestScenarioBase):
144     def test_notFound(self):
145         code, body = self.delete('notFound')
146         self.assertEqual(code, httplib.NOT_FOUND)
147
148     def test_success(self):
149         scenario = self.create_return_name(self.req_d)
150         code, _ = self.delete(scenario)
151         self.assertEqual(code, httplib.OK)
152         code, _ = self.get(scenario)
153         self.assertEqual(code, httplib.NOT_FOUND)
154
155
156 class TestScenarioUpdate(TestScenarioBase):
157     def setUp(self):
158         super(TestScenarioUpdate, self).setUp()
159         self.scenario = self.create_return_name(self.req_d)
160         self.scenario_2 = self.create_return_name(self.req_2)
161         self.update_url = ''
162         self.scenario_url = '/api/v1/scenarios/{}'.format(self.scenario)
163         self.installer = self.req_d['installers'][0]['installer']
164         self.version = self.req_d['installers'][0]['versions'][0]['version']
165         self.locate_project = 'installer={}&version={}&project={}'.format(
166             self.installer,
167             self.version,
168             'functest')
169
170     def update_url_fixture(item):
171         def _update_url_fixture(xstep):
172             def wrapper(self, *args, **kwargs):
173                 self.update_url = '{}/{}'.format(self.scenario_url, item)
174                 locator = None
175                 if item in ['projects', 'owner']:
176                     locator = 'installer={}&version={}'.format(
177                         self.installer,
178                         self.version)
179                 elif item in ['versions']:
180                     locator = 'installer={}'.format(
181                         self.installer)
182
183                 if locator:
184                     self.update_url = '{}?{}'.format(self.update_url, locator)
185
186                 xstep(self, *args, **kwargs)
187             return wrapper
188         return _update_url_fixture
189
190     def update_partial(operate, expected):
191         def _update_partial(set_update):
192             @functools.wraps(set_update)
193             def wrapper(self):
194                 update = set_update(self)
195                 code, body = getattr(self, operate)(update)
196                 getattr(self, expected)(code)
197             return wrapper
198         return _update_partial
199
200     @update_partial('_add', '_success')
201     def test_addScore(self):
202         add = models.ScenarioScore(date=str(datetime.now()), score='11/12')
203         projects = self.req_d['installers'][0]['versions'][0]['projects']
204         functest = filter(lambda f: f['project'] == 'functest', projects)[0]
205         functest['scores'].append(add.format())
206         self.update_url = '{}/scores?{}'.format(self.scenario_url,
207                                                 self.locate_project)
208
209         return add
210
211     @update_partial('_add', '_success')
212     def test_addTrustIndicator(self):
213         add = models.ScenarioTI(date=str(datetime.now()), status='gold')
214         projects = self.req_d['installers'][0]['versions'][0]['projects']
215         functest = filter(lambda f: f['project'] == 'functest', projects)[0]
216         functest['trust_indicators'].append(add.format())
217         self.update_url = '{}/trust_indicators?{}'.format(self.scenario_url,
218                                                           self.locate_project)
219
220         return add
221
222     @update_partial('_add', '_success')
223     def test_addCustoms(self):
224         adds = ['odl', 'parser', 'vping_ssh']
225         projects = self.req_d['installers'][0]['versions'][0]['projects']
226         functest = filter(lambda f: f['project'] == 'functest', projects)[0]
227         functest['customs'] = list(set(functest['customs'] + adds))
228         self.update_url = '{}/customs?{}'.format(self.scenario_url,
229                                                  self.locate_project)
230         return adds
231
232     @update_partial('_update', '_success')
233     def test_updateCustoms(self):
234         updates = ['odl', 'parser', 'vping_ssh']
235         projects = self.req_d['installers'][0]['versions'][0]['projects']
236         functest = filter(lambda f: f['project'] == 'functest', projects)[0]
237         functest['customs'] = updates
238         self.update_url = '{}/customs?{}'.format(self.scenario_url,
239                                                  self.locate_project)
240
241         return updates
242
243     @update_partial('_delete', '_success')
244     def test_deleteCustoms(self):
245         deletes = ['vping_ssh']
246         projects = self.req_d['installers'][0]['versions'][0]['projects']
247         functest = filter(lambda f: f['project'] == 'functest', projects)[0]
248         functest['customs'] = ['healthcheck']
249         self.update_url = '{}/customs?{}'.format(self.scenario_url,
250                                                  self.locate_project)
251
252         return deletes
253
254     @update_url_fixture('projects')
255     @update_partial('_add', '_success')
256     def test_addProjects_succ(self):
257         add = models.ScenarioProject(project='qtip').format()
258         self.req_d['installers'][0]['versions'][0]['projects'].append(add)
259         return [add]
260
261     @update_url_fixture('projects')
262     @update_partial('_add', '_conflict')
263     def test_addProjects_already_exist(self):
264         add = models.ScenarioProject(project='functest').format()
265         return [add]
266
267     @update_url_fixture('projects')
268     @update_partial('_add', '_bad_request')
269     def test_addProjects_bad_schema(self):
270         add = models.ScenarioProject(project='functest').format()
271         add['score'] = None
272         return [add]
273
274     @update_url_fixture('projects')
275     @update_partial('_update', '_success')
276     def test_updateProjects_succ(self):
277         update = models.ScenarioProject(project='qtip').format()
278         self.req_d['installers'][0]['versions'][0]['projects'] = [update]
279         return [update]
280
281     @update_url_fixture('projects')
282     @update_partial('_update', '_conflict')
283     def test_updateProjects_duplicated(self):
284         update = models.ScenarioProject(project='qtip').format()
285         return [update, update]
286
287     @update_url_fixture('projects')
288     @update_partial('_update', '_bad_request')
289     def test_updateProjects_bad_schema(self):
290         update = models.ScenarioProject(project='functest').format()
291         update['score'] = None
292         return [update]
293
294     @update_url_fixture('projects')
295     @update_partial('_delete', '_success')
296     def test_deleteProjects(self):
297         deletes = ['functest']
298         projects = self.req_d['installers'][0]['versions'][0]['projects']
299         self.req_d['installers'][0]['versions'][0]['projects'] = filter(
300             lambda f: f['project'] != 'functest',
301             projects)
302         return deletes
303
304     @update_url_fixture('owner')
305     @update_partial('_update', '_success')
306     def test_changeOwner(self):
307         new_owner = 'new_owner'
308         update = models.ScenarioChangeOwnerRequest(new_owner).format()
309         self.req_d['installers'][0]['versions'][0]['owner'] = new_owner
310         return update
311
312     @update_url_fixture('versions')
313     @update_partial('_add', '_success')
314     def test_addVersions_succ(self):
315         add = models.ScenarioVersion(version='Euphrates').format()
316         self.req_d['installers'][0]['versions'].append(add)
317         return [add]
318
319     @update_url_fixture('versions')
320     @update_partial('_add', '_conflict')
321     def test_addVersions_already_exist(self):
322         add = models.ScenarioVersion(version='master').format()
323         return [add]
324
325     @update_url_fixture('versions')
326     @update_partial('_add', '_bad_request')
327     def test_addVersions_bad_schema(self):
328         add = models.ScenarioVersion(version='euphrates').format()
329         add['notexist'] = None
330         return [add]
331
332     @update_url_fixture('versions')
333     @update_partial('_update', '_success')
334     def test_updateVersions_succ(self):
335         update = models.ScenarioVersion(version='euphrates').format()
336         self.req_d['installers'][0]['versions'] = [update]
337         return [update]
338
339     @update_url_fixture('versions')
340     @update_partial('_update', '_conflict')
341     def test_updateVersions_duplicated(self):
342         update = models.ScenarioVersion(version='euphrates').format()
343         return [update, update]
344
345     @update_url_fixture('versions')
346     @update_partial('_update', '_bad_request')
347     def test_updateVersions_bad_schema(self):
348         update = models.ScenarioVersion(version='euphrates').format()
349         update['not_owner'] = 'Iam'
350         return [update]
351
352     @update_url_fixture('versions')
353     @update_partial('_delete', '_success')
354     def test_deleteVersions(self):
355         deletes = ['master']
356         versions = self.req_d['installers'][0]['versions']
357         self.req_d['installers'][0]['versions'] = filter(
358             lambda f: f['version'] != 'master',
359             versions)
360         return deletes
361
362     @update_url_fixture('installers')
363     @update_partial('_add', '_success')
364     def test_addInstallers_succ(self):
365         add = models.ScenarioInstaller(installer='daisy').format()
366         self.req_d['installers'].append(add)
367         return [add]
368
369     @update_url_fixture('installers')
370     @update_partial('_add', '_conflict')
371     def test_addInstallers_already_exist(self):
372         add = models.ScenarioInstaller(installer='apex').format()
373         return [add]
374
375     @update_url_fixture('installers')
376     @update_partial('_add', '_bad_request')
377     def test_addInstallers_bad_schema(self):
378         add = models.ScenarioInstaller(installer='daisy').format()
379         add['not_exist'] = 'not_exist'
380         return [add]
381
382     @update_url_fixture('installers')
383     @update_partial('_update', '_success')
384     def test_updateInstallers_succ(self):
385         update = models.ScenarioInstaller(installer='daisy').format()
386         self.req_d['installers'] = [update]
387         return [update]
388
389     @update_url_fixture('installers')
390     @update_partial('_update', '_conflict')
391     def test_updateInstallers_duplicated(self):
392         update = models.ScenarioInstaller(installer='daisy').format()
393         return [update, update]
394
395     @update_url_fixture('installers')
396     @update_partial('_update', '_bad_request')
397     def test_updateInstallers_bad_schema(self):
398         update = models.ScenarioInstaller(installer='daisy').format()
399         update['not_exist'] = 'not_exist'
400         return [update]
401
402     @update_url_fixture('installers')
403     @update_partial('_delete', '_success')
404     def test_deleteInstallers(self):
405         deletes = ['apex']
406         installers = self.req_d['installers']
407         self.req_d['installers'] = filter(
408             lambda f: f['installer'] != 'apex',
409             installers)
410         return deletes
411
412     def _add(self, update_req):
413         return self.post_direct_url(self.update_url, update_req)
414
415     def _update(self, update_req):
416         return self.update_direct_url(self.update_url, update_req)
417
418     def _delete(self, update_req):
419         return self.delete_direct_url(self.update_url, update_req)
420
421     def _success(self, status):
422         self.assertEqual(status, httplib.OK)
423         self.get_and_assert(self.req_d['name'])
424
425     def _forbidden(self, status):
426         self.assertEqual(status, httplib.FORBIDDEN)
427
428     def _bad_request(self, status):
429         self.assertEqual(status, httplib.BAD_REQUEST)
430
431     def _conflict(self, status):
432         self.assertEqual(status, httplib.CONFLICT)