OLD | NEW |
1 # Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 # Copyright (c) 2012 The Chromium Authors. All rights reserved. |
2 # Use of this source code is governed by a BSD-style license that can be | 2 # Use of this source code is governed by a BSD-style license that can be |
3 # found in the LICENSE file. | 3 # found in the LICENSE file. |
4 | 4 |
5 # This will attempt to import the actual App Engine modules, and if it fails, | 5 # This will attempt to import the actual App Engine modules, and if it fails, |
6 # they will be replaced with fake modules. This is useful during testing. | 6 # they will be replaced with fake modules. This is useful during testing. |
| 7 |
| 8 import time |
| 9 |
| 10 class InMemoryMemcache(object): |
| 11 """A memcache that stores items in memory instead of using the memcache |
| 12 module. |
| 13 """ |
| 14 class _CacheEntry(object): |
| 15 def __init__(self, value, expire_time): |
| 16 self.value = value |
| 17 self._never_expires = (expire_time == 0) |
| 18 self._expiry = time.time() + expire_time |
| 19 |
| 20 def HasExpired(self): |
| 21 if self._never_expires: |
| 22 return False |
| 23 return time.time() > self._expiry |
| 24 |
| 25 def __init__(self): |
| 26 self._cache = {} |
| 27 |
| 28 def set(self, key, value, namespace, time=60): |
| 29 if namespace not in self._cache: |
| 30 self._cache[namespace] = {} |
| 31 self._cache[namespace][key] = self._CacheEntry(value, time) |
| 32 |
| 33 def get(self, key, namespace): |
| 34 if namespace not in self._cache: |
| 35 return None |
| 36 cache_entry = self._cache[namespace].get(key, None) |
| 37 if not cache_entry: |
| 38 return None |
| 39 if cache_entry.HasExpired(): |
| 40 self.delete(key, namespace) |
| 41 return None |
| 42 return cache_entry.value |
| 43 |
| 44 def delete(self, key, namespace): |
| 45 if namespace in self._cache: |
| 46 self._cache[namespace].pop(key) |
| 47 |
7 try: | 48 try: |
8 import google.appengine.ext.blobstore as blobstore | 49 import google.appengine.ext.blobstore as blobstore |
9 from google.appengine.ext.blobstore.blobstore import BlobReferenceProperty | 50 from google.appengine.ext.blobstore.blobstore import BlobReferenceProperty |
10 import google.appengine.ext.db as db | 51 import google.appengine.ext.db as db |
11 import google.appengine.ext.webapp as webapp | 52 import google.appengine.ext.webapp as webapp |
12 import google.appengine.api.files as files | 53 import google.appengine.api.files as files |
13 import google.appengine.api.memcache as memcache | 54 #import google.appengine.api.memcache as memcache |
| 55 memcache = InMemoryMemcache() |
14 import google.appengine.api.urlfetch as urlfetch | 56 import google.appengine.api.urlfetch as urlfetch |
15 except ImportError: | 57 except ImportError: |
16 import re | 58 import re |
17 | 59 |
18 FAKE_URL_FETCHER_CONFIGURATION = None | 60 FAKE_URL_FETCHER_CONFIGURATION = None |
19 | 61 |
20 def ConfigureFakeUrlFetch(configuration): | 62 def ConfigureFakeUrlFetch(configuration): |
21 """|configuration| is a dictionary mapping strings to fake urlfetch classes. | 63 """|configuration| is a dictionary mapping strings to fake urlfetch classes. |
22 A fake urlfetch class just needs to have a fetch method. The keys of the | 64 A fake urlfetch class just needs to have a fetch method. The keys of the |
23 dictionary are treated as regex, and they are matched with the URL to | 65 dictionary are treated as regex, and they are matched with the URL to |
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
66 rpc.result = self.fetch(url) | 108 rpc.result = self.fetch(url) |
67 urlfetch = FakeUrlFetch() | 109 urlfetch = FakeUrlFetch() |
68 | 110 |
69 class NotImplemented(object): | 111 class NotImplemented(object): |
70 def __getattr__(self, attr): | 112 def __getattr__(self, attr): |
71 raise NotImplementedError() | 113 raise NotImplementedError() |
72 | 114 |
73 blobstore = NotImplemented() | 115 blobstore = NotImplemented() |
74 files = NotImplemented() | 116 files = NotImplemented() |
75 | 117 |
76 class InMemoryMemcache(object): | |
77 """A memcache that stores items in memory instead of using the memcache | |
78 module. | |
79 """ | |
80 def __init__(self): | |
81 self._cache = {} | |
82 | |
83 def set(self, key, value, namespace, time=60): | |
84 if namespace not in self._cache: | |
85 self._cache[namespace] = {} | |
86 self._cache[namespace][key] = value | |
87 | |
88 def get(self, key, namespace): | |
89 if namespace not in self._cache: | |
90 return None | |
91 return self._cache[namespace].get(key, None) | |
92 | |
93 def delete(self, key, namespace): | |
94 if namespace in self._cache: | |
95 self._cache[namespace].pop(key) | |
96 memcache = InMemoryMemcache() | 118 memcache = InMemoryMemcache() |
97 | 119 |
98 # A fake webapp.RequestHandler class for Handler to extend. | 120 # A fake webapp.RequestHandler class for Handler to extend. |
99 class webapp(object): | 121 class webapp(object): |
100 class RequestHandler(object): | 122 class RequestHandler(object): |
101 def __init__(self, request, response): | 123 def __init__(self, request, response): |
102 self.request = request | 124 self.request = request |
103 self.response = response | 125 self.response = response |
104 | 126 |
105 def redirect(self, path): | 127 def redirect(self, path): |
106 self.request.path = path | 128 self.request.path = path |
107 | 129 |
108 class _Db_Result(object): | 130 class _Db_Result(object): |
109 def get(self): | 131 def get(self): |
110 return [] | 132 return [] |
111 | 133 |
112 class db(object): | 134 class db(object): |
113 class StringProperty(object): | 135 class StringProperty(object): |
114 pass | 136 pass |
115 | 137 |
116 class Model(object): | 138 class Model(object): |
117 @staticmethod | 139 @staticmethod |
118 def gql(*args): | 140 def gql(*args): |
119 return _Db_Result() | 141 return _Db_Result() |
120 | 142 |
121 class BlobReferenceProperty(object): | 143 class BlobReferenceProperty(object): |
122 pass | 144 pass |
OLD | NEW |