Пример #1
0
class TestErrorClient(unittest.TestCase):
    def setUp(self):
        # Initialize ams in localhost with token s3cr3t and project TEST
        self.ams = ArgoMessagingService(endpoint="localhost", token="s3cr3t", project="TEST")
        self.errormocks = ErrorMocks()
        self.topicmocks = TopicMocks()
        self.submocks = SubMocks()

        # set defaults for testing of retries
        retry = 0
        retrysleep = 0.1
        retrybackoff = None
        if sys.version_info < (3, ):
            self.ams._retry_make_request.im_func.func_defaults = (None, None, retry, retrysleep, retrybackoff)
        else:
            self.ams._retry_make_request.__func__.__defaults__ = (None, None, retry, retrysleep, retrybackoff)

    # Test create topic client request
    def testCreateTopics(self):
        # Execute ams client with mocked response
        with HTTMock(self.errormocks.create_topic_alreadyexist_mock):
            try:
                resp = self.ams.create_topic("topic1")
            except Exception as e:
                assert isinstance(e, AmsServiceException)
                self.assertEqual(e.status, 'ALREADY_EXIST')
                self.assertEqual(e.code, 409)

    # Test delete topic client request
    def testDeleteTopics(self):
        # Execute ams client with mocked response
        with HTTMock(self.errormocks.delete_topic_notfound_mock):
            try:
                resp = self.ams.delete_topic("topic1")
            except Exception as e:
                assert isinstance(e, AmsServiceException)
                self.assertEqual(e.status, 'NOT_FOUND')
                self.assertEqual(e.code, 404)

    def testCreateSubscription(self):
        # Execute ams client with mocked response
        with HTTMock(self.topicmocks.get_topic_mock,
                     self.errormocks.create_subscription_alreadyexist_mock):
            try:
                resp = self.ams.create_sub("subscription1", "topic1", 10)
            except Exception as e:
                assert isinstance(e, AmsServiceException)
                self.assertEqual(e.status, 'ALREADY_EXIST')
                self.assertEqual(e.code, 409)

    # Test Publish client request
    def testFailedPublish(self):
        # Mock response for POST publish to topic
        @urlmatch(netloc="localhost", path="/v1/projects/TEST/topics/topic1:publish",
                  method="POST")
        def publish_mock(url, request):
            assert url.path == "/v1/projects/TEST/topics/topic1:publish"
            # Check request produced by ams client
            req_body = json.loads(request.body)
            assert req_body["messages"][0]["data"] == "Zm9vMQ=="
            assert req_body["messages"][0]["attributes"]["bar1"] == "baz1"
            return response(504, '<htmI><body><h1>504 Gateway Time-out</h1>\nThe server didn\'t respond in time.\n</body></html>\n', None, None, 5, request)

        # Execute ams client with mocked response
        with HTTMock(publish_mock):
            msg = AmsMessage(data='foo1', attributes={'bar1': 'baz1'})
            try:
                resp = self.ams.publish("topic1", msg)
            except Exception as e:
                assert isinstance(e, AmsTimeoutException)
                self.assertEqual(e.code, 504)

    # Tests for plaintext or JSON encoded backend error messages
    def testErrorMsgBackend(self):
        @urlmatch(netloc="localhost", path="/v1/projects/TEST/topics/topic1",
                  method='GET')
        def error_plaintxt(url, request):
            assert url.path == "/v1/projects/TEST/topics/topic1"
            return response(500, "Cannot get topic", None, None, 5, request)

        with HTTMock(error_plaintxt):
            try:
                resp = self.ams.get_topic("topic1")
            except AmsServiceException as e:
                if sys.version_info < (3, 6 ):
                    response_string = "Cannot get topic"
                else:
                    response_string = "b'Cannot get topic'"
                self.assertEqual(e.msg, "While trying the [topic_get]: " + response_string)

        @urlmatch(netloc="localhost", path="/v1/projects/TEST/topics/topic1",
                  method='GET')
        def error_json(url, request):
            assert url.path == "/v1/projects/TEST/topics/topic1"
            return response(500, '{"error": {"code": 500,\
                                              "message": "Cannot get topic",\
                                              "status": "INTERNAL_SERVER_ERROR"\
                                            }}', None, None, 5, request)

        with HTTMock(error_json):
            try:
                resp = self.ams.get_topic("topic1")
            except AmsServiceException as e:
                self.assertEqual(e.code, 500)
                self.assertEqual(e.msg, "While trying the [topic_get]: Cannot get topic")
                self.assertEqual(e.status, "INTERNAL_SERVER_ERROR")

    def testUnauthorized(self):
        @urlmatch(netloc="localhost", path="/v1/projects/TEST/topics/topic1",
                  method='GET')
        def error_unauth(url, request):
            assert url.path == "/v1/projects/TEST/topics/topic1"
            return response(401, '{"error": {"code": 401, \
                                             "message": "Unauthorized", \
                                             "status": "UNAUTHORIZED"}}')
        with HTTMock(error_unauth):
            try:
                resp = self.ams.get_topic("topic1")
            except AmsServiceException as e:
                self.assertEqual(e.code, 401)
                self.assertEqual(e.msg, 'While trying the [topic_get]: Unauthorized')
                self.assertEqual(e.status, 'UNAUTHORIZED')

    @mock.patch('pymod.ams.requests.get')
    def testRetryConnectionProblems(self, mock_requests_get):
        mock_requests_get.side_effect = [requests.exceptions.ConnectionError,
                                         requests.exceptions.ConnectionError,
                                         requests.exceptions.ConnectionError,
                                         requests.exceptions.ConnectionError]
        retry = 3
        retrysleep = 0.1
        if sys.version_info < (3, ):
            self.ams._retry_make_request.im_func.func_defaults = (None, None, retry, retrysleep, None)
        else:
            self.ams._retry_make_request.__func__.__defaults__ = (None, None, retry, retrysleep, None)
        self.assertRaises(AmsConnectionException, self.ams.list_topics)
        self.assertEqual(mock_requests_get.call_count, retry + 1)

    @mock.patch('pymod.ams.requests.get')
    def testBackoffRetryConnectionProblems(self, mock_requests_get):
        mock_requests_get.side_effect = [requests.exceptions.ConnectionError,
                                         requests.exceptions.ConnectionError,
                                         requests.exceptions.ConnectionError,
                                         requests.exceptions.ConnectionError]
        retry = 3
        retrysleep = 0.1
        retrybackoff = 0.1
        if sys.version_info < (3, ):
            self.ams._retry_make_request.im_func.func_defaults = (None, None, retry, retrysleep, retrybackoff)
        else:
            self.ams._retry_make_request.__func__.__defaults__ = (None, None, retry, retrysleep, retrybackoff)
        self.assertRaises(AmsConnectionException, self.ams.list_topics)
        self.assertEqual(mock_requests_get.call_count, retry + 1)

    @mock.patch('pymod.ams.requests.post')
    def testRetryAmsBalancerTimeout408(self, mock_requests_post):
        retry = 4
        retrysleep = 0.2
        errmsg = "<html><body><h1>408 Request Time-out</h1>\nYour browser didn't send a complete request in time.\n</body></html>\n"
        mock_response = mock.create_autospec(requests.Response)
        mock_response.status_code = 408
        mock_response.content = errmsg
        mock_requests_post.return_value = mock_response
        try:
            self.ams.pull_sub('subscription1', retry=retry, retrysleep=retrysleep)
        except Exception as e:
            assert isinstance(e, AmsTimeoutException)
            self.assertEqual(e.code, 408)
            self.assertEqual(e.msg, 'While trying the [sub_pull]: ' + errmsg)
        self.assertEqual(mock_requests_post.call_count, retry + 1)

    @mock.patch('pymod.ams.requests.post')
    def testRetryAmsBalancer502(self, mock_requests_post):
        retry = 4
        retrysleep = 0.2
        errmsg = "<html><body><h1>502 Bad Gateway</h1>\nThe server returned an invalid or incomplete response.\n</body></html>\n"
        mock_response = mock.create_autospec(requests.Response)
        mock_response.status_code = 502
        mock_response.content = errmsg
        mock_requests_post.return_value = mock_response
        try:
            self.ams.pull_sub('subscription1', retry=retry, retrysleep=retrysleep)
        except Exception as e:
            assert isinstance(e, AmsBalancerException)
            self.assertEqual(e.code, 502)
            self.assertEqual(e.msg, 'While trying the [sub_pull]: ' + errmsg)
        self.assertEqual(mock_requests_post.call_count, retry + 1)

    @mock.patch('pymod.ams.requests.post')
    def testRetryAmsBalancer503(self, mock_requests_post):
        retry = 4
        retrysleep = 0.2
        errmsg = "<html><body><h1>503 Service Unavailable</h1>\nNo server is available to handle this request.\n</body></html>\n"
        mock_response = mock.create_autospec(requests.Response)
        mock_response.status_code = 503
        mock_response.content = errmsg
        mock_requests_post.return_value = mock_response
        try:
            self.ams.pull_sub('subscription1', retry=retry, retrysleep=retrysleep)
        except Exception as e:
            assert isinstance(e, AmsBalancerException)
            self.assertEqual(e.code, 503)
            self.assertEqual(e.msg, 'While trying the [sub_pull]: ' + errmsg)
        self.assertEqual(mock_requests_post.call_count, retry + 1)

    @mock.patch('pymod.ams.requests.post')
    def testRetryAmsBalancerTimeout504(self, mock_requests_post):
        retry = 4
        retrysleep = 0.2
        errmsg = "<html><body><h1>504 Gateway Time-out</h1>\nThe server didn't respond in time.\n</body></html>\n"
        mock_response = mock.create_autospec(requests.Response)
        mock_response.status_code = 504
        mock_response.content = errmsg
        mock_requests_post.return_value = mock_response
        try:
            self.ams.pull_sub('subscription1', retry=retry, retrysleep=retrysleep)
        except Exception as e:
            assert isinstance(e, AmsTimeoutException)
            self.assertEqual(e.code, 504)
            self.assertEqual(e.msg, 'While trying the [sub_pull]: ' + errmsg)
        self.assertEqual(mock_requests_post.call_count, retry + 1)

    @mock.patch('pymod.ams.requests.get')
    def testRetryAckDeadlineAmsTimeout(self, mock_requests_get):
        mock_response = mock.create_autospec(requests.Response)
        mock_response.status_code = 408
        mock_response.content = '{"error": {"code": 408, \
                                            "message": "Ams Timeout", \
                                            "status": "TIMEOUT"}}'
        mock_requests_get.return_value = mock_response
        retry = 3
        retrysleep = 0.1
        if sys.version_info < (3, ):
            self.ams._retry_make_request.im_func.__defaults__ = (None, None, retry, retrysleep, None)
        else:
            self.ams._retry_make_request.__func__.__defaults__ = (None, None, retry, retrysleep, None)
        self.assertRaises(AmsTimeoutException, self.ams.list_topics)
        self.assertEqual(mock_requests_get.call_count, retry + 1)
