def testReport(self): report_time = datetime(2018, 8, 27) report = TotalFlakinessReport.Get(report_time, 'chromium') self.assertEqual(6, report.test_count) self.assertEqual(8, report.GetTotalOccurrenceCount()) self.assertEqual(3, report.GetTotalCLCount()) report_data = { 'id': '2018-08-27@chromium', 'test_count': 6, 'bug_count': 4, 'new_bug_count': 0, 'impacted_cl_counts': { 'cq_false_rejection': 3, 'retry_with_patch': 0, 'total': 3 }, 'occurrence_counts': { 'cq_false_rejection': 7, 'retry_with_patch': 1, 'total': 8 } } self.assertEqual(report_data, report.ToSerializable()) self.assertEqual('chromium', report.GetProject()) self.assertIn('luci_project::chromium', report.tags) component_report_A = ComponentFlakinessReport.Get( report.key, 'ComponentA') self.assertEqual(4, component_report_A.test_count) self.assertEqual(6, component_report_A.GetTotalOccurrenceCount()) self.assertEqual(3, component_report_A.GetTotalCLCount()) self.assertEqual(3, component_report_A.false_rejected_cl_count) reports_queried_by_component = ComponentFlakinessReport.query( ComponentFlakinessReport.tags == 'component::ComponentA').fetch() self.assertEqual(component_report_A, reports_queried_by_component[0]) component_test_report_A_B = TestFlakinessReport.Get( component_report_A.key, 'testB') self.assertEqual(1, component_test_report_A_B.test_count) self.assertEqual(2, component_test_report_A_B.GetTotalOccurrenceCount()) self.assertEqual(2, component_test_report_A_B.GetTotalCLCount()) reports_queried_by_test = TestFlakinessReport.query( TestFlakinessReport.tags == 'test::testB').fetch() self.assertEqual(component_test_report_A_B, reports_queried_by_test[0])
def _QueryTopComponents(total_report_key): """Queries previous week's flake report and return the top n components. Returns: A list of top n components in the previous week ranked by various criteria. [{ 'rank_by': 'rank_by', 'components': [ComponentFlakinessReport.ToSerializable()] }] """ component_report_query = ComponentFlakinessReport.query( ancestor=total_report_key) top_components = [] for rank_by, rank_property in _RANK_PROPERTY_TUPLES: components = component_report_query.order(-rank_property).fetch( _DEFAULT_TOP_COMPONENT_NUM) query_result = { 'rank_by': rank_by, 'components': [component.ToSerializable() for component in components] } top_components.append(query_result) return top_components
def SaveReportToDatastore(counters, report_date, save_test_report=False): # The entities to persist. entities = [] for luci_project, p_counters in counters.iteritems(): project_tag = ('luci_project', luci_project) report = TotalFlakinessReport.FromTallies( None, p_counters, report_date, additional_tags=[project_tag]) entities.append(report) for component, c_counters in p_counters.iteritems(): if component.startswith('_'): continue component_tag = ('component', component) component_row = ComponentFlakinessReport.FromTallies( report.key, c_counters, report_date, additional_tags=[project_tag, component_tag]) entities.append(component_row) if not save_test_report: continue for test, t_counters in c_counters.iteritems(): if test.startswith('_'): continue test_tag = ('test', test) entities.append( TestFlakinessReport.FromTallies( component_row.key, t_counters, report_date, additional_tags=[project_tag, component_tag, test_tag])) ndb.put_multi(entities)
def _QueryComponentReports(component, luci_project, limit=_DEFAULT_MAX_ROW_NUM): tags = [ ComponentFlakinessReport.GenerateTag('luci_project', luci_project), ComponentFlakinessReport.GenerateTag('component', component), # Only displays one report per week, though we may generate report more # frequently. ComponentFlakinessReport.GenerateTag('day', 1), ] query = ComponentFlakinessReport.query() for tag in tags: query = query.filter(ComponentFlakinessReport.tags == tag) return query.order(-ComponentFlakinessReport.report_time).fetch(limit)
def HandleGet(self): total = self.request.get('total').strip() component = self.request.get('component').strip() luci_project = self.request.get( 'luci_project').strip() or DEFAULT_LUCI_PROJECT if not component and not total: return self.CreateError( 'A component is required to show its flake report, or add total=1 to ' 'show total numbers.', return_code=404) if component: component_reports = _QueryComponentReports(component, luci_project) if not component_reports: return self.CreateError( 'Didn\'t find reports for project {}, component {}.'. format(luci_project, component), return_code=404) report_json = _GenerateComponentReportJson(component_reports) top_flakes, _, _, _, _ = flake_detection_utils.GetFlakesByFilter( ComponentFlakinessReport.GenerateTag('component', component), luci_project, cursor=None, direction='next', page_size=_DEFAULT_TOP_FLAKE_NUM) else: total_reports = _QueryTotalReports(luci_project) report_json = _GenerateComponentReportJson(total_reports) top_flakes = Flake.query().order( -Flake.flake_score_last_week).fetch(_DEFAULT_TOP_FLAKE_NUM) flakes_data = flake_detection_utils.GenerateFlakesData(top_flakes) data = { 'report_json': report_json, 'component': component if component else 'All', 'top_flakes': flakes_data, 'total': total, 'luci_project': (luci_project if luci_project != DEFAULT_LUCI_PROJECT else ''), } return {'template': 'flake/report/component_report.html', 'data': data}
def testBasicReportNoTestReports(self, _): report_date = datetime(2018, 8, 27) component_report.Report() report = TotalFlakinessReport.Get(report_date, 'chromium') self.assertEqual(6, report.test_count) self.assertEqual(4, report.bug_count) self.assertEqual(3, report.new_bug_count) expected_report_counts = { FlakeType.CQ_FALSE_REJECTION: (7, 3), FlakeType.RETRY_WITH_PATCH: (1, 0), FlakeType.CQ_HIDDEN_FLAKE: (0, 0), FlakeType.CI_FAILED_STEP: (0, 0) } for occurrence_count in report.occurrence_counts: self.assertEqual( expected_report_counts[occurrence_count.flake_type][0], occurrence_count.count) for cl_count in report.impacted_cl_counts: self.assertEqual(expected_report_counts[cl_count.flake_type][1], cl_count.count) component_report_A = ComponentFlakinessReport.Get( report.key, 'ComponentA') self.assertEqual(4, component_report_A.test_count) self.assertEqual(3, component_report_A.bug_count) self.assertEqual(2, component_report_A.new_bug_count) expected_A_counts = { FlakeType.CQ_FALSE_REJECTION: (5, 3), FlakeType.RETRY_WITH_PATCH: (1, 0), FlakeType.CQ_HIDDEN_FLAKE: (0, 0), FlakeType.CI_FAILED_STEP: (0, 0) } for occurrence_count in component_report_A.occurrence_counts: self.assertEqual(expected_A_counts[occurrence_count.flake_type][0], occurrence_count.count) for cl_count in component_report_A.impacted_cl_counts: self.assertEqual(expected_A_counts[cl_count.flake_type][1], cl_count.count) component_report_unknown = ComponentFlakinessReport.Get( report.key, 'Unknown') self.assertEqual(1, component_report_unknown.test_count) self.assertEqual(1, component_report_unknown.bug_count) self.assertEqual(1, component_report_unknown.new_bug_count) expected_Unknown_counts = { FlakeType.CQ_FALSE_REJECTION: (1, 1), FlakeType.RETRY_WITH_PATCH: (0, 0), FlakeType.CQ_HIDDEN_FLAKE: (0, 0), FlakeType.CI_FAILED_STEP: (0, 0) } for occurrence_count in component_report_unknown.occurrence_counts: self.assertEqual( expected_Unknown_counts[occurrence_count.flake_type][0], occurrence_count.count) for cl_count in component_report_unknown.impacted_cl_counts: self.assertEqual(expected_Unknown_counts[cl_count.flake_type][1], cl_count.count)