add yardstick iruya 9.0.0 release notes
[yardstick.git] / api / resources / v2 / tasks.py
1 ##############################################################################
2 # Copyright (c) 2017 Huawei Technologies Co.,Ltd.
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 import uuid
10 import logging
11 import os
12 import errno
13 from datetime import datetime
14
15 from oslo_serialization import jsonutils
16
17 from api import ApiResource
18 from api.database.v2.handlers import V2TaskHandler
19 from api.database.v2.handlers import V2ProjectHandler
20 from api.database.v2.handlers import V2EnvironmentHandler
21 from api.utils.thread import TaskThread
22 from yardstick.common.utils import result_handler
23 from yardstick.common.utils import change_obj_to_dict
24 from yardstick.common import constants as consts
25 from yardstick.benchmark.core.task import Task
26 from yardstick.benchmark.core import Param
27
28 LOG = logging.getLogger(__name__)
29 LOG.setLevel(logging.DEBUG)
30
31
32 class V2Tasks(ApiResource):
33
34     def get(self):
35         task_handler = V2TaskHandler()
36         tasks = [change_obj_to_dict(t) for t in task_handler.list_all()]
37
38         for t in tasks:
39             result = t['result']
40             t['result'] = jsonutils.loads(result) if result else None
41             params = t['params']
42             t['params'] = jsonutils.loads(params) if params else None
43
44         return result_handler(consts.API_SUCCESS, {'tasks': tasks})
45
46     def post(self):
47         return self._dispatch_post()
48
49     def create_task(self, args):
50         try:
51             name = args['name']
52         except KeyError:
53             return result_handler(consts.API_ERROR, 'name must be provided')
54
55         try:
56             project_id = args['project_id']
57         except KeyError:
58             return result_handler(consts.API_ERROR, 'project_id must be provided')
59
60         task_id = str(uuid.uuid4())
61         create_time = datetime.now()
62         task_handler = V2TaskHandler()
63
64         LOG.info('create task in database')
65         task_init_data = {
66             'uuid': task_id,
67             'project_id': project_id,
68             'name': name,
69             'time': create_time,
70             'status': -1
71         }
72         task_handler.insert(task_init_data)
73
74         LOG.info('create task in project')
75         project_handler = V2ProjectHandler()
76         project_handler.append_attr(project_id, {'tasks': task_id})
77
78         return result_handler(consts.API_SUCCESS, {'uuid': task_id})
79
80
81 class V2Task(ApiResource):
82
83     def get(self, task_id):
84         try:
85             uuid.UUID(task_id)
86         except ValueError:
87             return result_handler(consts.API_ERROR, 'invalid task id')
88
89         task_handler = V2TaskHandler()
90         try:
91             task = task_handler.get_by_uuid(task_id)
92         except ValueError:
93             return result_handler(consts.API_ERROR, 'no such task id')
94
95         task_info = change_obj_to_dict(task)
96         result = task_info['result']
97         task_info['result'] = jsonutils.loads(result) if result else None
98
99         params = task_info['params']
100         task_info['params'] = jsonutils.loads(params) if params else None
101
102         return result_handler(consts.API_SUCCESS, {'task': task_info})
103
104     def delete(self, task_id):
105         try:
106             uuid.UUID(task_id)
107         except ValueError:
108             return result_handler(consts.API_ERROR, 'invalid task id')
109
110         task_handler = V2TaskHandler()
111         try:
112             project_id = task_handler.get_by_uuid(task_id).project_id
113         except ValueError:
114             return result_handler(consts.API_ERROR, 'no such task id')
115
116         LOG.info('delete task in database')
117         task_handler.delete_by_uuid(task_id)
118
119         project_handler = V2ProjectHandler()
120         project = project_handler.get_by_uuid(project_id)
121
122         if project.tasks:
123             LOG.info('update tasks in project')
124             new_task_list = project.tasks.split(',')
125             new_task_list.remove(task_id)
126             if new_task_list:
127                 new_tasks = ','.join(new_task_list)
128             else:
129                 new_tasks = None
130             project_handler.update_attr(project_id, {'tasks': new_tasks})
131
132         return result_handler(consts.API_SUCCESS, {'task': task_id})
133
134     def put(self, task_id):
135         try:
136             uuid.UUID(task_id)
137         except ValueError:
138             return result_handler(consts.API_ERROR, 'invalid task id')
139
140         task_handler = V2TaskHandler()
141         try:
142             task_handler.get_by_uuid(task_id)
143         except ValueError:
144             return result_handler(consts.API_ERROR, 'no such task id')
145
146         return self._dispatch_post(task_id=task_id)
147
148     def add_environment(self, args):
149
150         task_id = args['task_id']
151         try:
152             environment_id = args['environment_id']
153         except KeyError:
154             return result_handler(consts.API_ERROR, 'environment_id must be provided')
155
156         try:
157             uuid.UUID(environment_id)
158         except ValueError:
159             return result_handler(consts.API_ERROR, 'invalid environment id')
160
161         environment_handler = V2EnvironmentHandler()
162         try:
163             environment_handler.get_by_uuid(environment_id)
164         except ValueError:
165             return result_handler(consts.API_ERROR, 'no such environment id')
166
167         LOG.info('update environment_id in task')
168         task_handler = V2TaskHandler()
169         task_handler.update_attr(task_id, {'environment_id': environment_id})
170
171         return result_handler(consts.API_SUCCESS, {'uuid': task_id})
172
173     def add_params(self, args):
174         task_id = args['task_id']
175         try:
176             params = args['params']
177         except KeyError:
178             return result_handler(consts.API_ERROR, 'params must be provided')
179
180         LOG.info('update params info in task')
181
182         task_handler = V2TaskHandler()
183         task_update_data = {'params': jsonutils.dumps(params)}
184         task_handler.update_attr(task_id, task_update_data)
185
186         return result_handler(consts.API_SUCCESS, {'uuid': task_id})
187
188     def add_case(self, args):
189         task_id = args['task_id']
190         try:
191             name = args['case_name']
192         except KeyError:
193             return result_handler(consts.API_ERROR, 'case_name must be provided')
194
195         try:
196             content = args['case_content']
197         except KeyError:
198             return result_handler(consts.API_ERROR, 'case_content must be provided')
199
200         LOG.info('update case info in task')
201         task_handler = V2TaskHandler()
202         task_update_data = {
203             'case_name': name,
204             'content': content,
205             'suite': False
206         }
207         task_handler.update_attr(task_id, task_update_data)
208
209         return result_handler(consts.API_SUCCESS, {'uuid': task_id})
210
211     def add_suite(self, args):
212         task_id = args['task_id']
213         try:
214             name = args['suite_name']
215         except KeyError:
216             return result_handler(consts.API_ERROR, 'suite_name must be provided')
217
218         try:
219             content = args['suite_content']
220         except KeyError:
221             return result_handler(consts.API_ERROR, 'suite_content must be provided')
222
223         LOG.info('update suite info in task')
224         task_handler = V2TaskHandler()
225         task_update_data = {
226             'case_name': name,
227             'content': content,
228             'suite': True
229         }
230         task_handler.update_attr(task_id, task_update_data)
231
232         return result_handler(consts.API_SUCCESS, {'uuid': task_id})
233
234     def run(self, args):
235         try:
236             task_id = args['task_id']
237         except KeyError:
238             return result_handler(consts.API_ERROR, 'task_id must be provided')
239
240         try:
241             uuid.UUID(task_id)
242         except ValueError:
243             return result_handler(consts.API_ERROR, 'invalid task id')
244
245         task_handler = V2TaskHandler()
246         try:
247             task = task_handler.get_by_uuid(task_id)
248         except ValueError:
249             return result_handler(consts.API_ERROR, 'no such task id')
250
251         if not task.environment_id:
252             return result_handler(consts.API_ERROR, 'environment not set')
253
254         if not task.case_name or not task.content:
255             return result_handler(consts.API_ERROR, 'case not set')
256
257         if task.status == 0:
258             return result_handler(consts.API_ERROR, 'task is already running')
259
260         with open('/tmp/{}.yaml'.format(task.case_name), 'w') as f:
261             f.write(task.content)
262
263         data = {
264             'inputfile': ['/tmp/{}.yaml'.format(task.case_name)],
265             'task_id': task_id,
266             'task-args': task.params
267         }
268         if task.suite:
269             data.update({'suite': True})
270
271         LOG.info('start task thread')
272         param = Param(data)
273         task_thread = TaskThread(Task().start, param, task_handler)
274         task_thread.start()
275
276         return result_handler(consts.API_SUCCESS, {'uuid': task_id})
277
278
279 class V2TaskLog(ApiResource):
280
281     def get(self, task_id):
282         try:
283             uuid.UUID(task_id)
284         except ValueError:
285             return result_handler(consts.API_ERROR, 'invalid task id')
286
287         task_handler = V2TaskHandler()
288         try:
289             task = task_handler.get_by_uuid(task_id)
290         except ValueError:
291             return result_handler(consts.API_ERROR, 'no such task id')
292
293         index = int(self._get_args().get('index', 0))
294
295         try:
296             with open(os.path.join(consts.TASK_LOG_DIR, '{}.log'.format(task_id))) as f:
297                 f.seek(index)
298                 data = f.readlines()
299                 index = f.tell()
300         except OSError as e:
301             if e.errno == errno.ENOENT:
302                 return result_handler(consts.API_ERROR, 'log file does not exist')
303             return result_handler(consts.API_ERROR, 'error with log file')
304
305         return_data = {
306             'index': index,
307             'data': data
308         }
309
310         return result_handler(task.status, return_data)