/* * Copyright 2016 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.engine.map; import net.openhft.chronicle.core.Jvm; import net.openhft.chronicle.engine.ThreadMonitoringTest; import net.openhft.chronicle.engine.api.map.KeyValueStore; import net.openhft.chronicle.engine.api.map.MapEvent; import net.openhft.chronicle.engine.api.map.MapView; import net.openhft.chronicle.engine.api.tree.AssetTree; import net.openhft.chronicle.engine.server.ServerEndpoint; import net.openhft.chronicle.engine.tree.VanillaAssetTree; import net.openhft.chronicle.network.TCPRegistry; import net.openhft.chronicle.wire.WireType; import net.openhft.chronicle.wire.YamlLogging; import org.jetbrains.annotations.NotNull; import org.junit.Assert; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; import org.junit.runners.Parameterized; import java.io.IOException; import java.util.ArrayList; import java.util.Collection; import java.util.List; import java.util.concurrent.ArrayBlockingQueue; import java.util.concurrent.BlockingQueue; import static java.util.concurrent.TimeUnit.SECONDS; /** * @author Rob Austin. */ @RunWith(value = Parameterized.class) public class TestInsertUpdateChronicleMapView extends ThreadMonitoringTest { private final WireType wireType; @NotNull public String connection = "RemoteSubscriptionTest.host.port"; @NotNull private AssetTree clientAssetTree = new VanillaAssetTree().forTesting(); private VanillaAssetTree serverAssetTree; private ServerEndpoint serverEndpoint; public TestInsertUpdateChronicleMapView(WireType wireType) { this.wireType = wireType; } @NotNull @Parameterized.Parameters public static Collection<Object[]> data() { @NotNull final List<Object[]> list = new ArrayList<>(); list.add(new Object[]{WireType.BINARY}); // list.add(new Object[]{WireType.TEXT}); return list; } @Before public void before() throws IOException { serverAssetTree = new VanillaAssetTree().forTesting(); YamlLogging.setAll(false); connection = "TestInsertUpdateChronicleMapView.host.port"; TCPRegistry.createServerSocketChannelFor(connection); serverEndpoint = new ServerEndpoint(connection, serverAssetTree); serverAssetTree.root().addWrappingRule(MapView.class, "map directly to " + "KeyValueStore", VanillaMapView::new, KeyValueStore.class); serverAssetTree.root().addLeafRule(KeyValueStore.class, "use Chronicle Map", (context, asset) -> new ChronicleMapKeyValueStore(context.basePath(null).entries(100) .putReturnsNull(false), asset)); clientAssetTree = new VanillaAssetTree().forRemoteAccess(connection, wireType); } public void preAfter() { clientAssetTree.close(); Jvm.pause(100); if (serverEndpoint != null) serverEndpoint.close(); serverAssetTree.close(); } @Test public void testInsertFollowedByUpdate() throws InterruptedException { //Note you have to set the bootstrap to false in order for this test to work. //Otherwise it is possible that that you can get 2 insert events. @NotNull final MapView<String, String> serverMap = serverAssetTree.acquireMap ("name?putReturnsNull=false", String.class, String .class); @NotNull final BlockingQueue<MapEvent> events = new ArrayBlockingQueue<>(1); clientAssetTree.registerSubscriber("name?putReturnsNull=false&bootstrap=false", MapEvent.class, events::add); Jvm.pause(500); { serverMap.put("hello", "world"); final MapEvent event = events.poll(10, SECONDS); Assert.assertTrue(event instanceof InsertedEvent); } { serverMap.put("hello", "world2"); final MapEvent event = events.poll(10, SECONDS); Assert.assertTrue(event instanceof UpdatedEvent); } } @Test public void testInsertFollowedByUpdateWhenPutReturnsNullTrue() throws InterruptedException { @NotNull final MapView<String, String> serverMap = serverAssetTree.acquireMap ("name?putReturnsNull=true", String.class, String .class); @NotNull final BlockingQueue<MapEvent> events = new ArrayBlockingQueue<>(1); clientAssetTree.registerSubscriber("name?putReturnsNull=true", MapEvent.class, events::add); Jvm.pause(500); { serverMap.put("hello", "world"); final MapEvent event = events.poll(10, SECONDS); Assert.assertTrue(event instanceof InsertedEvent); } { serverMap.put("hello", "world2"); final MapEvent event = events.poll(10, SECONDS); Assert.assertTrue(event instanceof UpdatedEvent); } } }