Esempio n. 1
0
    def test_invalidate_client(self, mock_collab):
        job = utils.create_job()
        client = utils.create_client()
        client2 = utils.create_client(name="client2")
        mock_collab.return_value = True
        url = reverse('ci:invalidate', args=[job.pk])
        post_data = {}
        self.set_counts()
        response = self.client.post(url, data=post_data)
        self.assertEqual(response.status_code, 302) #redirect
        self.compare_counts(ready=1, invalidated=1, num_changelog=1)
        self.check_job_invalidated(job)
        job.client = client
        job.save()

        self.set_counts()
        post_data["client_list"] = client.pk
        response = self.client.post(url, data=post_data)
        self.assertEqual(response.status_code, 302) #redirect
        self.compare_counts(num_changelog=1)
        self.check_job_invalidated(job, True, client)

        self.set_counts()
        post_data["client_list"] = client2.pk
        response = self.client.post(url, data=post_data)
        self.assertEqual(response.status_code, 302) #redirect
        self.compare_counts(num_changelog=1)
        self.check_job_invalidated(job, True, client2)

        self.set_counts()
        post_data["client_list"] = 0
        response = self.client.post(url, data=post_data)
        self.assertEqual(response.status_code, 302) #redirect
        self.compare_counts(num_changelog=1)
        self.check_job_invalidated(job, False)
Esempio n. 2
0
 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()
Esempio n. 3
0
    def test_update_status(self, mock_allowed):
        mock_allowed.return_value = True
        ev = self.create_event_with_jobs()
        job = ev.jobs.first()
        url = reverse('ci:view_job', args=[job.pk])
        self.get(url)
        self.check_job(job)

        job.ready = True
        job.client = utils.create_client()
        job.save()
        job.recipe.private = False
        job.recipe.save()
        self.wait_for_js()
        self.check_js_error()
        # job wasn't ready so JS didn't update it
        with self.assertRaises(Exception):
            self.check_job(job)

        self.get(url)
        self.check_job(job)

        job.status = models.JobStatus.SUCCESS
        job.complete = True
        job.invalidated = True
        job.save()
        self.wait_for_js()
        self.check_job(job)
Esempio n. 4
0
    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")
Esempio n. 5
0
    def test_invalidate(self, mock_collab):
        # only post is allowed
        url = reverse('ci:invalidate', args=[1000])
        self.set_counts()
        response = self.client.get(url)
        self.assertEqual(response.status_code, 405) # not allowed
        self.compare_counts()

        # invalid job
        self.set_counts()
        response = self.client.post(url)
        self.assertEqual(response.status_code, 404) # not found
        self.compare_counts()

        # can't invalidate
        step_result = utils.create_step_result()
        job = step_result.job
        job.event.pull_request = utils.create_pr()
        job.event.comments_url = "some url"
        job.event.save()
        mock_collab.return_value = False
        url = reverse('ci:invalidate', args=[job.pk])
        self.set_counts()
        response = self.client.post(url)
        self.assertEqual(response.status_code, 403) # forbidden
        self.compare_counts()

        # valid
        client = utils.create_client()
        job.client = client
        job.save()
        post_data = {"post_to_pr": "on",
            "comment": "some comment",
            "same_client": None,
            }

        mock_collab.return_value = True
        self.set_counts()
        response = self.client.post(url, data=post_data)
        self.assertEqual(response.status_code, 302) #redirect
        self.compare_counts(ready=1, invalidated=1, num_changelog=1)
        job.refresh_from_db()
        redir_url = reverse('ci:view_job', args=[job.pk])
        self.assertRedirects(response, redir_url)
        self.check_job_invalidated(job)

        post_data["same_client"] = "on"
        utils.create_step_result(job=job)
        job.client = client
        job.save()
        self.set_counts()
        response = self.client.post(url, data=post_data)
        self.assertEqual(response.status_code, 302) #redirect
        self.compare_counts(num_changelog=1)
        job.refresh_from_db()
        self.assertRedirects(response, redir_url)
        self.check_job_invalidated(job, True, client)
Esempio n. 6
0
 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
