/// <exception cref="System.Exception"></exception> public virtual void TestGetActiveReplications() { Uri remote = GetReplicationURL(); Replication replication = (Replication)database.CreatePullReplication(remote); NUnit.Framework.Assert.AreEqual(0, database.GetAllReplications().Count); NUnit.Framework.Assert.AreEqual(0, database.GetActiveReplications().Count); replication.Start(); NUnit.Framework.Assert.AreEqual(1, database.GetAllReplications().Count); NUnit.Framework.Assert.AreEqual(1, database.GetActiveReplications().Count); CountDownLatch replicationDoneSignal = new CountDownLatch(1); LiteTestCase.ReplicationFinishedObserver replicationFinishedObserver = new LiteTestCase.ReplicationFinishedObserver (replicationDoneSignal); replication.AddChangeListener(replicationFinishedObserver); bool success = replicationDoneSignal.Await(60, TimeUnit.Seconds); NUnit.Framework.Assert.IsTrue(success); NUnit.Framework.Assert.AreEqual(1, database.GetAllReplications().Count); NUnit.Framework.Assert.AreEqual(0, database.GetActiveReplications().Count); }
/// <exception cref="System.Exception"></exception> public virtual void TestGetReplicator() { IDictionary<string, object> properties = new Dictionary<string, object>(); properties.Put("source", DefaultTestDb); properties.Put("target", GetReplicationURL().ToExternalForm()); IDictionary<string, object> headers = new Dictionary<string, object>(); string coolieVal = "SyncGatewaySession=c38687c2696688a"; headers.Put("Cookie", coolieVal); properties.Put("headers", headers); Replication replicator = manager.GetReplicator(properties); NUnit.Framework.Assert.IsNotNull(replicator); NUnit.Framework.Assert.AreEqual(GetReplicationURL().ToExternalForm(), replicator. GetRemoteUrl().ToExternalForm()); NUnit.Framework.Assert.IsTrue(!replicator.IsPull()); NUnit.Framework.Assert.IsFalse(replicator.IsContinuous()); NUnit.Framework.Assert.IsFalse(replicator.IsRunning()); NUnit.Framework.Assert.IsTrue(replicator.GetHeaders().ContainsKey("Cookie")); NUnit.Framework.Assert.AreEqual(replicator.GetHeaders().Get("Cookie"), coolieVal); // add replication observer CountDownLatch replicationDoneSignal = new CountDownLatch(1); LiteTestCase.ReplicationFinishedObserver replicationFinishedObserver = new LiteTestCase.ReplicationFinishedObserver (replicationDoneSignal); replicator.AddChangeListener(replicationFinishedObserver); // start the replicator Log.D(Tag, "Starting replicator " + replicator); replicator.Start(); // now lets lookup existing replicator and stop it Log.D(Tag, "Looking up replicator"); properties.Put("cancel", true); Replication activeReplicator = manager.GetReplicator(properties); Log.D(Tag, "Found replicator " + activeReplicator + " and calling stop()"); activeReplicator.Stop(); Log.D(Tag, "called stop(), waiting for it to finish"); // wait for replication to finish bool didNotTimeOut = replicationDoneSignal.Await(180, TimeUnit.Seconds); Log.D(Tag, "replicationDoneSignal.await done, didNotTimeOut: " + didNotTimeOut); NUnit.Framework.Assert.IsTrue(didNotTimeOut); NUnit.Framework.Assert.IsFalse(activeReplicator.IsRunning()); }
/// <summary>https://github.com/couchbase/couchbase-lite-java-core/issues/95</summary> /// <exception cref="System.Exception"></exception> public virtual void TestPushReplicationCanMissDocs() { NUnit.Framework.Assert.AreEqual(0, database.GetLastSequenceNumber()); IDictionary<string, object> properties1 = new Dictionary<string, object>(); properties1.Put("doc1", "testPushReplicationCanMissDocs"); Document doc1 = CreateDocWithProperties(properties1); IDictionary<string, object> properties2 = new Dictionary<string, object>(); properties1.Put("doc2", "testPushReplicationCanMissDocs"); Document doc2 = CreateDocWithProperties(properties2); UnsavedRevision doc2UnsavedRev = doc2.CreateRevision(); InputStream attachmentStream = GetAsset("attachment.png"); doc2UnsavedRev.SetAttachment("attachment.png", "image/png", attachmentStream); SavedRevision doc2Rev = doc2UnsavedRev.Save(); NUnit.Framework.Assert.IsNotNull(doc2Rev); CustomizableMockHttpClient mockHttpClient = new CustomizableMockHttpClient(); mockHttpClient.AddResponderFakeLocalDocumentUpdate404(); mockHttpClient.SetResponder("_bulk_docs", new _Responder_1506()); mockHttpClient.SetResponder(doc2.GetId(), new _Responder_1514(doc2)); // create a replication obeserver to wait until replication finishes CountDownLatch replicationDoneSignal = new CountDownLatch(1); LiteTestCase.ReplicationFinishedObserver replicationFinishedObserver = new LiteTestCase.ReplicationFinishedObserver (replicationDoneSignal); // create replication and add observer manager.SetDefaultHttpClientFactory(MockFactoryFactory(mockHttpClient)); Replication pusher = database.CreatePushReplication(GetReplicationURL()); pusher.AddChangeListener(replicationFinishedObserver); // save the checkpoint id for later usage string checkpointId = pusher.RemoteCheckpointDocID(); // kick off the replication pusher.Start(); // wait for it to finish bool success = replicationDoneSignal.Await(60, TimeUnit.Seconds); NUnit.Framework.Assert.IsTrue(success); Log.D(Tag, "replicationDoneSignal finished"); // we would expect it to have recorded an error because one of the docs (the one without the attachment) // will have failed. NUnit.Framework.Assert.IsNotNull(pusher.GetLastError()); // workaround for the fact that the replicationDoneSignal.wait() call will unblock before all // the statements in Replication.stopped() have even had a chance to execute. // (specifically the ones that come after the call to notifyChangeListeners()) Sharpen.Thread.Sleep(500); string localLastSequence = database.LastSequenceWithCheckpointId(checkpointId); Log.D(Tag, "database.lastSequenceWithCheckpointId(): " + localLastSequence); Log.D(Tag, "doc2.getCurrentRevision().getSequence(): " + doc2.GetCurrentRevision( ).GetSequence()); string msg = "Since doc1 failed, the database should _not_ have had its lastSequence bumped" + " to doc2's sequence number. If it did, it's bug: github.com/couchbase/couchbase-lite-java-core/issues/95"; NUnit.Framework.Assert.IsFalse(msg, System.Convert.ToString(doc2.GetCurrentRevision ().GetSequence()).Equals(localLastSequence)); NUnit.Framework.Assert.IsNull(localLastSequence); NUnit.Framework.Assert.IsTrue(doc2.GetCurrentRevision().GetSequence() > 0); }
/// <summary>https://github.com/couchbase/couchbase-lite-android/issues/247</summary> /// <exception cref="System.Exception"></exception> public virtual void RunPushReplicationWithTransientError(int statusCode, string statusMsg , bool expectReplicatorError) { IDictionary<string, object> properties1 = new Dictionary<string, object>(); properties1.Put("doc1", "testPushReplicationTransientError"); CreateDocWithProperties(properties1); CustomizableMockHttpClient mockHttpClient = new CustomizableMockHttpClient(); mockHttpClient.AddResponderFakeLocalDocumentUpdate404(); CustomizableMockHttpClient.Responder sentinal = CustomizableMockHttpClient.FakeBulkDocsResponder (); Queue<CustomizableMockHttpClient.Responder> responders = new List<CustomizableMockHttpClient.Responder >(); responders.AddItem(CustomizableMockHttpClient.TransientErrorResponder(statusCode, statusMsg)); ResponderChain responderChain = new ResponderChain(responders, sentinal); mockHttpClient.SetResponder("_bulk_docs", responderChain); // create a replication observer to wait until replication finishes CountDownLatch replicationDoneSignal = new CountDownLatch(1); LiteTestCase.ReplicationFinishedObserver replicationFinishedObserver = new LiteTestCase.ReplicationFinishedObserver (replicationDoneSignal); // create replication and add observer manager.SetDefaultHttpClientFactory(MockFactoryFactory(mockHttpClient)); Replication pusher = database.CreatePushReplication(GetReplicationURL()); pusher.AddChangeListener(replicationFinishedObserver); // save the checkpoint id for later usage string checkpointId = pusher.RemoteCheckpointDocID(); // kick off the replication pusher.Start(); // wait for it to finish bool success = replicationDoneSignal.Await(60, TimeUnit.Seconds); NUnit.Framework.Assert.IsTrue(success); Log.D(Tag, "replicationDoneSignal finished"); if (expectReplicatorError == true) { NUnit.Framework.Assert.IsNotNull(pusher.GetLastError()); } else { NUnit.Framework.Assert.IsNull(pusher.GetLastError()); } // workaround for the fact that the replicationDoneSignal.wait() call will unblock before all // the statements in Replication.stopped() have even had a chance to execute. // (specifically the ones that come after the call to notifyChangeListeners()) Sharpen.Thread.Sleep(500); string localLastSequence = database.LastSequenceWithCheckpointId(checkpointId); if (expectReplicatorError == true) { NUnit.Framework.Assert.IsNull(localLastSequence); } else { NUnit.Framework.Assert.IsNotNull(localLastSequence); } }
/// <exception cref="System.Exception"></exception> public virtual void TestOnlineOfflinePusher() { Uri remote = GetReplicationURL(); // mock sync gateway CustomizableMockHttpClient mockHttpClient = new CustomizableMockHttpClient(); mockHttpClient.AddResponderFakeLocalDocumentUpdate404(); mockHttpClient.AddResponderRevDiffsSmartResponder(); HttpClientFactory mockHttpClientFactory = MockFactoryFactory(mockHttpClient); manager.SetDefaultHttpClientFactory(mockHttpClientFactory); // create a replication observer CountDownLatch replicationDoneSignal = new CountDownLatch(1); LiteTestCase.ReplicationFinishedObserver replicationFinishedObserver = new LiteTestCase.ReplicationFinishedObserver (replicationDoneSignal); // create a push replication Replication pusher = database.CreatePushReplication(remote); Log.D(Database.Tag, "created pusher: " + pusher); pusher.AddChangeListener(replicationFinishedObserver); pusher.SetContinuous(true); pusher.Start(); for (int i = 0; i < 5; i++) { Log.D(Database.Tag, "testOnlineOfflinePusher, i: " + i); string docFieldName = "testOnlineOfflinePusher" + i; // put the replication offline PutReplicationOffline(pusher); // add a response listener to wait for a bulk_docs request from the pusher CountDownLatch gotBulkDocsRequest = new CountDownLatch(1); CustomizableMockHttpClient.ResponseListener bulkDocsListener = new _ResponseListener_1334 (docFieldName, gotBulkDocsRequest); mockHttpClient.AddResponseListener(bulkDocsListener); // add a document string docFieldVal = "foo" + i; IDictionary<string, object> properties = new Dictionary<string, object>(); properties.Put(docFieldName, docFieldVal); CreateDocumentWithProperties(database, properties); // put the replication online, which should trigger it to send outgoing bulk_docs request PutReplicationOnline(pusher); // wait until we get a bulk docs request Log.D(Database.Tag, "waiting for bulk docs request with " + docFieldName); bool succeeded = gotBulkDocsRequest.Await(90, TimeUnit.Seconds); NUnit.Framework.Assert.IsTrue(succeeded); Log.D(Database.Tag, "got bulk docs request with " + docFieldName); mockHttpClient.RemoveResponseListener(bulkDocsListener); mockHttpClient.ClearCapturedRequests(); } Log.D(Database.Tag, "calling pusher.stop()"); pusher.Stop(); Log.D(Database.Tag, "called pusher.stop()"); // wait for replication to finish Log.D(Database.Tag, "waiting for replicationDoneSignal"); bool didNotTimeOut = replicationDoneSignal.Await(90, TimeUnit.Seconds); Log.D(Database.Tag, "done waiting for replicationDoneSignal. didNotTimeOut: " + didNotTimeOut); NUnit.Framework.Assert.IsTrue(didNotTimeOut); NUnit.Framework.Assert.IsFalse(pusher.IsRunning()); }
/// <summary>Test for the private goOffline() method, which still in "incubation".</summary> /// <remarks> /// Test for the private goOffline() method, which still in "incubation". /// This test is brittle because it depends on the following observed behavior, /// which will probably change: /// - the replication will go into an "idle" state after starting the change listener /// Which does not match: https://github.com/couchbase/couchbase-lite-android/wiki/Replicator-State-Descriptions /// The reason we need to wait for it to go into the "idle" state, is otherwise the following sequence happens: /// 1) Call replicator.start() /// 2) Call replicator.goOffline() /// 3) Does not cancel changetracker, because changetracker is still null /// 4) After getting the remote sequence from http://sg/_local/.., it starts the ChangeTracker /// 5) Now the changetracker is running even though we've told it to go offline. /// </remarks> /// <exception cref="System.Exception"></exception> public virtual void TestGoOffline() { Uri remote = GetReplicationURL(); Replication replicator = database.CreatePullReplication(remote); replicator.SetContinuous(true); // add replication "idle" observer - exploit the fact that during observation, // the replication will go into an "idle" state after starting the change listener. CountDownLatch countDownLatch = new CountDownLatch(1); LiteTestCase.ReplicationIdleObserver replicationObserver = new LiteTestCase.ReplicationIdleObserver (countDownLatch); replicator.AddChangeListener(replicationObserver); // add replication observer CountDownLatch countDownLatch2 = new CountDownLatch(1); LiteTestCase.ReplicationFinishedObserver replicationFinishedObserver = new LiteTestCase.ReplicationFinishedObserver (countDownLatch2); replicator.AddChangeListener(replicationFinishedObserver); replicator.Start(); bool success = countDownLatch.Await(30, TimeUnit.Seconds); NUnit.Framework.Assert.IsTrue(success); PutReplicationOffline(replicator); NUnit.Framework.Assert.IsTrue(replicator.GetStatus() == Replication.ReplicationStatus .ReplicationOffline); replicator.Stop(); bool success2 = countDownLatch2.Await(30, TimeUnit.Seconds); NUnit.Framework.Assert.IsTrue(success2); }