private void RunReplication(ReplicatorConfiguration config, int expectedErrCode, C4ErrorDomain expectedErrDomain) { Misc.SafeSwap(ref _repl, new Replicator(config)); _waitAssert = new WaitAssert(); var token = _repl.AddChangeListener((sender, args) => { _waitAssert.RunConditionalAssert(() => { VerifyChange(args, expectedErrCode, expectedErrDomain); if (config.Continuous && args.Status.Activity == ReplicatorActivityLevel.Idle && args.Status.Progress.Completed == args.Status.Progress.Total) { ((Replicator)sender).Stop(); } return(args.Status.Activity == ReplicatorActivityLevel.Stopped); }); }); _repl.Start(); try { _waitAssert.WaitForResult(TimeSpan.FromSeconds(10)); } catch { _repl.Stop(); throw; } finally { _repl.RemoveChangeListener(token); } }
private void WithActiveReplicatorAndURLEndpointListeners(bool isCloseNotDelete) { WaitAssert waitIdleAssert1 = new WaitAssert(); WaitAssert waitStoppedAssert1 = new WaitAssert(); _listener = CreateListener(); var _listener2 = CreateNewListener(); _listener.Config.Database.ActiveStoppables.Count.Should().Be(2); _listener2.Config.Database.ActiveStoppables.Count.Should().Be(2); using (var doc1 = new MutableDocument("doc1")) using (var doc2 = new MutableDocument("doc2")) { doc1.SetString("name", "Sam"); Db.Save(doc1); doc2.SetString("name", "Mary"); OtherDb.Save(doc2); } var target = new DatabaseEndpoint(Db); var config1 = CreateConfig(target, ReplicatorType.PushAndPull, true, sourceDb: OtherDb); var repl1 = new Replicator(config1); repl1.AddChangeListener((sender, args) => { waitIdleAssert1.RunConditionalAssert(() => { return(args.Status.Activity == ReplicatorActivityLevel.Idle); }); waitStoppedAssert1.RunConditionalAssert(() => { return(args.Status.Activity == ReplicatorActivityLevel.Stopped); }); }); repl1.Start(); waitIdleAssert1.WaitForResult(TimeSpan.FromSeconds(10)); OtherDb.ActiveStoppables.Count.Should().Be(3); if (isCloseNotDelete) { OtherDb.Close(); } else { OtherDb.Delete(); } OtherDb.ActiveStoppables.Count.Should().Be(0); OtherDb.IsClosedLocked.Should().Be(true); waitStoppedAssert1.WaitForResult(TimeSpan.FromSeconds(30)); }
public void TestStopContinuousReplicator() { var config = CreateConfig(true, false, true); using (var r = new Replicator(config)) { var stopWhen = new[] { ReplicatorActivityLevel.Connecting, ReplicatorActivityLevel.Busy, ReplicatorActivityLevel.Idle, ReplicatorActivityLevel.Idle }; foreach (var when in stopWhen) { var stopped = 0; var waitAssert = new WaitAssert(); var token = r.AddChangeListener((sender, args) => { waitAssert.RunConditionalAssert(() => { VerifyChange(args, 0, 0); // On Windows, at least, sometimes the connection is so fast that Connecting never gets called if ((args.Status.Activity == when || (when == ReplicatorActivityLevel.Connecting && args.Status.Activity > when)) && Interlocked.Exchange(ref stopped, 1) == 0) { WriteLine("***** Stop Replicator *****"); ((Replicator)sender).Stop(); } if (args.Status.Activity == ReplicatorActivityLevel.Stopped) { WriteLine("Stopped!"); } return(args.Status.Activity == ReplicatorActivityLevel.Stopped); }); }); WriteLine("***** Start Replicator *****"); r.Start(); try { waitAssert.WaitForResult(TimeSpan.FromSeconds(5)); } finally { r.RemoveChangeListener(token); } Task.Delay(100).Wait(); } } }
private void DocumentChanged(object sender, DocumentChangedEventArgs args) { if (_docCallbackShouldThrow) { _wa.RunAssert(() => throw new InvalidOperationException("Unexpected doc change notification")); } else { WriteLine($"Received {args.DocumentID}"); _wa.RunConditionalAssert(() => { lock (_expectedDocumentChanges) { _expectedDocumentChanges.Should() .Contain(args.DocumentID, "because otherwise a rogue notification came"); _expectedDocumentChanges.Remove(args.DocumentID); WriteLine( $"Expecting {_expectedDocumentChanges.Count} more changes ({JsonConvert.SerializeObject(_expectedDocumentChanges)})"); return(_expectedDocumentChanges.Count == 0); } }); } }
public void TestStatus() { ulong maxConnectionCount = 0UL; ulong maxActiveCount = 0UL; //init and start a listener _listener = CreateListener(false); //listener is started at this point _listener.Status.ConnectionCount.Should().Be(0, "Listener's connection count should be 0 because no client connection has been established."); _listener.Status.ActiveConnectionCount.Should().Be(0, "Listener's active connection count should be 0 because no client connection has been established."); using (var doc1 = new MutableDocument()) using (var doc2 = new MutableDocument()) { doc1.SetString("name", "Sam"); Db.Save(doc1); doc2.SetString("name", "Mary"); OtherDb.Save(doc2); } var targetEndpoint = _listener.LocalEndpoint(); var config = new ReplicatorConfiguration(Db, targetEndpoint); using (var repl = new Replicator(config)) { var waitAssert = new WaitAssert(); var token = repl.AddChangeListener((sender, args) => { WriteLine($"Yeehaw {_listener.Status.ConnectionCount} / {_listener.Status.ActiveConnectionCount}"); maxConnectionCount = Math.Max(maxConnectionCount, _listener.Status.ConnectionCount); maxActiveCount = Math.Max(maxActiveCount, _listener.Status.ActiveConnectionCount); waitAssert.RunConditionalAssert(() => { return(args.Status.Activity == ReplicatorActivityLevel.Stopped); }); }); repl.Start(); while (repl.Status.Activity != ReplicatorActivityLevel.Busy) { Thread.Sleep(100); } // For some reason running on mac throws off the timing enough so that the active connection count // of 1 is never seen. So record the value right after it becomes busy. maxConnectionCount = Math.Max(maxConnectionCount, _listener.Status.ConnectionCount); maxActiveCount = Math.Max(maxActiveCount, _listener.Status.ActiveConnectionCount); try { waitAssert.WaitForResult(TimeSpan.FromSeconds(100)); } finally { repl.RemoveChangeListener(token); } } maxConnectionCount.Should().Be(1); maxActiveCount.Should().Be(1); //stop the listener _listener.Stop(); _listener.Status.ConnectionCount.Should().Be(0, "Listener's connection count should be 0 because the connection is stopped."); _listener.Status.ActiveConnectionCount.Should().Be(0, "Listener's active connection count should be 0 because the connection is stopped."); }