Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 698d028

Browse files
committed
Make memcache/taskqueue stubs throw better error messages.
1 parent 2a29f25 commit 698d028

File tree

2 files changed

+82
-42
lines changed

2 files changed

+82
-42
lines changed

ndb/tasklets.py

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1192,6 +1192,18 @@ def _make_cloud_datastore_context(app_id, external_app_ids=()):
11921192
except:
11931193
pass # The stub is already installed.
11941194
# TODO(pcostello): Ensure the current stub is connected to the right project.
1195+
1196+
# Install a memcache and taskqueue stub which throws on everything.
1197+
try:
1198+
apiproxy_stub_map.apiproxy.RegisterStub('memcache', _ThrowingStub())
1199+
except:
1200+
pass # The stub is already installed.
1201+
try:
1202+
apiproxy_stub_map.apiproxy.RegisterStub('taskqueue', _ThrowingStub())
1203+
except:
1204+
pass # The stub is already installed.
1205+
1206+
11951207
return make_context(conn=conn)
11961208

11971209

@@ -1200,6 +1212,17 @@ def set_context(new_context):
12001212
os.environ[_CONTEXT_KEY] = '1'
12011213
_state.current_context = new_context
12021214

1215+
class _ThrowingStub(object):
1216+
"""A Stub implementation which always throws a NotImplementedError."""
1217+
1218+
# pylint: disable=invalid-name
1219+
def MakeSyncCall(self, service, call, request, response):
1220+
raise NotImplementedError('In order to use %s.%s you must '
1221+
'install the Remote API.' % (service, call))
1222+
1223+
# pylint: disable=invalid-name
1224+
def CreateRPC(self):
1225+
return apiproxy_rpc.RPC(stub=self)
12031226

12041227
# TODO: Rework the following into documentation.
12051228

ndb/tasklets_test.py

Lines changed: 59 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626
from .google_imports import datastore_pbs
2727
from .google_imports import datastore_rpc
2828
from .google_imports import namespace_manager
29+
from .google_imports import taskqueue
2930
from .google_test_imports import unittest
3031
from .google_test_imports import real_unittest
3132

@@ -785,48 +786,6 @@ class Employee(model.Model):
785786
self.assertEqual(fn(m), True)
786787
self.assertEqual(key.Key(Employee, 'mykey').get().name, 'Patrick')
787788

788-
@real_unittest.skipUnless(
789-
datastore_pbs._CLOUD_DATASTORE_ENABLED,
790-
"V1 must be supported to run V1 tests.")
791-
def testCloudDatastoreContext(self):
792-
del os.environ['APPLICATION_ID'] # Clear APPLICATION_ID for test.
793-
os.environ['DATASTORE_PROJECT_ID'] = 'project'
794-
# Setting just a project id isn't enough info.
795-
self.assertRaisesRegexp(ValueError,
796-
'Could not determine app id\..*',
797-
tasklets.make_default_context)
798-
# Unless the override is specified.
799-
os.environ['DATASTORE_USE_PROJECT_ID_AS_APP_ID'] = 'True'
800-
ctx = tasklets.make_default_context()
801-
self.assertEqual(datastore_rpc._CLOUD_DATASTORE_V1, ctx._conn._api_version)
802-
os.environ['DATASTORE_APP_ID'] = 's~project'
803-
# App id and override should not both be specified
804-
self.assertRaisesRegexp(ValueError,
805-
'App id was provided .* but .* was set to true\.',
806-
tasklets.make_default_context)
807-
del os.environ['DATASTORE_USE_PROJECT_ID_AS_APP_ID']
808-
ctx = tasklets.make_default_context()
809-
self.assertEqual(datastore_rpc._CLOUD_DATASTORE_V1, ctx._conn._api_version)
810-
os.environ['DATASTORE_APP_ID'] = 's~anotherproject'
811-
# The provided app id must resolve to the provided project id.
812-
self.assertRaises(ValueError, tasklets.make_default_context)
813-
os.environ['DATASTORE_APP_ID'] = 's~project'
814-
os.environ['DATASTORE_ADDITIONAL_APP_IDS'] = 's~anotherapp,s~andanother'
815-
ctx = tasklets.make_default_context()
816-
converter = ctx._conn.adapter.get_entity_converter()
817-
self.assertEquals('s~anotherapp', converter.project_to_app_id('anotherapp'))
818-
self.assertEquals('s~andanother', converter.project_to_app_id('andanother'))
819-
820-
@real_unittest.skipUnless(
821-
datastore_pbs._CLOUD_DATASTORE_ENABLED,
822-
"V1 must be supported to run V1 tests.")
823-
def testCloudDatastoreContextWithExistingApplicationId(self):
824-
os.environ['DATASTORE_APP_ID'] = 's~project'
825-
os.environ['DATASTORE_PROJECT_ID'] = 'project'
826-
os.environ['APPLICATION_ID'] = 's~a-different-project'
827-
# If things are set propertly but APPLICATION_ID is already set, we fail.
828-
self.assertRaises(ValueError, tasklets.make_default_context)
829-
830789