Пример #2
0
class TestErrorClient(unittest.TestCase):
    def setUp(self):
        # Initialize ams in localhost with token s3cr3t and project TEST
        self.ams = ArgoMessagingService(endpoint="localhost", token="s3cr3t", project="TEST")
        self.errormocks = ErrorMocks()
        self.topicmocks = TopicMocks()
        self.submocks = SubMocks()

    # Test create topic client request
    def testCreateTopics(self):
        # Execute ams client with mocked response
        with HTTMock(self.errormocks.create_topic_alreadyexist_mock):
            try:
                resp = self.ams.create_topic("topic1")
            except Exception as e:
                assert isinstance(e, AmsServiceException)
                self.assertEqual(e.status, 'ALREADY_EXIST')
                self.assertEqual(e.code, 409)

    def testCreateSubscription(self):
        # Execute ams client with mocked response
        with HTTMock(self.topicmocks.get_topic_mock,
                     self.errormocks.create_subscription_alreadyexist_mock):
            try:
                resp = self.ams.create_sub("subscription1", "topic1", 10)
            except Exception as e:
                assert isinstance(e, AmsServiceException)
                self.assertEqual(e.status, 'ALREADY_EXIST')
                self.assertEqual(e.code, 409)

    # Test Publish client request
    def testFailedPublish(self):
        # Mock response for POST publish to topic
        @urlmatch(netloc="localhost", path="/v1/projects/TEST/topics/topic1:publish",
                  method="POST")
        def publish_mock(url, request):
            assert url.path == "/v1/projects/TEST/topics/topic1:publish"
            # Check request produced by ams client
            req_body = json.loads(request.body)
            assert req_body["messages"][0]["data"] == "Zm9vMQ=="
            assert req_body["messages"][0]["attributes"]["bar1"] == "baz1"
            return response(504, '<htmI><body><h1>504 Gateway Time-out</h1>\nThe server didn\'t respond in time.\n</body></html>\n', None, None, 5, request)

        # Execute ams client with mocked response
        with HTTMock(publish_mock):
            msg = AmsMessage(data='foo1', attributes={'bar1': 'baz1'})
            try:
                resp = self.ams.publish("topic1", msg)
            except Exception as e:
                assert isinstance(e, AmsServiceException)
                self.assertEqual(e.code, 504)

    # Tests for plaintext or JSON encoded backend error messages
    def testErrorMsgBackend(self):
        @urlmatch(netloc="localhost", path="/v1/projects/TEST/topics/topic1",
                  method='GET')
        def error_plaintxt(url, request):
            assert url.path == "/v1/projects/TEST/topics/topic1"
            return response(500, "Cannot get topic", None, None, 5, request)

        with HTTMock(error_plaintxt):
            try:
                resp = self.ams.get_topic("topic1")
            except AmsServiceException as e:
                self.assertEqual(e.msg, "While trying the [topic_get]: Cannot get topic")

        @urlmatch(netloc="localhost", path="/v1/projects/TEST/topics/topic1",
                  method='GET')
        def error_json(url, request):
            assert url.path == "/v1/projects/TEST/topics/topic1"
            return response(500, json.loads('{"error": {"code": 500,\
                                              "message": "Cannot get topic",\
                                              "status": "INTERNAL_SERVER_ERROR"\
                                              }}'), None, None, 5, request)

        with HTTMock(error_json):
            try:
                resp = self.ams.get_topic("topic1")
            except AmsServiceException as e:
                self.assertEqual(e.code, 500)
                self.assertEqual(e.msg, "While trying the [topic_get]: Cannot get topic")
                self.assertEqual(e.status, "INTERNAL_SERVER_ERROR")
