diff options
Diffstat (limited to 'restful_server')
-rw-r--r-- | restful_server/db.py | 41 | ||||
-rw-r--r-- | restful_server/qtip_server.py | 52 |
2 files changed, 77 insertions, 16 deletions
diff --git a/restful_server/db.py b/restful_server/db.py index 42808b80..916fc031 100644 --- a/restful_server/db.py +++ b/restful_server/db.py @@ -10,6 +10,7 @@ from datetime import datetime import uuid jobs = {} +threads = {} def create_job(args): @@ -23,8 +24,8 @@ def create_job(args): 'suite_name': args["suite_name"], 'max-minutes': args["max-minutes"], 'type': args["type"], - 'start-time': str(datetime.now()), - 'end-time': None, + 'start_time': str(datetime.now()), + 'end_time': None, 'state': 'processing', 'state_detail': [], 'result': []} @@ -33,7 +34,9 @@ def create_job(args): def delete_job(job_id): - if job_id in jobs.keys(): + if job_id in threads: + stop_thread(job_id) + if job_id in jobs: jobs[job_id]['end_time'] = str(datetime.now()) jobs[job_id]['state'] = 'terminated' return True @@ -42,23 +45,24 @@ def delete_job(job_id): def get_job_info(job_id): - if job_id in jobs.keys(): + if job_id in jobs: return jobs[job_id] else: return None -def finish_job(job_id, state): - jobs[job_id]['end-time'] = str(datetime.now()) - jobs[job_id]['state'] = state +def finish_job(job_id): + jobs[job_id]['end_time'] = str(datetime.now()) + jobs[job_id]['state'] = 'finished' + del threads[job_id] def update_job_state_detail(job_id, state_detail): - jobs[job_id][state_detail] = state_detail + jobs[job_id]['state_detail'] = state_detail def update_job_result(job_id, result): - jobs[job_id][result] = result + jobs[job_id]['result'] = result def is_job_timeout(job_id): @@ -66,3 +70,22 @@ def is_job_timeout(job_id): "%Y-%m-%d %H:%M:%S.%f") return True if jobs[job_id]['max-minutes'] * 60 < period.total_seconds()\ else False + + +def start_thread(job_id, thread, thread_stop): + threads[job_id] = {'thread': thread, + 'thread_stop': thread_stop} + thread.start() + + +def stop_thread(job_id): + if threads[job_id]['thread'].isAlive(): + threads[job_id]['thread_stop'].set() + threads[job_id]['thread'].join() + if job_id in threads: + del threads[job_id] + + +def update_benmark_state_in_state_detail(job_id, benchmark, benchmark_state): + filter(lambda x: x["benchmark"] == benchmark, + get_job_info(job_id)["state_detail"])[0]['state'] = benchmark_state diff --git a/restful_server/qtip_server.py b/restful_server/qtip_server.py index 00d598a0..ccd8978f 100644 --- a/restful_server/qtip_server.py +++ b/restful_server/qtip_server.py @@ -9,7 +9,10 @@ from flask import Flask, abort from flask_restful import Api, Resource, fields, reqparse from flask_restful_swagger import swagger +import threading +from copy import copy import db +import func.args_handler as args_handler app = Flask(__name__) @@ -89,12 +92,12 @@ class JobList(Resource): "installer_ip": The installer ip of the pod, "max-minutes": If specified, the maximum duration in minutes -for any single test iteration, default is '10', +for any single test iteration, default is '60', "pod_name": If specified, the Pod name, default is 'default', -"suite_name": If specified, Test suite name, for example 'compute', 'network', 'storage', 'all', -default is 'all' +"suite_name": If specified, Test suite name, for example 'compute', 'network', 'storage', +default is 'compute' "type": BM or VM,default is 'BM' """, "required": True, @@ -122,13 +125,48 @@ default is 'all' parser = reqparse.RequestParser() parser.add_argument('installer_type', type=str, required=True, help='Installer_type is required') parser.add_argument('installer_ip', type=str, required=True, help='Installer_ip is required') - parser.add_argument('max-minutes', type=int, required=False, default=10, help='max-minutes should be integer') + parser.add_argument('max-minutes', type=int, required=False, default=60, help='max-minutes should be integer') parser.add_argument('pod_name', type=str, required=False, default='default', help='pod_name should be string') - parser.add_argument('suite_name', type=str, required=False, default='all', help='suite_name should be string') + parser.add_argument('suite_name', type=str, required=False, default='compute', help='suite_name should be string') parser.add_argument('type', type=str, required=False, default='BM', help='type should be BM, VM and ALL') args = parser.parse_args() - ret = db.create_job(args) - return {'job_id': str(ret)} if ret else abort(409, 'message:It already has one job running now!') + if not args_handler.check_suit_in_test_list(args["suite_name"]): + return abort(404, 'message:Test Suit {0} does not exist in test_list'.format(args["suite_name"])) + if not args_handler.check_lab_name(args["pod_name"]): + return abort(404, 'message: You have specified a lab {0}\ + that is not present in test_cases'.format(args['pod_name'])) + + job_id = db.create_job(args) + if not job_id: + return abort(409, 'message:It already has one job running now!') + + benchmarks = args_handler.get_files_in_test_list(args["suite_name"], + args["type"].lower()) + test_cases = args_handler.get_files_in_test_case(args["pod_name"], + args["suite_name"], + args["type"].lower()) + benchmarks_list = filter(lambda x: x in test_cases, benchmarks) + state_detail = map(lambda x: {'benchmark': x, 'state': 'idle'}, benchmarks_list) + db.update_job_state_detail(job_id, copy(state_detail)) + thread_stop = threading.Event() + post_thread = threading.Thread(target=self.thread_post, args=(args["installer_type"], + benchmarks_list, + args["pod_name"], + args["suite_name"], + job_id, + thread_stop)) + db.start_thread(job_id, post_thread, thread_stop) + return {'job_id': str(job_id)} + + def thread_post(self, installer_type, benchmarks_list, pod_name, suite_name, job_id, stop_event): + for benchmark in benchmarks_list: + if db.is_job_timeout(job_id) or stop_event.is_set(): + break + db.update_benmark_state_in_state_detail(job_id, benchmark, 'processing') + args_handler.prepare_and_run_benchmark(installer_type, '/home', + args_handler.get_benchmark_path(pod_name, suite_name, benchmark)) + db.update_benmark_state_in_state_detail(job_id, benchmark, 'finished') + db.finish_job(job_id) api.add_resource(JobList, '/api/v1.0/jobs') |