mirror of
https://github.com/OpenHFT/Chronicle-Map.git
synced 2021-09-13 01:26:12 +00:00
345 lines
12 KiB
Java
345 lines
12 KiB
Java
/*
|
|
* Copyright 2014 Higher Frequency Trading
|
|
*
|
|
* http://www.higherfrequencytrading.com
|
|
*
|
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
* you may not use this file except in compliance with the License.
|
|
* You may obtain a copy of the License at
|
|
*
|
|
* http://www.apache.org/licenses/LICENSE-2.0
|
|
*
|
|
* Unless required by applicable law or agreed to in writing, software
|
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
* See the License for the specific language governing permissions and
|
|
* limitations under the License.
|
|
*/
|
|
|
|
package net.openhft.chronicle.map;
|
|
|
|
import net.openhft.chronicle.hash.replication.TimeProvider;
|
|
import net.openhft.chronicle.map.jrs166.JSR166TestCase;
|
|
import org.junit.Test;
|
|
import org.mockito.Mockito;
|
|
|
|
import java.io.File;
|
|
import java.io.IOException;
|
|
import java.util.concurrent.TimeUnit;
|
|
|
|
import static org.junit.Assert.*;
|
|
|
|
/**
|
|
* @author Rob Austin.
|
|
*/
|
|
public class TimeBasedReplicationTest extends JSR166TestCase {
|
|
|
|
|
|
public static final byte IDENTIFIER = 1;
|
|
|
|
private static File getPersistenceFile() {
|
|
String TMP = System.getProperty("java.io.tmpdir");
|
|
File file = new File(TMP + "/chm-test" + System.nanoTime());
|
|
file.deleteOnExit();
|
|
return file;
|
|
}
|
|
|
|
|
|
@Test
|
|
public void testIgnoreALatePut() throws IOException {
|
|
|
|
final TimeProvider timeProvider = Mockito.mock(TimeProvider.class);
|
|
ChronicleMap map = ChronicleMapBuilder.of(CharSequence.class, CharSequence.class)
|
|
.entries(10)
|
|
.timeProvider(timeProvider)
|
|
.createReplicated((byte) 1);
|
|
|
|
current(timeProvider);
|
|
|
|
// we do a put at the current time
|
|
map.put("key-1", "value-1");
|
|
assertEquals(map.size(), 1);
|
|
assertEquals(map.get("key-1"), "value-1");
|
|
|
|
// now test assume that we receive a late update to the map, the following update should be ignored
|
|
late(timeProvider);
|
|
|
|
|
|
map.put("key-1", "value-2");
|
|
|
|
// we'll now flip the time back to the current in order to do the read the result
|
|
current(timeProvider);
|
|
assertEquals(map.size(), 1);
|
|
assertEquals(map.get("key-1"), "value-1");
|
|
|
|
}
|
|
|
|
@Test
|
|
public void testIgnoreALatePutIfAbsent() throws IOException {
|
|
|
|
final TimeProvider timeProvider = Mockito.mock(TimeProvider.class);
|
|
ChronicleMap map = ChronicleMapBuilder.of(CharSequence.class, CharSequence.class)
|
|
.entries(10)
|
|
.timeProvider(timeProvider)
|
|
.createReplicated((byte) 1);
|
|
|
|
current(timeProvider);
|
|
|
|
// we do a put at the current time
|
|
map.put("key-1", "value-1");
|
|
assertEquals(map.size(), 1);
|
|
assertEquals(map.get("key-1"), "value-1");
|
|
|
|
// now test assume that we receive a late update to the map, the following update should be ignored
|
|
late(timeProvider);
|
|
|
|
|
|
final Object o = map.putIfAbsent("key-1", "value-2");
|
|
assertEquals(o, null);
|
|
|
|
// we'll now flip the time back to the current in order to do the read the result
|
|
current(timeProvider);
|
|
assertEquals(1, map.size());
|
|
assertEquals(map.get("key-1"), "value-1");
|
|
|
|
}
|
|
|
|
@Test
|
|
public void testIgnoreALateReplace() throws IOException {
|
|
|
|
final TimeProvider timeProvider = Mockito.mock(TimeProvider.class);
|
|
ChronicleMap map = ChronicleMapBuilder.of(CharSequence.class, CharSequence.class)
|
|
.entries(10)
|
|
.timeProvider(timeProvider)
|
|
.createReplicated((byte) 1);
|
|
|
|
current(timeProvider);
|
|
|
|
|
|
// we do a put at the current time
|
|
map.put("key-1", "value-1");
|
|
assertEquals(1, map.size());
|
|
assertEquals("value-1", map.get("key-1"));
|
|
|
|
|
|
// now test assume that we receive a late update to the map,
|
|
// the following update should be ignored
|
|
late(timeProvider);
|
|
|
|
|
|
final Object o = map.replace("key-1", "value-2");
|
|
assertEquals(o, null);
|
|
|
|
// we'll now flip the time back to the current in order to do the read the result
|
|
current(timeProvider);
|
|
assertEquals(map.size(), 1);
|
|
assertEquals("value-1", map.get("key-1"));
|
|
|
|
}
|
|
|
|
@Test
|
|
public void testIgnoreALateReplaceWithValue() throws IOException {
|
|
|
|
final TimeProvider timeProvider = Mockito.mock(TimeProvider.class);
|
|
ChronicleMap map = ChronicleMapBuilder.of(CharSequence.class, CharSequence.class)
|
|
.entries(10)
|
|
.timeProvider(timeProvider)
|
|
.createReplicated((byte) 1);
|
|
|
|
current(timeProvider);
|
|
|
|
// we do a put at the current time
|
|
map.put("key-1", "value-1");
|
|
assertEquals(1, map.size());
|
|
assertEquals("value-1", map.get("key-1"));
|
|
|
|
// now test assume that we receive a late update to the map, the following update should be ignored
|
|
late(timeProvider);
|
|
|
|
|
|
assertEquals(null, map.replace("key-1", "value-2"));
|
|
|
|
|
|
// we'll now flip the time back to the current in order to do the read the result
|
|
current(timeProvider);
|
|
assertEquals(1, map.size());
|
|
assertEquals("value-1", map.get("key-1"));
|
|
|
|
}
|
|
|
|
@Test
|
|
public void testIgnoreALateRemoveWithValue() throws IOException {
|
|
|
|
final TimeProvider timeProvider = Mockito.mock(TimeProvider.class);
|
|
ChronicleMap map = ChronicleMapBuilder.of(CharSequence.class, CharSequence.class)
|
|
.entries(10)
|
|
.timeProvider(timeProvider)
|
|
.createReplicated((byte) 1);
|
|
|
|
current(timeProvider);
|
|
|
|
// we do a put at the current time
|
|
map.put("key-1", "value-1");
|
|
assertEquals(1, map.size());
|
|
assertEquals("value-1", map.get("key-1"));
|
|
|
|
// now test assume that we receive a late update to the map, the following update should be ignored
|
|
late(timeProvider);
|
|
|
|
|
|
assertEquals(false, map.remove("key-1", "value-1"));
|
|
|
|
// we'll now flip the time back to the current in order to do the read the result
|
|
current(timeProvider);
|
|
assertEquals(1, map.size());
|
|
assertEquals("value-1", map.get("key-1"));
|
|
|
|
}
|
|
|
|
@Test
|
|
public void testIgnoreALateRemove() throws IOException {
|
|
|
|
final TimeProvider timeProvider = Mockito.mock(TimeProvider.class);
|
|
ChronicleMap map = ChronicleMapBuilder.of(CharSequence.class, CharSequence.class)
|
|
.entries(10)
|
|
.timeProvider(timeProvider)
|
|
.createReplicated((byte) 1);
|
|
|
|
current(timeProvider);
|
|
|
|
// we do a put at the current time
|
|
map.put("key-1", "value-1");
|
|
assertEquals(1, map.size());
|
|
assertEquals("value-1", map.get("key-1"));
|
|
|
|
// now test assume that we receive a late update to the map, the following update should be ignored
|
|
late(timeProvider);
|
|
|
|
map.remove("key-1");
|
|
|
|
// we'll now flip the time back to the current in order to do the read the result
|
|
current(timeProvider);
|
|
assertEquals(1, map.size());
|
|
assertEquals("value-1", map.get("key-1"));
|
|
|
|
}
|
|
|
|
|
|
@Test
|
|
public void testIgnoreWithRemoteRemove() throws IOException {
|
|
|
|
final TimeProvider timeProvider = Mockito.mock(TimeProvider.class);
|
|
ReplicatedChronicleMap map = (ReplicatedChronicleMap) ChronicleMapBuilder.of(CharSequence.class, CharSequence.class)
|
|
.entries(10)
|
|
.timeProvider(timeProvider)
|
|
.createReplicated((byte) 1);
|
|
|
|
current(timeProvider);
|
|
|
|
// we do a put at the current time
|
|
map.put("key-1", "value-1");
|
|
assertEquals(1, map.size());
|
|
assertEquals("value-1", map.get("key-1"));
|
|
|
|
// now test assume that we receive a late update to the map, the following update should be ignored
|
|
final long late = System.currentTimeMillis() - TimeUnit.SECONDS.toMillis(5);
|
|
assertEquals(null, map.remove("key-1", "value-2", IDENTIFIER, late));
|
|
|
|
// we'll now flip the time back to the current in order to do the read the result
|
|
current(timeProvider);
|
|
assertEquals(1, map.size());
|
|
assertEquals("value-1", map.get("key-1"));
|
|
assertTrue(map.containsValue("value-1"));
|
|
assertFalse(map.containsValue("value-2"));
|
|
}
|
|
|
|
|
|
@Test
|
|
public void testIgnoreWithRemotePut() throws IOException {
|
|
|
|
|
|
final TimeProvider timeProvider = Mockito.mock(TimeProvider.class);
|
|
ReplicatedChronicleMap map = (ReplicatedChronicleMap) ChronicleMapBuilder.of(CharSequence.class, CharSequence.class)
|
|
.entries(10)
|
|
.timeProvider(timeProvider)
|
|
.createReplicated((byte) 1);
|
|
|
|
current(timeProvider);
|
|
|
|
// we do a put at the current time
|
|
map.put("key-1", "value-1");
|
|
assertEquals(1, map.size());
|
|
assertEquals("value-1", map.get("key-1"));
|
|
|
|
// now test assume that we receive a late update to the map, the following update should be ignored
|
|
// now test assume that we receive a late update to the map, the following update should be ignored
|
|
final long late = System.currentTimeMillis() - TimeUnit.SECONDS.toMillis(5);
|
|
assertEquals(null, map.put("key-1", "value-2", IDENTIFIER, late));
|
|
|
|
|
|
// we'll now flip the time back to the current in order to do the read the result
|
|
current(timeProvider);
|
|
|
|
assertEquals("value-1", map.get("key-1"));
|
|
assertEquals(1, map.size(), 0);
|
|
}
|
|
|
|
|
|
@Test
|
|
public void testRemoveFollowedByLatePut() throws IOException {
|
|
|
|
final TimeProvider timeProvider = Mockito.mock(TimeProvider.class);
|
|
ReplicatedChronicleMap map = (ReplicatedChronicleMap) ChronicleMapBuilder.of(CharSequence.class, CharSequence.class)
|
|
.entries(10)
|
|
.timeProvider(timeProvider)
|
|
.createReplicated((byte) 1);
|
|
|
|
current(timeProvider);
|
|
|
|
// we do a put at the current time
|
|
map.put("key-1", "value-1");
|
|
map.remove("key-1", "value-1");
|
|
assertEquals(0, map.size());
|
|
assertEquals(null, map.get("key-1"));
|
|
assertEquals(false, map.containsKey("key-1"));
|
|
|
|
// test assume that we receive a late update to the map, the following update should be ignored
|
|
final long late = System.currentTimeMillis() - TimeUnit.SECONDS.toMillis(50);
|
|
assertEquals(null, map.put("key-1", "value-2", IDENTIFIER, late));
|
|
|
|
assertEquals(null, map.get("key-1"));
|
|
assertEquals(false, map.containsKey("key-1"));
|
|
assertEquals(0, map.size(), 0);
|
|
}
|
|
|
|
|
|
@Test
|
|
public void testPutRemovePut() throws IOException {
|
|
|
|
final TimeProvider timeProvider = Mockito.mock(TimeProvider.class);
|
|
ChronicleMap map = ChronicleMapBuilder.of(CharSequence.class, CharSequence.class)
|
|
.entries(10)
|
|
.timeProvider(timeProvider)
|
|
.createReplicated((byte) 1);
|
|
|
|
current(timeProvider);
|
|
|
|
// we do a put at the current time
|
|
map.put("key-1", "value-1");
|
|
map.remove("key-1");
|
|
assertEquals(0, map.size());
|
|
assertEquals(null, map.put("key-1", "new-value-2"));
|
|
assertEquals(true, map.containsKey("key-1"));
|
|
assertEquals("new-value-2", map.get("key-1"));
|
|
assertEquals(1, map.size(), 0);
|
|
}
|
|
|
|
private void current(TimeProvider timeProvider) {
|
|
Mockito.when(timeProvider.currentTimeMillis()).thenReturn(System.currentTimeMillis());
|
|
}
|
|
|
|
private void late(TimeProvider timeProvider) {
|
|
Mockito.when(timeProvider.currentTimeMillis()).thenReturn(System.currentTimeMillis() - TimeUnit.SECONDS.toMillis(5));
|
|
}
|
|
}
|