Esempio n. 7
0
 def test_complete_step_result_bad_client(self):
     job, result = self.create_running_job()
     post_data = self.create_complete_step_result_post_data(result.position)
     # bad client
     client2 = utils.create_client(name='other_client')
     url = self.complete_step_result_url(job, name=client2.name)
     self.set_counts()
     response = self.client_post_json(url, post_data)
     self.compare_counts()
     self.assertEqual(response.status_code, 400)  # bad request
Esempio n. 8
0
    def handle(self, *args, **options):
        factory = RequestFactory()
        client = utils.create_client()
        job = utils.create_job()
        user = job.recipe.build_user

        orig_recipe_dir = settings.RECIPE_BASE_DIR
        recipe_dir = utils.create_recipe_dir()
        settings.RECIPE_BASE_DIR = recipe_dir

        try:
            args = [user.build_key, client.name]
            request = factory.get(reverse("ci:client:ready_jobs", args=args))
            reply = views.ready_jobs(request, user.build_key, client.name)

            args = [user.build_key, job.config.name, client.name]
            claim_job_url = reverse("ci:client:claim_job", args=args)
            data = json.dumps({"job_id": job.pk})
            request = factory.post(claim_job_url,
                                   data,
                                   content_type="application/json")
            reply = views.claim_job(request, user.build_key, job.config.name,
                                    client.name)

            if reply.status_code == 200:
                this_file = os.path.realpath(__file__)
                test_dir = os.path.join(os.path.dirname(this_file), "..", "..",
                                        "..", "client", "tests")
                fname = os.path.join(os.path.abspath(test_dir),
                                     "claim_response.json")
                # to makes diffs better, hardcode job and recipe ids
                data = json.loads(reply.content)
                data["job_id"] = 1
                data["job_info"]["job_id"] = 1
                data["job_info"]["environment"]["job_id"] = 1
                data["job_info"]["environment"]["recipe_id"] = 1
                data["job_info"]["environment"]["CIVET_JOB_ID"] = 1
                data["job_info"]["environment"]["CIVET_RECIPE_ID"] = 1
                self.stdout.write("Writing: %s" % fname)
                with open(fname, "w") as f:
                    json.dump(data, f, indent=2, sort_keys=True)
                    f.write("\n")
            else:
                self.stderr.write(reply.status_code)
                self.stderr.write(reply.content)
        except Exception as e:
            self.stderr.write(traceback.format_exc())
            self.stderr.write("Error occurred: %s" % e)
        job.recipe.delete()
        shutil.rmtree(recipe_dir)
        settings.RECIPE_BASE_DIR = orig_recipe_dir
        settings.RECIPE_BASE_DIR = orig_recipe_dir
Esempio n. 9
0
    def test_client_list(self, mock_allowed):
        mock_allowed.return_value = False
        for i in range(10):
            c = utils.create_client(name="client%s" % i)
            c.status = models.Client.RUNNING
            c.save()
        # not allowed
        response = self.client.get(reverse('ci:client_list'))
        self.assertEqual(response.status_code, 200)
        for c in models.Client.objects.all():
            self.assertNotContains(response, c.name)

        # allowed
        mock_allowed.return_value = True
        response = self.client.get(reverse('ci:client_list'))
        self.assertEqual(response.status_code, 200)
        for i in range(10):
            name = "client%s" % i
            self.assertContains(response, name)
            self.assertContains(response, 'status_%i" class="client_Running"' % (i+1))

        inactive = []
        for i in range(5):
            c = models.Client.objects.get(name="client%s" % i)
            # we need to do it like this because a save() will automatically update it to current time
            models.Client.objects.filter(pk=c.pk).update(last_seen=c.last_seen - datetime.timedelta(seconds=120))
            inactive.append(c.name)

        response = self.client.get(reverse('ci:client_list'))
        self.assertEqual(response.status_code, 200)
        for i in range(10):
            name = "client%s" % i
            self.assertContains(response, name)
            if name in inactive:
                self.assertContains(response, 'status_%i" class="client_NotSeen"' % (i+1))
            else:
                self.assertContains(response, 'status_%i" class="client_Running"' % (i+1))

        for name in inactive:
            c = models.Client.objects.get(name=name)
            models.Client.objects.filter(pk=c.pk).update(last_seen=c.last_seen - datetime.timedelta(seconds=2*7*24*60*60))

        response = self.client.get(reverse('ci:client_list'))
        self.assertEqual(response.status_code, 200)
        for c in models.Client.objects.all():
            if c.name in inactive:
                self.assertNotContains(response, c.name)
                self.assertEqual(c.status, models.Client.DOWN)
            else:
                self.assertContains(response, c.name)
