| Index: third_party/google-endpoints/endpoints/test/apiserving_test.py
|
| diff --git a/third_party/google-endpoints/endpoints/test/apiserving_test.py b/third_party/google-endpoints/endpoints/test/apiserving_test.py
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..8028647bd09b4e9d70daee20b9eead8710b5fc2b
|
| --- /dev/null
|
| +++ b/third_party/google-endpoints/endpoints/test/apiserving_test.py
|
| @@ -0,0 +1,303 @@
|
| +#!/usr/bin/python2.4
|
| +#
|
| +# Copyright 2016 Google Inc. All Rights Reserved.
|
| +#
|
| +# Licensed under the Apache License, Version 2.0 (the "License");
|
| +# you may not use this file except in compliance with the License.
|
| +# You may obtain a copy of the License at
|
| +#
|
| +# http://www.apache.org/licenses/LICENSE-2.0
|
| +#
|
| +# Unless required by applicable law or agreed to in writing, software
|
| +# distributed under the License is distributed on an "AS IS" BASIS,
|
| +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
| +# See the License for the specific language governing permissions and
|
| +# limitations under the License.
|
| +
|
| +"""Tests for Apiserving library.
|
| +
|
| +Tests:
|
| + ModuleInterfaceTest: Tests interface of module.
|
| + ApiServerTest: Tests core functionality: registry, requests, errors.
|
| +"""
|
| +
|
| +import httplib
|
| +import json
|
| +import logging
|
| +import unittest
|
| +import urllib2
|
| +
|
| +import endpoints.api_backend_service as api_backend_service
|
| +import endpoints.api_config as api_config
|
| +import endpoints.api_exceptions as api_exceptions
|
| +import endpoints.apiserving as apiserving
|
| +import mox
|
| +from protorpc import message_types
|
| +from protorpc import messages
|
| +from protorpc import protojson
|
| +from protorpc import registry
|
| +from protorpc import remote
|
| +from protorpc import transport
|
| +
|
| +import endpoints.resource_container as resource_container
|
| +import test_util
|
| +
|
| +import webtest
|
| +
|
| +package = 'endpoints.test'
|
| +
|
| +
|
| +class ExceptionRequest(messages.Message):
|
| + exception_type = messages.StringField(1)
|
| + message = messages.StringField(2)
|
| +
|
| +
|
| +class Custom405Exception(api_exceptions.ServiceException):
|
| + http_status = httplib.METHOD_NOT_ALLOWED
|
| +
|
| +
|
| +class Custom408Exception(api_exceptions.ServiceException):
|
| + http_status = httplib.REQUEST_TIMEOUT
|
| +
|
| +
|
| +@api_config.api('aservice', 'v2', hostname='aservice.appspot.com',
|
| + description='A Service API')
|
| +class AService(remote.Service):
|
| +
|
| + @api_config.method(name='noopname', path='nooppath')
|
| + def Noop(self, unused_request):
|
| + return message_types.VoidMessage()
|
| +
|
| + @api_config.method(path='type_error')
|
| + def RaiseTypeError(self, unused_request):
|
| + raise TypeError('a type error')
|
| +
|
| + @api_config.method(path='app_error')
|
| + def RaiseNormalApplicationError(self, unused_request):
|
| + raise remote.ApplicationError('whatever')
|
| +
|
| + # Silence warning about not deriving from Exception
|
| + # pylint: disable=nonstandard-exception
|
| + @api_config.method(ExceptionRequest, path='exception')
|
| + def RaiseException(self, request):
|
| + exception_class = (getattr(api_exceptions, request.exception_type, None) or
|
| + globals().get(request.exception_type))
|
| + raise exception_class(request.message)
|
| +
|
| +
|
| +@api_config.api('bservice', 'v3', hostname='bservice.appspot.com',
|
| + description='Another Service API')
|
| +class BService(remote.Service):
|
| +
|
| + @api_config.method(path='noop')
|
| + def Noop(self, unused_request):
|
| + return message_types.VoidMessage()
|
| +
|
| +
|
| +test_request = resource_container.ResourceContainer(
|
| + message_types.VoidMessage,
|
| + id=messages.IntegerField(1, required=True))
|
| +
|
| +
|
| +@api_config.api(name='testapi', version='v3', description='A wonderful API.')
|
| +class TestService(remote.Service):
|
| +
|
| + @api_config.method(test_request,
|
| + message_types.VoidMessage,
|
| + http_method='DELETE', path='items/{id}')
|
| + # Silence lint warning about method naming conventions
|
| + # pylint: disable=g-bad-name
|
| + def delete(self, unused_request):
|
| + return message_types.VoidMessage()
|
| +
|
| +
|
| +@api_config.api(name='testapicustomurl', version='v3',
|
| + description='A wonderful API.', base_path='/my/base/path/')
|
| +class TestServiceCustomUrl(remote.Service):
|
| +
|
| + @api_config.method(test_request,
|
| + message_types.VoidMessage,
|
| + http_method='DELETE', path='items/{id}')
|
| + # Silence lint warning about method naming conventions
|
| + # pylint: disable=g-bad-name
|
| + def delete(self, unused_request):
|
| + return message_types.VoidMessage()
|
| +
|
| +
|
| +my_api = api_config.api(name='My Service', version='v1')
|
| +
|
| +
|
| +@my_api.api_class()
|
| +class MultiClassService1(remote.Service):
|
| +
|
| + @api_config.method(path='s1')
|
| + def S1method(self, unused_request):
|
| + return message_types.VoidMessage()
|
| +
|
| +
|
| +@my_api.api_class()
|
| +class MultiClassService2(remote.Service):
|
| +
|
| + @api_config.method(path='s2')
|
| + def S2method(self, unused_request):
|
| + return message_types.VoidMessage()
|
| +
|
| +
|
| +TEST_SERVICE_API_CONFIG = {'items': [{
|
| + 'abstract': False,
|
| + 'adapter': {
|
| + 'bns': 'https://None/_ah/api',
|
| + 'type': 'lily',
|
| + 'deadline': 10.0
|
| + },
|
| + 'defaultVersion': True,
|
| + 'description': 'A wonderful API.',
|
| + 'descriptor': {
|
| + 'methods': {
|
| + 'TestService.delete': {}
|
| + },
|
| + 'schemas': {
|
| + 'ProtorpcMessageTypesVoidMessage': {
|
| + 'description': 'Empty message.',
|
| + 'id': 'ProtorpcMessageTypesVoidMessage',
|
| + 'properties': {},
|
| + 'type': 'object'
|
| + }
|
| + }
|
| + },
|
| + 'extends': 'thirdParty.api',
|
| + 'methods': {
|
| + 'testapi.delete': {
|
| + 'httpMethod': 'DELETE',
|
| + 'path': 'items/{id}',
|
| + 'request': {
|
| + 'body': 'empty',
|
| + 'parameterOrder': ['id'],
|
| + 'parameters': {
|
| + 'id': {
|
| + 'required': True,
|
| + 'type': 'int64',
|
| + }
|
| + }
|
| + },
|
| + 'response': {
|
| + 'body': 'empty'
|
| + },
|
| + 'rosyMethod': 'TestService.delete',
|
| + 'scopes': ['https://www.googleapis.com/auth/userinfo.email'],
|
| + 'clientIds': ['292824132082.apps.googleusercontent.com'],
|
| + 'authLevel': 'NONE'
|
| + }
|
| + },
|
| + 'name': 'testapi',
|
| + 'root': 'https://None/_ah/api',
|
| + 'version': 'v3'
|
| +}]}
|
| +
|
| +
|
| +TEST_SERVICE_CUSTOM_URL_API_CONFIG = {'items': [{
|
| + 'abstract': False,
|
| + 'adapter': {
|
| + 'bns': 'https://None/my/base/path',
|
| + 'type': 'lily',
|
| + 'deadline': 10.0
|
| + },
|
| + 'defaultVersion': True,
|
| + 'description': 'A wonderful API.',
|
| + 'descriptor': {
|
| + 'methods': {
|
| + 'TestServiceCustomUrl.delete': {}
|
| + },
|
| + 'schemas': {
|
| + 'ProtorpcMessageTypesVoidMessage': {
|
| + 'description': 'Empty message.',
|
| + 'id': 'ProtorpcMessageTypesVoidMessage',
|
| + 'properties': {},
|
| + 'type': 'object'
|
| + }
|
| + }
|
| + },
|
| + 'extends': 'thirdParty.api',
|
| + 'methods': {
|
| + 'testapicustomurl.delete': {
|
| + 'httpMethod': 'DELETE',
|
| + 'path': 'items/{id}',
|
| + 'request': {
|
| + 'body': 'empty',
|
| + 'parameterOrder': ['id'],
|
| + 'parameters': {
|
| + 'id': {
|
| + 'required': True,
|
| + 'type': 'int64',
|
| + }
|
| + }
|
| + },
|
| + 'response': {
|
| + 'body': 'empty'
|
| + },
|
| + 'rosyMethod': 'TestServiceCustomUrl.delete',
|
| + 'scopes': ['https://www.googleapis.com/auth/userinfo.email'],
|
| + 'clientIds': ['292824132082.apps.googleusercontent.com'],
|
| + 'authLevel': 'NONE'
|
| + }
|
| + },
|
| + 'name': 'testapicustomurl',
|
| + 'root': 'https://None/my/base/path',
|
| + 'version': 'v3'
|
| +}]}
|
| +
|
| +
|
| +class ModuleInterfaceTest(test_util.ModuleInterfaceTest,
|
| + unittest.TestCase):
|
| +
|
| + MODULE = apiserving
|
| +
|
| +
|
| +class ApiServerBaseTest(unittest.TestCase):
|
| +
|
| + def setUp(self):
|
| + super(ApiServerBaseTest, self).setUp()
|
| +
|
| +
|
| +class ApiServerTestApiConfigRegistryEndToEnd(unittest.TestCase):
|
| + # Show diff with expected API config
|
| + maxDiff = None
|
| +
|
| + def setUp(self):
|
| + super(ApiServerTestApiConfigRegistryEndToEnd, self).setUp()
|
| +
|
| + def testGetApiConfigs(self):
|
| + my_app = apiserving.api_server([TestService])
|
| +
|
| + # 200 with X-Appengine-Peer: apiserving header
|
| + configs = my_app.get_api_configs()
|
| + self.assertEqual(TEST_SERVICE_API_CONFIG, configs)
|
| +
|
| +
|
| +class GetAppRevisionTest(unittest.TestCase):
|
| + def testGetAppRevision(self):
|
| + environ = {'CURRENT_VERSION_ID': '1.1'}
|
| + self.assertEqual('1', apiserving._get_app_revision(environ=environ))
|
| +
|
| + def testGetAppRevisionWithNoEntry(self):
|
| + environ = {}
|
| + self.assertEqual(None, apiserving._get_app_revision(environ=environ))
|
| +
|
| +
|
| +class ApiServerTestApiConfigRegistryEndToEndCustomUrl(unittest.TestCase):
|
| + # Show diff with expected API config
|
| + maxDiff = None
|
| +
|
| + def setUp(self):
|
| + super(ApiServerTestApiConfigRegistryEndToEndCustomUrl, self).setUp()
|
| +
|
| + def testGetApiConfigs(self):
|
| + my_app = apiserving.api_server([TestServiceCustomUrl])
|
| +
|
| + # 200 with X-Appengine-Peer: apiserving header
|
| + configs = my_app.get_api_configs()
|
| + self.assertEqual(TEST_SERVICE_CUSTOM_URL_API_CONFIG, configs)
|
| +
|
| +
|
| +if __name__ == '__main__':
|
| + unittest.main()
|
|
|