Merge lp:~gholt/swift/autocreate into lp:~hudson-openstack/swift/trunk
- autocreate
- Merge into trunk
Proposed by
gholt
Status: | Merged | ||||
---|---|---|---|---|---|
Approved by: | David Goetz | ||||
Approved revision: | 311 | ||||
Merged at revision: | 308 | ||||
Proposed branch: | lp:~gholt/swift/autocreate | ||||
Merge into: | lp:~hudson-openstack/swift/trunk | ||||
Diff against target: |
334 lines (+92/-21) 10 files modified
doc/source/deployment_guide.rst (+4/-0) etc/proxy-server.conf-sample (+3/-0) swift/common/bench.py (+2/-2) swift/common/daemon.py (+2/-1) swift/common/middleware/staticweb.py (+1/-1) swift/common/utils.py (+1/-1) swift/proxy/server.py (+29/-12) swift/stats/log_uploader.py (+1/-1) test/unit/common/test_utils.py (+4/-0) test/unit/proxy/test_server.py (+45/-3) |
||||
To merge this branch: | bzr merge lp:~gholt/swift/autocreate | ||||
Related bugs: |
|
||||
Related blueprints: |
Account Auto Create Option
(Undefined)
|
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
David Goetz (community) | Approve | ||
John Dickinson | Approve | ||
Review via email: mp+64206@code.launchpad.net |
Commit message
Description of the change
Added account_autocreate mode where authorized requests to accounts that don't yet exist within Swift will cause those accounts to be automatically created. Also did a small refactor surrounding swift.common.
To post a comment you must log in.
Revision history for this message
gholt (gholt) wrote : | # |
Well, it's 2xx but yeah. Is there more you'd like it to do?
Revision history for this message
gholt (gholt) wrote : | # |
Oh, I guess you mentioned retry. Not sure I'd want to implement retries on that since we don't really do that elsewhere in the proxy. But even if we don't retry, it seems like I should change non-2xx to cause a 5xx on the original request rather than a 404 or something.
Revision history for this message
gholt (gholt) wrote : | # |
Okay, I made a failed account autocreate cause a 5xx now, which indicates the client should retry their request if desired.
Preview Diff
[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1 | === modified file 'doc/source/deployment_guide.rst' | |||
2 | --- doc/source/deployment_guide.rst 2011-05-26 02:24:12 +0000 | |||
3 | +++ doc/source/deployment_guide.rst 2011-06-10 16:57:25 +0000 | |||
4 | @@ -547,6 +547,10 @@ | |||
5 | 547 | node error limited | 547 | node error limited |
6 | 548 | allow_account_management false Whether account PUTs and DELETEs | 548 | allow_account_management false Whether account PUTs and DELETEs |
7 | 549 | are even callable | 549 | are even callable |
8 | 550 | account_autocreate false If set to 'true' authorized | ||
9 | 551 | accounts that do not yet exist | ||
10 | 552 | within the Swift cluster will | ||
11 | 553 | be automatically created. | ||
12 | 550 | ============================ =============== ============================= | 554 | ============================ =============== ============================= |
13 | 551 | 555 | ||
14 | 552 | [tempauth] | 556 | [tempauth] |
15 | 553 | 557 | ||
16 | === modified file 'etc/proxy-server.conf-sample' | |||
17 | --- etc/proxy-server.conf-sample 2011-05-26 02:24:12 +0000 | |||
18 | +++ etc/proxy-server.conf-sample 2011-06-10 16:57:25 +0000 | |||
19 | @@ -40,6 +40,9 @@ | |||
20 | 40 | # If set to 'true' any authorized user may create and delete accounts; if | 40 | # If set to 'true' any authorized user may create and delete accounts; if |
21 | 41 | # 'false' no one, even authorized, can. | 41 | # 'false' no one, even authorized, can. |
22 | 42 | # allow_account_management = false | 42 | # allow_account_management = false |
23 | 43 | # If set to 'true' authorized accounts that do not yet exist within the Swift | ||
24 | 44 | # cluster will be automatically created. | ||
25 | 45 | # account_autocreate = false | ||
26 | 43 | 46 | ||
27 | 44 | [filter:tempauth] | 47 | [filter:tempauth] |
28 | 45 | use = egg:swift#tempauth | 48 | use = egg:swift#tempauth |
29 | 46 | 49 | ||
30 | === modified file 'swift/common/bench.py' | |||
31 | --- swift/common/bench.py 2011-05-25 11:56:53 +0000 | |||
32 | +++ swift/common/bench.py 2011-06-10 16:57:25 +0000 | |||
33 | @@ -43,7 +43,7 @@ | |||
34 | 43 | self.user = conf.user | 43 | self.user = conf.user |
35 | 44 | self.key = conf.key | 44 | self.key = conf.key |
36 | 45 | self.auth_url = conf.auth | 45 | self.auth_url = conf.auth |
38 | 46 | self.use_proxy = conf.use_proxy in TRUE_VALUES | 46 | self.use_proxy = conf.use_proxy.lower() in TRUE_VALUES |
39 | 47 | if self.use_proxy: | 47 | if self.use_proxy: |
40 | 48 | url, token = client.get_auth(self.auth_url, self.user, self.key) | 48 | url, token = client.get_auth(self.auth_url, self.user, self.key) |
41 | 49 | self.token = token | 49 | self.token = token |
42 | @@ -125,7 +125,7 @@ | |||
43 | 125 | self.logger = logger | 125 | self.logger = logger |
44 | 126 | self.conf = conf | 126 | self.conf = conf |
45 | 127 | self.names = [] | 127 | self.names = [] |
47 | 128 | self.delete = conf.delete in TRUE_VALUES | 128 | self.delete = conf.delete.lower() in TRUE_VALUES |
48 | 129 | self.gets = int(conf.num_gets) | 129 | self.gets = int(conf.num_gets) |
49 | 130 | 130 | ||
50 | 131 | def run(self): | 131 | def run(self): |
51 | 132 | 132 | ||
52 | === modified file 'swift/common/daemon.py' | |||
53 | --- swift/common/daemon.py 2011-02-21 18:50:56 +0000 | |||
54 | +++ swift/common/daemon.py 2011-06-10 16:57:25 +0000 | |||
55 | @@ -75,7 +75,8 @@ | |||
56 | 75 | log_name=kwargs.get('log_name')) | 75 | log_name=kwargs.get('log_name')) |
57 | 76 | 76 | ||
58 | 77 | # once on command line (i.e. daemonize=false) will over-ride config | 77 | # once on command line (i.e. daemonize=false) will over-ride config |
60 | 78 | once = once or conf.get('daemonize', 'true') not in utils.TRUE_VALUES | 78 | once = once or \ |
61 | 79 | conf.get('daemonize', 'true').lower() not in utils.TRUE_VALUES | ||
62 | 79 | 80 | ||
63 | 80 | # pre-configure logger | 81 | # pre-configure logger |
64 | 81 | if 'logger' in kwargs: | 82 | if 'logger' in kwargs: |
65 | 82 | 83 | ||
66 | === modified file 'swift/common/middleware/staticweb.py' | |||
67 | --- swift/common/middleware/staticweb.py 2011-05-26 02:24:12 +0000 | |||
68 | +++ swift/common/middleware/staticweb.py 2011-06-10 16:57:25 +0000 | |||
69 | @@ -270,7 +270,7 @@ | |||
70 | 270 | :param start_response: The original WSGI start_response hook. | 270 | :param start_response: The original WSGI start_response hook. |
71 | 271 | :param prefix: Any prefix desired for the container listing. | 271 | :param prefix: Any prefix desired for the container listing. |
72 | 272 | """ | 272 | """ |
74 | 273 | if self._listings not in TRUE_VALUES: | 273 | if self._listings.lower() not in TRUE_VALUES: |
75 | 274 | resp = HTTPNotFound()(env, self._start_response) | 274 | resp = HTTPNotFound()(env, self._start_response) |
76 | 275 | return self._error_response(resp, env, start_response) | 275 | return self._error_response(resp, env, start_response) |
77 | 276 | tmp_env = self._get_escalated_env(env) | 276 | tmp_env = self._get_escalated_env(env) |
78 | 277 | 277 | ||
79 | === modified file 'swift/common/utils.py' | |||
80 | --- swift/common/utils.py 2011-04-20 19:54:28 +0000 | |||
81 | +++ swift/common/utils.py 2011-06-10 16:57:25 +0000 | |||
82 | @@ -72,7 +72,7 @@ | |||
83 | 72 | pass | 72 | pass |
84 | 73 | 73 | ||
85 | 74 | # Used when reading config values | 74 | # Used when reading config values |
87 | 75 | TRUE_VALUES = set(('true', '1', 'yes', 'True', 'Yes', 'on', 'On', 't', 'y')) | 75 | TRUE_VALUES = set(('true', '1', 'yes', 'on', 't', 'y')) |
88 | 76 | 76 | ||
89 | 77 | 77 | ||
90 | 78 | def validate_configuration(): | 78 | def validate_configuration(): |
91 | 79 | 79 | ||
92 | === modified file 'swift/proxy/server.py' | |||
93 | --- swift/proxy/server.py 2011-05-12 15:57:35 +0000 | |||
94 | +++ swift/proxy/server.py 2011-06-10 16:57:25 +0000 | |||
95 | @@ -41,8 +41,8 @@ | |||
96 | 41 | from webob import Request, Response | 41 | from webob import Request, Response |
97 | 42 | 42 | ||
98 | 43 | from swift.common.ring import Ring | 43 | from swift.common.ring import Ring |
101 | 44 | from swift.common.utils import get_logger, normalize_timestamp, split_path, \ | 44 | from swift.common.utils import cache_from_env, ContextPool, get_logger, \ |
102 | 45 | cache_from_env, ContextPool | 45 | normalize_timestamp, split_path, TRUE_VALUES |
103 | 46 | from swift.common.bufferedhttp import http_connect | 46 | from swift.common.bufferedhttp import http_connect |
104 | 47 | from swift.common.constraints import check_metadata, check_object_creation, \ | 47 | from swift.common.constraints import check_metadata, check_object_creation, \ |
105 | 48 | check_utf8, CONTAINER_LISTING_LIMIT, MAX_ACCOUNT_NAME_LENGTH, \ | 48 | check_utf8, CONTAINER_LISTING_LIMIT, MAX_ACCOUNT_NAME_LENGTH, \ |
106 | @@ -338,7 +338,7 @@ | |||
107 | 338 | node['errors'] = self.app.error_suppression_limit + 1 | 338 | node['errors'] = self.app.error_suppression_limit + 1 |
108 | 339 | node['last_error'] = time.time() | 339 | node['last_error'] = time.time() |
109 | 340 | 340 | ||
111 | 341 | def account_info(self, account): | 341 | def account_info(self, account, autocreate=False): |
112 | 342 | """ | 342 | """ |
113 | 343 | Get account information, and also verify that the account exists. | 343 | Get account information, and also verify that the account exists. |
114 | 344 | 344 | ||
115 | @@ -353,7 +353,7 @@ | |||
116 | 353 | result_code = self.app.memcache.get(cache_key) | 353 | result_code = self.app.memcache.get(cache_key) |
117 | 354 | if result_code == 200: | 354 | if result_code == 200: |
118 | 355 | return partition, nodes | 355 | return partition, nodes |
120 | 356 | elif result_code == 404: | 356 | elif result_code == 404 and not autocreate: |
121 | 357 | return None, None | 357 | return None, None |
122 | 358 | result_code = 0 | 358 | result_code = 0 |
123 | 359 | attempts_left = self.app.account_ring.replica_count | 359 | attempts_left = self.app.account_ring.replica_count |
124 | @@ -386,6 +386,17 @@ | |||
125 | 386 | except (Exception, TimeoutError): | 386 | except (Exception, TimeoutError): |
126 | 387 | self.exception_occurred(node, _('Account'), | 387 | self.exception_occurred(node, _('Account'), |
127 | 388 | _('Trying to get account info for %s') % path) | 388 | _('Trying to get account info for %s') % path) |
128 | 389 | if result_code == 404 and autocreate: | ||
129 | 390 | if len(account) > MAX_ACCOUNT_NAME_LENGTH: | ||
130 | 391 | return None, None | ||
131 | 392 | headers = {'X-Timestamp': normalize_timestamp(time.time()), | ||
132 | 393 | 'X-Trans-Id': self.trans_id} | ||
133 | 394 | resp = self.make_requests(Request.blank('/v1' + path), | ||
134 | 395 | self.app.account_ring, partition, 'PUT', | ||
135 | 396 | path, [headers] * len(nodes)) | ||
136 | 397 | if resp.status_int // 100 != 2: | ||
137 | 398 | raise Exception('Could not autocreate account %r' % path) | ||
138 | 399 | result_code = 200 | ||
139 | 389 | if self.app.memcache and result_code in (200, 404): | 400 | if self.app.memcache and result_code in (200, 404): |
140 | 390 | if result_code == 200: | 401 | if result_code == 200: |
141 | 391 | cache_timeout = self.app.recheck_account_existence | 402 | cache_timeout = self.app.recheck_account_existence |
142 | @@ -397,7 +408,7 @@ | |||
143 | 397 | return partition, nodes | 408 | return partition, nodes |
144 | 398 | return None, None | 409 | return None, None |
145 | 399 | 410 | ||
147 | 400 | def container_info(self, account, container): | 411 | def container_info(self, account, container, account_autocreate=False): |
148 | 401 | """ | 412 | """ |
149 | 402 | Get container information and thusly verify container existance. | 413 | Get container information and thusly verify container existance. |
150 | 403 | This will also make a call to account_info to verify that the | 414 | This will also make a call to account_info to verify that the |
151 | @@ -423,7 +434,7 @@ | |||
152 | 423 | return partition, nodes, read_acl, write_acl | 434 | return partition, nodes, read_acl, write_acl |
153 | 424 | elif status == 404: | 435 | elif status == 404: |
154 | 425 | return None, None, None, None | 436 | return None, None, None, None |
156 | 426 | if not self.account_info(account)[1]: | 437 | if not self.account_info(account, autocreate=account_autocreate)[1]: |
157 | 427 | return None, None, None, None | 438 | return None, None, None, None |
158 | 428 | result_code = 0 | 439 | result_code = 0 |
159 | 429 | read_acl = None | 440 | read_acl = None |
160 | @@ -854,7 +865,8 @@ | |||
161 | 854 | if error_response: | 865 | if error_response: |
162 | 855 | return error_response | 866 | return error_response |
163 | 856 | container_partition, containers, _junk, req.acl = \ | 867 | container_partition, containers, _junk, req.acl = \ |
165 | 857 | self.container_info(self.account_name, self.container_name) | 868 | self.container_info(self.account_name, self.container_name, |
166 | 869 | account_autocreate=self.app.account_autocreate) | ||
167 | 858 | if 'swift.authorize' in req.environ: | 870 | if 'swift.authorize' in req.environ: |
168 | 859 | aresp = req.environ['swift.authorize'](req) | 871 | aresp = req.environ['swift.authorize'](req) |
169 | 860 | if aresp: | 872 | if aresp: |
170 | @@ -911,7 +923,8 @@ | |||
171 | 911 | def PUT(self, req): | 923 | def PUT(self, req): |
172 | 912 | """HTTP PUT request handler.""" | 924 | """HTTP PUT request handler.""" |
173 | 913 | container_partition, containers, _junk, req.acl = \ | 925 | container_partition, containers, _junk, req.acl = \ |
175 | 914 | self.container_info(self.account_name, self.container_name) | 926 | self.container_info(self.account_name, self.container_name, |
176 | 927 | account_autocreate=self.app.account_autocreate) | ||
177 | 915 | if 'swift.authorize' in req.environ: | 928 | if 'swift.authorize' in req.environ: |
178 | 916 | aresp = req.environ['swift.authorize'](req) | 929 | aresp = req.environ['swift.authorize'](req) |
179 | 917 | if aresp: | 930 | if aresp: |
180 | @@ -1219,7 +1232,8 @@ | |||
181 | 1219 | resp.body = 'Container name length of %d longer than %d' % \ | 1232 | resp.body = 'Container name length of %d longer than %d' % \ |
182 | 1220 | (len(self.container_name), MAX_CONTAINER_NAME_LENGTH) | 1233 | (len(self.container_name), MAX_CONTAINER_NAME_LENGTH) |
183 | 1221 | return resp | 1234 | return resp |
185 | 1222 | account_partition, accounts = self.account_info(self.account_name) | 1235 | account_partition, accounts = self.account_info(self.account_name, |
186 | 1236 | autocreate=self.app.account_autocreate) | ||
187 | 1223 | if not accounts: | 1237 | if not accounts: |
188 | 1224 | return HTTPNotFound(request=req) | 1238 | return HTTPNotFound(request=req) |
189 | 1225 | container_partition, containers = self.app.container_ring.get_nodes( | 1239 | container_partition, containers = self.app.container_ring.get_nodes( |
190 | @@ -1249,7 +1263,8 @@ | |||
191 | 1249 | self.clean_acls(req) or check_metadata(req, 'container') | 1263 | self.clean_acls(req) or check_metadata(req, 'container') |
192 | 1250 | if error_response: | 1264 | if error_response: |
193 | 1251 | return error_response | 1265 | return error_response |
195 | 1252 | account_partition, accounts = self.account_info(self.account_name) | 1266 | account_partition, accounts = self.account_info(self.account_name, |
196 | 1267 | autocreate=self.app.account_autocreate) | ||
197 | 1253 | if not accounts: | 1268 | if not accounts: |
198 | 1254 | return HTTPNotFound(request=req) | 1269 | return HTTPNotFound(request=req) |
199 | 1255 | container_partition, containers = self.app.container_ring.get_nodes( | 1270 | container_partition, containers = self.app.container_ring.get_nodes( |
200 | @@ -1391,7 +1406,7 @@ | |||
201 | 1391 | self.put_queue_depth = int(conf.get('put_queue_depth', 10)) | 1406 | self.put_queue_depth = int(conf.get('put_queue_depth', 10)) |
202 | 1392 | self.object_chunk_size = int(conf.get('object_chunk_size', 65536)) | 1407 | self.object_chunk_size = int(conf.get('object_chunk_size', 65536)) |
203 | 1393 | self.client_chunk_size = int(conf.get('client_chunk_size', 65536)) | 1408 | self.client_chunk_size = int(conf.get('client_chunk_size', 65536)) |
205 | 1394 | self.log_headers = conf.get('log_headers') == 'True' | 1409 | self.log_headers = conf.get('log_headers', 'no').lower() in TRUE_VALUES |
206 | 1395 | self.error_suppression_interval = \ | 1410 | self.error_suppression_interval = \ |
207 | 1396 | int(conf.get('error_suppression_interval', 60)) | 1411 | int(conf.get('error_suppression_interval', 60)) |
208 | 1397 | self.error_suppression_limit = \ | 1412 | self.error_suppression_limit = \ |
209 | @@ -1401,7 +1416,7 @@ | |||
210 | 1401 | self.recheck_account_existence = \ | 1416 | self.recheck_account_existence = \ |
211 | 1402 | int(conf.get('recheck_account_existence', 60)) | 1417 | int(conf.get('recheck_account_existence', 60)) |
212 | 1403 | self.allow_account_management = \ | 1418 | self.allow_account_management = \ |
214 | 1404 | conf.get('allow_account_management', 'false').lower() == 'true' | 1419 | conf.get('allow_account_management', 'no').lower() in TRUE_VALUES |
215 | 1405 | self.resellers_conf = ConfigParser() | 1420 | self.resellers_conf = ConfigParser() |
216 | 1406 | self.resellers_conf.read(os.path.join(swift_dir, 'resellers.conf')) | 1421 | self.resellers_conf.read(os.path.join(swift_dir, 'resellers.conf')) |
217 | 1407 | self.object_ring = object_ring or \ | 1422 | self.object_ring = object_ring or \ |
218 | @@ -1413,6 +1428,8 @@ | |||
219 | 1413 | self.memcache = memcache | 1428 | self.memcache = memcache |
220 | 1414 | mimetypes.init(mimetypes.knownfiles + | 1429 | mimetypes.init(mimetypes.knownfiles + |
221 | 1415 | [os.path.join(swift_dir, 'mime.types')]) | 1430 | [os.path.join(swift_dir, 'mime.types')]) |
222 | 1431 | self.account_autocreate = \ | ||
223 | 1432 | conf.get('account_autocreate', 'no').lower() in TRUE_VALUES | ||
224 | 1416 | 1433 | ||
225 | 1417 | def get_controller(self, path): | 1434 | def get_controller(self, path): |
226 | 1418 | """ | 1435 | """ |
227 | 1419 | 1436 | ||
228 | === modified file 'swift/stats/log_uploader.py' | |||
229 | --- swift/stats/log_uploader.py 2011-05-24 20:51:07 +0000 | |||
230 | +++ swift/stats/log_uploader.py 2011-06-10 16:57:25 +0000 | |||
231 | @@ -69,7 +69,7 @@ | |||
232 | 69 | self.internal_proxy = InternalProxy(proxy_server_conf) | 69 | self.internal_proxy = InternalProxy(proxy_server_conf) |
233 | 70 | self.new_log_cutoff = int(cutoff or | 70 | self.new_log_cutoff = int(cutoff or |
234 | 71 | uploader_conf.get('new_log_cutoff', '7200')) | 71 | uploader_conf.get('new_log_cutoff', '7200')) |
236 | 72 | self.unlink_log = uploader_conf.get('unlink_log', 'True').lower() in \ | 72 | self.unlink_log = uploader_conf.get('unlink_log', 'true').lower() in \ |
237 | 73 | utils.TRUE_VALUES | 73 | utils.TRUE_VALUES |
238 | 74 | self.filename_pattern = regex or \ | 74 | self.filename_pattern = regex or \ |
239 | 75 | uploader_conf.get('source_filename_pattern', | 75 | uploader_conf.get('source_filename_pattern', |
240 | 76 | 76 | ||
241 | === modified file 'test/unit/common/test_utils.py' | |||
242 | --- test/unit/common/test_utils.py 2011-03-30 20:04:15 +0000 | |||
243 | +++ test/unit/common/test_utils.py 2011-06-10 16:57:25 +0000 | |||
244 | @@ -768,6 +768,10 @@ | |||
245 | 768 | self.assertEquals(utils.human_readable(1237940039285380274899124224), | 768 | self.assertEquals(utils.human_readable(1237940039285380274899124224), |
246 | 769 | '1024Yi') | 769 | '1024Yi') |
247 | 770 | 770 | ||
248 | 771 | def test_TRUE_VALUES(self): | ||
249 | 772 | for v in utils.TRUE_VALUES: | ||
250 | 773 | self.assertEquals(v, v.lower()) | ||
251 | 774 | |||
252 | 771 | 775 | ||
253 | 772 | if __name__ == '__main__': | 776 | if __name__ == '__main__': |
254 | 773 | unittest.main() | 777 | unittest.main() |
255 | 774 | 778 | ||
256 | === modified file 'test/unit/proxy/test_server.py' | |||
257 | --- test/unit/proxy/test_server.py 2011-05-09 20:21:34 +0000 | |||
258 | +++ test/unit/proxy/test_server.py 2011-06-10 16:57:25 +0000 | |||
259 | @@ -393,6 +393,48 @@ | |||
260 | 393 | test(404, 507, 503) | 393 | test(404, 507, 503) |
261 | 394 | test(503, 503, 503) | 394 | test(503, 503, 503) |
262 | 395 | 395 | ||
263 | 396 | def test_account_info_account_autocreate(self): | ||
264 | 397 | with save_globals(): | ||
265 | 398 | self.memcache.store = {} | ||
266 | 399 | proxy_server.http_connect = \ | ||
267 | 400 | fake_http_connect(404, 404, 404, 201, 201, 201) | ||
268 | 401 | partition, nodes = \ | ||
269 | 402 | self.controller.account_info(self.account, autocreate=False) | ||
270 | 403 | self.check_account_info_return(partition, nodes, is_none=True) | ||
271 | 404 | |||
272 | 405 | self.memcache.store = {} | ||
273 | 406 | proxy_server.http_connect = \ | ||
274 | 407 | fake_http_connect(404, 404, 404, 201, 201, 201) | ||
275 | 408 | partition, nodes = \ | ||
276 | 409 | self.controller.account_info(self.account) | ||
277 | 410 | self.check_account_info_return(partition, nodes, is_none=True) | ||
278 | 411 | |||
279 | 412 | self.memcache.store = {} | ||
280 | 413 | proxy_server.http_connect = \ | ||
281 | 414 | fake_http_connect(404, 404, 404, 201, 201, 201) | ||
282 | 415 | partition, nodes = \ | ||
283 | 416 | self.controller.account_info(self.account, autocreate=True) | ||
284 | 417 | self.check_account_info_return(partition, nodes) | ||
285 | 418 | |||
286 | 419 | self.memcache.store = {} | ||
287 | 420 | proxy_server.http_connect = \ | ||
288 | 421 | fake_http_connect(404, 404, 404, 503, 201, 201) | ||
289 | 422 | partition, nodes = \ | ||
290 | 423 | self.controller.account_info(self.account, autocreate=True) | ||
291 | 424 | self.check_account_info_return(partition, nodes) | ||
292 | 425 | |||
293 | 426 | self.memcache.store = {} | ||
294 | 427 | proxy_server.http_connect = \ | ||
295 | 428 | fake_http_connect(404, 404, 404, 503, 201, 503) | ||
296 | 429 | exc = None | ||
297 | 430 | try: | ||
298 | 431 | partition, nodes = \ | ||
299 | 432 | self.controller.account_info(self.account, autocreate=True) | ||
300 | 433 | except Exception, err: | ||
301 | 434 | exc = err | ||
302 | 435 | self.assertEquals(str(exc), | ||
303 | 436 | "Could not autocreate account '/some_account'") | ||
304 | 437 | |||
305 | 396 | def check_container_info_return(self, ret, is_none=False): | 438 | def check_container_info_return(self, ret, is_none=False): |
306 | 397 | if is_none: | 439 | if is_none: |
307 | 398 | partition, nodes, read_acl, write_acl = None, None, None, None | 440 | partition, nodes, read_acl, write_acl = None, None, None, None |
308 | @@ -406,7 +448,7 @@ | |||
309 | 406 | self.assertEqual(write_acl, ret[3]) | 448 | self.assertEqual(write_acl, ret[3]) |
310 | 407 | 449 | ||
311 | 408 | def test_container_info_invalid_account(self): | 450 | def test_container_info_invalid_account(self): |
313 | 409 | def account_info(self, account): | 451 | def account_info(self, account, autocreate=False): |
314 | 410 | return None, None | 452 | return None, None |
315 | 411 | 453 | ||
316 | 412 | with save_globals(): | 454 | with save_globals(): |
317 | @@ -417,7 +459,7 @@ | |||
318 | 417 | 459 | ||
319 | 418 | # tests if 200 is cached and used | 460 | # tests if 200 is cached and used |
320 | 419 | def test_container_info_200(self): | 461 | def test_container_info_200(self): |
322 | 420 | def account_info(self, account): | 462 | def account_info(self, account, autocreate=False): |
323 | 421 | return True, True | 463 | return True, True |
324 | 422 | 464 | ||
325 | 423 | with save_globals(): | 465 | with save_globals(): |
326 | @@ -443,7 +485,7 @@ | |||
327 | 443 | 485 | ||
328 | 444 | # tests if 404 is cached and used | 486 | # tests if 404 is cached and used |
329 | 445 | def test_container_info_404(self): | 487 | def test_container_info_404(self): |
331 | 446 | def account_info(self, account): | 488 | def account_info(self, account, autocreate=False): |
332 | 447 | return True, True | 489 | return True, True |
333 | 448 | 490 | ||
334 | 449 | with save_globals(): | 491 | with save_globals(): |
account_info doesn't retry or handle any results other than 200 to the autocreate PUT. Should it do more?