def _structure_artifact_data(self, image_tag, bp, jp): log.info('Extracting metadata for jobpair', image_tag + '.') reproduced = Packager._is_jobpair_reproduced(jp) repo = bp['repo'] reproduce_successes, reproduce_attempts, stability = Packager._calc_stability(jp) failed_job = jp['failed_job'] passed_job = jp['passed_job'] builds = [bp['failed_build'], bp['passed_build']] jobs = [failed_job, passed_job] today = str(date.today()) status = 'Unreproducible' if reproduce_successes == 5: status = 'Reproducible' elif 0 < reproduce_successes < 5: status = 'Flaky' current_status = { 'time_stamp': today, 'status': status } d = { 'tag': image_tag, 'image_tag': image_tag, 'repo': repo, 'repo_mined_version': bp['repo_mined_version'], 'pr_num': int(bp['pr_num']), 'branch': bp['branch'], 'base_branch': bp['base_branch'], 'lang': [j['language'] for j in bp['failed_build']['jobs'] if j['job_id'] == failed_job['job_id']][0].title(), # Assume the build system and test framework is the same for both jobs. In some rare cases, this assumption # will not hold. 'build_system': failed_job['orig_result']['tr_build_system'] if failed_job['orig_result'] else '', 'test_framework': failed_job['orig_result']['tr_log_frameworks'] if failed_job['orig_result'] else '', 'merged_at': bp['merged_at'], 'is_error_pass': bp['is_error_pass'], 'reproduced': reproduced, 'match': Packager._calc_match_over_run(jp) if reproduced else '', 'reproduce_successes': reproduce_successes, 'reproduce_attempts': reproduce_attempts, 'stability': stability, 'creation_time': int(time.time()), # Evaluation info. 'filtered_reason': jp.get('filtered_reason', ''), # Metrics. Empty by default and will be populated later by other components during post-processing. 'metrics': {}, 'current_status': current_status } for i in range(2): job_key = 'failed_job' if i == 0 else 'passed_job' patches = {} job = jobs[i] # Find index of job in builds[i]['jobs']. job_id = job['job_id'] jobs_index = next(i for i, j in enumerate(builds[i]['jobs']) if j['job_id'] == job_id) # Add patch information if the job is Java 7 and has at least one reproduce success. job_config = builds[i]['jobs'][jobs_index]['config'] if job_config.get('jdk') in ['oraclejdk7', 'openjdk7']: # TODO: Collect patch names as each patch is applied. That is, do not wait until this method because the # patches created now may not exactly match the patches applied. patches['mvn-tls'] = today if job.get('pip_patch'): patches['pip-yaml-patch'] = today patches['remove-ppa'] = today d[job_key] = { 'base_sha': builds[i]['base_sha'], 'build_id': builds[i]['build_id'], 'build_job': [j['build_job'] for j in builds[i]['jobs'] if j['job_id'] == jobs[i]['job_id']][0], 'committed_at': builds[i]['committed_at'], 'failed_tests': jobs[i]['orig_result']['tr_log_tests_failed'] if jobs[i]['orig_result'] else '', 'job_id': job_id, 'message': builds[i]['message'], 'mismatch_attrs': jobs[i]['mismatch_attrs'], 'num_tests_failed': jobs[i]['orig_result']['tr_log_num_tests_failed'] if jobs[i]['orig_result'] else '', 'num_tests_run': jobs[i]['orig_result']['tr_log_num_tests_run'] if jobs[i]['orig_result'] else '', 'trigger_sha': builds[i]['travis_merge_sha'] if builds[i]['travis_merge_sha'] else builds[i]['head_sha'], 'is_git_repo': Packager._artifact_is_git_repo(builds[i]), 'config': job_config, 'patches': patches, 'component_versions': { 'analyzer': Utils.get_analyzer_version(), 'reproducer': Utils.get_reproducer_version(), }, } return d
def _structure_artifact_data(self, image_tag, bp, jp): log.info('Extracting metadata for jobpair', image_tag + '.') reproduced = Packager._is_jobpair_reproduced(jp) repo = bp['repo'] reproduce_successes, reproduce_attempts, stability = Packager._calc_stability(jp) failed_job = jp['failed_job'] passed_job = jp['passed_job'] builds = [bp['failed_build'], bp['passed_build']] jobs = [failed_job, passed_job] # In the case where "No files are changed", determined by our pair-classifier.py, there would not be a # classification key for that jobpair. We insert a blank template in case the artifact is populated to our # website try: classification = jp['classification'] classification = { 'test': classification['test'], 'build': classification['build'], 'code': classification['code'], 'exceptions': classification['exceptions'] } except KeyError: classification = { 'test': 'NA', 'build': 'NA', 'code': 'NA', 'exceptions': [] } today = str(date.today()) status = 'Unreproducible' if reproduce_successes == 5: status = 'Reproducible' elif 0 < reproduce_successes < 5: status = 'Flaky' current_status = { 'time_stamp': today, 'status': status } # Previously mined jobpairs that are ran through the Reproducer, for example from generated pairs, # may not contain any 'metrics' so we add add a blank template for updating try: metrics = jp['metrics'] except KeyError: metrics = {} d = { 'current_image_tag': image_tag, 'image_tag': image_tag, 'repo': repo, 'repo_mined_version': bp['repo_mined_version'], 'pr_num': int(bp['pr_num']), 'branch': bp['branch'], 'base_branch': bp['base_branch'], 'lang': [j['language'] for j in bp['failed_build']['jobs'] if j['job_id'] == failed_job['job_id']][0].title(), # Assume the build system and test framework is the same for both jobs. In some rare cases, this assumption # will not hold. 'build_system': failed_job['orig_result']['tr_build_system'] if failed_job['orig_result'] else '', 'test_framework': failed_job['orig_result']['tr_log_frameworks'] if failed_job['orig_result'] else '', 'merged_at': bp['merged_at'], 'is_error_pass': bp['is_error_pass'], 'reproduced': reproduced, 'match': Packager._calc_match_over_run(jp) if reproduced else '', 'reproduce_successes': reproduce_successes, 'reproduce_attempts': reproduce_attempts, 'stability': stability, 'creation_time': int(time.time()), # Evaluation info. 'filtered_reason': jp.get('filtered_reason', ''), 'metrics': metrics, 'current_status': current_status, 'classification': classification } for i in range(2): job_key = 'failed_job' if i == 0 else 'passed_job' patches = {} job = jobs[i] # Find index of job in builds[i]['jobs']. job_id = job['job_id'] jobs_index = next(i for i, j in enumerate(builds[i]['jobs']) if j['job_id'] == job_id) # Add patch information if the job is Java 7 and has at least one reproduce success. job_config = builds[i]['jobs'][jobs_index]['config'] if job_config.get('jdk') in ['oraclejdk7', 'openjdk7']: # TODO: Collect patch names as each patch is applied. That is, do not wait until this method because the # patches created now may not exactly match the patches applied. patches['mvn-tls'] = today if job.get('pip_patch'): patches['pip-yaml-patch'] = today patches['remove-ppa'] = today d[job_key] = { 'base_sha': builds[i]['base_sha'], 'build_id': builds[i]['build_id'], 'build_job': [j['build_job'] for j in builds[i]['jobs'] if j['job_id'] == jobs[i]['job_id']][0], 'committed_at': builds[i]['committed_at'], 'failed_tests': jobs[i]['orig_result']['tr_log_tests_failed'] if jobs[i]['orig_result'] else '', 'job_id': job_id, 'message': builds[i]['message'], 'mismatch_attrs': jobs[i]['mismatch_attrs'], 'num_tests_failed': jobs[i]['orig_result']['tr_log_num_tests_failed'] if jobs[i]['orig_result'] else '', 'num_tests_run': jobs[i]['orig_result']['tr_log_num_tests_run'] if jobs[i]['orig_result'] else '', 'trigger_sha': builds[i]['travis_merge_sha'] if builds[i]['travis_merge_sha'] else builds[i]['head_sha'], 'is_git_repo': Packager._artifact_is_git_repo(builds[i]), 'config': job_config, 'patches': patches, 'component_versions': { 'analyzer': Utils.get_analyzer_version(), 'reproducer': Utils.get_reproducer_version(), }, } return d