Esempio n. 10
0
    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)
Esempio n. 11
0
    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
Esempio n. 12
0
    def test_invalidate_event(self, mock_collab):
        # only post is allowed
        url = reverse('ci:invalidate_event', args=[1000])
        self.set_counts()
        response = self.client.get(url)
        self.assertEqual(response.status_code, 405) # not allowed
        self.compare_counts()

        # invalid event
        self.set_counts()
        response = self.client.post(url)
        self.assertEqual(response.status_code, 404) # not found
        self.compare_counts()

        # can't invalidate
        j0, j1, j2, j3 = utils.create_test_jobs()
        mock_collab.return_value = False
        url = reverse('ci:invalidate_event', args=[j0.event.pk])
        self.set_counts()
        response = self.client.post(url)
        self.assertEqual(response.status_code, 302) # redirect with error message
        self.compare_counts()

        client = utils.create_client()
        for j in [j0, j1, j2, j3]:
            j.client = client
            j.ready = True
            j.complete = True
            j.status = models.JobStatus.SUCCESS
            j.event.complete = False
            j.save()
        # valid
        post_data = {'same_client': None}
        mock_collab.return_value = True
        self.set_counts()
        response = self.client.post(url, data=post_data)
        self.assertEqual(response.status_code, 302) #redirect
        self.compare_counts(ready=-3, num_jobs_completed=-4, invalidated=4, num_changelog=4)
        redir_url = reverse('ci:view_event', args=[j0.event.pk])
        for j in [j0, j1, j2, j3]:
            j.refresh_from_db()
            self.assertRedirects(response, redir_url)
            self.assertEqual(j.step_results.count(), 0)
            self.assertFalse(j.complete)
            self.assertTrue(j.active)
            self.assertTrue(j.invalidated)
            self.assertFalse(j.same_client)
            self.assertEqual(j.client, None)
            self.assertEqual(j.seconds.seconds, 0)
            self.assertEqual(j.status, models.JobStatus.NOT_STARTED)
            self.assertFalse(j.event.complete)
            self.assertEqual(j.event.status, models.JobStatus.NOT_STARTED)
        self.assertTrue(j0.ready)
        self.assertFalse(j1.ready)
        self.assertFalse(j2.ready)
        self.assertFalse(j3.ready)

        # valid
        for j in [j0, j1, j2, j3]:
            j.client = client
            j.ready = True
            j.complete = True
            j.status = models.JobStatus.SUCCESS
            j.event.complete = False
            j.save()
            utils.create_step_result(job=j)
        post_data = {'same_client': 'on'}
        self.set_counts()
        response = self.client.post(url, data=post_data)
        self.assertEqual(response.status_code, 302) #redirect
        self.compare_counts(num_changelog=4, ready=-3, num_jobs_completed=-4)
        for j in [j0, j1, j2, j3]:
            j.refresh_from_db()
            self.assertRedirects(response, redir_url)
            self.assertEqual(j.step_results.count(), 0)
            self.assertFalse(j.complete)
            self.assertTrue(j.active)
            self.assertTrue(j.invalidated)
            self.assertTrue(j.same_client)
            self.assertEqual(j.client, client)
            self.assertEqual(j.seconds.seconds, 0)
            self.assertEqual(j.status, models.JobStatus.NOT_STARTED)
            self.assertFalse(j.event.complete)
            self.assertEqual(j.event.status, models.JobStatus.NOT_STARTED)

        self.assertTrue(j0.ready)
        self.assertFalse(j1.ready)
        self.assertFalse(j2.ready)
        self.assertFalse(j3.ready)

        post_data["comment"] = "some comment"
        post_data["post_to_pr"] = "on"
        self.set_counts()
        response = self.client.post(url, data=post_data)
        self.assertEqual(response.status_code, 302) #redirect
        self.compare_counts(num_changelog=4)

        # Make sure when the first job completes the other
        # jobs will become ready
        j0.complete = True
        j0.status = models.JobStatus.SUCCESS
        j0.save()
        self.set_counts()
        j0.event.make_jobs_ready()
        self.compare_counts(ready=2)
        self.assertFalse(j0.event.check_done())
