diff --git a/gcloud/pubsub/__init__.py b/gcloud/pubsub/__init__.py index fb9965ac8b90..ffc96aa890c8 100644 --- a/gcloud/pubsub/__init__.py +++ b/gcloud/pubsub/__init__.py @@ -29,6 +29,7 @@ from gcloud.connection import get_scoped_connection from gcloud.pubsub import _implicit_environ from gcloud.pubsub._implicit_environ import get_default_connection +from gcloud.pubsub.api import list_topics from gcloud.pubsub.connection import Connection diff --git a/gcloud/pubsub/api.py b/gcloud/pubsub/api.py index 8fb2c9bcc57f..56eaa21b4c87 100644 --- a/gcloud/pubsub/api.py +++ b/gcloud/pubsub/api.py @@ -16,6 +16,7 @@ from gcloud._helpers import get_default_project from gcloud.pubsub._implicit_environ import get_default_connection +from gcloud.pubsub.topic import Topic def list_topics(page_size=None, page_token=None, @@ -42,9 +43,9 @@ def list_topics(page_size=None, page_token=None, defaults to the connection inferred from the environment. - :rtype: dict - :returns: keys include ``topics`` (a list of topic mappings) and - ``nextPageToken`` (a string: if non-empty, indicates that + :rtype: tuple, (list, str) + :returns: list of :class:`gcloud.pubsub.topic.Topic`, plus a + "next page token" string: if not None, indicates that more topics can be retrieved with another call (pass that value as ``page_token``). """ @@ -63,7 +64,12 @@ def list_topics(page_size=None, page_token=None, params['pageToken'] = page_token path = '/projects/%s/topics' % project - return connection.api_request(method='GET', path=path, query_params=params) + resp = connection.api_request(method='GET', path=path, query_params=params) + topics = [] + for full_name in [topic['name'] for topic in resp['topics']]: + _, t_project, _, name = full_name.split('/') + topics.append(Topic(name, t_project, connection)) + return topics, resp.get('nextPageToken') def list_subscriptions(page_size=None, page_token=None, topic_name=None, diff --git a/gcloud/pubsub/test_api.py b/gcloud/pubsub/test_api.py index 430f6afbbe33..cca0defe1bda 100644 --- a/gcloud/pubsub/test_api.py +++ b/gcloud/pubsub/test_api.py @@ -22,17 +22,18 @@ def _callFUT(self, *args, **kw): return list_topics(*args, **kw) def test_w_explicit_connection_no_paging(self): + from gcloud.pubsub.topic import Topic TOPIC_NAME = 'topic_name' PROJECT = 'PROJECT' - TOKEN = 'TOKEN' - returned = {'topics': [{'name': TOPIC_NAME}], - 'nextPageToken': TOKEN} + TOPIC_PATH = 'projects/%s/topics/%s' % (PROJECT, TOPIC_NAME) + returned = {'topics': [{'name': TOPIC_PATH}]} conn = _Connection(returned) - response = self._callFUT(project=PROJECT, connection=conn) - topics = response['topics'] + topics, next_page_token = self._callFUT(project=PROJECT, + connection=conn) self.assertEqual(len(topics), 1) - self.assertEqual(topics[0], {'name': TOPIC_NAME}) - self.assertEqual(response['nextPageToken'], TOKEN) + self.assertTrue(isinstance(topics[0], Topic)) + self.assertEqual(topics[0].name, TOPIC_NAME) + self.assertEqual(next_page_token, None) self.assertEqual(len(conn._requested), 1) req = conn._requested[0] self.assertEqual(req['method'], 'GET') @@ -42,19 +43,21 @@ def test_w_explicit_connection_no_paging(self): def test_w_implicit_connection_and_project_wo_paging(self): from gcloud._testing import _monkey_defaults as _monkey_base_defaults from gcloud.pubsub._testing import _monkey_defaults + from gcloud.pubsub.topic import Topic TOPIC_NAME = 'topic_name' PROJECT = 'PROJECT' + TOPIC_PATH = 'projects/%s/topics/%s' % (PROJECT, TOPIC_NAME) TOKEN = 'TOKEN' - returned = {'topics': [{'name': TOPIC_NAME}], + returned = {'topics': [{'name': TOPIC_PATH}], 'nextPageToken': TOKEN} conn = _Connection(returned) with _monkey_base_defaults(project=PROJECT): with _monkey_defaults(connection=conn): - response = self._callFUT() - topics = response['topics'] + topics, next_page_token = self._callFUT() self.assertEqual(len(topics), 1) - self.assertEqual(topics[0], {'name': TOPIC_NAME}) - self.assertEqual(response['nextPageToken'], TOKEN) + self.assertTrue(isinstance(topics[0], Topic)) + self.assertEqual(topics[0].name, TOPIC_NAME) + self.assertEqual(next_page_token, TOKEN) self.assertEqual(len(conn._requested), 1) req = conn._requested[0] self.assertEqual(req['method'], 'GET') @@ -62,19 +65,21 @@ def test_w_implicit_connection_and_project_wo_paging(self): self.assertEqual(req['query_params'], {}) def test_w_explicit_connection_and_project_w_paging(self): + from gcloud.pubsub.topic import Topic TOPIC_NAME = 'topic_name' PROJECT = 'PROJECT' + TOPIC_PATH = 'projects/%s/topics/%s' % (PROJECT, TOPIC_NAME) TOKEN1 = 'TOKEN1' TOKEN2 = 'TOKEN2' SIZE = 1 - returned = {'topics': [{'name': TOPIC_NAME}], + returned = {'topics': [{'name': TOPIC_PATH}], 'nextPageToken': TOKEN2} conn = _Connection(returned) - response = self._callFUT(SIZE, TOKEN1, PROJECT, conn) - topics = response['topics'] + topics, next_page_token = self._callFUT(SIZE, TOKEN1, PROJECT, conn) self.assertEqual(len(topics), 1) - self.assertEqual(topics[0], {'name': TOPIC_NAME}) - self.assertEqual(response['nextPageToken'], TOKEN2) + self.assertTrue(isinstance(topics[0], Topic)) + self.assertEqual(topics[0].name, TOPIC_NAME) + self.assertEqual(next_page_token, TOKEN2) self.assertEqual(len(conn._requested), 1) req = conn._requested[0] self.assertEqual(req['method'], 'GET') diff --git a/regression/pubsub.py b/regression/pubsub.py index 116b9329204e..7df330986787 100644 --- a/regression/pubsub.py +++ b/regression/pubsub.py @@ -12,6 +12,8 @@ # See the License for the specific language governing permissions and # limitations under the License. +import time + import unittest2 from gcloud import _helpers @@ -40,3 +42,23 @@ def test_create_topic(self): self.to_delete.append(topic) self.assertTrue(topic.exists()) self.assertEqual(topic.name, new_topic_name) + + def test_list_topics(self): + topics_to_create = [ + 'new%d' % (1000 * time.time(),), + 'newer%d' % (1000 * time.time(),), + 'newest%d' % (1000 * time.time(),), + ] + created_topics = [] + for topic_name in topics_to_create: + topic = Topic(topic_name) + topic.create() + self.to_delete.append(topic) + + # Retrieve the topics. + all_topics, _ = pubsub.list_topics() + project_id = pubsub.get_default_project() + created_topics = [topic for topic in all_topics + if topic.name in topics_to_create and + topic.project == project_id] + self.assertEqual(len(created_topics), len(topics_to_create))