package com.rubiconproject.oss.kv.test.backends; import java.util.concurrent.TimeUnit; import com.rubiconproject.oss.kv.KeyValueStoreUnavailable; import com.rubiconproject.oss.kv.backends.MemcachedKeyValueStore; import com.rubiconproject.oss.kv.backends.RateLimitingKeyValueStore; import com.rubiconproject.oss.kv.test.KeyValueStoreBackendTestCase; import com.rubiconproject.oss.kv.util.MemcachedRateLimiter; import com.rubiconproject.oss.kv.util.RateLimiter; import com.rubiconproject.oss.kv.util.SimpleRateLimiter; public class RateLimitingStoreBackendTestCase extends KeyValueStoreBackendTestCase { public void testBackend() throws Exception { MemcachedKeyValueStore mcc = new MemcachedKeyValueStore(); mcc.setHosts("localhost:11211"); mcc.start(); RateLimitingKeyValueStore store = new RateLimitingKeyValueStore(); store.setMaster(mcc); // test behavior w/ no limits doTestBackend(store); // add a write limit of one per 100ms RateLimiter limiter = new SimpleRateLimiter(TimeUnit.MILLISECONDS, 100, 1); store.setWriteRateLimiter(limiter); store.set("test.key", "test.value"); try { store.set("test.key2", "test.value2"); fail("Rate limit exceeded. Should have failed!"); } catch (KeyValueStoreUnavailable e) { assertEquals(limiter.getCounter(), 1); } // sleep for 100ms - should succeed Thread.sleep(100l); store.set("test.key2", "test.value2"); assertEquals(limiter.getCounter(), 1); // test a memcached rate limiter (2 per sec.) limiter = new MemcachedRateLimiter(mcc); limiter.setLimit(TimeUnit.SECONDS, 1, 2); store.setWriteRateLimiter(limiter); store.set("test.key", "test.value"); store.set("test.key", "test.value.2"); try { store.set("test.key2", "test.value3"); fail("Rate limit exceeded. Should have failed!"); } catch (KeyValueStoreUnavailable e) { assertEquals(limiter.getCounter(), 2); } // sleep for 1000ms - should succeed Thread.sleep(1000l); store.set("test.key2", "test.value2"); assertEquals(limiter.getCounter(), 1); } }