|
1 #!/usr/bin/env python |
|
2 # |
|
3 # Copyright 2007 Google Inc. |
|
4 # |
|
5 # Licensed under the Apache License, Version 2.0 (the "License"); |
|
6 # you may not use this file except in compliance with the License. |
|
7 # You may obtain a copy of the License at |
|
8 # |
|
9 # http://www.apache.org/licenses/LICENSE-2.0 |
|
10 # |
|
11 # Unless required by applicable law or agreed to in writing, software |
|
12 # distributed under the License is distributed on an "AS IS" BASIS, |
|
13 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
|
14 # See the License for the specific language governing permissions and |
|
15 # limitations under the License. |
|
16 # |
|
17 |
|
18 """Container of APIProxy stubs for more convenient unittesting. |
|
19 |
|
20 Classes/variables/functions defined here: |
|
21 APIProxyStubMap: container of APIProxy stubs. |
|
22 apiproxy: global instance of an APIProxyStubMap. |
|
23 MakeSyncCall: APIProxy entry point. |
|
24 """ |
|
25 |
|
26 |
|
27 |
|
28 |
|
29 |
|
30 import sys |
|
31 |
|
32 def MakeSyncCall(service, call, request, response): |
|
33 """The APIProxy entry point. |
|
34 |
|
35 Args: |
|
36 service: string representing which service to call |
|
37 call: string representing which function to call |
|
38 request: protocol buffer for the request |
|
39 response: protocol buffer for the response |
|
40 |
|
41 Raises: |
|
42 apiproxy_errors.Error or a subclass. |
|
43 """ |
|
44 stub = apiproxy.GetStub(service) |
|
45 assert stub, 'No api proxy found for service "%s"' % service |
|
46 stub.MakeSyncCall(service, call, request, response) |
|
47 |
|
48 |
|
49 class APIProxyStubMap: |
|
50 """Container of APIProxy stubs for more convenient unittesting. |
|
51 |
|
52 Stubs may be either trivial implementations of APIProxy services (e.g. |
|
53 DatastoreFileStub, UserServiceStub) or "real" implementations. |
|
54 |
|
55 For unittests, we may want to mix and match real and trivial implementations |
|
56 of services in order to better focus testing on individual service |
|
57 implementations. To achieve this, we allow the client to attach stubs to |
|
58 service names, as well as define a default stub to be used if no specific |
|
59 matching stub is identified. |
|
60 """ |
|
61 |
|
62 |
|
63 def __init__(self, default_stub=None): |
|
64 """Constructor. |
|
65 |
|
66 Args: |
|
67 default_stub: optional stub |
|
68 |
|
69 'default_stub' will be used whenever no specific matching stub is found. |
|
70 """ |
|
71 self.__stub_map = {} |
|
72 self.__default_stub = default_stub |
|
73 |
|
74 def RegisterStub(self, service, stub): |
|
75 """Register the provided stub for the specified service. |
|
76 |
|
77 Args: |
|
78 service: string |
|
79 stub: stub |
|
80 """ |
|
81 assert not self.__stub_map.has_key(service) |
|
82 self.__stub_map[service] = stub |
|
83 |
|
84 if service == 'datastore': |
|
85 self.RegisterStub('datastore_v3', stub) |
|
86 |
|
87 def GetStub(self, service): |
|
88 """Retrieve the stub registered for the specified service. |
|
89 |
|
90 Args: |
|
91 service: string |
|
92 |
|
93 Returns: |
|
94 stub |
|
95 |
|
96 Returns the stub registered for 'service', and returns the default stub |
|
97 if no such stub is found. |
|
98 """ |
|
99 return self.__stub_map.get(service, self.__default_stub) |
|
100 |
|
101 def GetDefaultAPIProxy(): |
|
102 try: |
|
103 runtime = __import__('google.appengine.runtime', globals(), locals(), |
|
104 ['apiproxy']) |
|
105 return APIProxyStubMap(runtime.apiproxy) |
|
106 except (AttributeError, ImportError): |
|
107 return APIProxyStubMap() |
|
108 |
|
109 apiproxy = GetDefaultAPIProxy() |