def test_view_owner_repo(self): # invalid repo response = self.client.get(reverse('ci:view_owner_repo', args=["foo", "bar"])) self.assertEqual(response.status_code, 404) # valid repo with branches repo = utils.create_repo() branch = utils.create_branch(repo=repo) branch.status = models.JobStatus.FAILED branch.save() utils.create_event(user=repo.user, branch1=branch, branch2=branch) response = self.client.get(reverse('ci:view_owner_repo', args=[repo.user.name, repo.name])) self.assertEqual(response.status_code, 200)
def setUp(self): self.client = Client() self.factory = RequestFactory() for i in range(5): repo = utils.create_repo(name="repo%s" % i) repo.active = True repo.status = models.JobStatus.SUCCESS repo.save() for j in range(2): b = utils.create_branch(name="branch%s" % j, repo=repo) b.status = models.JobStatus.SUCCESS b.save() for j in range(3): b = repo.branches.first() pr = utils.create_pr(title="pr%s" % j, number=j+1, repo=repo) pr.closed = False pr.status = models.JobStatus.SUCCESS pr.save() ev = utils.create_event(user=repo.user, branch1=b, branch2=b, commit1="%s" % j) ev.pull_request = pr ev.save() for k in range(3): r = utils.create_recipe(name="%s%s" % (repo.name, k), repo=repo, branch=b) r.private = False r.save() job = utils.create_job(recipe=r, event=ev) job.status = models.JobStatus.SUCCESS job.client = utils.create_client(name="client%s/%s" % (repo.name, k)) job.save() utils.create_step_result(job=job) utils.create_osversion() utils.create_loadedmodule()
def test_cancel_event(self): ev = utils.create_event() jobs = [] for i in range(3): r = utils.create_recipe(name="recipe %s" % i, user=ev.build_user) j = utils.create_job(recipe=r, event=ev, user=ev.build_user) jobs.append(j) msg = "Test cancel" self.set_counts() event.cancel_event(ev, msg) # The status on the branch should get updated self.compare_counts(canceled=3, events_canceled=1, num_changelog=3, num_jobs_completed=3, num_events_completed=1, active_branches=1) ev.refresh_from_db() self.assertEqual(ev.status, models.JobStatus.CANCELED) self.assertEqual(ev.complete, True) for j in jobs: j.refresh_from_db() self.assertEqual(j.status, models.JobStatus.CANCELED) self.assertTrue(j.complete)
def create_event_with_jobs(self, commit='1234', user=None, branch1=None, branch2=None, cause=models.Event.PULL_REQUEST): ev = utils.create_event(commit2=commit, user=user, branch1=branch1, branch2=branch2, cause=cause) ev.base.branch.repository.active = True ev.base.branch.repository.save() alt_recipe = utils.create_recipe( name="alt recipe", cause=models.Recipe.CAUSE_PULL_REQUEST_ALT) utils.create_step(name="step0_alt", recipe=alt_recipe, position=0) utils.create_step(name="step1_alt", recipe=alt_recipe, position=1) if cause == models.Event.PULL_REQUEST: pr = utils.create_pr(title="Foo {a, b} & <bar> …") pr.alternate_recipes.add(alt_recipe) ev.pull_request = pr ev.save() r0 = utils.create_recipe(name="r0", cause=cause) utils.create_step(name="step1_r0", recipe=r0, position=1) utils.create_step(name="step2_r0", recipe=r0, position=2) r1 = utils.create_recipe(name="r1", cause=cause) utils.create_step(name="step1_r1", recipe=r1, position=1) utils.create_step(name="step2_r1", recipe=r1, position=2) r1.depends_on.add(r1) utils.create_job(event=ev, recipe=r0) utils.create_job(event=ev, recipe=r1) return ev
def test_repo_update(self): url = reverse('ci:ajax:repo_update') # no parameters response = self.client.get(url) self.assertEqual(response.status_code, 400) pr_open = utils.create_pr(title='Foo <type> & bar …', number=1) ev_open = utils.create_event() pr_open.closed = False pr_open.save() ev_open.pull_request = pr_open ev_open.save() pr_closed = utils.create_pr(title='closed_pr', number=2) pr_closed.closed = True pr_closed.save() ev_closed = utils.create_event(commit1='2345') ev_closed.pull_request = pr_closed ev_closed.save() pr_open.repository.active = True pr_open.repository.save() ev_branch = utils.create_event(commit1='1', commit2='2', cause=models.Event.PUSH) ev_branch.base.branch.status = models.JobStatus.RUNNING ev_branch.base.branch.save() recipe, depends_on = utils.create_recipe_dependency() utils.create_job(recipe=recipe) utils.create_job(recipe=depends_on) data = {'last_request': 10, 'limit': 30} # missing repo id response = self.client.get(url, data) self.assertEqual(response.status_code, 400) data["repo_id"] = pr_open.repository.pk response = self.client.get(url, data) self.assertEqual(response.status_code, 200) json_data = response.json() self.assertIn('repo_status', json_data) self.assertIn('closed', json_data) self.assertEqual(len(json_data['repo_status']), 1) self.assertEqual(len(json_data['repo_status'][0]['prs']), 1) self.assertIn(escape(pr_open.title), json_data['repo_status'][0]['prs'][0]['description']) self.assertEqual(pr_closed.pk, json_data['closed'][0]['id'])
def test_sha_events(self): e = utils.create_event() repo = e.head.branch.repository url = reverse('ci:sha_events', args=["no_exist", repo.name, e.head.sha]) response = self.client.get(url) self.assertEqual(response.status_code, 404) url = reverse('ci:sha_events', args=[repo.user.name, repo.name, e.head.sha]) response = self.client.get(url) self.assertEqual(response.status_code, 200)
def test_multi_line(self): self.create_events() e = utils.create_event(user=self.owner, commit1='456', branch1=self.branch, branch2=self.branch, cause=models.Event.PUSH) e.description = "some description" e.save() event_q = EventsStatus.get_default_events_query()[:30] info = EventsStatus.multiline_events_info(event_q, max_jobs_per_line=100) self.assertEqual(len(info), 3) self.assertEqual(len(info[0]["jobs"]), 6) info = EventsStatus.multiline_events_info(event_q, max_jobs_per_line=1) self.assertEqual(len(info), 18)
def test_event_update(self): ev = utils.create_event() url = reverse('ci:ajax:event_update', args=[1000]) # no parameters response = self.client.get(url) self.assertEqual(response.status_code, 404) url = reverse('ci:ajax:event_update', args=[ev.pk]) response = self.client.get(url) self.assertEqual(response.status_code, 200) json_data = response.json() self.assertIn('events', json_data)
def test_update_pr_status(self, mock_post): mock_post.return_value = utils.Response() ev = utils.create_event(user=self.build_user) pr = utils.create_pr(server=self.server) ev.pull_request = pr ev.save() # no state is set so just run for coverage with self.settings( INSTALLED_GITSERVERS=[utils.gitlab_config( remote_update=True)]): mock_post.return_value = utils.Response(status_code=200, content="some content") api = self.server.api() api.update_pr_status(ev.base, ev.head, api.PENDING, 'event', 'desc', 'context', api.STATUS_JOB_STARTED) self.assertEqual(mock_post.call_count, 1) api.update_pr_status(ev.base, ev.head, api.PENDING, 'event', 'desc', 'context', api.STATUS_CONTINUE_RUNNING) self.assertEqual(mock_post.call_count, 1) # Not updated api.update_pr_status(ev.base, ev.head, api.PENDING, 'event', 'desc', 'context', api.STATUS_START_RUNNING) self.assertEqual(mock_post.call_count, 1) mock_post.return_value = utils.Response( json_data={"error": "some error"}, status_code=404) api.update_pr_status(ev.base, ev.head, api.PENDING, 'event', 'desc', 'context', api.STATUS_JOB_STARTED) self.assertEqual(mock_post.call_count, 2) mock_post.return_value = utils.Response( json_data={"error": "some error"}, status_code=205) api.update_pr_status(ev.base, ev.head, api.PENDING, 'event', 'desc', 'context', api.STATUS_JOB_STARTED) self.assertEqual(mock_post.call_count, 3) mock_post.side_effect = Exception('BAM!') api.update_pr_status(ev.base, ev.head, api.PENDING, 'event', 'desc', 'context', api.STATUS_JOB_STARTED) self.assertEqual(mock_post.call_count, 4) # This should just return api = self.server.api() api.update_pr_status(ev.base, ev.head, api.PENDING, 'event', 'desc', 'context', api.STATUS_JOB_STARTED) self.assertEqual(mock_post.call_count, 4)
def test_check_automerge(self, mock_get): mock_get.return_value = utils.Response() e0 = utils.create_event(cause=models.Event.PUSH) e0.cause = models.Event.PULL_REQUEST e0.status = models.JobStatus.SUCCESS e0.pull_request = utils.create_pr() e0.save() with self.settings( INSTALLED_GITSERVERS=[utils.github_config( remote_update=True)]): # Not configured for automerge UpdateRemoteStatus.check_automerge(e0) self.assertEqual(mock_get.call_count, 0) auto_merge_settings = { "auto_merge_label": "Auto Merge", "auto_merge_require_review": False, "auto_merge_enabled": True, } repo = e0.base.branch.repository repo_settings = { "%s/%s" % (repo.user.name, repo.name): auto_merge_settings } git_config = utils.github_config(remote_update=True, repo_settings=repo_settings) with self.settings(INSTALLED_GITSERVERS=[git_config]): # Only works for pull requests e0.cause = models.Event.PUSH e0.save() UpdateRemoteStatus.check_automerge(e0) self.assertEqual(mock_get.call_count, 0) # Only works if the event status is SUCCESS e0.cause = models.Event.PULL_REQUEST e0.status = models.JobStatus.FAILED_OK e0.pull_request = utils.create_pr() e0.save() UpdateRemoteStatus.check_automerge(e0) self.assertEqual(mock_get.call_count, 0) e0.status = models.JobStatus.SUCCESS e0.save() # Should try to auto merge UpdateRemoteStatus.check_automerge(e0) self.assertEqual(mock_get.call_count, 1)
def test_dump_latest(self): out = StringIO() management.call_command("dump_latest", stdout=out) self.assertIn("Dumping 0 events", out.getvalue()) ev = utils.create_event() management.call_command("dump_latest", stdout=out) self.assertIn("Dumping 1 events", out.getvalue()) with open("out.json", "r") as f: data = f.read() out = json.loads(data) count = 0 for entry in out: if entry["model"] == "ci.event": self.assertEqual(ev.pk, entry["pk"]) count = 1 self.assertEqual(count, 1)
def create_events(self): self.set_counts() self.build_user = utils.create_user_with_token(name="moosebuild") self.owner = utils.create_user(name="idaholab") self.repo = utils.create_repo(name="civet", user=self.owner) self.branch = utils.create_branch(name="devel", repo=self.repo) pre = utils.create_recipe(name="Precheck", user=self.build_user, repo=self.repo) test = utils.create_recipe(name="Test", user=self.build_user, repo=self.repo) test1 = utils.create_recipe(name="Test1", user=self.build_user, repo=self.repo) test.depends_on.add(pre) test1.depends_on.add(pre) merge = utils.create_recipe(name="Merge", user=self.build_user, repo=self.repo) merge.depends_on.add(test) merge.depends_on.add(test1) pr = utils.create_pr(title="{a, b} & <c> … somereallylongwordthatshouldgettruncated", repo=self.repo) pr.username = '******' pr.save() for commit in ['1234', '2345', '3456']: e = utils.create_event(user=self.owner, commit1=commit, branch1=self.branch, branch2=self.branch) e.pull_request = pr e.description = "some description" e.save() j = utils.create_job(recipe=pre, event=e, user=self.build_user) j.seconds = datetime.timedelta(seconds=10) j.failed_step = 'failed step' j.running_step = '3/5' j.save() utils.create_job(recipe=test, event=e, user=self.build_user) utils.create_job(recipe=test1, event=e, user=self.build_user) utils.create_job(recipe=merge, event=e, user=self.build_user) self.compare_counts(recipes=4, deps=4, current=4, jobs=12, active=12, num_pr_recipes=4, events=3, users=2, repos=1, branches=1, commits=3, prs=1)
def test_view_event(self, mock_collab): """ testing ci:view_event """ mock_collab.return_value = False #invalid event response = self.client.get(reverse('ci:view_event', args=[1000,])) self.assertEqual(response.status_code, 404) #valid event ev = utils.create_event() response = self.client.get(reverse('ci:view_event', args=[ev.pk])) self.assertEqual(response.status_code, 200) #valid event while signed in user = utils.get_test_user() utils.simulate_login(self.client.session, user) response = self.client.get(reverse('ci:view_event', args=[ev.pk])) self.assertEqual(response.status_code, 200)
def test_create_event_summary(self, mock_get, mock_post): mock_get.return_value = utils.Response() mock_post.return_value = utils.Response() ev = utils.create_event() ev.comments_url = 'url' ev.save() j0 = utils.create_job(event=ev) config = utils.create_build_config("config1") j0.recipe.build_configs.add(config) utils.create_job(event=ev, recipe=j0.recipe, config=config) r1 = utils.create_recipe(name="r1") j1 = utils.create_job(recipe=r1, event=ev) j0.recipe.depends_on.add(r1) with self.settings(INSTALLED_GITSERVERS=[ utils.github_config(post_event_summary=False, remote_update=True) ]): # Not posting the summary so we should not do anything UpdateRemoteStatus.create_event_summary(ev) self.assertEqual(mock_post.call_count, 0) self.assertEqual(mock_get.call_count, 0) with self.settings(INSTALLED_GITSERVERS=[ utils.github_config(post_event_summary=True, remote_update=True) ]): # Configured to post the summary UpdateRemoteStatus.create_event_summary(ev) self.assertEqual(mock_post.call_count, 1) # 1 for adding comment self.assertEqual(mock_get.call_count, 1) # 1 for getting current comments utils.update_job(j1, status=models.JobStatus.FAILED, complete=True, invalidated=True) utils.create_step_result(job=j1, status=models.JobStatus.FAILED) self.assertEqual(len(ev.get_unrunnable_jobs()), 2) UpdateRemoteStatus.create_event_summary(ev) self.assertEqual(mock_post.call_count, 2) self.assertEqual(mock_get.call_count, 2)
def test_view_user(self): user = utils.create_user() url = reverse('ci:view_user', args=["no_exist"]) response = self.client.get(url) self.assertEqual(response.status_code, 404) url = reverse('ci:view_user', args=[user.name]) response = self.client.get(url) self.assertEqual(response.status_code, 200) ev = utils.create_event() pr = utils.create_pr() pr.closed = True pr.username = user.name pr.save() ev.pull_request = pr ev.save() utils.create_job(event=ev) response = self.client.get(url) self.assertEqual(response.status_code, 200)
def test_ready_jobs_with_current_event(self): """ If a branch is specified with "auto_cancel_push_events_except_current" then jobs on the "current" event get priority over subsequent events. Basically the normal sort of (-priority, created) gets changed to (created, -priority) for those jobs. """ user = utils.get_test_user() r0 = utils.create_recipe(name='recipe0', user=user) r0.priority = 30 r0.save() r1 = utils.create_recipe(name='recipe1', user=user) r1.priority = 20 r1.save() r2 = utils.create_recipe(name='recipe2', user=user) r2.priority = 10 r2.save() e0 = utils.create_event(user=user, cause=models.Event.PUSH) j0 = utils.create_job(recipe=r0, event=e0, user=user) j1 = utils.create_job(recipe=r1, event=e0, user=user) j2 = utils.create_job(recipe=r2, event=e0, user=user) e1 = utils.create_event(user=user, cause=models.Event.PUSH, commit1='12345') j3 = utils.create_job(recipe=r0, event=e1, user=user) j4 = utils.create_job(recipe=r1, event=e1, user=user) j5 = utils.create_job(recipe=r2, event=e1, user=user) for j in models.Job.objects.all(): j.active = True j.ready = True j.save() url = reverse('ci:client:ready_jobs', args=[user.build_key, 'client']) self.set_counts() response = self.client.get(url) self.compare_counts(num_clients=1) self.assertEqual(response.status_code, 200) data = response.json() self.assertIn('jobs', data) jobs = data["jobs"] self.assertEqual(len(jobs), 6) # Normally jobs are sorted by (-priority, created) self.assertEqual(jobs[0]["id"], j0.pk) self.assertEqual(jobs[1]["id"], j3.pk) self.assertEqual(jobs[2]["id"], j1.pk) self.assertEqual(jobs[3]["id"], j4.pk) self.assertEqual(jobs[4]["id"], j2.pk) self.assertEqual(jobs[5]["id"], j5.pk) repo_name = "%s/%s" % (e0.base.branch.repository.user.name, e0.base.branch.repository.name) branch_name = e0.base.branch.name repo_settings = { repo_name: { "branch_settings": { branch_name: { "auto_cancel_push_events_except_current": True } } } } with self.settings(INSTALLED_GITSERVERS=[ utils.github_config(repo_settings=repo_settings) ]): response = self.client.get(url) self.compare_counts(num_clients=1) self.assertEqual(response.status_code, 200) data = response.json() self.assertIn('jobs', data) jobs = data["jobs"] self.assertEqual(len(jobs), 6) # Jobs now are (created, -priority) self.assertEqual(jobs[0]["id"], j0.pk) self.assertEqual(jobs[1]["id"], j1.pk) self.assertEqual(jobs[2]["id"], j2.pk) self.assertEqual(jobs[3]["id"], j3.pk) self.assertEqual(jobs[4]["id"], j4.pk) self.assertEqual(jobs[5]["id"], j5.pk)
def test_event_odd_deps(self): """ Had the scenario where we have: Precheck -> Test:linux, Test:clang -> Merge where Test had 2 build configs. But the merge recipe had a depends_on with an outdated recipe make_jobs_ready started the merge without waiting for the two Test jobs to finish """ e = utils.create_event() e.cause = models.Event.PUSH e.save() r0 = utils.create_recipe(name='precheck') r1 = utils.create_recipe(name='test') r2 = utils.create_recipe(name='merge') r3 = utils.create_recipe(name='test') # These two need to have the same filename r1.filename = "my filename" r1.save() r3.filename = r1.filename r3.save() r1.build_configs.add(utils.create_build_config("Otherconfig")) utils.create_recipe_dependency(recipe=r1, depends_on=r0) utils.create_recipe_dependency(recipe=r2, depends_on=r3) j0 = utils.create_job(recipe=r0, event=e) j1a = utils.create_job(recipe=r1, event=e, config=r1.build_configs.first()) j1b = utils.create_job(recipe=r1, event=e, config=r1.build_configs.last()) j2 = utils.create_job(recipe=r2, event=e) self.set_counts() e.make_jobs_ready() self.compare_counts(ready=1) j0.refresh_from_db() j1a.refresh_from_db() j1b.refresh_from_db() j2.refresh_from_db() self.assertEqual(j0.ready, True) self.assertEqual(j1a.ready, False) self.assertEqual(j1b.ready, False) self.assertEqual(j2.ready, False) j0.complete = True j0.status = models.JobStatus.SUCCESS j0.save() self.set_counts() e.make_jobs_ready() self.compare_counts(ready=2) j0.refresh_from_db() j1a.refresh_from_db() j1b.refresh_from_db() j2.refresh_from_db() self.assertEqual(j0.ready, True) self.assertEqual(j1a.ready, True) self.assertEqual(j1b.ready, True) self.assertEqual(j2.ready, False) j1a.complete = True j1a.status = models.JobStatus.SUCCESS j1a.save() self.set_counts() e.make_jobs_ready() self.compare_counts() j1b.complete = True j1b.status = models.JobStatus.SUCCESS j1b.save() self.set_counts() e.make_jobs_ready() self.compare_counts(ready=1) j2.refresh_from_db() self.assertEqual(j2.ready, True)
def test_start_canceled_on_fail(self): user = utils.get_test_user() r0 = utils.create_recipe(name='recipe0', user=user) r1 = utils.create_recipe(name='recipe1', user=user) r2 = utils.create_recipe(name='recipe2', user=user) e0 = utils.create_event(user=user, cause=models.Event.PUSH) j0 = utils.create_job(recipe=r0, event=e0, user=user) utils.update_job(j0, status=models.JobStatus.SUCCESS, complete=True) j1 = utils.create_job(recipe=r1, event=e0, user=user) utils.update_job(j1, status=models.JobStatus.CANCELED, complete=True) j2 = utils.create_job(recipe=r2, event=e0, user=user) utils.update_job(j2, status=models.JobStatus.RUNNING, complete=True) e1 = utils.create_event(user=user, cause=models.Event.PUSH, commit1='12345') j3 = utils.create_job(recipe=r0, event=e1, user=user) utils.update_job(j3, status=models.JobStatus.SUCCESS, complete=True) j4 = utils.create_job(recipe=r1, event=e1, user=user) utils.update_job(j4, status=models.JobStatus.CANCELED, complete=True) j5 = utils.create_job(recipe=r2, event=e1, user=user) utils.update_job(j5, status=models.JobStatus.RUNNING, complete=True) e2 = utils.create_event(user=user, cause=models.Event.PUSH, commit1='123456') j6 = utils.create_job(recipe=r0, event=e2, user=user) utils.update_job(j6, status=models.JobStatus.SUCCESS, complete=True) j7 = utils.create_job(recipe=r1, event=e2, user=user) utils.update_job(j7, status=models.JobStatus.FAILED, complete=True) j8 = utils.create_job(recipe=r2, event=e2, user=user) utils.update_job(j8, status=models.JobStatus.FAILED_OK, complete=True) # If the job isn't a fail then it shouldn't do anything self.set_counts() UpdateRemoteStatus.start_canceled_on_fail(j6) self.compare_counts() # Normal behavior, a job fails and doesn't do anything to the previous event self.set_counts() UpdateRemoteStatus.start_canceled_on_fail(j7) self.compare_counts() repo_name = "%s/%s" % (e0.base.branch.repository.user.name, e0.base.branch.repository.name) branch_name = e0.base.branch.name branch_settings = { "auto_cancel_push_events_except_current": True, "auto_uncancel_previous_event": True } repo_settings = { repo_name: { "branch_settings": { branch_name: branch_settings } } } with self.settings(INSTALLED_GITSERVERS=[ utils.github_config(repo_settings=repo_settings) ]): # If the job isn't a fail then it shouldn't do anything self.set_counts() UpdateRemoteStatus.start_canceled_on_fail(j3) self.compare_counts() # A job fails and should go to the previous event and uncancel any jobs self.set_counts() UpdateRemoteStatus.start_canceled_on_fail(j7) self.compare_counts(ready=1, active_branches=1, canceled=-1, invalidated=1, num_changelog=1, num_jobs_completed=-1) j0.refresh_from_db() self.assertEqual(j0.status, models.JobStatus.SUCCESS) j1.refresh_from_db() self.assertEqual(j1.status, models.JobStatus.CANCELED) self.assertTrue(j1.complete) j2.refresh_from_db() self.assertEqual(j2.status, models.JobStatus.RUNNING) j3.refresh_from_db() self.assertEqual(j3.status, models.JobStatus.SUCCESS) j4.refresh_from_db() self.assertEqual(j4.status, models.JobStatus.NOT_STARTED) self.assertFalse(j4.complete) j5.refresh_from_db() self.assertEqual(j5.status, models.JobStatus.RUNNING) # If another job on the same event fails, it shouldn't try to uncancel previous events utils.update_job(j8, status=models.JobStatus.FAILED) utils.update_job(j4, status=models.JobStatus.CANCELED, complete=True) self.set_counts() UpdateRemoteStatus.start_canceled_on_fail(j7) self.compare_counts()
def test_event_complete(self, mock_del, mock_get, mock_post): ev = utils.create_event(cause=models.Event.PUSH) ev.comments_url = 'url' ev.save() git_config = utils.github_config(post_event_summary=False, failed_but_allowed_label_name=None, remote_update=True) with self.settings(INSTALLED_GITSERVERS=[git_config]): # Not complete, shouldn't do anything UpdateRemoteStatus.event_complete(ev) self.assertEqual(mock_get.call_count, 0) self.assertEqual(mock_post.call_count, 0) self.assertEqual(mock_del.call_count, 0) ev.complete = True ev.save() # event isn't a pull request, so we shouldn't do anything UpdateRemoteStatus.event_complete(ev) self.assertEqual(mock_get.call_count, 0) self.assertEqual(mock_post.call_count, 0) self.assertEqual(mock_del.call_count, 0) ev.cause = models.Event.PULL_REQUEST ev.status = models.JobStatus.SUCCESS ev.pull_request = utils.create_pr() ev.save() # No label so we shouldn't do anything UpdateRemoteStatus.event_complete(ev) self.assertEqual(mock_get.call_count, 0) self.assertEqual(mock_post.call_count, 0) self.assertEqual(mock_del.call_count, 0) git_config = utils.github_config(post_event_summary=False, failed_but_allowed_label_name='foo', remote_update=True) with self.settings(INSTALLED_GITSERVERS=[git_config]): # event is SUCCESS, so we shouldn't add a label but # we will try to remove an existing label UpdateRemoteStatus.event_complete(ev) self.assertEqual(mock_get.call_count, 0) self.assertEqual(mock_post.call_count, 0) self.assertEqual(mock_del.call_count, 1) # removing the label ev.status = models.JobStatus.FAILED ev.save() # Don't put anything if the event is FAILED UpdateRemoteStatus.event_complete(ev) self.assertEqual(mock_get.call_count, 0) self.assertEqual(mock_post.call_count, 0) self.assertEqual(mock_del.call_count, 2) ev.status = models.JobStatus.FAILED_OK ev.save() # should try to add a label UpdateRemoteStatus.event_complete(ev) self.assertEqual(mock_get.call_count, 0) self.assertEqual(mock_post.call_count, 1) # add the label self.assertEqual(mock_del.call_count, 2)
def test_scheduled(self): utils.create_event() response = self.client.get(reverse('ci:scheduled')) self.assertEqual(response.status_code, 200)
def test_view_pr(self, mock_collab): """ testing ci:view_pr """ # bad pr url = reverse('ci:view_pr', args=[1000,]) response = self.client.get(url) self.assertEqual(response.status_code, 404) pr = utils.create_pr() ev = utils.create_event() ev.pull_request = pr ev.save() utils.create_job(event=ev) user = utils.get_test_user() utils.simulate_login(self.client.session, user) # user not a collaborator, no alternate recipe form mock_collab.return_value = False url = reverse('ci:view_pr', args=[pr.pk,]) self.set_counts() response = self.client.get(url) self.compare_counts() self.assertEqual(response.status_code, 200) # user a collaborator, they get alternate recipe form mock_collab.return_value = True r0 = utils.create_recipe(name="Recipe 0", repo=ev.base.branch.repository, cause=models.Recipe.CAUSE_PULL_REQUEST_ALT) r1 = utils.create_recipe(name="Recipe 1", repo=ev.base.branch.repository, cause=models.Recipe.CAUSE_PULL_REQUEST_ALT) self.set_counts() response = self.client.get(url) self.compare_counts() self.assertEqual(response.status_code, 200) self.set_counts() # post an invalid alternate recipe form response = self.client.post(url, {}) self.assertEqual(response.status_code, 200) self.assertEqual(pr.alternate_recipes.count(), 0) self.compare_counts() utils.simulate_login(self.client.session, user) # post a valid alternate recipe form self.set_counts() response = self.client.post(url, {"recipes": [r0.pk, r1.pk]}) self.assertEqual(response.status_code, 200) self.assertEqual(pr.alternate_recipes.count(), 2) # The original job plus the two alternate jobs are ready self.compare_counts(jobs=2, ready=3, active=2, num_pr_alts=2) # post again with the same recipes self.set_counts() response = self.client.post(url, {"recipes": [r0.pk, r1.pk]}) self.assertEqual(response.status_code, 200) self.assertEqual(pr.alternate_recipes.count(), 2) self.compare_counts() # post again different recipes. We don't auto cancel jobs. self.set_counts() response = self.client.post(url, {"recipes": [r0.pk]}) self.assertEqual(response.status_code, 200) self.assertEqual(pr.alternate_recipes.count(), 1) self.compare_counts(num_pr_alts=-1) # clear alt recipes self.set_counts() response = self.client.post(url, {"recipes": []}) self.assertEqual(response.status_code, 200) self.assertEqual(pr.alternate_recipes.count(), 0) self.compare_counts(num_pr_alts=-1)
def test_user_open_prs(self): user = utils.create_user() url = reverse('ci:ajax:user_open_prs', args=["no_exist"]) response = self.client.get(url) self.assertEqual(response.status_code, 400) url = reverse('ci:ajax:user_open_prs', args=[user.name]) response = self.client.get(url) self.assertEqual(response.status_code, 400) get_data = {'last_request': 10} response = self.client.get(url, get_data) self.assertEqual(response.status_code, 200) data = response.json() self.assertEqual(len(data["repos"]), 0) self.assertEqual(len(data["prs"]), 0) self.assertEqual(len(data["events"]), 0) self.assertEqual(len(data["changed_events"]), 0) self.assertEqual(len(data["repo_status"]), 0) ev = utils.create_event() pr = utils.create_pr() pr.closed = True pr.username = user.name pr.save() ev.pull_request = pr ev.save() utils.create_job(event=ev) # not open response = self.client.get(url, get_data) self.assertEqual(response.status_code, 200) data = response.json() self.assertEqual(len(data["repos"]), 0) self.assertEqual(len(data["prs"]), 0) self.assertEqual(len(data["events"]), 0) self.assertEqual(len(data["changed_events"]), 0) self.assertEqual(len(data["repo_status"]), 0) # should be OK pr.closed = False pr.save() response = self.client.get(url, get_data) self.assertEqual(response.status_code, 200) data = response.json() self.assertEqual(len(data["repos"]), 1) self.assertEqual(len(data["prs"]), 1) self.assertEqual(len(data["events"]), 1) self.assertEqual(len(data["changed_events"]), 1) self.assertEqual(len(data["repo_status"]), 1) # use the last request. The changed_* shouldn't be set get_data["last_request"] = data["last_request"] + 10 response = self.client.get(url, get_data) self.assertEqual(response.status_code, 200) data = response.json() self.assertEqual(len(data["repos"]), 1) self.assertEqual(len(data["prs"]), 1) self.assertEqual(len(data["events"]), 1) self.assertEqual(len(data["changed_events"]), 0) self.assertEqual(len(data["repo_status"]), 0)
def test_claim_job(self): post_data = {'job_id': 0} user = utils.get_test_user() url = reverse('ci:client:claim_job', args=[user.build_key, 'testconfig', 'testClient']) # only post allowed self.set_counts() response = self.client.get(url) self.compare_counts() self.assertEqual(response.status_code, 405) # not allowed # setup a ready job job = utils.create_job(user=user) job.ready = True job.active = True job.event.cause = models.Event.PULL_REQUEST pr = utils.create_pr() job.event.pull_request = pr job.event.save() job.status = models.JobStatus.NOT_STARTED job_id = job.pk job.save() # bad config post_data = {'job_id': job_id} self.set_counts() response = self.client_post_json(url, post_data) self.compare_counts() self.assertEqual(response.status_code, 400) # bad request # config different than job utils.create_build_config(name="otherBuildConfig") config2 = models.BuildConfig.objects.exclude(pk=job.config.pk).first() url = reverse('ci:client:claim_job', args=[user.build_key, config2.name, 'testClient']) post_data = {'job_id': job_id} self.set_counts() response = self.client_post_json(url, post_data) self.compare_counts() self.assertEqual(response.status_code, 400) # bad request # bad job url = reverse('ci:client:claim_job', args=[user.build_key, job.config.name, 'testClient']) post_data = {'job_id': 0} self.set_counts() response = self.client_post_json(url, post_data) self.compare_counts() self.assertEqual(response.status_code, 400) # bad request # valid job, should be ok post_data = {'job_id': job_id} self.set_counts() response = self.client_post_json(url, post_data) self.compare_counts(num_clients=1) self.assertEqual(response.status_code, 200) data = response.json() self.assertEqual(data['job_id'], job_id) self.assertEqual(data['status'], 'OK') job.refresh_from_db() job.event.refresh_from_db() job.event.pull_request.refresh_from_db() self.assertEqual(job.status, models.JobStatus.RUNNING) self.assertEqual(job.event.status, models.JobStatus.RUNNING) self.assertEqual(job.event.pull_request.status, models.JobStatus.RUNNING) # create a job with a newer event. # This allows to test the update_status() function event2 = utils.create_event(commit1="2345", commit2="2345") job2 = utils.create_job(user=user, event=event2) job2.ready = True job2.active = True job2.event.cause = models.Event.PULL_REQUEST job2.event.pull_request = pr job2.event.save() job2.status = models.JobStatus.NOT_STARTED job2.save() job.status = models.JobStatus.NOT_STARTED job.client = None job.save() job.event.status = models.JobStatus.SUCCESS job.event.save() job.event.pull_request.status = models.JobStatus.SUCCESS job.event.pull_request.save() # valid job, should be ok, shouldn't update the status since # there is a newer event self.set_counts() response = self.client_post_json(url, post_data) self.compare_counts() self.assertEqual(response.status_code, 200) data = response.json() self.assertEqual(data['job_id'], job_id) self.assertEqual(data['status'], 'OK') job.refresh_from_db() job.event.refresh_from_db() job.event.pull_request.refresh_from_db() self.assertEqual(job.status, models.JobStatus.RUNNING) self.assertEqual(job.event.status, models.JobStatus.RUNNING) # there is a newer event so this event doesn't update the PullRequest status self.assertEqual(job.event.pull_request.status, models.JobStatus.SUCCESS) # valid job, but wrong client job.invalidated = True job.same_client = True job.status = models.JobStatus.NOT_STARTED client = utils.create_client(name='old_client') job.client = client job.save() self.set_counts() response = self.client_post_json(url, post_data) self.compare_counts() self.assertEqual(response.status_code, 400) # valid job, and correct client url = reverse('ci:client:claim_job', args=[user.build_key, job.config.name, client.name]) self.set_counts() response = self.client_post_json(url, post_data) self.compare_counts() self.assertEqual(response.status_code, 200) data = response.json() self.assertEqual(data['job_id'], job_id) self.assertEqual(data['status'], 'OK') # valid job, and job client was null, should go through job.client = None job.save() url = reverse('ci:client:claim_job', args=[user.build_key, job.config.name, 'new_client']) self.set_counts() response = self.client_post_json(url, post_data) self.compare_counts(num_clients=1) self.assertEqual(response.status_code, 200) data = response.json() self.assertEqual(data['job_id'], job_id) self.assertEqual(data['status'], 'OK') job.refresh_from_db() job.event.refresh_from_db() job.event.pull_request.refresh_from_db() self.assertEqual(job.status, models.JobStatus.RUNNING) self.assertEqual(job.event.status, models.JobStatus.RUNNING) # there is a newer event so this event doesn't update the PullRequest status self.assertEqual(job.event.pull_request.status, models.JobStatus.SUCCESS)
def test_get_user_repos_info(self): request = self.factory.get('/') request.session = self.client.session repos = [] for i in range(3): repo = utils.create_repo(name="repo%s" % i) repo.active = True repo.save() branch = utils.create_branch(name="branch0", user=repo.user, repo=repo) branch.status = models.JobStatus.SUCCESS branch.save() ev = utils.create_event(branch1=branch, branch2=branch, user=repo.user) utils.create_job(event=ev, user=repo.user) repos.append(repo) # user not logged in repo_status, evinfo, default = views.get_user_repos_info(request) self.assertEqual(len(repo_status), 3) self.assertEqual(len(evinfo), 3) self.assertFalse(default) # user not logged in, default enforced request = self.factory.get('/?default') repo_status, evinfo, default = views.get_user_repos_info(request) self.assertEqual(len(repo_status), 3) self.assertEqual(len(evinfo), 3) self.assertTrue(default) request = self.factory.get('/') user = repos[0].user utils.simulate_login(self.client.session, user) request.session = self.client.session # user is logged in but no prefs set repo_status, evinfo, default = views.get_user_repos_info(request) self.assertEqual(len(repo_status), 3) self.assertEqual(len(evinfo), 3) self.assertFalse(default) # user is logged in, add repos to prefs for i in range(3): user.preferred_repos.add(repos[i]) repo_status, evinfo, default = views.get_user_repos_info(request) self.assertEqual(len(repo_status), i+1) self.assertEqual(len(evinfo), i+1) self.assertFalse(default) # user has one pref but default is enforced user.preferred_repos.clear() user.preferred_repos.add(repos[0]) request = self.factory.get('/?default') repo_status, evinfo, default = views.get_user_repos_info(request) self.assertEqual(len(repo_status), 3) self.assertEqual(len(evinfo), 3) self.assertTrue(default) with self.settings(INSTALLED_GITSERVERS=[utils.github_config(hostname="server_does_not_exist")]): user.preferred_repos.clear() user.preferred_repos.add(repos[0]) request = self.factory.get('/') repo_status, evinfo, default = views.get_user_repos_info(request) self.assertEqual(len(repo_status), 3) self.assertEqual(len(evinfo), 3) self.assertFalse(default)