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 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_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 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_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_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 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_job_finished_status(self): user = utils.get_test_user() recipe = utils.create_recipe(user=user) job = utils.create_job(recipe=recipe, user=user) step0 = utils.create_step(name='step0', recipe=recipe) step1 = utils.create_step(name='step1', recipe=recipe, position=1) step0_result = utils.create_step_result(step=step0, job=job) step1_result = utils.create_step_result(step=step1, job=job) step0_result.status = models.JobStatus.FAILED_OK step0_result.save() step1_result.status = models.JobStatus.SUCCESS step1_result.save() client = utils.create_client() job.client = client job.save() job.event.comments_url = 'http://localhost' job.event.pull_request = utils.create_pr() job.event.save() url = reverse('ci:client:job_finished', args=[user.build_key, client.name, job.pk]) # A step has FAILED_OK # So final status is FAILED_OK and we update the PR post_data = {'seconds': 0, 'complete': True} with patch('ci.github.api.GitHubAPI') as mock_api: self.set_counts() response = self.client_post_json(url, post_data) self.compare_counts(num_events_completed=1, num_jobs_completed=1) self.assertEqual(response.status_code, 200) self.assertTrue(mock_api.called) self.assertTrue(mock_api.return_value.update_pr_status.called) job.refresh_from_db() self.assertEqual(job.status, models.JobStatus.FAILED_OK) os_obj = models.OSVersion.objects.get(name="Other") self.assertEqual(job.operating_system.pk, os_obj.pk) self.assertEqual(job.loaded_modules.count(), 1) self.assertEqual(job.loaded_modules.first().name, "None") # A step FAILED # So final status is FAILED and we update the PR step0_result.status = models.JobStatus.FAILED step0_result.save() with patch('ci.github.api.GitHubAPI') as mock_api: self.set_counts() response = self.client_post_json(url, post_data) self.compare_counts() self.assertEqual(response.status_code, 200) self.assertTrue(mock_api.called) self.assertTrue(mock_api.return_value.update_pr_status.called) job.refresh_from_db() self.assertEqual(job.status, models.JobStatus.FAILED) step0_result.status = models.JobStatus.SUCCESS step0_result.save() # All steps passed # So final status is SUCCESS and we update the PR with patch('ci.github.api.GitHubAPI') as mock_api: self.set_counts() response = self.client_post_json(url, post_data) self.compare_counts() self.assertEqual(response.status_code, 200) self.assertTrue(mock_api.called) self.assertTrue(mock_api.return_value.update_pr_status.called) job.refresh_from_db() self.assertEqual(job.status, models.JobStatus.SUCCESS) step0_result.status = models.JobStatus.FAILED step0_result.save() # A step FAILED # So final status is FAILED and we update the PR with patch('ci.github.api.GitHubAPI') as mock_api: self.set_counts() response = self.client_post_json(url, post_data) self.compare_counts() self.assertEqual(response.status_code, 200) self.assertTrue(mock_api.called) self.assertTrue(mock_api.return_value.update_pr_status.called) job.refresh_from_db() self.assertEqual(job.status, models.JobStatus.FAILED)