def test_builds_email_custom_template(self): # update ProjectStatus UpdateProjectStatus()(self.testrun2) UpdateProjectStatus()(self.testrun3) response = self.client.get('/api/builds/%d/email/?template=%s' % (self.build3.id, self.validemailtemplate.pk)) self.assertEqual(200, response.status_code) self.assertEqual("text/plain", response['Content-Type'])
def test_builds_email_custom_baseline(self): UpdateProjectStatus()(self.testrun) UpdateProjectStatus()(self.testrun3) response = self.client.get( '/api/builds/%d/email/?baseline=%s&output=text/plain' % (self.build3.id, self.build.id)) self.assertContains(response, "Regressions (compared to build 1)")
def test_builds_email_custom_invalid_template(self): response = self.client.get('/api/builds/%d/email/?template=%s' % (self.build3.id, self.invalidemailtemplate.pk)) self.assertEqual(404, response.status_code) # create ProjectStatus UpdateProjectStatus()(self.testrun2) UpdateProjectStatus()(self.testrun3) response = self.client.get('/api/builds/%d/email/?template=%s' % (self.build3.id, self.invalidemailtemplate.pk)) self.assertEqual(500, response.status_code)
def test_email_notification(self, email_notification_mock): UpdateProjectStatus()(self.testrun) UpdateProjectStatus()(self.testrun2) report = self.build2.delayed_reports.create() report.email_recipient = "*****@*****.**" report.save() prepared_report = prepare_report(report.pk) self.assertEqual(200, prepared_report.status_code) email_notification_mock.assert_called_with(report.pk)
def test_callback_notification(self, callback_notification_mock): UpdateProjectStatus()(self.testrun) UpdateProjectStatus()(self.testrun2) report = self.build2.delayed_reports.create() report.callback = "http://foo.bar.com" report.save() prepared_report = prepare_report(report.pk) self.assertEqual(200, prepared_report.status_code) callback_notification_mock.assert_called_with(report.pk)
def test_builds_email(self): # update ProjectStatus self.build2.test_jobs.all().delete() self.build3.test_jobs.all().delete() UpdateProjectStatus()(self.testrun2) UpdateProjectStatus()(self.testrun3) response = self.hit('/api/builds/%d/email/' % self.build3.id) self.assertIn('foo/test2', response) # sanity check self.assertIn('Regressions (compared to build 2)', response) # make sure proper baseline is used
def test_project_compare_builds_with_finished_status_and_regressions(self): foo_suite, _ = self.project.suites.get_or_create(slug='foo') foo_metadata, _ = models.SuiteMetadata.objects.get_or_create(suite=foo_suite.slug, name='dummy', kind='test') self.testrun4.tests.get_or_create(suite=foo_suite, metadata=foo_metadata, result=True, build=self.testrun4.build, environment=self.testrun4.environment) self.testrun6.tests.get_or_create(suite=foo_suite, metadata=foo_metadata, result=False, build=self.testrun6.build, environment=self.testrun6.environment) UpdateProjectStatus()(self.testrun4) UpdateProjectStatus()(self.testrun6) data = self.hit('/api/projects/%d/compare_builds/?baseline=%d&to_compare=%d' % (self.project.id, self.build4.id, self.build6.id)) self.assertEqual(1, len(data['regressions']['myenv']['foo']))
def test_builds_status(self): self.build2.test_jobs.all().delete() self.build3.test_jobs.all().delete() UpdateProjectStatus()(self.testrun2) UpdateProjectStatus()(self.testrun3) data = self.hit('/api/builds/%d/status/' % self.build3.id) self.assertIn('foo/test2', data['regressions']) self.assertIn('foo/test1', data['fixes'])
def test_builds_email(self): response = self.client.get('/api/builds/%d/email/' % self.build3.id) self.assertEqual(404, response.status_code) # create ProjectStatus self.build2.test_jobs.all().delete() self.build3.test_jobs.all().delete() UpdateProjectStatus()(self.testrun2) UpdateProjectStatus()(self.testrun3) response = self.hit('/api/builds/%d/email/' % self.build3.id) self.assertIn('foo/test2', response) # sanity check
def test_sends_notification(self, maybe_notify_project_status): ParseTestRunData()(self.testrun) RecordTestRunStatus()(self.testrun) UpdateProjectStatus()(self.testrun) status = ProjectStatus.objects.last() maybe_notify_project_status.delay.assert_called_with(status.id)
def __handle__(self, old_project, new_project, env): for build in old_project.builds.all(): if build.test_runs.filter(environment=env): print("moving build: %s" % build) new_build, _ = Build.objects.get_or_create( version=build.version, datetime=build.datetime, project=new_project, created_at=build.created_at) for testrun in build.test_runs.filter(environment=env): testrun.build = new_build testrun.save() testrun.environment.project = new_project testrun.environment.save() for testjob in testrun.test_jobs.all(): testjob.target = new_project testjob.save() UpdateProjectStatus()(testrun) new_build.status.created_at = build.status.created_at new_build.status.last_updated = build.status.last_updated new_build.status.save() else: print("No matching test runs found in build: %s" % build) env.project = new_project env.save() for suite in old_project.suites.all(): new_suite, _ = new_project.suites.get_or_create( slug=suite.slug, defaults={'name': suite.name}) for model in [Status, Test, Metric]: model.objects.filter( suite=suite, test_run__build__project_id=new_project.id, ).update(suite=new_suite)
def really_fetch(self, test_job): implementation = self.get_implementation() test_job.last_fetch_attempt = timezone.now() test_job.save() results = implementation.fetch(test_job) if results: # create TestRun status, completed, metadata, tests, metrics, logs = results test_job.job_status = status if not completed: if tests or metrics: # this means the job produced 'some' results # and can be reported on completed = True test_job.can_resubmit = True if completed and not tests and not metrics: # test job produced no results # mark it incomplete completed = False test_job.can_resubmit = True metadata['job_id'] = test_job.job_id metadata['job_status'] = test_job.job_status if test_job.url is not None: metadata['job_url'] = test_job.url try: receive = ReceiveTestRun(test_job.target, update_project_status=False) testrun = receive( version=test_job.build, environment_slug=test_job.environment, metadata_file=json.dumps(metadata), tests_file=json.dumps(tests), metrics_file=json.dumps(metrics), log_file=logs, completed=completed, ) test_job.testrun = testrun test_job.fetched = True test_job.fetched_at = timezone.now() test_job.save() self.__postprocess_testjob__(test_job) UpdateProjectStatus()(testrun) except InvalidMetadata as exception: # mark test job as fetched to prevent resubmission # on next fetch attempt test_job.fetched = True test_job.failure = str(exception) test_job.fetched_at = timezone.now() test_job.save()
def really_fetch(self, test_job): test_job.last_fetch_attempt = timezone.now() implementation = self.get_implementation() results = implementation.fetch(test_job) if not results: test_job.save() return status, completed, metadata, tests, metrics, logs = results test_job.job_status = status if not completed: tests = {} metrics = {} test_job.can_resubmit = True if completed and not tests and not metrics: # test job produced no results # mark it incomplete completed = False test_job.can_resubmit = True metadata['job_id'] = test_job.job_id metadata['job_status'] = test_job.job_status if test_job.url is not None: metadata['job_url'] = test_job.url try: # create TestRun receive = ReceiveTestRun(test_job.target, update_project_status=False) testrun = receive( version=test_job.target_build.version, environment_slug=test_job.environment, metadata_file=json.dumps(metadata), tests_file=json.dumps(tests), metrics_file=json.dumps(metrics), log_file=logs, completed=completed, ) test_job.testrun = testrun except InvalidMetadata as exception: test_job.failure = str(exception) except DuplicatedTestJob as exception: logger.error('Failed to fetch test_job(%d): "%s"' % (test_job.id, str(exception))) # mark test job as fetched to prevent resubmission # on next fetch attempt test_job.fetched = True test_job.fetched_at = timezone.now() test_job.save() if test_job.testrun: self.__postprocess_testjob__(test_job) UpdateProjectStatus()(testrun)
def test_dispatch_callback_on_build_finished(self, requests_post): url = 'http://callback-target.com' callback = self.build.callbacks.create( url=url, event=Callback.events.ON_BUILD_FINISHED) ParseTestRunData()(self.testrun) RecordTestRunStatus()(self.testrun) UpdateProjectStatus()(self.testrun) callback.refresh_from_db() self.assertTrue(callback.is_sent) requests_post.assert_called_with(url)
def test_dont_update_project_status(self, UpdateProjectStatus): receive = ReceiveTestRun(self.project, update_project_status=False) receive('199', 'myenv') UpdateProjectStatus.assert_not_called()
def test_builds_email_custom_invalid_baseline(self): UpdateProjectStatus()(self.testrun) response = self.client.get('/api/builds/%d/email/?baseline=999' % (self.build.id)) self.assertEqual(400, response.status_code)
def test_builds_email_custom_baseline_missing_status(self): UpdateProjectStatus()(self.testrun) self.build2.status.delete() response = self.client.get('/api/builds/%d/email/?baseline=%s' % (self.build.id, self.build2.id)) self.assertEqual(400, response.status_code)
def fetch(self, job_id): with transaction.atomic(): try: test_job = TestJob.objects.select_for_update(nowait=True).get( pk=job_id) if test_job.fetched or test_job.fetch_attempts >= test_job.backend.max_fetch_attempts: return except DatabaseError: # another thread is working on this testjob return try: test_job.last_fetch_attempt = timezone.now() results = self.get_implementation().fetch(test_job) if results is None: # empty results mean the job is still in progress # or in the queue test_job.save() return except FetchIssue as issue: logger.warning("error fetching job %s: %s" % (test_job.id, str(issue))) test_job.failure = str(issue) test_job.fetched = not issue.retry test_job.fetch_attempts += 1 test_job.save() return test_job.fetched = True test_job.fetched_at = timezone.now() test_job.save() status, completed, metadata, tests, metrics, logs = results test_job.job_status = status if not completed: tests = {} metrics = {} test_job.can_resubmit = True if completed and not tests and not metrics: # test job produced no results # mark it incomplete completed = False test_job.can_resubmit = True metadata['job_id'] = test_job.job_id metadata['job_status'] = test_job.job_status if test_job.url is not None: metadata['job_url'] = test_job.url try: receive = ReceiveTestRun(test_job.target, update_project_status=False) testrun, _ = receive( version=test_job.target_build.version, environment_slug=test_job.environment, metadata_file=json.dumps(metadata), tests_file=json.dumps(tests), metrics_file=json.dumps(metrics), log_file=logs, completed=completed, ) test_job.testrun = testrun except InvalidMetadata as exception: test_job.failure = str(exception) except DuplicatedTestJob as exception: logger.error('Failed to fetch test_job(%d): "%s"' % (test_job.id, str(exception))) test_job.save() if test_job.testrun: self.__postprocess_testjob__(test_job) UpdateProjectStatus()(test_job.testrun)
def test_builds_email_custom_baseline(self): UpdateProjectStatus()(self.testrun) UpdateProjectStatus()(self.testrun3) self.hit('/api/builds/%d/email/?baseline=%s' % (self.build3.id, self.build.id))
def test_prepare_report(self): UpdateProjectStatus()(self.testrun) UpdateProjectStatus()(self.testrun2) report = self.build2.delayed_reports.create() prepared_report = prepare_report(report.pk) self.assertEqual(200, prepared_report.status_code)
def test_builds_status(self): response = self.client.get('/api/builds/%d/status/') self.assertEqual(404, response.status_code) # create ProjectStatus UpdateProjectStatus()(self.testrun) self.hit('/api/builds/%d/status/' % self.build.id)