Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

GEODE-8647: Support multiple instances of DistributedMap #5667

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
Expand Up @@ -14,11 +14,13 @@
*/
package org.apache.geode.test.dunit.rules.tests;

import static java.util.Arrays.asList;
import static org.apache.geode.test.dunit.VM.getAllVMs;
import static org.apache.geode.test.dunit.VM.getController;
import static org.apache.geode.test.dunit.VM.getVM;
import static org.apache.geode.test.dunit.VM.getVMId;
import static org.apache.geode.test.dunit.VM.toArray;
import static org.apache.geode.test.junit.runners.TestRunner.runTestWithValidation;
import static org.assertj.core.api.Assertions.assertThat;

import java.io.Serializable;
Expand All @@ -27,15 +29,17 @@
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
import java.util.concurrent.atomic.AtomicReference;

import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;

import org.apache.geode.test.dunit.VM;
import org.apache.geode.test.dunit.rules.DistributedMap;

@SuppressWarnings("serial")
public class DistributedMapDistributedTest implements Serializable {
public class DistributedMapTest implements Serializable {

@Rule
public DistributedMap<Object, Object> distributedMap = new DistributedMap<>();
Expand Down Expand Up @@ -491,4 +495,162 @@ public void getReturnsSameValueInEveryVmAsPutInOtherVm() {
});
}
}

@Test
public void accessesDistributedMapInEachVm() {
runTestWithValidation(HasDistributedMap.class);
}

@Test
public void tearsDownDistributedMapInEachVm() {
runTestWithValidation(HasDistributedMap.class);

getController().invoke(() -> {
assertThat(HasDistributedMap.map.get()).isEmpty();
});
}

@Test
public void accessesTwoDistributedMapsInEachVm() {
runTestWithValidation(HasTwoDistributedMaps.class);
}

@Test
public void tearsDownTwoDistributedMapsInEachVm() {
runTestWithValidation(HasTwoDistributedMaps.class);

getController().invoke(() -> {
assertThat(HasTwoDistributedMaps.map1.get()).isEmpty();
assertThat(HasTwoDistributedMaps.map2.get()).isEmpty();
});
}

@Test
public void accessesManyDistributedMapsInEachVm() {
runTestWithValidation(HasManyDistributedMaps.class);
}

@Test
public void tearsDownManyDistributedMapsInEachVm() {
runTestWithValidation(HasManyDistributedMaps.class);

getController().invoke(() -> {
assertThat(HasManyDistributedMaps.map1.get()).isEmpty();
assertThat(HasManyDistributedMaps.map2.get()).isEmpty();
assertThat(HasManyDistributedMaps.map3.get()).isEmpty();
});
}

public static class HasDistributedMap implements Serializable {

private static final AtomicReference<Map<Object, Object>> map = new AtomicReference<>();

@Rule
public DistributedMap<Object, Object> distributedMap = new DistributedMap<>();

@Before
public void setUp() {
getController().invoke(() -> {
map.set(distributedMap.map());
distributedMap.put("key1", "value1");
});
}

@Test
public void distributedMapIsAccessibleInEveryVm() {
for (VM vm : asList(getVM(0), getVM(1), getVM(2), getVM(3), getController())) {
vm.invoke(() -> {
assertThat(distributedMap.map()).isSameAs(map.get());
assertThat(distributedMap.get("key1")).isEqualTo("value1");
});
}
}
}

public static class HasTwoDistributedMaps implements Serializable {

private static final AtomicReference<Map<Object, Object>> map1 = new AtomicReference<>();
private static final AtomicReference<Map<Object, Object>> map2 = new AtomicReference<>();

@Rule
public DistributedMap<Object, Object> distributedMap1 = new DistributedMap<>();
@Rule
public DistributedMap<Object, Object> distributedMap2 = new DistributedMap<>();

@Before
public void setUp() {
getController().invoke(() -> {
map1.set(distributedMap1.map());
distributedMap1.put("key1", "value1");

map2.set(distributedMap2.map());
distributedMap2.put("key2", "value2");
});
}

@Test
public void twoDistributedMapsAreAccessibleInEveryVm() {
for (VM vm : asList(getVM(0), getVM(1), getVM(2), getVM(3), getController())) {
vm.invoke(() -> {
assertThat(distributedMap1.map()).isSameAs(map1.get());
assertThat(distributedMap1.get("key1")).isEqualTo("value1");
assertThat(distributedMap1.get("key2")).isNull();

assertThat(distributedMap2.map()).isSameAs(map2.get());
assertThat(distributedMap2.get("key1")).isNull();
assertThat(distributedMap2.get("key2")).isEqualTo("value2");
});
}
}
}