Esempio n. 13
0
    def test_job_results(self, mock_allowed, mock_is_collaborator):
        mock_is_collaborator.return_value = False
        mock_allowed.return_value = True
        url = reverse('ci:ajax:job_results')
        # no parameters
        response = self.client.get(url)
        self.assertEqual(response.status_code, 400)

        client = utils.create_client()
        step_result = utils.create_step_result()
        step_result.complete = True
        step_result.save()
        step_result.job.save()

        data = {'last_request': 10, 'job_id': 0}
        # not signed in, not a collaborator
        response = self.client.get(url, data)
        self.assertEqual(response.status_code, 404)
        data['job_id'] = step_result.job.pk
        recipe = step_result.job.recipe
        recipe.private = True
        recipe.save()
        # not signed in, not a collaborator on a private recipe
        response = self.client.get(url, data)
        self.assertEqual(response.status_code, 403)

        recipe.private = False
        recipe.save()
        # recipe no longer private, should work
        response = self.client.get(url, data)
        self.assertEqual(response.status_code, 200)
        json_data = response.json()
        self.assertEqual(json_data['job_info']['client_name'], '')
        self.assertEqual(json_data['job_info']['client_url'], '')

        user = utils.get_test_user()
        utils.simulate_login(self.client.session, user)
        mock_is_collaborator.return_value = True
        recipe.private = True
        recipe.save()

        job = step_result.job
        job.client = client
        job.save()

        # should work now
        response = self.client.get(url, data)
        self.assertEqual(response.status_code, 200)
        json_data = response.json()
        self.assertIn('job_info', json_data)
        self.assertIn('results', json_data)
        self.assertEqual(step_result.job.pk, json_data['job_info']['id'])
        self.assertEqual(step_result.pk, json_data['results'][0]['id'])
        self.assertEqual(json_data['job_info']['client_name'], client.name)

        # should work now but return no results since nothing has changed
        data['last_request'] = json_data['last_request'] + 10
        response = self.client.get(url, data)
        self.assertEqual(response.status_code, 200)
        json_data = response.json()
        self.assertIn('job_info', json_data)
        self.assertIn('results', json_data)
        # job_info is always returned
        self.assertNotEqual('', json_data['job_info'])
        self.assertEqual([], json_data['results'])
        self.assertEqual(json_data['job_info']['client_name'], '')