Пример #3
0
class TestClient(unittest.TestCase):
    def setUp(self):
        # Initialize ams in localhost with token s3cr3t and project TEST
        self.ams = ArgoMessagingService(endpoint="localhost", token="s3cr3t", project="TEST")
        self.submocks = SubMocks()
        self.topicmocks = TopicMocks()

    # Test create topic client request
    def testCreateTopics(self):
        # Execute ams client with mocked response
        with HTTMock(self.topicmocks.create_topic_mock):
            resp = self.ams.create_topic("topic1")
            resp_obj = self.ams.create_topic("topic1", retobj=True)
            # Assert that ams client handled the json response correctly
            name = resp["name"]
            assert name == "/projects/TEST/topics/topic1"
            assert isinstance(resp_obj, AmsTopic)
            self.assertEqual(resp_obj.name, "topic1")

    # Test Pull client request
    def testPull(self):
        # Mock response for POST pull from subscription
        @urlmatch(netloc="localhost",
                  path="/v1/projects/TEST/subscriptions/subscription1:pull",
                  method="POST")
        def pull_mock(url, request):
            assert url.path == "/v1/projects/TEST/subscriptions/subscription1:pull"

            # Check request produced by ams client
            req_body = json.loads(request.body)
            assert req_body["maxMessages"] == "1"
            return '{"receivedMessages":[{"ackId":"projects/TEST/subscriptions/subscription1:1221",\
                    "message":{"messageId":"1221","attributes":{"foo":"bar"},"data":"YmFzZTY0ZW5jb2RlZA==",\
                    "publishTime":"2016-02-24T11:55:09.786127994Z"}}]}'

        # Execute ams client with mocked response
        with HTTMock(pull_mock, self.submocks.ack_mock, self.submocks.get_sub_mock):

            # msg = AmsMessage(data='foo1', attributes={'bar1': 'baz1'}).dict()
            resp_pull = self.ams.pull_sub("subscription1", 1)
            ack_id, msg = resp_pull[0]
            assert ack_id == "projects/TEST/subscriptions/subscription1:1221"
            assert msg.get_data() == "base64encoded"
            assert msg.get_msgid() == "1221"
            # Note: Maybe ack_sub should return a boolean
            resp_ack = self.ams.ack_sub("subscription1", ["1221"])
            assert resp_ack == True

    # Test Create subscription client request
    def testCreateSubscription(self):
        # Execute ams client with mocked response
        with HTTMock(self.topicmocks.get_topic_mock,
                     self.submocks.create_subscription_mock):
            resp = self.ams.create_sub("subscription1", "topic1", 10)

            # Assert that ams client handled the json response correctly
            name = resp["name"]
            assert name == "/projects/TEST/subscriptions/subscription1"

    # Test the Modify offset client request
    def testModifyOffset(self):
        # Execute ams client with mocked response
        with HTTMock(self.submocks.modifyoffset_sub_mock):
            resp = self.ams.modifyoffset_sub("subscription1", 79)
            self.assertEquals(resp, {})

    # Test the Get offsets client request
    def testGetOffsets(self):
        # Execute ams client with mocked response
        with HTTMock(self.submocks.getoffsets_sub_mock):
            # should return a dict with all the offsets
            resp_all = self.ams.getoffsets_sub("subscription1")
            resp_dict_all = {
                "max": 79,
                "min": 0,
                "current": 78
            }
            # should return the max offset
            resp_max = self.ams.getoffsets_sub("subscription1", "max")
            # should return the current offset
            resp_current = self.ams.getoffsets_sub("subscription1", "current")
            # should return the min offset
            resp_min = self.ams.getoffsets_sub("subscription1", "min")

            self.assertEquals(resp_all, resp_dict_all)
            self.assertEquals(resp_max, 79)
            self.assertEquals(resp_current, 78)
            self.assertEquals(resp_min, 0)

    # Test List topics client request
    def testListTopics(self):
        # Execute ams client with mocked response
        with HTTMock(self.topicmocks.list_topics_mock):
            resp = self.ams.list_topics()
            # Assert that ams client handled the json response correctly
            topics = resp["topics"]
            topic_objs = self.ams.topics.values()
            assert len(topics) == 2
            assert topics[0]["name"] == "/projects/TEST/topics/topic1"
            assert topics[1]["name"] == "/projects/TEST/topics/topic2"
            assert isinstance(topic_objs[0], AmsTopic)
            assert isinstance(topic_objs[1], AmsTopic)
            self.assertEqual(topic_objs[0].fullname, "/projects/TEST/topics/topic1")
            self.assertEqual(topic_objs[1].fullname, "/projects/TEST/topics/topic2")

    # Test Iteration over AmsTopic objects
    def testIterTopics(self):
        # Mock response for GET topics request
        @urlmatch(netloc="localhost", path="/v1/projects/TEST/topics",
                  method="GET")
        def iter_topics_mock(url, request):
            assert url.path == "/v1/projects/TEST/topics"
            # Return two topics in json format
            return response(200, '{"topics":[{"name":"/projects/TEST/topics/topic1"},\
                                  {"name":"/projects/TEST/topics/topic2"}]}', None, None, 5, request)

        # Execute ams client with mocked response
        with HTTMock(iter_topics_mock):
            resp = self.ams.iter_topics()
            # Assert that ams client handled the json response correctly
            obj1 = resp.next()
            obj2 = resp.next()
            assert isinstance(obj1, AmsTopic)
            assert isinstance(obj2, AmsTopic)
            self.assertRaises(StopIteration, resp.next)
            self.assertEqual(obj1.name, 'topic1')
            self.assertEqual(obj2.name, 'topic2')

    # Test Get a subscription ACL client request
    def testGetAclSubscription(self):
        # Execute ams client with mocked response
        with HTTMock(self.submocks.getacl_subscription_mock, self.submocks.get_sub_mock):
            resp = self.ams.getacl_sub("subscription1")
            users = resp['authorized_users']
            self.assertEqual(users, [])

    # Test Modify a topic ACL client request
    def testModifyAclSubscription(self):
        @urlmatch(netloc="localhost", path="/v1/projects/TEST/subscriptions/subscription1:acl",
                  method="GET")
        def getacl_subscription_mock_filled(url, request):
            assert url.path == "/v1/projects/TEST/subscriptions/subscription1:acl"
            # Return the details of a topic in json format
            return response(200, '{"authorized_users": ["user1", "user2"]}', None, None, 5, request)


        # Execute ams client with mocked response
        with HTTMock(self.submocks.modifyacl_subscription_mock,
                     getacl_subscription_mock_filled,
                     self.submocks.get_sub_mock):
            resp = self.ams.modifyacl_sub("subscription1", ["user1", "user2"])
            self.assertTrue(resp)
            resp_users = self.ams.getacl_sub("subscription1")
            users = resp_users['authorized_users']
            self.assertEqual(users, ["user1", "user2"])

    # Test Get a topic ACL client request
    def testGetAclTopic(self):
        # Execute ams client with mocked response
        with HTTMock(self.topicmocks.getacl_topic_mock,
                     self.topicmocks.get_topic_mock):
            resp = self.ams.getacl_topic("topic1")
            users = resp['authorized_users']
            self.assertEqual(users, [])

    # Test Modify a topic ACL client request
    def testModifyAclTopic(self):
        @urlmatch(netloc="localhost", path="/v1/projects/TEST/topics/topic1:acl",
                  method="GET")
        def getacl_topic_mock_filled(url, request):
            assert url.path == "/v1/projects/TEST/topics/topic1:acl"
            # Return the details of a topic in json format
            return response(200, '{"authorized_users": ["user1", "user2"]}', None, None, 5, request)

        # Execute ams client with mocked response
        with HTTMock(self.topicmocks.modifyacl_topic_mock,
                     getacl_topic_mock_filled, self.topicmocks.get_topic_mock):
            resp = self.ams.modifyacl_topic("topic1", ["user1", "user2"])
            self.assertTrue(resp)
            resp_users = self.ams.getacl_topic("topic1")
            users = resp_users['authorized_users']
            self.assertEqual(users, ["user1", "user2"])

    # Test Get a topic client request
    def testGetTopic(self):
        # Execute ams client with mocked response
        with HTTMock(self.topicmocks.get_topic_mock):
            resp = self.ams.get_topic("topic1")
            resp_obj = self.ams.get_topic("topic1", retobj=True)
            # Assert that ams client handled the json response correctly
            name = resp["name"]
            assert(name == "/projects/TEST/topics/topic1")
            assert isinstance(resp_obj, AmsTopic)
            self.assertEqual(resp_obj.name, 'topic1')

    # Test Publish client request
    def testPublish(self):
        # Mock response for POST publish to topic
        @urlmatch(netloc="localhost", path="/v1/projects/TEST/topics/topic1:publish",
                  method="POST")
        def publish_mock(url, request):
            assert url.path == "/v1/projects/TEST/topics/topic1:publish"
            # Check request produced by ams client
            req_body = json.loads(request.body)
            assert(req_body["messages"][0]["data"] == "Zm9vMQ==")
            assert (req_body["messages"][0]["attributes"]["bar1"] == "baz1")

            return '{"msgIds":["1"]}'

        # Execute ams client with mocked response
        with HTTMock(publish_mock):
            msg = AmsMessage(data='foo1', attributes={'bar1': 'baz1'}).dict()
            msg_bulk = [AmsMessage(data='foo1', attributes={'bar1': 'baz1'}), AmsMessage(data='foo2', attributes={'bar2': 'baz2'})]
            resp = self.ams.publish("topic1", msg)
            assert resp["msgIds"][0] == "1"
            resp_bulk = self.ams.publish("topic1", msg_bulk)
            assert resp["msgIds"][0] == "1"

        @urlmatch(netloc="localhost", path="/v1/projects/TEST/topics/topic1:publish",
                  method="POST")
        def publish_bulk_mock(url, request):
            assert url.path == "/v1/projects/TEST/topics/topic1:publish"
            # Check request produced by ams client
            req_body = json.loads(request.body)
            self.assertEqual(req_body["messages"][0]["data"], "Zm9vMQ==")
            self.assertEqual(req_body["messages"][0]["attributes"]["bar1"], "baz1")
            self.assertEqual(req_body["messages"][1]["data"], "Zm9vMg==")
            self.assertEqual(req_body["messages"][1]["attributes"]["bar2"], "baz2")

            return '{"msgIds":["1", "2"]}'

        with HTTMock(publish_bulk_mock):
            msg_bulk = [AmsMessage(data='foo1', attributes={'bar1': 'baz1'}), AmsMessage(data='foo2', attributes={'bar2': 'baz2'})]
            resp_bulk = self.ams.publish("topic1", msg_bulk)
            self.assertEqual(len(resp_bulk["msgIds"]), 2)
            self.assertEqual(resp_bulk["msgIds"][0], "1")
            self.assertEqual(resp_bulk["msgIds"][1], "2")

    # Test List Subscriptions client request
    def testListSubscriptions(self):
        # Mock response for GET Subscriptions request
        @urlmatch(netloc="localhost", path="/v1/projects/TEST/subscriptions",
                  method="GET")
        def list_subs_mock(url, request):
            assert url.path == "/v1/projects/TEST/subscriptions"
            # Return two topics in json format
            return response(200, '{"subscriptions":[{"name": "/projects/TEST/subscriptions/subscription1",\
                                  "topic": "/projects/TEST/topics/topic1","pushConfig": \
                                  {"pushEndpoint": "","retryPolicy": {}},"ackDeadlineSeconds": 10},\
                                  {"name": "/projects/TEST/subscriptions/subscription2", \
                                  "topic": "/projects/TEST/topics/topic1", \
                                  "pushConfig": {"pushEndpoint": "","retryPolicy": {}},\
                                  "ackDeadlineSeconds": 10}]}', None, None, 5, request)

        # Execute ams client with mocked response
        with HTTMock(list_subs_mock):
            resp = self.ams.list_subs()
            subscriptions = resp["subscriptions"]
            subscription_objs = self.ams.subs.values()
            topic_objs = self.ams.topics.values()
            # Assert that ams client handled the json response correctly
            assert len(subscriptions) == 2
            assert subscriptions[0]["name"] == "/projects/TEST/subscriptions/subscription1"
            assert subscriptions[1]["name"] == "/projects/TEST/subscriptions/subscription2"
            assert isinstance(subscription_objs[0], AmsSubscription)
            assert isinstance(subscription_objs[1], AmsSubscription)
            self.assertEqual(subscription_objs[0].fullname, "/projects/TEST/subscriptions/subscription1")
            self.assertEqual(subscription_objs[1].fullname, "/projects/TEST/subscriptions/subscription2")
            assert isinstance(topic_objs[0], AmsTopic)
            self.assertEqual(topic_objs[0].fullname, "/projects/TEST/topics/topic1")

    # Test Iteration over AmsSubscription objects
    def testIterSubscriptions(self):
        # Mock response for GET Subscriptions request
        @urlmatch(netloc="localhost", path="/v1/projects/TEST/subscriptions",
                  method="GET")
        def iter_subs_mock(url, request):
            assert url.path == "/v1/projects/TEST/subscriptions"
            # Return two topics in json format
            return response(200, '{"subscriptions":[{"name": "/projects/TEST/subscriptions/subscription1",\
                                  "topic": "/projects/TEST/topics/topic1","pushConfig": \
                                  {"pushEndpoint": "","retryPolicy": {}},"ackDeadlineSeconds": 10},\
                                  {"name": "/projects/TEST/subscriptions/subscription2", \
                                  "topic": "/projects/TEST/topics/topic1", \
                                  "pushConfig": {"pushEndpoint": "","retryPolicy": {}},\
                                  "ackDeadlineSeconds": 10}]}', None, None, 5, request)

        # Execute ams client with mocked response
        with HTTMock(iter_subs_mock):
            resp = self.ams.iter_subs()
            obj1 = resp.next()
            obj2 = resp.next()
            assert isinstance(obj1, AmsSubscription)
            assert isinstance(obj2, AmsSubscription)
            self.assertRaises(StopIteration, resp.next)
            self.assertEqual(obj1.name, 'subscription1')
            self.assertEqual(obj2.name, 'subscription2')

    # Test Get a subscriptions client request
    def testGetSubscription(self):
        # Execute ams client with mocked response
        with HTTMock(self.submocks.get_sub_mock):
            resp = self.ams.get_sub("subscription1")
            resp_obj = self.ams.get_sub("subscription1", retobj=True)
            # Assert that ams client handled the json response correctly
            name = resp["name"]
            assert name == "/projects/TEST/subscriptions/subscription1"
            assert isinstance(resp_obj, AmsSubscription)
            self.assertEqual(resp_obj.name, 'subscription1')

    # Test has topic client
    def testHasTopic(self):
        with HTTMock(self.topicmocks.get_topic_mock):
            self.assertTrue(self.ams.has_topic('topic1'))

    # Test has subscription client
    def testHasSub(self):
        with HTTMock(self.submocks.get_sub_mock):
            self.assertTrue(self.ams.has_sub('subscription1'))