def test_session(self): user = utils.get_test_user() oauth = self.server.auth() self.assertEqual(oauth.start_session(self.client.session), None) session = self.client.session self.assertFalse(oauth.is_signed_in(session)) session[self.oauth._user_key] = 'no_user' session.save() self.assertFalse(oauth.is_signed_in(session)) session[self.oauth._token_key] = 'token' session.save() self.assertTrue(oauth.is_signed_in(session)) self.assertEqual(oauth.signed_in_user(user.server, session), None) self.assertNotEqual(oauth.start_session(session), None) session[self.oauth._user_key] = user.name session.save() self.assertEqual(oauth.signed_in_user(user.server, session), user) self.assertNotEqual(oauth.user_token_to_oauth_token(user), None) user2 = utils.create_user() self.assertEqual(oauth.user_token_to_oauth_token(user2), None) self.assertNotEqual(oauth.start_session_for_user(user), None) oauth.set_browser_session_from_user(session, user) session.save() self.assertEqual(session[self.oauth._user_key], user.name)
def test_start_session_by_name(self): with self.settings(DEBUG=True): # invalid name response = self.client.get( reverse('ci:start_session_by_name', args=['nobody'])) self.assertEqual(response.status_code, 404) user = utils.get_test_user() owner = utils.get_owner() # owner doesn't have a token response = self.client.get( reverse('ci:start_session_by_name', args=[owner.name])) self.assertEqual(response.status_code, 404) # valid, user has a token response = self.client.get( reverse('ci:start_session_by_name', args=[user.name])) self.assertEqual(response.status_code, 302) auth = user.auth() self.assertIn(auth._user_key, self.client.session) self.assertIn(auth._token_key, self.client.session) with self.settings(DEBUG=False): response = self.client.get( reverse('ci:start_session_by_name', args=[user.name])) self.assertEqual(response.status_code, 404)
def test_job_script(self, mock_collab): # bad pk mock_collab.return_value = False response = self.client.get(reverse('ci:job_script', args=[1000])) self.assertEqual(response.status_code, 404) with utils.RecipeDir(): user = utils.get_test_user() job = utils.create_job(user=user) job.recipe.build_user = user job.recipe.save() utils.create_prestepsource(recipe=job.recipe) utils.create_recipe_environment(recipe=job.recipe) step = utils.create_step(recipe=job.recipe, filename='scripts/1.sh') utils.create_step_environment(step=step) url = reverse('ci:job_script', args=[job.pk]) response = self.client.get(url) # owner doesn't have permission self.assertEqual(response.status_code, 404) mock_collab.return_value = True utils.simulate_login(self.client.session, user) response = self.client.get(url) self.assertEqual(response.status_code, 200) self.assertContains(response, job.recipe.name)
def test_ensure_single_new_comment(self, mock_del, mock_get, mock_post): user = utils.get_test_user() api = user.api() # No comments, just create a new one mock_get.return_value = utils.Response() ProcessCommands.ensure_single_new_comment(api, user, "some_url", "Some message", "Some re") self.assertEqual(mock_get.call_count, 1) # 1 call to get existing comments self.assertEqual(mock_del.call_count, 0) self.assertEqual(mock_post.call_count, 1) # 1 call to create a comment # Existing comments, they are deleted and a new one is created c0 = { "user": { "login": user.name }, "body": "some message", "url": "url1" } c1 = { "user": { "login": user.name }, "body": "some message 2", "url": "url2" } mock_get.return_value = utils.Response([c0, c1]) ProcessCommands.ensure_single_new_comment(api, user, "some_url", "some message", "some me") self.assertEqual(mock_get.call_count, 2) self.assertEqual(mock_del.call_count, 2) self.assertEqual(mock_post.call_count, 2)
def test_view_client(self): user = utils.get_test_user() with self.settings(INSTALLED_GITSERVERS=[utils.github_config(authorized_users=[])]): url = reverse('ci:view_client', args=[1000,]) response = self.client.get(url) self.assertEqual(response.status_code, 404) client = utils.create_client() # not logged in url = reverse('ci:view_client', args=[client.pk,]) response = self.client.get(url) self.assertEqual(response.status_code, 200) self.assertContains(response, "You are not allowed") # logged in but not on the authorized list utils.simulate_login(self.client.session, user) response = self.client.get(url) self.assertEqual(response.status_code, 200) self.assertContains(response, "You are not allowed") with self.settings(INSTALLED_GITSERVERS=[utils.github_config(authorized_users=[user.name])]): # logged in and on the authorized list response = self.client.get(url) self.assertEqual(response.status_code, 200) self.assertNotContains(response, "You are not allowed") # Should be cached response = self.client.get(url) self.assertEqual(response.status_code, 200) self.assertNotContains(response, "You are not allowed")
def test_webhook(self): url = reverse('ci:gitlab:webhook', args=[10000]) # only post allowed response = self.client.get(url) self.assertEqual(response.status_code, 405) # not allowed # no user data = {'key': 'value'} response = self.client_post_json(url, data) self.assertEqual(response.status_code, 400) # not json user = utils.get_test_user(server=self.server) url = reverse('ci:gitlab:webhook', args=[user.build_key]) response = self.client.post(url, data) self.assertEqual(response.status_code, 400) # user with no recipes response = self.client_post_json(url, data) self.assertEqual(response.status_code, 400) # unknown json utils.create_recipe(user=user) response = self.client_post_json(url, data) self.assertEqual(response.status_code, 400)
def create_job_with_nested_bash(recipe_dir, name="TestJob", sleep=10): user = utils.get_test_user() recipe = utils.create_recipe(user=user, name=name) test_job = utils.create_job(user=user, recipe=recipe) test_job.ready = True test_job.client = None test_job.status = models.JobStatus.NOT_STARTED test_job.save() step = utils.create_step(name="step0", recipe=recipe, position=0) step.filename = "step0.sh" step.save() script_filename = os.path.join(recipe_dir, step.filename) sub_script_filename = os.path.join(recipe_dir, "step0_sub.sh") sub_sub_script_filename = os.path.join(recipe_dir, "step0_sub_sub.sh") with open(script_filename, "w") as f: f.write("#!/bin/bash\necho 'Launching {0}'\n{0}\necho '{0} returned '". format(sub_script_filename)) with open(sub_script_filename, "w") as f: f.write("#!/bin/bash\necho 'Launching {0}'\n{0}\necho '{0} returned'". format(sub_sub_script_filename)) import stat st = os.stat(sub_script_filename) os.chmod(sub_script_filename, st.st_mode | stat.S_IEXEC) with open(sub_sub_script_filename, "w") as f: f.write( "#!/bin/bash\necho 'Sleeping {0}...'\nsleep {0}\necho 'Finished sleeping'" .format(sleep)) st = os.stat(sub_sub_script_filename) os.chmod(sub_sub_script_filename, st.st_mode | stat.S_IEXEC) return test_job
def create_running_job(self): user = utils.get_test_user() job = utils.create_job(user=user) result = utils.create_step_result(job=job) client = utils.create_client() job.client = client job.event.cause = models.Event.PULL_REQUEST job.status = models.JobStatus.RUNNING job.save() return job, result
def test_update_user(self): user = utils.get_test_user() session = { self.oauth._token_key: json.loads(user.token), self.oauth._user_key: user.name } auth = self.server.auth() auth.update_user(session) user2 = utils.create_user() session[self.oauth._user_key] = user2.name auth.update_user(session)
def create_client_job(recipe_dir, name="TestJob", sleep=1, n_steps=3, extra_script=''): user = utils.get_test_user() recipe = utils.create_recipe(user=user, name=name) test_job = utils.create_job(user=user, recipe=recipe) test_job.ready = True test_job.client = None test_job.status = models.JobStatus.NOT_STARTED test_job.save() # create a prestep to make sure sourcing functions work prestep0 = utils.create_prestepsource( filename="prestep0_{}.sh".format(name), recipe=recipe) with open(os.path.join(recipe_dir, prestep0.filename), "w") as f: f.write('function start_message()\n{\n echo start "$*"\n}') # create a prestep to make sure sourcing functions work prestep1 = utils.create_prestepsource( filename="prestep1_{}.sh".format(name), recipe=recipe) with open(os.path.join(recipe_dir, prestep1.filename), "w") as f: f.write('function end_message()\n{\n echo end "$*"\n}') # create a global environment variable to test env works # as well as BUILD_ROOT replacement utils.create_recipe_environment(name="GLOBAL_NAME", value="BUILD_ROOT/global", recipe=recipe) count = 0 for s in [f"step{i}".format(i) for i in range(n_steps)]: step = utils.create_step(name=s, recipe=recipe, position=count) # create a step environment variable to test env works # as well as BUILD_ROOT replacement utils.create_step_environment(name="STEP_NAME", value="BUILD_ROOT/%s" % s, step=step) step.filename = "{}_{}.sh".format(s, name) step.save() count += 1 script_filename = os.path.join(recipe_dir, step.filename) job_script = "echo $GLOBAL_NAME $CIVET_RECIPE_NAME $STEP_NAME\n" job_script += "start_message {0}:{1}\n".format(recipe.name, s) job_script += "sleep {0}\n".format(sleep) job_script += "end_message {0}:{1}\n".format(recipe.name, s) job_script += extra_script with open(script_filename, "w") as f: f.write(job_script) return test_job
def check_output(self, output, os_name, os_version, os_other, mods): user = utils.get_test_user() job = utils.create_job(user=user) step_result = utils.create_step_result(job=job) step_result.output = output step_result.save() client = utils.create_client() job.client = client job.save() ParseOutput.set_job_info(job) job.refresh_from_db() self.assertEqual(job.operating_system.name, os_name) self.assertEqual(job.operating_system.version, os_version) self.assertEqual(job.operating_system.other, os_other) self.check_modules(job, mods)
def test_main(self): """ testing ci:main """ response = self.client.get(reverse('ci:main')) self.assertEqual(response.status_code, 200) self.assertContains(response, 'Sign in') self.assertNotContains(response, 'Sign out') user = utils.get_test_user() utils.simulate_login(self.client.session, user) auth = user.auth() self.assertIn(auth._user_key, self.client.session) response = self.client.get(reverse('ci:main')) self.assertContains(response, 'Sign out') self.assertNotContains(response, 'Sign in')
def test_edit_comment(self, mock_patch, mock_del, mock_get, mock_post): user = utils.get_test_user() api = user.api() mock_get.return_value = utils.Response() ProcessCommands.edit_comment(api, user, "some_url", "Some message", "Some re") self.assertEqual(mock_get.call_count, 1) # 1 call to get the current comments self.assertEqual(mock_del.call_count, 0) self.assertEqual(mock_patch.call_count, 0) self.assertEqual(mock_post.call_count, 1) # 1 call to post the comment # Only 1 existing comment, should just update it c0 = { "user": { "login": user.name }, "body": "some message", "url": "url" } mock_get.return_value = utils.Response([c0]) ProcessCommands.edit_comment(api, user, "some_url", "some other message", "some me") self.assertEqual(mock_get.call_count, 2) self.assertEqual(mock_del.call_count, 0) self.assertEqual(mock_patch.call_count, 1) # Updates the existing comment self.assertEqual(mock_post.call_count, 1) # 2 existing comment, 1 should be deleted and 1 should be updated c1 = { "user": { "login": user.name }, "body": "some message 2", "url": "url" } mock_get.return_value = utils.Response([c0, c1]) ProcessCommands.edit_comment(api, user, "some_url", "some other message", "some me") self.assertEqual(mock_get.call_count, 3) self.assertEqual(mock_del.call_count, 1) self.assertEqual(mock_patch.call_count, 2) self.assertEqual(mock_post.call_count, 1)
def create_client_job(recipe_dir, name="TestJob", sleep=1): user = utils.get_test_user() recipe = utils.create_recipe(user=user, name=name) test_job = utils.create_job(user=user, recipe=recipe) test_job.ready = True test_job.client = None test_job.status = models.JobStatus.NOT_STARTED test_job.save() # create a prestep to make sure sourcing functions work prestep0 = utils.create_prestepsource(filename="prestep0.sh", recipe=recipe) with open(os.path.join(recipe_dir, prestep0.filename), "w") as f: f.write('function start_message()\n{\n echo start "$*"\n}') # create a prestep to make sure sourcing functions work prestep1 = utils.create_prestepsource(filename="prestep1.sh", recipe=recipe) with open(os.path.join(recipe_dir, prestep1.filename), "w") as f: f.write('function end_message()\n{\n echo end "$*"\n}') # create a global environment variable to test env works # as well as BUILD_ROOT replacement utils.create_recipe_environment(name="GLOBAL_NAME", value="BUILD_ROOT/global", recipe=recipe) count = 0 for s in ["step0", "step1", "step2"]: step = utils.create_step(name=s, recipe=recipe, position=count) # create a step environment variable to test env works # as well as BUILD_ROOT replacement utils.create_step_environment(name="STEP_NAME", value="BUILD_ROOT/%s" % s, step=step) step.filename = "%s.sh" % s step.save() count += 1 script_filename = os.path.join(recipe_dir, step.filename) with open(script_filename, "w") as f: f.write( "echo $GLOBAL_NAME $recipe_name $STEP_NAME\nstart_message {0}:{1}\nsleep {2}\nend_message {0}:{1}\n" .format(recipe.name, s, sleep)) return test_job
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_activate_event(self, mock_collab): # only posts are allowed response = self.client.get(reverse('ci:activate_event', args=[1000])) self.assertEqual(response.status_code, 405) response = self.client.post(reverse('ci:activate_event', args=[1000])) self.assertEqual(response.status_code, 404) job = utils.create_job() job.active = False job.save() self.set_counts() response = self.client.post(reverse('ci:activate_event', args=[job.event.pk])) self.compare_counts() # not signed in self.assertEqual(response.status_code, 403) user = utils.get_test_user() utils.simulate_login(self.client.session, user) mock_collab.return_value = False self.set_counts() response = self.client.post(reverse('ci:activate_event', args=[job.event.pk])) self.compare_counts() # not a collaborator self.assertEqual(response.status_code, 403) mock_collab.return_value = True # A collaborator self.set_counts() response = self.client.post(reverse('ci:activate_event', args=[job.event.pk])) self.compare_counts(ready=1, active=1, num_changelog=1) self.assertEqual(response.status_code, 302) # redirect job.refresh_from_db() self.assertTrue(job.active) # no jobs to activate self.set_counts() response = self.client.post(reverse('ci:activate_event', args=[job.event.pk])) self.compare_counts() self.assertEqual(response.status_code, 302) # redirect job.refresh_from_db() self.assertTrue(job.active)
def test_update_session_token(self): """ Just get some coverage on the inner token updater functions. """ self.client = Client() user = utils.get_test_user() oauth = user.auth() oauth._token_key = 'token_key' oauth._client_id = 'client_id' oauth._secret_id = 'secret_id' oauth._user_key = 'user_key' oauth._server_type = user.server.host_type session = self.client.session session[oauth._user_key] = user.name session.save() token_json = {'token': 'new token'} oauth_api.update_session_token(session, oauth, token_json) user.refresh_from_db() self.assertEqual(user.token, json.dumps(token_json)) self.assertEqual(session[oauth._token_key], token_json)
def test_close_pr(self): user = utils.get_test_user(server=self.server) repo = utils.create_repo(user=user) pr = utils.create_pr(repo=repo, number=1) pr.closed = False pr.save() views.close_pr('foo', 'bar', 1, user.server) pr.refresh_from_db() self.assertFalse(pr.closed) views.close_pr(user.name, 'bar', 1, user.server) pr.refresh_from_db() self.assertFalse(pr.closed) views.close_pr(user.name, repo.name, 0, user.server) pr.refresh_from_db() self.assertFalse(pr.closed) views.close_pr(user.name, repo.name, 1, user.server) pr.refresh_from_db() self.assertTrue(pr.closed)
def test_view_profile(self): # invalid git server response = self.client.get(reverse('ci:view_profile', args=[1000, "no_exist"])) self.assertEqual(response.status_code, 404) # not signed in should redirect to sign in server = utils.create_git_server() response = self.client.get(reverse('ci:view_profile', args=[server.host_type, server.name])) self.assertEqual(response.status_code, 302) # redirect user = utils.get_test_user() repo1 = utils.create_repo(name='repo1', user=user) repo2 = utils.create_repo(name='repo2', user=user) repo3 = utils.create_repo(name='repo3', user=user) utils.create_recipe(name='r1', user=user, repo=repo1) utils.create_recipe(name='r2', user=user, repo=repo2) utils.create_recipe(name='r3', user=user, repo=repo3) # signed in utils.simulate_login(self.client.session, user) response = self.client.get(reverse('ci:view_profile', args=[user.server.host_type, user.server.name])) self.assertEqual(response.status_code, 200)
def test_callback(self, mock_get, mock_fetch_token): user = utils.get_test_user() auth = self.server.auth() mock_fetch_token.return_value = { 'access_token': '1234', 'token_type': 'bearer', 'scope': 'repo' } mock_get.return_value = utils.Response( {auth._callback_user_key: user.name}) session = self.client.session session[auth._state_key] = 'state' session.save() url = reverse('ci:github:callback', args=[self.server.name]) response = self.client.post(url) self.assertEqual(response.status_code, 302) mock_fetch_token.side_effect = Exception('Bam!') url = reverse('ci:github:callback', args=[self.server.name]) response = self.client.post(url) self.assertEqual(response.status_code, 302)
def test_job_finished_unrunnable(self, mock_status): 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) r2.depends_on.add(r1) r1.depends_on.add(r0) j0 = utils.create_job(user=user, recipe=r0) utils.create_job(user=user, recipe=r1) utils.create_job(user=user, recipe=r2) post_data = {'seconds': 0, 'complete': True} client = utils.create_client() j0.client = client j0.save() step_result = utils.create_step_result(job=j0) step_result.status = models.JobStatus.FAILED step_result.save() # should be ok url = reverse('ci:client:job_finished', args=[user.build_key, client.name, j0.pk]) self.set_counts() response = self.client_post_json(url, post_data) self.compare_counts(num_events_completed=1, num_jobs_completed=1, active_branches=1) self.assertEqual(response.status_code, 200) self.assertEqual( mock_status.call_count, 3) # 1 for the job complete update and 2 for the won't run update step_result.status = models.JobStatus.SUCCESS step_result.save() self.set_counts() response = self.client_post_json(url, post_data) self.compare_counts(ready=1) self.assertEqual(response.status_code, 200) self.assertEqual(mock_status.call_count, 4) # 1 for the job complete update
def test_get_result_output(self, mock_is_collaborator): mock_is_collaborator.return_value = False url = reverse('ci:ajax:get_result_output') # no parameters response = self.client.get(url) self.assertEqual(response.status_code, 400) result = utils.create_step_result() result.output = 'output' result.save() result.job.recipe.private = False result.job.recipe.save() data = {'result_id': result.pk} # should be ok since recipe isn't private response = self.client.get(url, data) self.assertEqual(response.status_code, 200) json_data = response.json() self.assertIn(result.output, json_data["contents"]) result.job.recipe.private = True result.job.recipe.save() # recipe is private and not signed in, shouldn't see it response = self.client.get(url, data) self.assertEqual(response.status_code, 403) user = utils.get_test_user() utils.simulate_login(self.client.session, user) # recipe is private, not a collaborator response = self.client.get(url, data) self.assertEqual(response.status_code, 403) mock_is_collaborator.return_value = True # recipe is private, but a collaborator response = self.client.get(url, data) self.assertEqual(response.status_code, 200) json_data = response.json() self.assertIn(result.output, json_data["contents"])
def test_get_job_info(self, contents_mock): with utils.RecipeDir(): contents_mock.return_value = 'contents' user = utils.get_test_user() job = utils.create_job(user=user) utils.create_prestepsource(recipe=job.recipe) step = utils.create_step(recipe=job.recipe) utils.create_step_environment(step=step) utils.create_recipe_environment(recipe=job.recipe) self.assertEqual(job.recipe_repo_sha, "") self.set_counts() data = views.get_job_info(job) self.compare_counts() job.refresh_from_db() self.assertNotEqual(job.recipe_repo_sha, "") # hex shas are 40 characters self.assertEqual(len(job.recipe_repo_sha), 40) self.assertIn('recipe_name', data) self.assertIn('environment', data) self.assertIn('job_id', data) self.assertIn('prestep_sources', data) self.assertIn('steps', data)
def test_get_job_results(self): # bad pk url = reverse('ci:job_results', args=[1000]) response = self.client.get(url) self.assertEqual(response.status_code, 404) user = utils.get_test_user() job = utils.create_job(user=user) step = utils.create_step(recipe=job.recipe, filename='common/1.sh') sr = utils.create_step_result(job=job, step=step) sr.output = "some output" sr.save() utils.create_step_environment(step=step) url = reverse('ci:job_results', args=[job.pk]) response = self.client.get(url) # owner doesn't have permission self.assertEqual(response.status_code, 403) # logged in, should get the results utils.simulate_login(self.client.session, user) response = self.client.get(url) self.assertEqual(response.status_code, 200)
def test_view_pr_matched(self, mock_collab): user = utils.get_test_user() utils.simulate_login(self.client.session, user) mock_collab.return_value = True with self.settings(INSTALLED_GITSERVERS=[utils.github_config(recipe_label_activation=utils.default_labels())]): self.set_label_on_recipes() changed_files = ["docs/foo", "docs/bar"] self.set_counts() self.create_pr_data(pr_num=2, changed_files=changed_files) self.compare_counts(jobs=2, active=2, events=1, ready=1, prs=1, num_pr_alts=1, active_repos=1) pr = models.PullRequest.objects.get(number=2) self.assertEqual(pr.alternate_recipes.count(), 1) url = reverse('ci:view_pr', args=[pr.pk,]) # try adding a default recipe recipes = models.Recipe.objects.order_by('created').filter(cause = models.Recipe.CAUSE_PULL_REQUEST) self.assertEqual(recipes.count(), 2) self.set_counts() data = {"recipes": [pr.alternate_recipes.first().pk], "default_recipes": [recipes[1].pk,]} response = self.client.post(url, data) self.assertEqual(response.status_code, 200) self.compare_counts(jobs=1, active=1) # shouldn't be able to remove one of the default self.set_counts() data["default_recipes"] = [] response = self.client.post(url, data) self.assertEqual(response.status_code, 200) self.compare_counts() # try the original again, should give a form error (which we can't detect) data["default_recipes"] = [recipes[1].pk,] self.set_counts() response = self.client.post(url, data) self.assertEqual(response.status_code, 200) self.compare_counts()
def test_step_start_pr_status(self, mock_post): user = utils.get_test_user() job = utils.create_job(user=user) utils.update_job(job, status=models.JobStatus.CANCELED) results = utils.create_step_result(job=job) results.exit_status = 1 results.save() job.event.cause = models.Event.PUSH job.event.save() with self.settings( INSTALLED_GITSERVERS=[utils.github_config( remote_update=True)]): # Wrong cause UpdateRemoteStatus.step_start_pr_status(results, job) self.assertEqual(mock_post.call_count, 0) job.event.cause = models.Event.PULL_REQUEST job.event.save() # OK UpdateRemoteStatus.step_start_pr_status(results, job) self.assertEqual(mock_post.call_count, 1)
def test_start_session(self): with self.settings(DEBUG=True): response = self.client.get(reverse('ci:start_session', args=[1000])) self.assertEqual(response.status_code, 404) user = utils.get_test_user() owner = utils.get_owner() response = self.client.get( reverse('ci:start_session', args=[owner.pk])) # owner doesn't have a token self.assertEqual(response.status_code, 404) response = self.client.get( reverse('ci:start_session', args=[user.pk])) self.assertEqual(response.status_code, 302) auth = user.auth() self.assertIn(auth._user_key, self.client.session) self.assertIn(auth._token_key, self.client.session) with self.settings(DEBUG=False): response = self.client.get( reverse('ci:start_session', args=[user.pk])) self.assertEqual(response.status_code, 404)
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_activate_job(self, mock_collab): # only posts are allowed response = self.client.get(reverse('ci:activate_job', args=[1000])) self.assertEqual(response.status_code, 405) response = self.client.post(reverse('ci:activate_job', args=[1000])) self.assertEqual(response.status_code, 404) job = utils.create_job() job.active = False job.save() self.set_counts() url = reverse('ci:activate_job', args=[job.pk]) self.assertEqual(job.event.base.branch.status, models.JobStatus.NOT_STARTED) response = self.client.post(url) self.compare_counts() # not signed in self.assertEqual(response.status_code, 403) user = utils.get_test_user() utils.simulate_login(self.client.session, user) mock_collab.return_value = False self.set_counts() response = self.client.post(url) self.compare_counts() # not a collaborator job = models.Job.objects.get(pk=job.pk) self.assertEqual(response.status_code, 403) self.assertFalse(job.active) mock_collab.return_value = True # A collaborator self.set_counts() response = self.client.post(url) self.compare_counts(ready=1, active=1, num_changelog=1) self.assertEqual(response.status_code, 302) # redirect job.refresh_from_db() self.assertTrue(job.active) # make sure activating a job doesn't mark it as ready r1 = utils.create_recipe(name='r1') job.recipe.depends_on.add(r1) j1 = utils.create_job(recipe=r1) job.active = False job.ready = False job.save() j1.active = False j1.ready = False j1.save() self.set_counts() response = self.client.post(url) self.compare_counts(active=1, num_changelog=1) self.assertEqual(response.status_code, 302) # redirect job.refresh_from_db() self.assertTrue(job.active) self.assertFalse(job.ready) # now it should be marked as ready j1.ready = True j1.complete = True j1.status = models.JobStatus.SUCCESS j1.save() job.ready = False job.active = False job.save() self.set_counts() response = self.client.post(url) # The branch is now set to RUNNING since there is an already finished job self.compare_counts(ready=1, active=1, num_changelog=1, active_branches=1) self.assertEqual(response.status_code, 302) # redirect job.refresh_from_db() job.event.base.branch.refresh_from_db() self.assertEqual(job.event.base.branch.status, models.JobStatus.RUNNING) self.assertTrue(job.active) self.assertTrue(job.ready) # Calling activate on an already active job shouldn't do anything self.set_counts() response = self.client.post(url) self.compare_counts() self.assertEqual(response.status_code, 302) # redirect
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)