def test_get_ratelimitable_key_tuples(self): current_rate = 13 conf_dict = { 'account_ratelimit': current_rate, 'container_ratelimit_3': 200 } fake_memcache = FakeMemcache() fake_memcache.store[get_container_memcache_key('a', 'c')] = \ {'container_size': 5} the_app = ratelimit.RateLimitMiddleware(None, conf_dict, logger=FakeLogger()) the_app.memcache_client = fake_memcache self.assertEquals( len(the_app.get_ratelimitable_key_tuples('GET', 'a', None, None)), 1) self.assertEquals( len(the_app.get_ratelimitable_key_tuples('POST', 'a', 'c', None)), 0) self.assertEquals( len(the_app.get_ratelimitable_key_tuples('PUT', 'a', 'c', None)), 1) self.assertEquals( len(the_app.get_ratelimitable_key_tuples('GET', 'a', 'c', None)), 1) self.assertEquals( len(the_app.get_ratelimitable_key_tuples('GET', 'a', 'c', 'o')), 0) self.assertEquals( len(the_app.get_ratelimitable_key_tuples('PUT', 'a', 'c', 'o')), 1)
def get_ratelimitable_key_tuples(self, req_method, account_name, container_name=None, obj_name=None): """ Returns a list of key (used in memcache), ratelimit tuples. Keys should be checked in order. :param req_method: HTTP method :param account_name: account name from path :param container_name: container name from path :param obj_name: object name from path """ keys = [] # COPYs are not limited if self.account_ratelimit and \ account_name and container_name and not obj_name and \ req_method in ('PUT', 'DELETE'): keys.append(("ratelimit/%s" % account_name, self.account_ratelimit)) if account_name and container_name and obj_name and \ req_method in ('PUT', 'DELETE', 'POST'): container_size = None memcache_key = get_container_memcache_key(account_name, container_name) container_info = self.memcache_client.get(memcache_key) if isinstance(container_info, dict): container_size = container_info.get('container_size', 0) container_rate = self.get_container_maxrate(container_size) if container_rate: keys.append(("ratelimit/%s/%s" % (account_name, container_name), container_rate)) return keys
def get_ratelimitable_key_tuples(self, req_method, account_name, container_name=None, obj_name=None): """ Returns a list of key (used in memcache), ratelimit tuples. Keys should be checked in order. :param req_method: HTTP method :param account_name: account name from path :param container_name: container name from path :param obj_name: object name from path """ keys = [] if ( self.account_ratelimit and account_name and ( not (container_name or obj_name) or (container_name and not obj_name and req_method in ("PUT", "DELETE")) ) ): keys.append(("ratelimit/%s" % account_name, self.account_ratelimit)) if ( account_name and container_name and ((not obj_name and req_method in ("GET", "HEAD")) or (obj_name and req_method in ("PUT", "DELETE"))) ): container_size = None memcache_key = get_container_memcache_key(account_name, container_name) container_info = self.memcache_client.get(memcache_key) if isinstance(container_info, dict): container_size = container_info.get("container_size", 0) container_rate = self.get_container_maxrate(container_size) if container_rate: keys.append(("ratelimit/%s/%s" % (account_name, container_name), container_rate)) return keys
def get_ratelimitable_key_tuples(self, req_method, account_name, container_name=None, obj_name=None): """ Returns a list of key (used in memcache), ratelimit tuples. Keys should be checked in order. :param req_method: HTTP method :param account_name: account name from path :param container_name: container name from path :param obj_name: object name from path """ keys = [] if self.account_ratelimit and account_name and ( not (container_name or obj_name) or (container_name and not obj_name and req_method in ('PUT', 'DELETE'))): keys.append(("ratelimit/%s" % account_name, self.account_ratelimit)) if account_name and container_name and ( (not obj_name and req_method in ('GET', 'HEAD')) or (obj_name and req_method in ('PUT', 'DELETE'))): container_size = None memcache_key = get_container_memcache_key(account_name, container_name) container_info = self.memcache_client.get(memcache_key) if isinstance(container_info, dict): container_size = container_info.get('container_size', 0) container_rate = self.get_container_maxrate(container_size) if container_rate: keys.append(("ratelimit/%s/%s" % (account_name, container_name), container_rate)) return keys
def test_get_ratelimitable_key_tuples(self): current_rate = 13 conf_dict = {'account_ratelimit': current_rate, 'container_ratelimit_3': 200} fake_memcache = FakeMemcache() fake_memcache.store[get_container_memcache_key('a', 'c')] = \ {'container_size': 5} the_app = ratelimit.RateLimitMiddleware(None, conf_dict, logger=FakeLogger()) the_app.memcache_client = fake_memcache self.assertEquals(len(the_app.get_ratelimitable_key_tuples( 'DELETE', 'a', None, None)), 0) self.assertEquals(len(the_app.get_ratelimitable_key_tuples( 'PUT', 'a', 'c', None)), 1) self.assertEquals(len(the_app.get_ratelimitable_key_tuples( 'DELETE', 'a', 'c', None)), 1) self.assertEquals(len(the_app.get_ratelimitable_key_tuples( 'GET', 'a', 'c', 'o')), 0) self.assertEquals(len(the_app.get_ratelimitable_key_tuples( 'PUT', 'a', 'c', 'o')), 1)
def test_ratelimit_acc_vrs_container(self): conf_dict = { 'clock_accuracy': 1000, 'account_ratelimit': 10, 'max_sleep_time_seconds': 4, 'container_ratelimit_10': 6, 'container_ratelimit_50': 2, 'container_ratelimit_75': 1 } self.test_ratelimit = dummy_filter_factory(conf_dict)(FakeApp()) ratelimit.http_connect = mock_http_connect(204) req = Request.blank('/v/a/c') req.environ['swift.cache'] = FakeMemcache() cont_key = get_container_memcache_key('a', 'c') class rate_caller(Thread): def __init__(self, parent, name): Thread.__init__(self) self.parent = parent self.name = name def run(self): self.result = self.parent.test_ratelimit( req.environ, start_response) def runthreads(threads, nt): for i in range(nt): rc = rate_caller(self, "thread %s" % i) rc.start() threads.append(rc) for thread in threads: thread.join() begin = time.time() req.environ['swift.cache'].set(cont_key, {'container_size': 20}) begin = time.time() threads = [] runthreads(threads, 3) time_took = time.time() - begin self.assert_(round(time_took, 1) == .4)
def test_ratelimit_acc_vrs_container(self): conf_dict = {'clock_accuracy': 1000, 'account_ratelimit': 10, 'max_sleep_time_seconds': 4, 'container_ratelimit_10': 6, 'container_ratelimit_50': 2, 'container_ratelimit_75': 1} self.test_ratelimit = dummy_filter_factory(conf_dict)(FakeApp()) ratelimit.http_connect = mock_http_connect(204) req = Request.blank('/v/a/c') req.environ['swift.cache'] = FakeMemcache() cont_key = get_container_memcache_key('a', 'c') class rate_caller(Thread): def __init__(self, parent, name): Thread.__init__(self) self.parent = parent self.name = name def run(self): self.result = self.parent.test_ratelimit(req.environ, start_response) def runthreads(threads, nt): for i in range(nt): rc = rate_caller(self, "thread %s" % i) rc.start() threads.append(rc) for thread in threads: thread.join() begin = time.time() req.environ['swift.cache'].set(cont_key, {'container_size': 20}) begin = time.time() threads = [] runthreads(threads, 3) time_took = time.time() - begin self.assert_(round(time_took, 1) == .4)