/* * 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; import net.openhft.chronicle.core.Jvm; import net.openhft.chronicle.core.OS; import net.openhft.chronicle.core.onoes.ExceptionKey; import net.openhft.chronicle.core.pool.ClassAliasPool; import net.openhft.chronicle.core.threads.ThreadDump; import net.openhft.chronicle.engine.api.EngineReplication; import net.openhft.chronicle.engine.api.map.KeyValueStore; import net.openhft.chronicle.engine.api.map.MapView; import net.openhft.chronicle.engine.api.tree.AssetTree; import net.openhft.chronicle.engine.fs.ChronicleMapGroupFS; import net.openhft.chronicle.engine.fs.FilePerKeyGroupFS; import net.openhft.chronicle.engine.map.CMap2EngineReplicator; import net.openhft.chronicle.engine.map.ChronicleMapKeyValueStore; import net.openhft.chronicle.engine.map.VanillaMapView; import net.openhft.chronicle.engine.server.ServerEndpoint; import net.openhft.chronicle.engine.tree.VanillaAssetTree; import net.openhft.chronicle.network.TCPRegistry; import net.openhft.chronicle.network.connection.TcpChannelHub; import net.openhft.chronicle.wire.WireType; import net.openhft.chronicle.wire.YamlLogging; import org.jetbrains.annotations.NotNull; import org.junit.*; import java.io.File; import java.io.IOException; import java.nio.file.Files; import java.nio.file.Paths; import java.util.Map; import java.util.concurrent.ConcurrentMap; import static org.junit.Assert.assertNotNull; /** * Created by Rob Austin */ @Ignore public class Replication10WayTest { public static final WireType WIRE_TYPE = WireType.TEXT; public static final String NAME = "/ChMaps/test"; public static final int NUMBER_OF_SIMULATED_SERVERS = 10; @NotNull public static ServerEndpoint[] serverEndpoint = new ServerEndpoint[NUMBER_OF_SIMULATED_SERVERS]; @NotNull private static AssetTree[] tree = new AssetTree[NUMBER_OF_SIMULATED_SERVERS]; private static Map<ExceptionKey, Integer> exceptions; private ThreadDump threadDump; @BeforeClass public static void before() throws IOException { exceptions = Jvm.recordExceptions(); YamlLogging.setAll(false); //YamlLogging.showServerWrites = true; ClassAliasPool.CLASS_ALIASES.addAlias(ChronicleMapGroupFS.class); ClassAliasPool.CLASS_ALIASES.addAlias(FilePerKeyGroupFS.class); //Delete any files from the last run Files.deleteIfExists(Paths.get(OS.TARGET, NAME)); for (int i = 0; i < NUMBER_OF_SIMULATED_SERVERS; i++) { TCPRegistry.createServerSocketChannelFor("host.port" + (i + 1)); } @NotNull WireType writeType = WireType.TEXT; for (int i = 0; i < NUMBER_OF_SIMULATED_SERVERS; i++) { tree[i] = create(i + 1, writeType, "clusterTen"); serverEndpoint[i] = new ServerEndpoint("host.port" + (i + 1), tree[i]); } } @AfterClass public static void after() { for (int i = 0; i < NUMBER_OF_SIMULATED_SERVERS; i++) { serverEndpoint[i].close(); } for (int i = 0; i < NUMBER_OF_SIMULATED_SERVERS; i++) { tree[i].close(); } TcpChannelHub.closeAllHubs(); TCPRegistry.reset(); if (!exceptions.isEmpty()) { Jvm.dumpException(exceptions); Jvm.resetExceptionHandlers(); Assert.fail(); } } @NotNull private static AssetTree create(final int hostId, WireType writeType, final String clusterTwo) { @NotNull AssetTree tree = new VanillaAssetTree((byte) hostId) .forTesting() .withConfig(resourcesDir() + "/10Way", OS.TARGET + "/" + hostId); tree.root().addWrappingRule(MapView.class, "map directly to KeyValueStore", VanillaMapView::new, KeyValueStore.class); tree.root().addLeafRule(EngineReplication.class, "Engine replication holder", CMap2EngineReplicator::new); tree.root().addLeafRule(KeyValueStore.class, "KVS is Chronicle Map", (context, asset) -> new ChronicleMapKeyValueStore(context.wireType(writeType).cluster(clusterTwo), asset)); // VanillaAssetTreeEgMain.registerTextViewofTree("host " + hostId, tree); return tree; } @NotNull public static String resourcesDir() { String path = ChronicleMapKeyValueStoreTest.class.getProtectionDomain().getCodeSource().getLocation().getPath(); if (path == null) return "."; return new File(path).getParentFile().getParentFile() + "/src/test/resources"; } @Before public void threadDump() { threadDump = new ThreadDump(); } @After public void checkThreadDump() { threadDump.assertNoNewThreads(); } @Ignore("because it uses too much resources on a PC") @Test public void testTenWay() throws InterruptedException { @NotNull ConcurrentMap<String, String>[] maps = new ConcurrentMap[NUMBER_OF_SIMULATED_SERVERS]; for (int i = 0; i < NUMBER_OF_SIMULATED_SERVERS; i++) { maps[i] = tree[i].acquireMap(NAME, String.class, String.class); assertNotNull(maps[i]); maps[i].put("hello" + (i + 1), "world" + (i + 1)); } OUTER: for (int i = 0; i < 100; i++) { for (int j = 0; j < NUMBER_OF_SIMULATED_SERVERS; j++) { final int size = maps[j].size(); if (size != NUMBER_OF_SIMULATED_SERVERS) { Jvm.pause(300); continue OUTER; } } System.out.println("got all ten"); } for (int i = 0; i < NUMBER_OF_SIMULATED_SERVERS; i++) { for (int j = 0; j < NUMBER_OF_SIMULATED_SERVERS; j++) { Assert.assertEquals("world" + (j + 1), maps[i].get("hello" + (j + 1))); } } } }