Esempio n. 14
0
    def test_ready_jobs_client(self):
        user = utils.get_test_user()
        client = utils.create_client()
        request = self.factory.get('/')
        client_ip = views.get_client_ip(request)
        client.ip = client_ip
        client.save()
        url = reverse('ci:client:ready_jobs',
                      args=[user.build_key, client.name])
        r0 = utils.create_recipe(name='recipe0', user=user)
        r1 = utils.create_recipe(name='recipe1', user=user)
        j0 = utils.create_job(user=user, recipe=r0)
        j1 = utils.create_job(user=user, recipe=r1)
        utils.update_job(j0,
                         ready=True,
                         complete=False,
                         status=models.JobStatus.RUNNING,
                         client=client)
        utils.update_job(j1,
                         ready=True,
                         active=True,
                         status=models.JobStatus.NOT_STARTED)
        # we have a client trying to get ready jobs but
        # there is a job that is in the RUNNING state
        # associated with that client. That must mean
        # that the client previously stopped without letting the
        # server know, so the previous job should get
        # canceled
        self.set_counts()
        response = self.client.get(url)
        self.compare_counts(canceled=1,
                            num_jobs_completed=1,
                            num_changelog=1,
                            active_branches=1)
        self.assertEqual(response.status_code, 200)
        j0.refresh_from_db()
        self.assertEqual(j0.status, models.JobStatus.CANCELED)

        # if all jobs are in running, the event should be canceled
        utils.update_job(j0, complete=False, status=models.JobStatus.RUNNING)
        utils.update_job(j1,
                         complete=False,
                         status=models.JobStatus.RUNNING,
                         client=client)
        self.set_counts()
        response = self.client.get(url)
        self.compare_counts(canceled=2,
                            num_jobs_completed=2,
                            num_changelog=2,
                            events_canceled=1,
                            num_events_completed=1)
        self.assertEqual(response.status_code, 200)
        j0.refresh_from_db()
        self.assertEqual(j0.status, models.JobStatus.CANCELED)
        j1.refresh_from_db()
        self.assertEqual(j1.status, models.JobStatus.CANCELED)

        # Try again, nothing should change
        self.set_counts()
        response = self.client.get(url)
        self.compare_counts()
        self.assertEqual(response.status_code, 200)
Esempio n. 15
0
    def test_update_step_result(self):
        user = utils.get_test_user()
        job = utils.create_job(user=user)
        result = utils.create_step_result(job=job)
        client = utils.create_client()
        client2 = utils.create_client(name='other_client')
        job.client = client
        job.event.cause = models.Event.PULL_REQUEST
        job.status = models.JobStatus.RUNNING
        job.save()

        post_data = {
            'step_num': result.position,
            'output': 'output',
            'time': 5,
            'complete': True,
            'exit_status': 0
        }
        url = reverse('ci:client:update_step_result',
                      args=[user.build_key, client.name, result.pk])
        # only post allowed
        self.set_counts()
        response = self.client.get(url)
        self.compare_counts()
        self.assertEqual(response.status_code, 405)  # not allowed

        # bad step result
        url = reverse('ci:client:update_step_result',
                      args=[user.build_key, client.name, 0])
        self.set_counts()
        response = self.client_post_json(url, post_data)
        self.compare_counts()
        self.assertEqual(response.status_code, 400)  # bad request

        # unknown client
        url = reverse('ci:client:update_step_result',
                      args=[user.build_key, 'unknown_client', result.pk])
        self.set_counts()
        response = self.client_post_json(url, post_data)
        self.compare_counts()
        self.assertEqual(response.status_code, 400)  # bad request

        # bad client
        url = reverse('ci:client:update_step_result',
                      args=[user.build_key, client2.name, result.pk])
        self.set_counts()
        response = self.client_post_json(url, post_data)
        self.compare_counts()
        self.assertEqual(response.status_code, 400)  # bad request

        # ok
        url = reverse('ci:client:update_step_result',
                      args=[user.build_key, client.name, result.pk])
        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["status"], "OK")
        self.assertEqual(data["command"], None)
        result.refresh_from_db()
        self.assertEqual(result.status, models.JobStatus.RUNNING)

        # test when the user invalidates a job while it is running
        job.status = models.JobStatus.NOT_STARTED
        job.save()
        self.set_counts()
        response = self.client_post_json(url, post_data)
        self.compare_counts()
        self.assertEqual(response.status_code, 200)
        result.refresh_from_db()
        data = response.json()
        self.assertEqual(result.status, models.JobStatus.NOT_STARTED)
        self.assertEqual(data["status"], "OK")
        self.assertEqual(data["command"], "cancel")

        # test when the user cancel a job while it is running
        job.status = models.JobStatus.CANCELED
        job.save()
        self.set_counts()
        response = self.client_post_json(url, post_data)
        self.compare_counts()
        self.assertEqual(response.status_code, 200)
        result.refresh_from_db()
        data = response.json()
        self.assertEqual(result.status, models.JobStatus.CANCELED)
        self.assertEqual(data["status"], "OK")
        self.assertEqual(data["command"], "cancel")

        # a step exited with nonzero, make sure we don't do the
        # next step
        job.status = models.JobStatus.RUNNING
        job.save()
        post_data['exit_status'] = 1
        self.set_counts()
        response = self.client_post_json(url, post_data)
        self.compare_counts()
        self.assertEqual(response.status_code, 200)
        result.refresh_from_db()
        self.assertEqual(result.exit_status, 1)
        self.assertEqual(result.status, models.JobStatus.RUNNING)
