@Test public void testAllUpdatesReflectedToMapStore() throws Exception { int nodeCount = 3; final MapStoreWithCounter mapStore = new MapStoreWithCounter<Integer, String>(); TestMapUsingMapStoreBuilder builder = TestMapUsingMapStoreBuilder.create() .withMapStore(mapStore) .withNodeCount(nodeCount) .withNodeFactory(createHazelcastInstanceFactory(nodeCount)) .withBackupCount(0) .withWriteCoalescing(false) .withWriteDelaySeconds(3); IMap<Object, Object> map = builder.build(); for (int i = 0; i < 500; i++) { map.put(i, randomString()); } for (int i = 0; i < 500; i++) { map.remove(i); } assertTrueEventually( new AssertTask() { @Override public void run() throws Exception { final int storeCount = mapStore.countStore.get(); final int deleteCount = mapStore.countDelete.get(); assertEquals(1000, storeCount + deleteCount); assertTrue(mapStore.store.isEmpty()); } }); }
@Test @Category(SlowTest.class) public void testPutTransientDoesNotStoreEntry_onPromotedReplica() { String mapName = randomMapName(); final MapStoreWithCounter mapStore = new MapStoreWithCounter<Integer, String>(); TestMapUsingMapStoreBuilder<String, Object> storeBuilder = TestMapUsingMapStoreBuilder.create(); TestHazelcastInstanceFactory factory = createHazelcastInstanceFactory(2); final IMap<String, Object> map = storeBuilder .mapName(mapName) .withMapStore(mapStore) .withNodeCount(2) .withNodeFactory(factory) .withWriteDelaySeconds(5) .withBackupCount(1) .withPartitionCount(1) .withBackupProcessingDelay(1) .build(); String key = UUID.randomUUID().toString(); map.putTransient(key, 1, 1, TimeUnit.DAYS); killKeyOwner(key, storeBuilder); sleepSeconds(10); assertEquals( "There should not be any store operation on promoted replica", 0, mapStore.countStore.get()); }
@Test(expected = ReachedMaxSizeException.class) public void testCounter_whenMaxCapacityExceeded() throws Exception { final int maxCapacityPerNode = 100; final int nodeCount = 1; final MapStoreWithCounter mapStore = new MapStoreWithCounter<Integer, String>(); final TestMapUsingMapStoreBuilder builder = TestMapUsingMapStoreBuilder.create() .withMapStore(mapStore) .withNodeCount(nodeCount) .withNodeFactory(createHazelcastInstanceFactory(1)) .withBackupCount(0) .withWriteCoalescing(false) .withWriteBehindQueueCapacity(maxCapacityPerNode) .withWriteDelaySeconds(100); final IMap<Object, Object> map = builder.build(); // exceed max write-behind queue capacity per node. populateMap(map, 2 * maxCapacityPerNode); }
@Test public void testCounter_against_one_node_zero_backup() throws Exception { final int maxCapacityPerNode = 100; final MapStoreWithCounter mapStore = new MapStoreWithCounter<Integer, String>(); final TestMapUsingMapStoreBuilder builder = TestMapUsingMapStoreBuilder.create() .withMapStore(mapStore) .withNodeCount(1) .withNodeFactory(createHazelcastInstanceFactory(1)) .withBackupCount(0) .withWriteDelaySeconds(100) .withWriteCoalescing(false) .withWriteBehindQueueCapacity(maxCapacityPerNode); final IMap<Object, Object> map = builder.build(); populateMap(map, maxCapacityPerNode); assertEquals(maxCapacityPerNode, map.size()); }
@Test public void testCounter_against_many_nodes() throws Exception { final int maxCapacityPerNode = 100; final int nodeCount = 2; final MapStoreWithCounter mapStore = new MapStoreWithCounter<Integer, String>(); final TestMapUsingMapStoreBuilder builder = TestMapUsingMapStoreBuilder.create() .withMapStore(mapStore) .withNodeCount(nodeCount) .withNodeFactory(createHazelcastInstanceFactory(nodeCount)) .withBackupCount(0) .withWriteCoalescing(false) .withWriteBehindQueueCapacity(maxCapacityPerNode) .withWriteDelaySeconds(100); final IMap<Object, Object> map = builder.build(); // put slightly more number of entries which is higher than max write-behind queue capacity per // node. populateMap(map, maxCapacityPerNode + 3); assertTrue(map.size() > maxCapacityPerNode); }
@Test public void testPutTransientDoesNotStoreEntry_onBackupPartition() { String mapName = randomMapName(); final MapStoreWithCounter mapStore = new MapStoreWithCounter<Integer, String>(); TestMapUsingMapStoreBuilder<Object, Object> storeBuilder = TestMapUsingMapStoreBuilder.create(); final IMap<Object, Object> map = storeBuilder .mapName(mapName) .withMapStore(mapStore) .withNodeCount(2) .withNodeFactory(createHazelcastInstanceFactory(2)) .withWriteDelaySeconds(1) .withBackupCount(1) .withPartitionCount(1) .withBackupProcessingDelay(1) .build(); map.putTransient(1, 1, 1, TimeUnit.DAYS); sleepSeconds(5); assertEquals("There should not be any store operation", 0, mapStore.countStore.get()); }
/** * {@link com.hazelcast.map.impl.mapstore.writebehind.StoreWorker} delays processing of * write-behind queues (wbq) by adding delay with {@link * com.hazelcast.instance.GroupProperty#MAP_REPLICA_SCHEDULED_TASK_DELAY_SECONDS} property. This * is used to provide some extra robustness against node disaster scenarios by trying to prevent * lost of entries in wbq-s. Normally backup nodes don't store entries only remove them from * wbq-s. Here, we are testing removal of entries occurred or not. */ @Test public void testBackupRemovesEntries_afterProcessingDelay() throws Exception { final int numberOfItems = 10; final String mapName = randomMapName(); final MapStoreWithCounter mapStore = new MapStoreWithCounter<Integer, String>(); TestMapUsingMapStoreBuilder<Object, Object> storeBuilder = TestMapUsingMapStoreBuilder.create(); final IMap<Object, Object> map = storeBuilder .mapName(mapName) .withMapStore(mapStore) .withNodeCount(2) .withNodeFactory(createHazelcastInstanceFactory(2)) .withWriteDelaySeconds(1) .withBackupCount(1) .withPartitionCount(1) .withBackupProcessingDelay(1) .build(); populateMap(map, numberOfItems); assertWriteBehindQueuesEmptyOnOwnerAndOnBackups( mapName, numberOfItems, mapStore, storeBuilder.getNodes()); }
private void killKeyOwner(String key, TestMapUsingMapStoreBuilder<String, Object> storeBuilder) { HazelcastInstance[] nodes = storeBuilder.getNodes(); HazelcastInstance ownerNode = getOwnerNode(key, nodes); ownerNode.shutdown(); }