/// <summary> /// Main difference to <seealso cref="shouldCopyStoreFromMasterIfBranched()"/> is that no instances are shut down /// during the course of the test. This to test functionality of some internal components being restarted. /// </summary> //JAVA TO C# CONVERTER TODO TASK: Most Java annotations will not have direct .NET equivalent attributes: //ORIGINAL LINE: @SuppressWarnings("unchecked") @Test public void shouldCopyStoreFromMasterIfBranchedInLiveScenario() throws Throwable //JAVA TO C# CONVERTER WARNING: Method 'throws' clauses are not available in C#: public virtual void ShouldCopyStoreFromMasterIfBranchedInLiveScenario() { // GIVEN a cluster of 3, all having the same data (node A) // thor is whoever is the master to begin with // odin is whoever is picked as _the_ slave given thor as initial master File storeDirectory = _directory.directory(); ClusterManager clusterManager = _life.add(new ClusterManager.Builder(storeDirectory) .withSharedConfig(stringMap(HaSettings.tx_push_factor.name(), "0", HaSettings.pull_interval.name(), "0")).build()); ClusterManager.ManagedCluster cluster = clusterManager.Cluster; cluster.Await(allSeesAllAsAvailable()); HighlyAvailableGraphDatabase thor = cluster.Master; string indexName = "valhalla"; CreateNode(thor, "A", AndIndexInto(indexName)); cluster.Sync(); // WHEN creating a node B1 on thor (note the disabled cluster transaction propagation) CreateNode(thor, "B1", AndIndexInto(indexName)); // and right after that failing the master so that it falls out of the cluster HighlyAvailableGraphDatabase odin = cluster.AnySlave; cluster.Info(format("%n ==== TAMPERING WITH " + thor + "'s CABLES ====%n")); ClusterManager.RepairKit thorRepairKit = cluster.Fail(thor); // try to create a transaction on odin until it succeeds cluster.Await(ClusterManager.masterAvailable(thor)); cluster.Await(ClusterManager.memberThinksItIsRole(odin, HighAvailabilityModeSwitcher.MASTER)); assertTrue(odin.Master); RetryOnTransactionFailure(odin, db => createNode(db, "B2", AndIndexInto(indexName))); // perform transactions so that index files changes under the hood ISet <File> odinLuceneFilesBefore = Iterables.asSet(GatherLuceneFiles(odin, indexName)); for (char prefix = 'C'; !Changed(odinLuceneFilesBefore, Iterables.asSet(GatherLuceneFiles(odin, indexName))); prefix++) { char fixedPrefix = prefix; RetryOnTransactionFailure(odin, db => createNodes(odin, fixedPrefix.ToString(), 10_000, AndIndexInto(indexName))); cluster.Force(); // Force will most likely cause lucene explicit indexes to commit and change file structure } // so anyways, when thor comes back into the cluster cluster.Info(format("%n ==== REPAIRING CABLES ====%n")); cluster.Await(memberThinksItIsRole(thor, UNKNOWN)); BranchMonitor thorHasBranched = InstallBranchedDataMonitor(cluster.GetMonitorsByDatabase(thor)); thorRepairKit.Repair(); cluster.Await(memberThinksItIsRole(thor, SLAVE)); cluster.Await(memberThinksItIsRole(odin, MASTER)); cluster.Await(allSeesAllAsAvailable()); assertFalse(thor.Master); assertTrue("No store-copy performed", thorHasBranched.CopyCompleted); assertTrue("Store-copy unsuccessful", thorHasBranched.CopySuccessful); // Now do some more transactions on current master (odin) and have thor pull those for (int i = 0; i < 3; i++) { int ii = i; RetryOnTransactionFailure(odin, db => createNodes(odin, ("" + ii).ToString(), 10, AndIndexInto(indexName))); cluster.Sync(); cluster.Force(); } // THEN thor should be a slave, having copied a store from master and good to go assertFalse(HasNode(thor, "B1")); assertTrue(HasNode(thor, "B2")); assertTrue(HasNode(thor, "C-0")); assertTrue(HasNode(thor, "0-0")); assertTrue(HasNode(odin, "0-0")); }