/* * Copyright 2015 OrientDB LTD (info--at--orientdb.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 com.orientechnologies.orient.server.distributed.scenariotest; import com.orientechnologies.common.util.OCallable; import com.orientechnologies.orient.core.db.ODatabaseRecordThreadLocal; import com.orientechnologies.orient.core.db.document.ODatabaseDocumentTx; import com.orientechnologies.orient.core.record.impl.ODocument; import com.orientechnologies.orient.core.sql.query.OSQLSynchQuery; import com.orientechnologies.orient.server.distributed.OModifiableDistributedConfiguration; import com.orientechnologies.orient.server.distributed.ServerRun; import com.orientechnologies.orient.server.hazelcast.OHazelcastPlugin; import org.junit.Test; import java.util.ArrayList; import java.util.List; import static org.junit.Assert.fail; /** * It checks the consistency in the cluster with the following scenario: * - 3 server (quorum=1) * - server3 is isolated (simulated by shutdown) * - 5 threads on both server1 and server2 write 100 records * - server3 joins the cluster * - server3 receive the delta from the cluster * - check consistency * * @author Gabriele Ponzi * @email <gabriele.ponzi--at--gmail.com> */ public class Quorum1ScenarioTest extends AbstractScenarioTest { @Test public void test() throws Exception { useTransactions = true; maxRetries = 10; init(SERVERS); prepare(false); // execute writes only on server1 and server2 executeTestsOnServers = new ArrayList<ServerRun>(); executeTestsOnServers.add(serverInstance.get(0)); executeTestsOnServers.add(serverInstance.get(1)); execute(); } @Override public void executeTest() throws Exception { /* * Test with quorum = 1 */ banner("Test with quorum = 1"); System.out.print("\nChanging configuration (writeQuorum=1, autoDeploy=false)..."); ODocument cfg = null; ServerRun server = serverInstance.get(0); OHazelcastPlugin manager = (OHazelcastPlugin) server.getServerInstance().getDistributedManager(); OModifiableDistributedConfiguration databaseConfiguration = manager.getDatabaseConfiguration(getDatabaseName()).modify(); cfg = databaseConfiguration.getDocument(); cfg.field("writeQuorum", 1); cfg.field("autoDeploy", true); cfg.field("version", (Integer) cfg.field("version") + 1); manager.updateCachedDatabaseConfiguration(getDatabaseName(), databaseConfiguration, true); System.out.println("\nConfiguration updated."); // execute writes on server1 and server2 executeMultipleWrites(super.executeTestsOnServers, "plocal"); // waiting for propagation waitForMultipleInsertsInClassPropagation(executeTestsOnServers.size() * writerCount * count, "Person", 5000L); // check consistency super.checkWritesAboveCluster(serverInstance, executeTestsOnServers); } @Override protected void onBeforeChecks() throws InterruptedException { // // WAIT UNTIL THE END final long e = count * writerCount * executeTestsOnServers.size(); waitFor(0, new OCallable<Boolean, ODatabaseDocumentTx>() { @Override public Boolean call(ODatabaseDocumentTx db) { final boolean ok = db.countClass("Person") >= e; if (!ok) System.out.println("FOUND " + db.countClass("Person") + " people on server 0 instead of expected " + e); return ok; } }, 10000); waitFor(1, new OCallable<Boolean, ODatabaseDocumentTx>() { @Override public Boolean call(ODatabaseDocumentTx db) { final boolean ok = db.countClass("Person") >= e; if (!ok) System.out.println("FOUND " + db.countClass("Person") + " people on server 1 instead of expected " + e); return ok; } }, 10000); Thread.sleep(2000); } @Override protected ODocument retrieveRecord(String dbUrl, String uniqueId) { ODatabaseDocumentTx dbServer = poolFactory.get(dbUrl, "admin", "admin").acquire(); ODatabaseRecordThreadLocal.INSTANCE.set(dbServer); List<ODocument> result = dbServer.query(new OSQLSynchQuery<ODocument>("select from Hero where id = '" + uniqueId + "'")); if (result.size() == 0) fail("No record found with id = '" + uniqueId + "'!"); else if (result.size() > 1) fail(result.size() + " records found with id = '" + uniqueId + "'!"); ODatabaseRecordThreadLocal.INSTANCE.set(null); return result.get(0); } @Override public String getDatabaseName() { return "distributed-quorum1scenario"; } }