Merge "jjb: xci: bifrost-verify: Disable errexit when uploading logs"
[releng.git] / utils / test / testapi / opnfv_testapi / resources / scenario_handlers.py
1 import functools
2
3 from opnfv_testapi.resources import handlers
4 import opnfv_testapi.resources.scenario_models as models
5 from opnfv_testapi.tornado_swagger import swagger
6
7
8 class GenericScenarioHandler(handlers.GenericApiHandler):
9     def __init__(self, application, request, **kwargs):
10         super(GenericScenarioHandler, self).__init__(application,
11                                                      request,
12                                                      **kwargs)
13         self.table = self.db_scenarios
14         self.table_cls = models.Scenario
15
16     def set_query(self, filters):
17         query = dict()
18         elem_query = dict()
19         for k, v in filters.iteritems():
20             if k == 'scenario':
21                 query['name'] = v
22             elif k == 'installer':
23                 elem_query["installer"] = v
24             elif k == 'version':
25                 elem_query["versions.version"] = v
26             elif k == 'project':
27                 elem_query["versions.projects.project"] = v
28             else:
29                 query[k] = v
30         if elem_query:
31             query['installers'] = {'$elemMatch': elem_query}
32         return query
33
34
35 class ScenariosCLHandler(GenericScenarioHandler):
36     @swagger.operation(nickname="queryScenarios")
37     def get(self):
38         """
39             @description: Retrieve scenario(s).
40             @notes: Retrieve scenario(s)
41                 Available filters for this request are :
42                  - name : scenario name
43
44                 GET /scenarios?name=scenario_1
45             @param name: scenario name
46             @type name: L{string}
47             @in name: query
48             @required name: False
49             @param installer: installer type
50             @type installer: L{string}
51             @in installer: query
52             @required installer: False
53             @param version: version
54             @type version: L{string}
55             @in version: query
56             @required version: False
57             @param project: project name
58             @type project: L{string}
59             @in project: query
60             @required project: False
61             @return 200: all scenarios satisfy queries,
62                          empty list if no scenario is found
63             @rtype: L{Scenarios}
64         """
65
66         def _set_query():
67             query = dict()
68             elem_query = dict()
69             for k in self.request.query_arguments.keys():
70                 v = self.get_query_argument(k)
71                 if k == 'installer':
72                     elem_query["installer"] = v
73                 elif k == 'version':
74                     elem_query["versions.version"] = v
75                 elif k == 'project':
76                     elem_query["versions.projects.project"] = v
77                 else:
78                     query[k] = v
79             if elem_query:
80                 query['installers'] = {'$elemMatch': elem_query}
81             return query
82
83         self._list(query=_set_query())
84
85     @swagger.operation(nickname="createScenario")
86     def post(self):
87         """
88             @description: create a new scenario by name
89             @param body: scenario to be created
90             @type body: L{ScenarioCreateRequest}
91             @in body: body
92             @rtype: L{CreateResponse}
93             @return 200: scenario is created.
94             @raise 403: scenario already exists
95             @raise 400:  body or name not provided
96         """
97         def query():
98             return {'name': self.json_args.get('name')}
99         miss_fields = ['name']
100         self._create(miss_fields=miss_fields, query=query)
101
102
103 class ScenarioGURHandler(GenericScenarioHandler):
104     @swagger.operation(nickname='getScenarioByName')
105     def get(self, name):
106         """
107             @description: get a single scenario by name
108             @rtype: L{Scenario}
109             @return 200: scenario exist
110             @raise 404: scenario not exist
111         """
112         self._get_one(query={'name': name})
113         pass
114
115     def put(self, name):
116         pass
117
118     @swagger.operation(nickname="deleteScenarioByName")
119     def delete(self, name):
120         """
121         @description: delete a scenario by name
122         @return 200: delete success
123         @raise 404: scenario not exist:
124         """
125         self._delete(query={'name': name})
126
127
128 class ScenarioUpdater(object):
129     def __init__(self, data, body=None,
130                  installer=None, version=None, project=None):
131         self.data = data
132         self.body = body
133         self.installer = installer
134         self.version = version
135         self.project = project
136
137     def update(self, item, op):
138         updates = {
139             ('score', 'add'): self._update_requests_add_score,
140         }
141         updates[(item, op)](self.data)
142
143         return self.data.format()
144
145     def iter_installers(xstep):
146         @functools.wraps(xstep)
147         def magic(self, data):
148             [xstep(self, installer)
149              for installer in self._filter_installers(data.installers)]
150         return magic
151
152     def iter_versions(xstep):
153         @functools.wraps(xstep)
154         def magic(self, installer):
155             [xstep(self, version)
156              for version in (self._filter_versions(installer.versions))]
157         return magic
158
159     def iter_projects(xstep):
160         @functools.wraps(xstep)
161         def magic(self, version):
162             [xstep(self, project)
163              for project in (self._filter_projects(version.projects))]
164         return magic
165
166     @iter_installers
167     @iter_versions
168     @iter_projects
169     def _update_requests_add_score(self, project):
170         project.scores.append(
171             models.ScenarioScore.from_dict(self.body))
172
173     def _filter_installers(self, installers):
174         return self._filter('installer', installers)
175
176     def _filter_versions(self, versions):
177         return self._filter('version', versions)
178
179     def _filter_projects(self, projects):
180         return self._filter('project', projects)
181
182     def _filter(self, item, items):
183         return filter(
184             lambda f: getattr(f, item) == getattr(self, item),
185             items)
186
187
188 class ScenarioScoresHandler(GenericScenarioHandler):
189     @swagger.operation(nickname="addScoreRecord")
190     def post(self, scenario):
191         """
192         @description: add a new score record
193         @notes: add a new score record to a project
194             POST /api/v1/scenarios/<scenario_name>/scores? \
195                 installer=<installer_name>& \
196                 version=<version_name>& \
197                 project=<project_name>
198         @param body: score to be added
199         @type body: L{ScenarioScore}
200         @in body: body
201         @param installer: installer type
202         @type installer: L{string}
203         @in installer: query
204         @required installer: True
205         @param version: version
206         @type version: L{string}
207         @in version: query
208         @required version: True
209         @param project: project name
210         @type project: L{string}
211         @in project: query
212         @required project: True
213         @rtype: L{Scenario}
214         @return 200: score is created.
215         @raise 404:  scenario/installer/version/project not existed
216         """
217         self.installer = self.get_query_argument('installer')
218         self.version = self.get_query_argument('version')
219         self.project = self.get_query_argument('project')
220
221         filters = {'scenario': scenario,
222                    'installer': self.installer,
223                    'version': self.version,
224                    'project': self.project}
225         db_keys = ['name']
226         self._update(query=self.set_query(filters=filters), db_keys=db_keys)
227
228     def _update_requests(self, data):
229         return ScenarioUpdater(data,
230                                self.json_args,
231                                self.installer,
232                                self.version,
233                                self.project).update('score', 'add')