Esempio n. 16
0
    def test_start_step_result(self):
        user = utils.get_test_user()
        job = utils.create_job(user=user)
        result = utils.create_step_result(job=job)
        client = utils.create_client()
        client2 = utils.create_client(name='other_client')
        job.client = client
        job.event.cause = models.Event.PULL_REQUEST
        job.event.pr = utils.create_pr()
        job.event.save()
        job.save()

        post_data = {
            'step_num': result.position,
            'output': 'output',
            'time': 5,
            'complete': True,
            'exit_status': 0
        }
        url = reverse('ci:client:start_step_result',
                      args=[user.build_key, client.name, result.pk])
        # only post allowed
        self.set_counts()
        response = self.client.get(url)
        self.compare_counts()
        self.assertEqual(response.status_code, 405)  # not allowed

        # bad step result
        url = reverse('ci:client:start_step_result',
                      args=[user.build_key, client.name, 0])
        self.set_counts()
        response = self.client_post_json(url, post_data)
        self.compare_counts()
        self.assertEqual(response.status_code, 400)  # bad request

        # unknown client
        url = reverse('ci:client:start_step_result',
                      args=[user.build_key, 'unknown_client', result.pk])
        self.set_counts()
        response = self.client_post_json(url, post_data)
        self.compare_counts()
        self.assertEqual(response.status_code, 400)  # bad request

        # bad client
        url = reverse('ci:client:start_step_result',
                      args=[user.build_key, client2.name, result.pk])
        self.set_counts()
        response = self.client_post_json(url, post_data)
        self.compare_counts()
        self.assertEqual(response.status_code, 400)  # bad request

        # ok
        url = reverse('ci:client:start_step_result',
                      args=[user.build_key, client.name, result.pk])
        self.set_counts()
        response = self.client_post_json(url, post_data)
        self.compare_counts()
        self.assertEqual(response.status_code, 200)
        result.refresh_from_db()
        self.assertEqual(result.status, models.JobStatus.RUNNING)
        data = response.json()
        self.assertEqual(data["command"], None)
        self.assertEqual(data["status"], "OK")

        # If a job got canceled, make sure it sends the command to the client
        job.status = models.JobStatus.CANCELED
        job.save()
        self.set_counts()
        response = self.client_post_json(url, post_data)
        self.compare_counts()
        self.assertEqual(response.status_code, 200)
        result.refresh_from_db()
        self.assertEqual(result.status, models.JobStatus.CANCELED)
        data = response.json()
        self.assertEqual(data["command"], "cancel")
        self.assertEqual(data["status"], "OK")
