/**
* Copyright (c) 2016 Couchbase, Inc. All rights reserved.
* <p/>
* 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
* <p/>
* http://www.apache.org/licenses/LICENSE-2.0
* <p/>
* 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.couchbase.lite.replicator;
import com.couchbase.lite.Document;
import com.couchbase.lite.LiteTestCaseWithDB;
import com.couchbase.lite.internal.RevisionInternal;
import com.couchbase.lite.mockserver.MockDispatcher;
import com.couchbase.lite.mockserver.MockHelper;
import com.couchbase.lite.mockserver.WrappedSmartMockResponse;
import com.couchbase.lite.support.CouchbaseLiteHttpClientFactory;
import com.couchbase.lite.support.PersistentCookieJar;
import com.couchbase.lite.util.Log;
import com.couchbase.lite.util.Utils;
import java.net.URL;
import java.util.ArrayList;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
import okhttp3.Response;
import okhttp3.mockwebserver.MockResponse;
import okhttp3.mockwebserver.MockWebServer;
public class BulkDownloaderTest extends LiteTestCaseWithDB {
/**
* https://github.com/couchbase/couchbase-lite-java-core/issues/331
*/
public void testErrorHandling() throws Exception {
PersistentCookieJar cookieStore = database.getPersistentCookieStore();
CouchbaseLiteHttpClientFactory factory = new CouchbaseLiteHttpClientFactory(cookieStore);
// create mockwebserver and custom dispatcher
MockDispatcher dispatcher = new MockDispatcher();
MockWebServer server = MockHelper.getMockWebServer(dispatcher);
dispatcher.setServerType(MockDispatcher.ServerType.SYNC_GW);
try {
// _bulk_docs response -- 406 errors
MockResponse mockResponse = new MockResponse().setResponseCode(406);
WrappedSmartMockResponse mockBulkDocs =
new WrappedSmartMockResponse(mockResponse, false);
mockBulkDocs.setSticky(true);
dispatcher.enqueueResponse(MockHelper.PATH_REGEX_BULK_DOCS, mockBulkDocs);
server.start();
ScheduledExecutorService requestExecutorService = Executors.newScheduledThreadPool(5);
ScheduledExecutorService workExecutorService = Executors
.newSingleThreadScheduledExecutor();
String urlString = String.format(Locale.ENGLISH, "%s/%s", server.url("/db").url(), "_local");
URL url = new URL(urlString);
// BulkDownloader expects to be given a list of RevisionInternal
List<RevisionInternal> revs = new ArrayList<RevisionInternal>();
Document doc = createDocumentForPushReplication("doc1", null, null);
RevisionInternal revisionInternal = database.getDocument(doc.getId(),
doc.getCurrentRevisionId(), true);
revs.add(revisionInternal);
// countdown latch to make sure we got an error
final CountDownLatch gotError = new CountDownLatch(1);
// create a bulkdownloader
RemoteBulkDownloaderRequest bulkDownloader = new RemoteBulkDownloaderRequest(
factory,
url,
true,
revs,
database,
null,
new RemoteBulkDownloaderRequest.BulkDownloaderDocument() {
public void onDocument(Map<String, Object> props, long size) {
// do nothing
Log.d(TAG, "onDocument called with %s, %d", props, size);
}
},
new RemoteRequestCompletion() {
public void onCompletion(Response httpResponse, Object result, Throwable e) {
Log.d(TAG, "RemoteRequestCompletionBlock called, result: %s e: %s",
result, e);
if (e != null) {
gotError.countDown();
}
}
}
);
// submit the request
Future future = requestExecutorService.submit(bulkDownloader);
// make sure our callback was called with an error, since
// we are returning a 4xx error to all _bulk_get requests
boolean success = gotError.await(60, TimeUnit.SECONDS);
assertTrue(success);
// wait for the future to return
future.get(300, TimeUnit.SECONDS);
// Note: ExecutorService should be called shutdown()
Utils.shutdownAndAwaitTermination(requestExecutorService);
Utils.shutdownAndAwaitTermination(workExecutorService);
} finally {
assertTrue(MockHelper.shutdown(server, dispatcher));
}
}
}