From 5443e14d7c6c105f3085966b60978d52071f8ae3 Mon Sep 17 00:00:00 2001 From: Tres Seaver Date: Wed, 21 Sep 2016 14:01:20 -0400 Subject: [PATCH 1/3] Model/parse 'job.cancel' API response correctly. Closes #2377. --- google/cloud/bigquery/job.py | 2 +- unit_tests/bigquery/test_job.py | 10 ++++++---- 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/google/cloud/bigquery/job.py b/google/cloud/bigquery/job.py index a4eb745b4942..5a88f8316fdb 100644 --- a/google/cloud/bigquery/job.py +++ b/google/cloud/bigquery/job.py @@ -375,7 +375,7 @@ def cancel(self, client=None): api_response = client.connection.api_request( method='POST', path='%s/cancel' % (self.path,)) - self._set_properties(api_response) + self._set_properties(api_response['job']) class _LoadConfiguration(object): diff --git a/unit_tests/bigquery/test_job.py b/unit_tests/bigquery/test_job.py index f4add8d8f7be..2d63f7b5bada 100644 --- a/unit_tests/bigquery/test_job.py +++ b/unit_tests/bigquery/test_job.py @@ -601,8 +601,9 @@ def test_reload_w_alternate_client(self): def test_cancel_w_bound_client(self): PATH = 'projects/%s/jobs/%s/cancel' % (self.PROJECT, self.JOB_NAME) - RESOURCE = self._makeResource() - conn = _Connection(RESOURCE) + RESOURCE = self._makeResource(ended=True) + RESPONSE = {'job': RESOURCE} + conn = _Connection(RESPONSE) client = _Client(project=self.PROJECT, connection=conn) table = _Table() job = self._makeOne(self.JOB_NAME, table, [self.SOURCE1], client) @@ -617,10 +618,11 @@ def test_cancel_w_bound_client(self): def test_cancel_w_alternate_client(self): PATH = 'projects/%s/jobs/%s/cancel' % (self.PROJECT, self.JOB_NAME) - RESOURCE = self._makeResource() + RESOURCE = self._makeResource(ended=True) + RESPONSE = {'job': RESOURCE} conn1 = _Connection() client1 = _Client(project=self.PROJECT, connection=conn1) - conn2 = _Connection(RESOURCE) + conn2 = _Connection(RESPONSE) client2 = _Client(project=self.PROJECT, connection=conn2) table = _Table() job = self._makeOne(self.JOB_NAME, table, [self.SOURCE1], client1) From b3f130ab8b126cbb85f40e33b604ccb6dfe156fb Mon Sep 17 00:00:00 2001 From: Tres Seaver Date: Wed, 21 Sep 2016 14:15:55 -0400 Subject: [PATCH 2/3] Add a system test for '_AsyncJob.cancel'. --- system_tests/bigquery.py | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/system_tests/bigquery.py b/system_tests/bigquery.py index c417e0538b54..f16cdf7cf056 100644 --- a/system_tests/bigquery.py +++ b/system_tests/bigquery.py @@ -435,3 +435,33 @@ def _job_done(instance): by_age = operator.itemgetter(1) self.assertEqual(sorted(rows, key=by_age), sorted(ROWS, key=by_age)) + + def test_job_cancel(self): + DATASET_NAME = _make_dataset_name('job_cancel') + JOB_NAME = 'fetch_' + DATASET_NAME + TABLE_NAME = 'test_table' + QUERY = 'SELECT * FROM %s.%s' % (DATASET_NAME, TABLE_NAME) + + dataset = Config.CLIENT.dataset(DATASET_NAME) + + retry_403(dataset.create)() + self.to_delete.append(dataset) + + full_name = bigquery.SchemaField('full_name', 'STRING', + mode='REQUIRED') + age = bigquery.SchemaField('age', 'INTEGER', mode='REQUIRED') + table = dataset.table(TABLE_NAME, schema=[full_name, age]) + table.create() + self.to_delete.insert(0, table) + + job = Config.CLIENT.run_async_query(JOB_NAME, QUERY) + job.begin() + job.cancel() + + def _job_done(instance): + return instance.state in ('DONE', 'done') + + retry = RetryInstanceState(_job_done, max_tries=8) + retry(job.reload)() + + self.assertEqual(job.state.lower(), 'done') From 14b8cc4486d6c018426f60f1bf1801f8c8c420da Mon Sep 17 00:00:00 2001 From: Tres Seaver Date: Wed, 21 Sep 2016 16:44:25 -0400 Subject: [PATCH 3/3] Replace redundant 'job done' assertion with a note. Explain why we can't make any real assertions about the status of the cancelled job. Addresses: https://github.com/GoogleCloudPlatform/google-cloud-python/pull/2379#issuecomment-248700812. --- system_tests/bigquery.py | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/system_tests/bigquery.py b/system_tests/bigquery.py index f16cdf7cf056..1c566b4e4e0d 100644 --- a/system_tests/bigquery.py +++ b/system_tests/bigquery.py @@ -464,4 +464,8 @@ def _job_done(instance): retry = RetryInstanceState(_job_done, max_tries=8) retry(job.reload)() - self.assertEqual(job.state.lower(), 'done') + # The `cancel` API doesn't leave any reliable traces on + # the status of the job resource, so we can't really assert for + # them here. The best we can do is not that the API call didn't + # raise an error, and that the job completed (in the `retry()` + # above).