def _show_analysis_results(self, uid, selected_analysis=None, root_uid=None): root_uid = none_to_none(root_uid) other_versions = None uids_for_comparison = get_comparison_uid_list_from_session() analysis_filter = [selected_analysis] if selected_analysis else [] with ConnectTo(FrontEndDbInterface, self._config) as sc: file_obj = sc.get_object(uid, analysis_filter=analysis_filter) if isinstance(file_obj, Firmware): root_uid = file_obj.get_uid() other_versions = sc.get_other_versions_of_firmware(file_obj) if file_obj: view = self._get_analysis_view(selected_analysis) if selected_analysis else get_template_as_string('show_analysis.html') with ConnectTo(FrontEndDbInterface, self._config) as sc: summary_of_included_files = sc.get_summary(file_obj, selected_analysis) if selected_analysis else None analysis_of_included_files_complete = not sc.all_uids_found_in_database(list(file_obj.files_included)) firmware_including_this_fo = self._get_firmware_ids_including_this_file(file_obj) with ConnectTo(InterComFrontEndBinding, self._config) as sc: analysis_plugins = sc.get_available_analysis_plugins() return render_template_string(view, uid=uid, firmware=file_obj, selected_analysis=selected_analysis, all_analyzed_flag=analysis_of_included_files_complete, summary_of_included_files=summary_of_included_files, root_uid=root_uid, firmware_including_this_fo=firmware_including_this_fo, analysis_plugin_dict=analysis_plugins, other_versions=other_versions, uids_for_comparison=uids_for_comparison, user_has_admin_clearance=user_has_privilege(current_user, privilege='delete')) else: return render_template('uid_not_found.html', uid=uid)
def get(self, uid=None): if not uid: paging, success = get_paging(request.args) if not success: return error_message(paging, self.URL, request_data=request.args) offset, limit = paging try: query = get_query(request.args) except ValueError as value_error: return error_message(str(value_error), self.URL, request_data=dict(query=request.args.get('query'))) try: with ConnectTo(FrontEndDbInterface, self.config) as connection: uids = connection.rest_get_file_object_uids(offset=offset, limit=limit, query=query) return success_message(dict(uids=uids), self.URL, dict(offset=offset, limit=limit, query=query)) except Exception: return error_message('Unknown exception on request', self.URL, dict(offset=offset, limit=limit, query=query)) else: with ConnectTo(FrontEndDbInterface, self.config) as connection: file_object = connection.get_file_object(uid) if not file_object: return error_message('No file object with UID {} found'.format(uid), self.URL, dict(uid=uid)) fitted_file_object = self._fit_file_object(file_object) return success_message(dict(file_object=fitted_file_object), self.URL, request_data=dict(uid=uid))
def _update_analysis(self, uid, update): with ConnectTo(FrontEndDbInterface, self.config) as connection: firmware = connection.get_firmware(uid) if not firmware: return error_message('No firmware with UID {} found'.format(uid), self.URL, dict(uid=uid)) unpack = 'unpacker' in update while 'unpacker' in update: update.remove('unpacker') firmware.scheduled_analysis = update with ConnectTo(InterComFrontEndBinding, self.config) as intercom: supported_plugins = intercom.get_available_analysis_plugins().keys( ) for item in update: if item not in supported_plugins: return error_message( 'Unknown analysis system \'{}\''.format(item), self.URL, dict(uid=uid, update=update)) intercom.add_re_analyze_task(firmware, unpack) if unpack: update.append('unpacker') return success_message({}, self.URL, dict(uid=uid, update=update))
def get(self, uid=None): if not uid: paging, success = get_paging(request.args) if not success: return error_message(paging, self.URL, request_data=request.args) offset, limit = paging try: recursive = get_recursive(request.args) query = get_query(request.args) except ValueError as value_error: return error_message(str(value_error), self.URL, request_data=dict(query=request.args.get('query'), recursive=request.args.get('recursive'))) if recursive and not query: return error_message('recursive search is only permissible with non-empty query', self.URL, request_data=dict(query=request.args.get('query'), recursive=request.args.get('recursive'))) try: with ConnectTo(FrontEndDbInterface, self.config) as connection: uids = connection.rest_get_firmware_uids(offset=offset, limit=limit, query=query, recursive=recursive) return success_message(dict(uids=uids), self.URL, dict(offset=offset, limit=limit, query=query, recursive=recursive)) except Exception: return error_message('Unknown exception on request', self.URL, dict(offset=offset, limit=limit, query=query, recursive=recursive)) else: summary = get_summary_flag(request.args) if summary: with ConnectTo(FrontEndDbInterface, self.config) as connection: firmware = connection.get_complete_object_including_all_summaries(uid) else: with ConnectTo(FrontEndDbInterface, self.config) as connection: firmware = connection.get_firmware(uid) if not firmware or not isinstance(firmware, Firmware): return error_message('No firmware with UID {} found'.format(uid), self.URL, dict(uid=uid)) fitted_firmware = self._fit_firmware(firmware) return success_message(dict(firmware=fitted_firmware), self.URL, request_data=dict(uid=uid))
def _app_upload(self): error = {} if request.method == 'POST': analysis_task = create_analysis_task(request) error = check_for_errors(analysis_task) if not error: fw = convert_analysis_task_to_fw_obj(analysis_task) with ConnectTo(InterComFrontEndBinding, self._config) as sc: sc.add_analysis_task(fw) return render_template('upload/upload_successful.html', uid=analysis_task['uid']) with ConnectTo(FrontEndDbInterface, self._config) as sc: device_class_list = sc.get_device_class_list() vendor_list = sc.get_vendor_list() device_name_dict = sc.get_device_name_dict() with ConnectTo(InterComFrontEndBinding, self._config) as sc: analysis_plugins = sc.get_available_analysis_plugins() analysis_presets = [key for key in self._config['default_plugins']] return render_template('upload/upload.html', device_classes=device_class_list, vendors=vendor_list, error=error, analysis_presets=analysis_presets, device_names=json.dumps(device_name_dict, sort_keys=True), analysis_plugin_dict=analysis_plugins)
def _schedule_re_analysis_task(self, uid, analysis_task, re_do): fw = convert_analysis_task_to_fw_obj(analysis_task) if re_do: with ConnectTo(AdminDbInterface, self._config) as sc: sc.delete_firmware(uid, delete_root_file=False) with ConnectTo(InterComFrontEndBinding, self._config) as sc: sc.add_re_analyze_task(fw)
def put(self): ''' The request data should have the form {"uid_list": uid_list, "<optional>redo": True} return value: the result dict from the compare ''' try: data = convert_rest_request(request.data) except TypeError as type_error: return error_message(str(type_error), self.URL, request_data=request.data) try: uid_string = ';'.join(data['uid_list']) compare_id = unify_string_list(uid_string) if 'redo' in data.keys(): redo = data['redo'] else: redo = False except Exception: # FIXME Please specify Exception types - would think at least TypeError might occur return error_message('Request should be of the form {"uid_list": uid_list, "redo": boolean}', self.URL, request_data=data) with ConnectTo(CompareDbInterface, self.config) as db_compare_service: if not db_compare_service.compare_result_is_in_db(compare_id) or redo: err = db_compare_service.object_existence_quick_check(compare_id) if err is not None: return error_message(err, self.URL, request_data=data, return_code=404) with ConnectTo(InterComFrontEndBinding, self.config) as intercom: intercom.add_compare_task(compare_id, force=redo) return success_message({'message': 'Compare started. Please use GET to get the results.'}, self.URL, request_data=data, return_code=202) return error_message('Compare already exists. Use "redo" to force re-compare.', self.URL, request_data=data, return_code=200)
def _app_show_browse_compare(self): page, per_page = self._get_page_items()[0:2] try: with ConnectTo(CompareDbInterface, self._config) as db_service: compare_list = db_service.page_compare_results(skip=per_page * (page - 1), limit=per_page) except Exception as exception: error_message = 'Could not query database: {} {}'.format( type(exception), str(exception)) logging.error(error_message) return render_template('error.html', message=error_message) with ConnectTo(CompareDbInterface, self._config) as connection: total = connection.get_total_number_of_results() pagination = self._get_pagination( page=page, per_page=per_page, total=total, record_name='compare results', ) return render_template('database/compare_browse.html', compare_list=compare_list, page=page, per_page=per_page, pagination=pagination)
def _app_show_start_compare(self): if 'uids_for_comparison' not in session or not isinstance( session['uids_for_comparison'], list) or len(session['uids_for_comparison']) < 2: return render_template('compare/error.html', error='No UIDs found for comparison') compare_id = convert_uid_list_to_compare_id( session['uids_for_comparison']) session['uids_for_comparison'] = None redo = True if request.args.get('force_recompare') else None with ConnectTo(CompareDbInterface, self._config) as sc: compare_exists = sc.compare_result_is_in_db(compare_id) if compare_exists and not redo: return redirect( url_for('/compare/<compare_id>', compare_id=compare_id)) try: with ConnectTo(CompareDbInterface, self._config) as sc: sc.check_objects_exist(compare_id) except FactCompareException as exception: return render_template('compare/error.html', error=exception.get_message()) with ConnectTo(InterComFrontEndBinding, self._config) as sc: sc.add_compare_task(compare_id, force=redo) return render_template('compare/wait.html', compare_id=compare_id)
def _download_base64_decoded_section(self, uid, section, expression_id): with ConnectTo(FrontEndDbInterface, self._config) as sc: file_obj = sc.get_object(uid, analysis_filter=['base64_decoder']) span_in_binary, span_in_section = None, (None, None) for expression in file_obj.processed_analysis['base64_decoder'][section]: if expression['id'] == int(expression_id): span_in_section = expression['span_in_section'] span_in_binary = expression['span_in_binary'] break if not span_in_binary: return render_template('error.html', message='Undisclosed error in base64 decoding') with ConnectTo(InterComFrontEndBinding, self._config) as connection: raw_binary = connection.get_binary_and_filename(file_obj.uid) binary, _ = remove_linebreaks_from_byte_string(raw_binary[0][span_in_binary[0]:span_in_binary[1]]) try: binary = binascii.a2b_base64(binary[span_in_section[0]:span_in_section[1]]) except binascii.Error as error: return render_template('error.html', message=str(error)) else: resp = make_response(binary) resp.headers['Content-Disposition'] = 'attachment; filename={}'.format(file_obj.file_name + '_0x%X' % (span_in_binary[0] + span_in_section[0]) + '-0x%X_decoded' % (span_in_binary[1] - span_in_section[2])) return resp
def _app_delete_firmware(self, uid): with ConnectTo(FrontEndDbInterface, config=self._config) as sc: is_firmware = sc.is_firmware(uid) if not is_firmware: return render_template('error.html', message='Firmware not found in database: {}'.format(uid)) else: with ConnectTo(AdminDbInterface, config=self._config) as sc: deleted_virtual_file_path_entries, deleted_files = sc.delete_firmware(uid) return render_template('delete_firmware.html', deleted_vps=deleted_virtual_file_path_entries, deleted_files=deleted_files, uid=uid)
def _start_single_file_analysis(self, uid): if user_has_privilege(current_user, privilege='submit_analysis'): with ConnectTo(FrontEndDbInterface, self._config) as database: file_object = database.get_object(uid) file_object.scheduled_analysis = request.form.getlist( 'analysis_systems') with ConnectTo(InterComFrontEndBinding, self._config) as intercom: intercom.add_single_file_task(file_object) else: flash('You have insufficient rights to add additional analyses')
def _app_home(self): stats = StatisticUpdater(config=self._config) with ConnectTo(FrontEndDbInterface, config=self._config) as sc: latest_firmware_submissions = sc.get_last_added_firmwares(int(self._config['database'].get('number_of_latest_firmwares_to_display', '10'))) latest_comments = sc.get_latest_comments(int(self._config['database'].get('number_of_latest_firmwares_to_display', '10'))) with ConnectTo(CompareDbInterface, config=self._config) as sc: latest_comparison_results = sc.page_compare_results(limit=10) general_stats = stats.get_general_stats() stats.shutdown() return render_template('home.html', general_stats=general_stats, latest_firmware_submissions=latest_firmware_submissions, latest_comments=latest_comments, latest_comparison_results=latest_comparison_results)
def _app_add_comment(self, uid): error = False if request.method == 'POST': comment = request.form['comment'] author = request.form['author'] with ConnectTo(FrontendEditingDbInterface, config=self._config) as sc: sc.add_comment_to_object(uid, comment, author, round(time())) return redirect(url_for('analysis/<uid>', uid=uid)) with ConnectTo(FrontEndDbInterface, config=self._config) as sc: if not sc.existence_quick_check(uid): error = True return render_template('add_comment.html', uid=uid, error=error)
def _show_system_health(self): components = ["frontend", "database", "backend"] status = [] with ConnectTo(StatisticDbViewer, self._config) as stats_db: for component in components: status.append(stats_db.get_statistic(component)) with ConnectTo(InterComFrontEndBinding, self._config) as sc: plugin_dict = sc.get_available_analysis_plugins() return render_template("system_health.html", status=status, analysis_plugin_info=plugin_dict)
def put(self): ''' The request data should have the form {"uid_list": uid_list, "<optional>redo": True} return value: the result dict from the compare ''' try: data = convert_rest_request(request.data) except TypeError as type_error: return error_message(str(type_error), self.URL, request_data=request.data) try: uid_string = ';'.join(data['uid_list']) compare_id = normalize_compare_id(uid_string) redo = data.get('redo', False) except (AttributeError, TypeError, KeyError): return error_message( 'Request should be of the form {"uid_list": uid_list, "redo": boolean}', self.URL, request_data=data) with ConnectTo(CompareDbInterface, self.config) as db_compare_service: if not db_compare_service.compare_result_is_in_db( compare_id) or redo: try: db_compare_service.check_objects_exist(compare_id) except FactCompareException as exception: return error_message(exception.get_message(), self.URL, request_data=data, return_code=404) with ConnectTo(InterComFrontEndBinding, self.config) as intercom: intercom.add_compare_task(compare_id, force=redo) return success_message( { 'message': 'Compare started. Please use GET to get the results.' }, self.URL, request_data=data, return_code=202) return error_message( 'Compare already exists. Use "redo" to force re-compare.', self.URL, request_data=data, return_code=200)
def _app_download_binary(self, uid): with ConnectTo(FrontEndDbInterface, self._config) as sc: object_exists = sc.existence_quick_check(uid) if not object_exists: return render_template('uid_not_found.html', uid=uid) else: with ConnectTo(InterComFrontEndBinding, self._config) as sc: result = sc.get_binary_and_filename(uid) if result is None: return render_template('error.html', message='timeout') else: binary, file_name = result resp = make_response(binary) resp.headers['Content-Disposition'] = 'attachment; filename={}'.format(file_name) return resp
def _show_analysis_results(self, uid, selected_analysis=None, root_uid=None): if request.method == 'POST': self._start_single_file_analysis(uid) other_versions = None with ConnectTo(CompareDbInterface, self._config) as db_service: all_comparisons = db_service.page_compare_results() known_comparisons = [ comparison for comparison in all_comparisons if uid in comparison[0] ] analysis_filter = [selected_analysis] if selected_analysis else [] with ConnectTo(FrontEndDbInterface, self._config) as sc: file_obj = sc.get_object(uid, analysis_filter=analysis_filter) if not file_obj: return render_template('uid_not_found.html', uid=uid) if isinstance(file_obj, Firmware): root_uid = file_obj.get_uid() other_versions = sc.get_other_versions_of_firmware(file_obj) summary_of_included_files = sc.get_summary( file_obj, selected_analysis) if selected_analysis else None included_fo_analysis_complete = not sc.all_uids_found_in_database( list(file_obj.files_included)) with ConnectTo(InterComFrontEndBinding, self._config) as sc: analysis_plugins = sc.get_available_analysis_plugins() return render_template_string( self._get_analysis_view(selected_analysis) if selected_analysis else get_template_as_string('show_analysis.html'), uid=uid, firmware=file_obj, selected_analysis=selected_analysis, all_analyzed_flag=included_fo_analysis_complete, summary_of_included_files=summary_of_included_files, root_uid=none_to_none(root_uid), firmware_including_this_fo=self. _get_firmware_ids_including_this_file(file_obj), analysis_plugin_dict=analysis_plugins, other_versions=other_versions, uids_for_comparison=get_comparison_uid_list_from_session(), user_has_admin_clearance=user_has_privilege(current_user, privilege='delete'), known_comparisons=known_comparisons, available_plugins=self._get_used_and_unused_plugins( file_obj.processed_analysis, [x for x in analysis_plugins.keys() if x != 'unpacker']))
def _update_analysis(self, uid, re_do=False): error = {} if request.method == 'POST': analysis_task = create_re_analyze_task(request, uid=uid) error = check_for_errors(analysis_task) if not error: self._schedule_re_analysis_task(uid, analysis_task, re_do) return render_template('upload/upload_successful.html', uid=uid) with ConnectTo(FrontEndDbInterface, self._config) as sc: old_firmware = sc.get_object(uid=uid, analysis_filter=[]) if old_firmware is None: return render_template('uid_not_found.html', uid=uid) with ConnectTo(FrontEndDbInterface, self._config) as sc: device_class_list = sc.get_device_class_list() device_class_list.remove(old_firmware.device_class) with ConnectTo(FrontEndDbInterface, self._config) as sc: vendor_list = sc.get_vendor_list() vendor_list.remove(old_firmware.vendor) with ConnectTo(FrontEndDbInterface, self._config) as sc: device_name_dict = sc.get_device_name_dict() device_name_dict[old_firmware.device_class][ old_firmware.vendor].remove(old_firmware.device_name) previously_processed_plugins = list( old_firmware.processed_analysis.keys()) with ConnectTo(InterComFrontEndBinding, self._config) as sc: plugin_dict = overwrite_default_plugins( sc, previously_processed_plugins) if re_do: title = 're-do analysis' else: title = 'update analysis' return render_template('upload/re-analyze.html', device_classes=device_class_list, vendors=vendor_list, error=error, device_names=json.dumps(device_name_dict, sort_keys=True), firmware=old_firmware, analysis_plugin_dict=plugin_dict, title=title)
def _get_live_stats(self, filter_query): with ConnectTo(StatisticUpdater, self._config) as stats_updater: stats_updater.set_match(filter_query) stats_dict = { "firmware_meta_stats": stats_updater._get_firmware_meta_stats(), "file_type_stats": stats_updater._get_file_type_stats(), "malware_stats": stats_updater._get_malware_stats(), "crypto_material_stats": stats_updater._get_crypto_material_stats(), "unpacker_stats": stats_updater._get_unpacking_stats(), "ip_and_uri_stats": stats_updater._get_ip_stats(), "architecture_stats": stats_updater._get_architecture_stats(), "release_date_stats": stats_updater._get_time_stats(), "general_stats": stats_updater.get_general_stats(), "exploit_mitigations_stats": stats_updater._get_exploit_mitigations_stats() } return stats_dict
def _upload_firmware_get(self): rv = self.test_client.get('/upload') self.assertIn(b'<h2>Upload Firmware</h2>', rv.data, 'upload page not displayed correctly') with ConnectTo(InterComFrontEndBinding, self.config) as connection: plugins = connection.get_available_analysis_plugins() mandatory_plugins = [p for p in plugins if plugins[p][1]] default_plugins = [p for p in plugins if plugins[p][2]] optional_plugins = [ p for p in plugins if not (plugins[p][1] or plugins[p][2]) ] for mandatory_plugin in mandatory_plugins: self.assertNotIn( mandatory_plugin.encode(), rv.data, 'mandatory plugin {} found erroneously'.format( mandatory_plugin)) for default_plugin in default_plugins: self.assertIn( 'value="{}" checked'.format(default_plugin).encode(), rv.data, 'default plugin {} erroneously unchecked or not found'.format( default_plugin)) for optional_plugin in optional_plugins: self.assertIn( 'value="{}" unchecked'.format(optional_plugin).encode(), rv.data, 'optional plugin {} erroneously checked or not found'.format( optional_plugin))
def test_unpack_analyse_and_compare(self): test_fw_1 = Firmware( file_path='{}/container/test.zip'.format(get_test_data_dir())) test_fw_1.release_date = '2017-01-01' test_fw_2 = Firmware( file_path='{}/container/test.7z'.format(get_test_data_dir())) test_fw_2.release_date = '2017-01-01' self._unpack_scheduler.add_task(test_fw_1) self._unpack_scheduler.add_task(test_fw_2) self.analysis_finished_event.wait(timeout=10) compare_id = unify_string_list(';'.join( [fw.uid for fw in [test_fw_1, test_fw_2]])) self.assertIsNone( self._compare_scheduler.add_task((compare_id, False)), 'adding compare task creates error') self.compare_finished_event.wait(timeout=10) with ConnectTo(CompareDbInterface, self._config) as sc: result = sc.get_compare_result(compare_id) self.assertFalse(isinstance(result, str), 'compare result should exist') self.assertEqual(result['plugins']['Software'], self._expected_result()['Software']) self.assertCountEqual( result['plugins']['File_Coverage']['exclusive_files'], self._expected_result()['File_Coverage']['exclusive_files'])
def get(self, compare_id=None): ''' The request data should have the form {"uid_list": uid_list, "<optional>redo": True} return value: the result dict from the compare ''' try: compare_id = normalize_compare_id(compare_id) except (AttributeError, TypeError): return error_message( 'Compare ID must be of the form uid1;uid2(;uid3..)', self.URL, request_data={'compare_id': compare_id}) with ConnectTo(CompareDbInterface, self.config) as db_compare_service: result = None with suppress(FactCompareException): if db_compare_service.compare_result_is_in_db(compare_id): result = db_compare_service.get_compare_result(compare_id) if result: return success_message(result, self.URL, request_data={'compare_id': compare_id}, return_code=202) return error_message( 'Compare not found in database. Please use /rest/start_compare to start the compare.', self.URL, request_data={'compare_id': compare_id}, return_code=404)
def _show_system_health(self): components = ["frontend", "database", "backend"] status = [] with ConnectTo(StatisticDbViewer, self._config) as stats_db: for component in components: status.append(stats_db.get_statistic(component)) return render_template("system_health.html", status=status)
def _get_stats_from_db(self): with ConnectTo(StatisticDbViewer, self._config) as stats_db: stats_dict = { "general_stats": stats_db.get_statistic("general"), "firmware_meta_stats": stats_db.get_statistic("firmware_meta"), "file_type_stats": stats_db.get_statistic("file_type"), "malware_stats": stats_db.get_statistic("malware"), "crypto_material_stats": stats_db.get_statistic("crypto_material"), "unpacker_stats": stats_db.get_statistic("unpacking"), "ip_and_uri_stats": stats_db.get_statistic("ips_and_uris"), "architecture_stats": stats_db.get_statistic("architecture"), "release_date_stats": stats_db.get_statistic("release_date"), "exploit_mitigations_stats": stats_db.get_statistic("exploit_mitigations") } return stats_dict
def _sync_view(self, plugin_path): if plugin_path: view_source = self._get_view_file_path(plugin_path) if view_source is not None: view = get_binary_from_file(view_source) with ConnectTo(ViewUpdater, self.config) as connection: connection.update_view(self.NAME, view)
def _ajax_get_tree_root(self, uid): root = list() with ConnectTo(FrontEndDbInterface, self._config) as sc: for node in sc.generate_file_tree_node( uid, uid): # only a single item in this 'iterable' root = [self._generate_jstree_node(node)] return jsonify(root)
def post(self): ''' The request data should have the form {"rule_file": rule_string, 'uid': firmware_uid} The uid parameter is optional and can be specified if the user want's to search in the files of a single firmware. rule_string can be something like "rule rule_name {strings: $a = \"foobar\" condition: $a}" ''' try: data = convert_rest_request(request.data) yara_rules = self._get_yara_rules(data) uid = self._get_firmware_uid(data) except TypeError as type_error: return error_message(str(type_error), self.URL, request_data=request.data) except RestBinarySearchException as exception: return error_message(exception.get_message(), self.URL, request_data=request.data) with ConnectTo(InterComFrontEndBinding, self.config) as intercom: search_id = intercom.add_binary_search_request(yara_rules, uid) return success_message( { 'message': 'Started binary search. Please use GET and the search_id to get the results' }, self.URL, request_data={'search_id': search_id})
def test_unpack_analyse_and_compare(self): test_fw_1 = Firmware( file_path='{}/container/test.zip'.format(get_test_data_dir())) test_fw_1.release_date = '2017-01-01' test_fw_2 = Firmware( file_path='{}/regression_one'.format(get_test_data_dir())) test_fw_2.release_date = '2017-01-01' self._unpack_scheduler.add_task(test_fw_1) self._unpack_scheduler.add_task(test_fw_2) self.analysis_finished_event.wait(timeout=20) compare_id = normalize_compare_id(';'.join( [fw.uid for fw in [test_fw_1, test_fw_2]])) self.assertIsNone( self._compare_scheduler.add_task((compare_id, False)), 'adding compare task creates error') self.compare_finished_event.wait(timeout=10) with ConnectTo(CompareDbInterface, self._config) as sc: result = sc.get_compare_result(compare_id) self.assertEqual(result['plugins']['Software'], self._expected_result()['Software']) self.assertCountEqual( result['plugins']['File_Coverage']['files_in_common'], self._expected_result()['File_Coverage']['files_in_common'])
def get(self, uid): with ConnectTo(FsMetadataRoutesDbInterface, self.config) as db: results = db.get_analysis_results_for_included_uid(uid) endpoint = self.ENDPOINTS[0][0] if not results: error_message('no results found for uid {}'.format(uid), endpoint, request_data={'uid': uid}) return success_message({AnalysisPlugin.NAME: results}, endpoint, request_data={'uid': uid})