Esempio n. 17
0
    def test_job_finished(self):
        user = utils.get_test_user()
        job = utils.create_job(user=user)
        step_result = utils.create_step_result(job=job)
        step_result.output = self.get_file("ubuntu_gcc_output.txt")
        step_result.save()
        client = utils.create_client()
        client2 = utils.create_client(name='other_client')
        job.client = client
        job.save()
        job.event.comments_url = 'http://localhost'
        job.event.save()

        post_data = {'seconds': 0, 'complete': True}
        url = reverse('ci:client:job_finished',
                      args=[user.build_key, client.name, job.pk])

        # only post allowed
        self.set_counts()
        response = self.client.get(url)
        self.compare_counts()
        self.assertEqual(response.status_code, 405)  # not allowed

        # bad url
        url = reverse('ci:client:job_finished',
                      args=[user.build_key, client.name, 0])
        self.set_counts()
        response = self.client_post_json(url, post_data)
        self.compare_counts()
        self.assertEqual(response.status_code, 400)  # bad request

        # unknown client
        url = reverse('ci:client:job_finished',
                      args=[user.build_key, 'unknown_client', job.pk])
        self.set_counts()
        response = self.client_post_json(url, post_data)
        self.compare_counts()
        self.assertEqual(response.status_code, 400)  # bad request

        # bad client
        url = reverse('ci:client:job_finished',
                      args=[user.build_key, client2.name, job.pk])
        self.set_counts()
        response = self.client_post_json(url, post_data)
        self.compare_counts()
        self.assertEqual(response.status_code, 400)  # bad request

        # should be ok
        url = reverse('ci:client:job_finished',
                      args=[user.build_key, client.name, job.pk])
        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)
        data = response.json()
        self.assertIn('message', data)
        self.assertEqual(data['status'], 'OK')
        job.refresh_from_db()
        self.assertTrue(job.complete)
        self.assertEqual(job.operating_system.name, "Ubuntu")
        self.assertEqual(job.operating_system.version, "14.04")
        self.assertEqual(job.operating_system.other, "trusty")
        self.check_modules(job, [
            'moose/.gcc_4.9.1',
            'moose/.tbb',
            'moose/.mpich-3.1.2_gcc',
            'moose/.mpich_petsc-3.6.3-gcc-superlu',
            'moose-tools',
            'moose/.ccache',
            'moose/.vtk-6',
            'moose-dev-gcc',
        ])

        job2 = utils.create_job(event=job.event)
        job2.ready = False
        job2.complete = False
        job2.status = models.JobStatus.NOT_STARTED
        job2.active = True
        job2.save()
        # should be ok. Make sure jobs get ready after one is finished.
        url = reverse('ci:client:job_finished',
                      args=[user.build_key, client.name, job.pk])
        self.set_counts()
        response = self.client_post_json(url, post_data)
        self.compare_counts(ready=1)
        self.assertEqual(response.status_code, 200)
        data = response.json()
        self.assertIn('message', data)
        self.assertEqual(data['status'], 'OK')
        job2 = models.Job.objects.get(pk=job2.pk)
        self.assertTrue(job2.ready)
Esempio n. 18
0
    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)
    def test_claim_job(self):
        # no jobs to claim
        ret = self.getter.claim_job([])
        self.assertEqual(ret, None)

        # successfull operation
        self.job.ready = True
        self.job.active = True
        self.job.complete = False
        self.job.save()
        jobs = [self.create_job_dict(self.job)]
        self.set_counts()
        ret = self.getter.claim_job(jobs)
        self.compare_counts(num_clients=1, active_branches=1)
        data = self.claim_job_dict(self.job)
        self.assertEqual(ret, data)

        # bad job
        self.job.status = models.JobStatus.RUNNING
        self.job.save()
        self.set_counts()
        ret = self.getter.claim_job(jobs)
        self.compare_counts()
        self.assertEqual(ret, None)

        # job was set invalidated and to run on same client
        self.job.status = models.JobStatus.NOT_STARTED
        self.job.invalidated = True
        self.job.same_client = True
        self.job.client = test_utils.create_client(name="another client")
        self.job.save()
        self.set_counts()
        ret = self.getter.claim_job(jobs)
        self.compare_counts()
        self.assertEqual(ret, None)

        # no jobs with matching config
        self.job.invalidated = False
        self.job.client = None
        self.job.config.name = "foobar"
        self.job.config.save()
        self.job.save()

        self.set_counts()
        ret = self.getter.claim_job(jobs)
        self.compare_counts()
        self.assertEqual(ret, None)

        # bad server
        with patch.object(requests, "post") as mock_post:
            mock_post.return_value = test_utils.Response(json_data={})
            self.client_info["server"] = "dummy_server"
            self.set_counts()
            ret = self.getter.claim_job(jobs)
            self.compare_counts()
            self.assertEqual(ret, None)

            mock_post.side_effect = Exception("BAM!")
            self.set_counts()
            ret = self.getter.claim_job(jobs)
            self.compare_counts()
            self.assertEqual(ret, None)
Esempio n. 20
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)