831790
class TracebackTests(test_utils.NDBTest):
832791
"""Checks that errors result in reasonable tracebacks."""
@@ -888,5 +847,63 @@ def testYieldError(self):
888847
str(err)))
889848

890849

850+
@real_unittest.skipUnless(datastore_pbs._CLOUD_DATASTORE_ENABLED,
851+
"V1 must be supported to run V1 tests.")
852+
class CloudDatastoreContextCreationTests(test_utils.NDBCloudDatastoreV1Test):
853+
"""Context tests that use a Cloud Datastore V1 connection."""
854+
855+
def setUp(self):
856+
super(CloudDatastoreContextCreationTests, self).setUp()
857+
self.HRTest()
858+
self.ctx = tasklets._make_cloud_datastore_context(self.APP_ID)
859+
tasklets.set_context(self.ctx)
860+
861+
def testCloudDatastoreContext(self):
862+
del os.environ['APPLICATION_ID'] # Clear APPLICATION_ID for test.
863+
os.environ['DATASTORE_PROJECT_ID'] = 'project'
864+
# Setting just a project id isn't enough info.
865+
self.assertRaisesRegexp(ValueError,
866+
'Could not determine app id\..*',
867+
tasklets.make_default_context)
868+
# Unless the override is specified.
869+
os.environ['DATASTORE_USE_PROJECT_ID_AS_APP_ID'] = 'True'
870+
ctx = tasklets.make_default_context()
871+
self.assertEqual(datastore_rpc._CLOUD_DATASTORE_V1, ctx._conn._api_version)
872+
os.environ['DATASTORE_APP_ID'] = 's~project'
873+
# App id and override should not both be specified
874+
self.assertRaisesRegexp(ValueError,
875+
'App id was provided .* but .* was set to true\.',
876+
tasklets.make_default_context)
877+
del os.environ['DATASTORE_USE_PROJECT_ID_AS_APP_ID']
878+
ctx = tasklets.make_default_context()
879+
self.assertEqual(datastore_rpc._CLOUD_DATASTORE_V1, ctx._conn._api_version)
880+
os.environ['DATASTORE_APP_ID'] = 's~anotherproject'
881+
# The provided app id must resolve to the provided project id.
882+
self.assertRaises(ValueError, tasklets.make_default_context)
883+
os.environ['DATASTORE_APP_ID'] = 's~project'
884+
os.environ['DATASTORE_ADDITIONAL_APP_IDS'] = 's~anotherapp,s~andanother'
885+
ctx = tasklets.make_default_context()
886+
converter = ctx._conn.adapter.get_entity_converter()
887+
self.assertEquals('s~anotherapp', converter.project_to_app_id('anotherapp'))
888+
self.assertEquals('s~andanother', converter.project_to_app_id('andanother'))
889+
890+
def testCloudDatastoreContextWithExistingApplicationId(self):
891+
os.environ['DATASTORE_APP_ID'] = 's~project'
892+
os.environ['DATASTORE_PROJECT_ID'] = 'project'
893+
os.environ['APPLICATION_ID'] = 's~a-different-project'
894+
# If things are set propertly but APPLICATION_ID is already set, we fail.
895+
self.assertRaises(ValueError, tasklets.make_default_context)
896+
897+
def testContext_MemcacheUnavailable(self):
898+
key = model.Key('Foo', 1)
899+
ent = model.Expando(key=key, bar=1)
900+
ctx = tasklets.get_context()
901+
ctx.set_memcache_policy(True)
902+
self.assertRaises(NotImplementedError, ctx.put(ent).get_result)
903+
904+
def testContext_TaskQueueUnavailable(self):
905+
self.assertRaises(NotImplementedError, taskqueue.add, url='/')
906+
907+
891908
if __name__ == '__main__':
892909
unittest.main()

0 commit comments

Comments
 (0)