diff --git a/squad/api/ci.py b/squad/api/ci.py index 34b3395f..2d75ee91 100644 --- a/squad/api/ci.py +++ b/squad/api/ci.py @@ -106,6 +106,16 @@ def watch_job(request, group_slug, project_slug, version, environment_slug): job_id=testjob_id ) + # check if backend is able to fetch job definition + try: + definition = backend.get_job_definition(testjob_id) + if not definition: + return HttpResponseBadRequest(f"No job definition found for job {testjob_id}: {definition}") + test_job.definition = definition + except NotImplementedError: + # backend does not work with job definitions + pass + # sanitize job_url try: backend.get_implementation().job_url(test_job) diff --git a/squad/ci/backend/fake.py b/squad/ci/backend/fake.py index e49556bb..4b3100e2 100644 --- a/squad/ci/backend/fake.py +++ b/squad/ci/backend/fake.py @@ -66,5 +66,8 @@ def cancel(self, test_job): def check_job_definition(self, definition): return True + def get_job_definition(self, test_job): + return "sample job definition" + def supports_callbacks(self): return False diff --git a/squad/ci/backend/lava.py b/squad/ci/backend/lava.py index 490c0c42..54374269 100644 --- a/squad/ci/backend/lava.py +++ b/squad/ci/backend/lava.py @@ -775,3 +775,14 @@ def check_job_definition(self, definition): return True except yaml.YAMLError as e: return str(e) + + def get_job_definition(self, job_id): + if self.use_xml_rpc: + return self.proxy.scheduler.jobs.definition(job_id) + job_resp = requests.get( + f'{self.api_url_base}/jobs/{job_id}/definition/', + headers=self.authentication, + timeout=self.settings.get(timeout_variable_name, DEFAULT_TIMEOUT) + ) + if job_resp.status_code == 200: + return job_resp.json() diff --git a/squad/ci/backend/null.py b/squad/ci/backend/null.py index 42d5c4d3..42ee1514 100644 --- a/squad/ci/backend/null.py +++ b/squad/ci/backend/null.py @@ -92,18 +92,24 @@ def cancel(self, test_job): """ raise NotImplementedError - def job_url(selt, test_job): + def job_url(self, test_job): """ Returns the URL of the test job in the backend """ raise NotImplementedError - def check_job_definition(selt, definition): + def check_job_definition(self, definition): """ Returns True if job definition checks out or an error message """ raise NotImplementedError + def get_job_definition(self, job_id): + """ + Returns the job definition for a given test job + """ + raise NotImplementedError + def supports_callbacks(self): """ Returns True if this backend supports callbacks, False otherwise diff --git a/squad/ci/models.py b/squad/ci/models.py index a92bbc63..e6d3b4da 100644 --- a/squad/ci/models.py +++ b/squad/ci/models.py @@ -216,6 +216,9 @@ def get_implementation(self): def check_job_definition(self, definition): return self.get_implementation().check_job_definition(definition) + def get_job_definition(self, job_id): + return self.get_implementation().get_job_definition(job_id) + def supports_callbacks(self): return self.get_implementation().supports_callbacks() diff --git a/test/api/test_ci.py b/test/api/test_ci.py index 6ee36946..ba19fce3 100644 --- a/test/api/test_ci.py +++ b/test/api/test_ci.py @@ -238,6 +238,8 @@ def test_watch_testjob(self, fetch): 1, testjob_queryset.count() ) + testjob = testjob_queryset.first() + self.assertTrue(len(testjob.definition) > 0) fetch.assert_called_with(testjob_queryset.first().id) logentry_queryset = LogEntry.objects.filter( user_id=self.project_privileged_user.pk,