public static class HasManyDistributedMaps implements Serializable {

private static final AtomicReference<Map<Object, Object>> map1 = new AtomicReference<>();
private static final AtomicReference<Map<Object, Object>> map2 = new AtomicReference<>();
private static final AtomicReference<Map<Object, Object>> map3 = new AtomicReference<>();

@Rule
public DistributedMap<Object, Object> distributedMap1 = new DistributedMap<>();
@Rule
public DistributedMap<Object, Object> distributedMap2 = new DistributedMap<>();
@Rule
public DistributedMap<Object, Object> distributedMap3 = new DistributedMap<>();

@Before
public void setUp() {
getController().invoke(() -> {
map1.set(distributedMap1.map());
distributedMap1.put("key1", "value1");

map2.set(distributedMap2.map());
distributedMap2.put("key2", "value2");

map3.set(distributedMap3.map());
distributedMap3.put("key3", "value3");
Comment on lines +624 to +630
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Might it be worth extracting the hardcoded string keys/values in this test class to constants?

});
}

@Test
public void manyDistributedMapsAreAccessibleInEveryVm() {
for (VM vm : asList(getVM(0), getVM(1), getVM(2), getVM(3), getController())) {
vm.invoke(() -> {
assertThat(distributedMap1.map()).isSameAs(map1.get());
assertThat(distributedMap1.get("key1")).isEqualTo("value1");
assertThat(distributedMap1.get("key2")).isNull();
assertThat(distributedMap1.get("key3")).isNull();

assertThat(distributedMap2.map()).isSameAs(map2.get());
assertThat(distributedMap2.get("key1")).isNull();
assertThat(distributedMap2.get("key2")).isEqualTo("value2");
assertThat(distributedMap2.get("key3")).isNull();

assertThat(distributedMap3.map()).isSameAs(map3.get());
assertThat(distributedMap3.get("key1")).isNull();
assertThat(distributedMap3.get("key2")).isNull();
assertThat(distributedMap3.get("key3")).isEqualTo("value3");
});
}
}
}
}
Expand Up @@ -14,6 +14,7 @@
*/
package org.apache.geode.test.dunit.rules;

import static java.lang.System.identityHashCode;
import static org.apache.geode.test.dunit.VM.DEFAULT_VM_COUNT;
import static org.apache.geode.test.dunit.VM.getController;
import static org.apache.geode.util.internal.UncheckedUtils.uncheckedCast;
Expand Down Expand Up @@ -54,9 +55,12 @@
@SuppressWarnings("serial,unused")
public class DistributedMap<K, V> extends AbstractDistributedRule implements Map<K, V> {

private static final AtomicReference<Map<?, ?>> MAP = new AtomicReference<>();
private static final AtomicReference<Map<Integer, Map<?, ?>>> MAPS =
new AtomicReference<>(new HashMap<>());

private final AtomicReference<VM> controller = new AtomicReference<>();
private final Map<K, V> initialEntries = new HashMap<>();
private final int identity;

public static Builder builder() {
return new Builder();
Expand All @@ -77,14 +81,24 @@ private DistributedMap(Builder<K, V> builder) {
private DistributedMap(int vmCount, Map<K, V> initialEntries) {
super(vmCount);
this.initialEntries.putAll(initialEntries);
identity = identityHashCode(this);
}

@Override
protected void before() {
MAP.set(new HashMap<K, V>());
controller.set(getController());

MAPS.get().put(identity, new HashMap<K, V>());
map().clear();
map().putAll(initialEntries);
controller.set(getController());
}

@Override
protected void after() {
for (Map<?, ?> map : MAPS.get().values()) {
map.clear();
}
MAPS.get().clear();
}

@Override
Expand Down Expand Up @@ -148,8 +162,8 @@ public Set<Entry<K, V>> entrySet() {
}

@Override
public boolean equals(Object o) {
return controller().invoke(() -> map().equals(o));
public boolean equals(Object obj) {
return controller().invoke(() -> map().equals(obj));
}

@Override
Expand All @@ -162,8 +176,8 @@ public String toString() {
return controller().invoke(() -> map().toString());
}

private Map<K, V> map() {
return uncheckedCast(MAP.get());
public Map<K, V> map() {
return uncheckedCast(MAPS.get().get(identity));
}

private VM controller() {
Expand Down