def cancel_results_from_testrun(testrun_id): """Cancel all results that are scheduled for this testrun.""" testrun = Testrun.objects(id=testrun_id).first() results_to_cancel = Result.objects(testrun__testrunId=testrun.id, status='NO_RESULT', runstatus__in=['SCHEDULED', 'TO_BE_RUN']) for result in results_to_cancel: cancel_individual_result(result.id) return JsonResponse(Result.objects(testrun__testrunId=testrun.id, status="FINISHED", runstatus="SKIPPED"))
def cancel_individual_result(result_id): """Reschedule a single result, only works on a result that was originally scheduled.""" orig = Result.objects(id=result_id).first() orig_status = orig.status if orig_status == "NO_RESULT": decrement_orig_status_by = "dec__summary__resultsByStatus__" + orig_status increment_skipped_status_by = "inc__summary__resultsByStatus__SKIPPED" Testrun.objects(id=orig.testrun.testrunId).update_one(**{decrement_orig_status_by: 1, increment_skipped_status_by: 1}) Result.objects(id=result_id).update(runstatus="FINISHED", status="SKIPPED", reason="Run cancelled from slick.") orig.reload() return JsonResponse(orig)
def get_scheduled_results(project, hostname): """Get scheduled tests and assign to a hostname.""" proj = get_project(project) args = request.args.to_dict() limit = 10 orderby = 'recorded' if 'limit' in args: limit = int(args['limit']) if 'orderby' in args: orderby = args['orderby'] Result.objects(project__id=proj.id, runstatus='SCHEDULED').order_by(orderby).limit(limit).update(runstatus='TO_BE_RUN', hostname=hostname) return JsonResponse(Result.objects(project__id=proj.id, status='NO_RESULT', runstatus='TO_BE_RUN', hostname=hostname).order_by(orderby))
def reschedule_individual_result(result_id): """Reschedule a single result, only works on a result that was originally scheduled.""" orig = Result.objects(id=result_id).first() orig_status = orig.status if orig_status != "NO_RESULT": decrement_orig_status_by = "dec__summary__resultsByStatus__" + orig_status increment_noresult_status_by = "inc__summary__resultsByStatus__NO_RESULT" Testrun.objects(id=orig.testrun.testrunId).update_one(**{decrement_orig_status_by: 1, increment_noresult_status_by: 1}) Result.objects(id=result_id).update(log=[], files=[], runstatus="SCHEDULED", status="NO_RESULT", unset__hostname=True, unset__started=True, unset__finished=True, unset__runlength=True, unset__reason=True) orig.reload() return JsonResponse(orig)
def find_history(result): assert isinstance(result, Result) estimated_runtime = 1 history = [] # other results with the same Test, Testplan, Environment, Release try: query = {"testcase__testcaseId": result.testcase.testcaseId, "recorded__lt":result.recorded} if hasattr(result, 'config') and result.config is not None: query['config__configId'] = result.config.configId else: query['config__exists'] = False if os.environ.get('HISTORY_IGNORE_RELEASE', 'false').lower() == 'true': pass elif hasattr(result, 'release') and result.release is not None: query['release__releaseId'] = result.release.releaseId else: query['release__exists'] = False if hasattr(result.testrun, 'testplanId') and result.testrun.testplanId is not None: query['testrun__testplanId'] = result.testrun.testplanId else: query['testrun__testplanId__exists'] = False for hresult in Result.objects(**query).fields(id=1, status=1, recorded=1, build=1, started=1, finished=1).order_by('-recorded').limit(10): if hresult.started and hresult.finished: hist_length = int(math.ceil((hresult.finished - hresult.started).total_seconds())) if hist_length > estimated_runtime: estimated_runtime = hist_length history.append(create_result_reference(hresult)) except: logger = logging.getLogger('slickqaweb.api.result.find_history') logger.error("Error in finding history", exc_info=sys.exc_info()) return history, estimated_runtime
def update_result(result_id): """Update an individual result.""" orig = Result.objects(id=result_id).first() update_event = events.UpdateEvent(before=orig) update = read_request() print((repr(update))) if 'status' in update and update['status'] != None and update['status'] != orig.status: atomic_update = { 'dec__summary__resultsByStatus__' + orig.status: 1, 'inc__summary__resultsByStatus__' + update['status']: 1 } update_testrun_event = None testrun = None if app.config['events']: testrun = Testrun.objects(id=orig.testrun.testrunId).first() update_testrun_event = events.UpdateEvent(before=testrun) Testrun.objects(id=orig.testrun.testrunId).update_one(**atomic_update) if app.config['events']: testrun.reload() update_testrun_event.after(testrun) deserialize_that(update, orig) apply_triage_notes(orig) orig.save() update_event.after(orig) return JsonResponse(orig)
def find_history(result): assert isinstance(result, Result) history = [] # other results with the same Test, Testplan, Environment, Release try: query = {"testcase__testcaseId": result.testcase.testcaseId, "recorded__lt":result.recorded} if hasattr(result, 'config') and result.config is not None: query['config__configId'] = result.config.configId else: query['config__exists'] = False if hasattr(result, 'release') and result.release is not None: query['release__releaseId'] = result.release.releaseId else: query['release__exists'] = False if hasattr(result.testrun, 'testplanId') and result.testrun.testplanId is not None: query['testrun__testplanId'] = result.testrun.testplanId else: query['testrun__testplanId__exists'] = False for hresult in Result.objects(**query).order_by('-recorded').limit(10): history.append(create_result_reference(hresult)) except: logger = logging.getLogger('slickqaweb.api.result.find_history') logger.error("Error in finding history", exc_info=sys.exc_info()) return history
def cancel_individual_result(result_id): """Reschedule a single result, only works on a result that was originally scheduled.""" orig = Result.objects(id=result_id).first() orig_status = orig.status if orig_status == "NO_RESULT": decrement_orig_status_by = "dec__summary__resultsByStatus__" + orig_status increment_skipped_status_by = "inc__summary__resultsByStatus__SKIPPED" Testrun.objects(id=orig.testrun.testrunId).update_one(**{decrement_orig_status_by: 1, increment_skipped_status_by: 1}) testrun = Testrun.objects(id=orig.testrun.testrunId).first() if testrun and testrun.summary.resultsByStatus.NO_RESULT == 0: # finish testrun testrun.runFinished = datetime.datetime.utcnow() testrun.state = "FINISHED" Testrun.objects(id=orig.testrun.testrunId).update_one(runFinished=testrun.runFinished, state=testrun.state) reason = request.args.get("reason") if request.args.get("reason") else "Run cancelled from slick." Result.objects(id=result_id).update(runstatus="FINISHED", status="SKIPPED", reason=reason) orig.reload() return JsonResponse(orig)
def reschedule_results_with_status_on_testrun(testrun_id, status): """Reschedule all results with a particular status for a testrun.""" testrun = Testrun.objects(id=testrun_id).first() results_to_reschedule = Result.objects(testrun__testrunId=testrun.id, status=status) for result in results_to_reschedule: reschedule_individual_result(result.id) # how_many = Result.objects(testrun__testrunId=testrun.id, status=status).update(log=[], files=[], # runstatus="SCHEDULED", # status="NO_RESULT", # unset__hostname=True, # unset__started=True, # unset__finished=True, # unset__runlength=True, # unset__reason=True) # setattr(testrun.summary.resultsByStatus, status, getattr(testrun.summary.resultsByStatus, status) - how_many) # testrun.summary.resultsByStatus.NO_RESULT += how_many # testrun.save() return JsonResponse(Result.objects(testrun__testrunId=testrun.id, status="NO_RESULT", runstatus="SCHEDULED"))
def add_stored_file_to_result(result_id): new_stored_file = deserialize_that(read_request(), StoredFile()) new_stored_file.chunkSize = 262144 new_stored_file.save() orig = Result.objects(id=result_id).first() if not hasattr(orig, 'files') or orig.files is None: orig.files = [] orig.files.append(new_stored_file) orig.save() return JsonResponse(new_stored_file)
def schedule_more_results(project, hostname): """Mark tests as scheduled for a particular hostname, only return those tests.""" proj = get_project(project) args = request.args.to_dict() limit = 10 orderby = 'recorded' if 'limit' in args: limit = int(args['limit']) if 'orderby' in args: orderby = args['orderby'] results_to_schedule = Result.objects(project__id=proj.id, runstatus='SCHEDULED').order_by(orderby).limit(limit) scheduled_results = [] for result in results_to_schedule: assert isinstance(result, Result) result_id = result.id number_of_updated = Result.objects(id=result_id, runstatus='SCHEDULED').update(runstatus='TO_BE_RUN', hostname=hostname) if number_of_updated > 0: result.reload() scheduled_results.append(result) return JsonResponse(scheduled_results)
def cancel_results_for_build(project_name, release_name, build_name): """Cancel all results that are scheduled for this build.""" project_id, release_id, build_id = Project.lookup_project_release_build_ids(project_name, release_name, build_name) canceled_results = [] if build_id is None: return JsonResponse(None) for testrun in Testrun.objects(build__buildId=build_id).order_by("-dateCreated"): results_to_cancel = Result.objects(testrun__testrunId=testrun.id, status='NO_RESULT', runstatus__in=['SCHEDULED', 'TO_BE_RUN']) canceled_results.extend(results_to_cancel) for result in results_to_cancel: cancel_individual_result(result.id) return JsonResponse(canceled_results)
def reschedule_results_with_status_on_build(project_name, release_name, build_name, status): """Reschedule all results with a particular status for a build.""" project_id, release_id, build_id = Project.lookup_project_release_build_ids(project_name, release_name, build_name) rescheduled_results = [] if build_id is None: return JsonResponse(None) for testrun in Testrun.objects(build__buildId=build_id).order_by("-dateCreated"): results_to_reschedule = Result.objects(testrun__testrunId=testrun.id, status=status) rescheduled_results.extend(results_to_reschedule) for result in results_to_reschedule: reschedule_individual_result(result.id) return JsonResponse(rescheduled_results)
def add_to_log(result_id): """Append log entries to a result.""" orig = Result.objects(id=result_id).first() if not hasattr(orig, 'log') or orig.log is None: orig.log = [] list_of_log_entries = read_request() if isinstance(list_of_log_entries, list): for entry_json in list_of_log_entries: orig.log.append(deserialize_that(entry_json, LogEntry())) else: orig.log.append(deserialize_that(list_of_log_entries, LogEntry())) orig.save() return JsonResponse(len(orig.log))
def reschedule_individual_result(result_id): """Reschedule a single result, only works on a result that was originally scheduled.""" orig = Result.objects(id=result_id).first() orig_status = orig.status log = [] if orig.log: log = orig.log if 'retry_count' in orig.attributes: orig.attributes['retry_count'] = str(int(orig.attributes['retry_count']) + 1) else: orig.attributes['retry_count'] = "1" if 'max_retry' not in orig.attributes: orig.attributes['max_retry'] = "3" if orig_status != "NO_RESULT": decrement_orig_status_by = "dec__summary__resultsByStatus__" + orig_status increment_noresult_status_by = "inc__summary__resultsByStatus__NO_RESULT" Testrun.objects(id=orig.testrun.testrunId).update_one(**{decrement_orig_status_by: 1, increment_noresult_status_by: 1}) log.append({"entryTime": datetime.datetime.utcnow(), "level": "INFO", "loggerName": "slick.note", "message": "Rescheduled. Count: {}. Max: {} {} {}".format(orig.attributes['retry_count'], orig.attributes['max_retry'], orig.hostname, orig.reason), "exceptionMessage": ""}) Result.objects(id=result_id).update(log=log, files=[], links=[], runstatus="SCHEDULED", status="NO_RESULT", recorded=datetime.datetime.utcnow(), unset__hostname=True, unset__started=True, unset__finished=True, unset__runlength=True, unset__reason=True, attributes=orig.attributes) orig.reload() return JsonResponse(orig)
def get_result_by_id(result_id): """Get a result by id.""" return JsonResponse(Result.objects(id=result_id).first())
def get_single_scheduled_result(hostname): parameters = read_request() """:type : dict""" rawquery = {'runstatus': 'SCHEDULED', 'status': 'NO_RESULT'} update = {'set__runstatus': 'TO_BE_RUN', 'set__hostname': hostname} attr_query = dict(**parameters) if 'project' in attr_query: del attr_query['project'] if 'release' in attr_query: del attr_query['release'] if 'build' in attr_query: del attr_query['build'] if 'provides' in attr_query: del attr_query['provides'] for key, value in list(attr_query.items()): rawquery["attributes.{}".format(key)] = value project_id, release_id, build_id = Project.lookup_project_release_build_ids(parameters.get('project', None), parameters.get('release', None), parameters.get('build', None)) if project_id is not None: rawquery['project.id'] = project_id else: rawquery['project.name'] = parameters.get('project', None) if release_id is not None: rawquery['release.releaseId'] = release_id elif parameters.get('release', None) is not None: rawquery['release.name'] = parameters.get('release', None) if build_id is not None: rawquery['build.buildId'] = build_id elif parameters.get('build', None) is not None: rawquery['build.name'] = parameters.get('build', None) # if 'project' in parameters: # project = get_project(parameters["project"]) # if project is not None: # rawquery['project.id'] = project.id # else: # rawquery['project.name'] = parameters["project"] # if 'release' in parameters: # if project is not None: # release = get_release(project, parameters['release']) # if release is not None: # rawquery['release.releaseId'] = release.id # else: # rawquery['release.name'] = parameters['release'] # if 'build' in parameters: # if release is not None: # build = get_build(release, parameters['build']) # if build is not None: # rawquery['build.buildId'] = build.id # else: # rawquery['build.name'] = parameters['build'] provides = [] if 'provides' in parameters: provides = parameters['provides'] # from http://stackoverflow.com/questions/22518867/mongodb-querying-array-field-with-exclusion rawquery['requirements'] = {'$not': {'$elemMatch': {'$nin': provides}}} import mongoengine # mongoengine.QuerySet.modify() result = Result.objects(__raw__=rawquery).order_by("recorded").modify(new=True, full_response=False, **update) # query = {} # if 'project' in parameters: # query['project__name'] = parameters['project'] # if 'release' in parameters: # query['release__name'] = parameters['release'] # if 'build' in parameters: # query['build__name'] = parameters['build'] return JsonResponse(result)