From 76a48671f70580629985fbc2acdcc607fe599d6d Mon Sep 17 00:00:00 2001 From: cortadocodes Date: Tue, 23 Apr 2024 10:58:37 +0100 Subject: [PATCH] ENH: Raise error if no events found when calling `get_events` skipci --- octue/cloud/pub_sub/bigquery.py | 14 ++++++++++++-- tests/cloud/pub_sub/test_bigquery.py | 26 +++++++++++++++++++++++++- 2 files changed, 37 insertions(+), 3 deletions(-) diff --git a/octue/cloud/pub_sub/bigquery.py b/octue/cloud/pub_sub/bigquery.py index 2aa8d5f7d..70b278b4d 100644 --- a/octue/cloud/pub_sub/bigquery.py +++ b/octue/cloud/pub_sub/bigquery.py @@ -3,6 +3,7 @@ from google.cloud.bigquery import Client, QueryJobConfig, ScalarQueryParameter from octue.cloud.events.validation import VALID_EVENT_KINDS +from octue.exceptions import ServiceNotFound from octue.resources import Manifest @@ -15,6 +16,8 @@ def get_events(table_id, sender, question_uuid, kind=None, include_backend_metad :param str|None kind: the kind of event to get; if `None`, all event kinds are returned :param bool include_backend_metadata: if `True`, include the service backend metadata :param int limit: the maximum number of events to return + :raise ValueError: if the `kind` parameter is invalid + :raise octue.exceptions.ServiceNotFound: if the sender hasn't emitted any events related to the question UUID (or any events at all) :return list(dict): the events for the question """ if kind: @@ -64,8 +67,15 @@ def get_events(table_id, sender, question_uuid, kind=None, include_backend_metad ) query_job = client.query(query, job_config=job_config) - rows = query_job.result() - df = rows.to_dataframe() + result = query_job.result() + + if result.total_rows == 0: + raise ServiceNotFound( + f"No events found. The requested sender {sender!r} may not exist or it hasn't emitted any events for " + f"question {question_uuid!r} (or any events at all)." + ) + + df = result.to_dataframe() # Convert JSON strings to python primitives. df["event"] = df["event"].map(json.loads) diff --git a/tests/cloud/pub_sub/test_bigquery.py b/tests/cloud/pub_sub/test_bigquery.py index fcdf9c0f9..05d1dc370 100644 --- a/tests/cloud/pub_sub/test_bigquery.py +++ b/tests/cloud/pub_sub/test_bigquery.py @@ -1,7 +1,25 @@ from unittest import TestCase -from unittest.mock import patch +from unittest.mock import MagicMock, patch from octue.cloud.pub_sub.bigquery import get_events +from octue.exceptions import ServiceNotFound + + +class MockEmptyResult: + """A mock empty query result.""" + + def __init__(self, total_rows=0): + self.total_rows = total_rows + + def result(self): + return MagicMock(total_rows=self.total_rows) + + +class MockEmptyBigQueryClient: + """A mock BigQuery client that returns a mock empty query result.""" + + def query(self, *args, **kwargs): + return MockEmptyResult() class TestGetEvents(TestCase): @@ -15,6 +33,12 @@ def test_error_raised_if_event_kind_invalid(self): kind="frisbee_tournament", ) + def test_error_raised_if_no_events_found(self): + """Test that an error is raised if no events are found.""" + with patch("octue.cloud.pub_sub.bigquery.Client", MockEmptyBigQueryClient): + with self.assertRaises(ServiceNotFound): + get_events(table_id="blah", sender="octue/test-service:1.0.0", question_uuid="blah") + def test_without_kind(self): """Test the query used to retrieve events of all kinds.""" with patch("octue.cloud.pub_sub.bigquery.Client") as mock_client: