diff --git a/Jenkinsfile b/Jenkinsfile
index 99e321357..4509d0ba5 100644
--- a/Jenkinsfile
+++ b/Jenkinsfile
@@ -1,7 +1,7 @@
#!groovy
/*
- * Copyright © 2016, 2017 IBM Corp. All rights reserved.
+ * Copyright © 2016, 2018 IBM Corp. All rights reserved.
*
* 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
@@ -31,7 +31,7 @@ def runTests(testEnv, isServiceTests) {
try {
sh './gradlew -Dtest.couch.username=$DB_USER -Dtest.couch.password=$DB_PASSWORD -Dtest.couch.host=$DB_HOST -Dtest.couch.port=$DB_PORT -Dtest.couch.http=$DB_HTTP $GRADLE_TARGET'
} finally {
- junit '**/build/test-results/*.xml'
+ junit '**/build/test-results/**/*.xml'
}
}
}
diff --git a/build.gradle b/build.gradle
index 759f15d88..efb1014f0 100644
--- a/build.gradle
+++ b/build.gradle
@@ -1,5 +1,5 @@
/*
- * Copyright © 2016 IBM Corp. All rights reserved.
+ * Copyright © 2016, 2018 IBM Corp. All rights reserved.
*
* 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
diff --git a/cloudant-client/build.gradle b/cloudant-client/build.gradle
index 291f56778..592931ac6 100644
--- a/cloudant-client/build.gradle
+++ b/cloudant-client/build.gradle
@@ -1,5 +1,5 @@
/*
- * Copyright © 2016, 2017 IBM Corp. All rights reserved.
+ * Copyright © 2016, 2018 IBM Corp. All rights reserved.
*
* 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
@@ -25,7 +25,10 @@ dependencies {
compile project(':cloudant-http')
linkableJavadoc project(':cloudant-http')
//test dependencies
- testCompile group: 'junit', name: 'junit', version: '4.12'
+ testRuntime group: 'org.junit.jupiter', name: 'junit-jupiter-engine', version: '5.1.0'
+ testRuntime group: 'org.junit.platform', name: 'junit-platform-console', version: '1.1.0'
+ testCompile group: 'org.junit.jupiter', name: 'junit-jupiter-api', version: '5.1.0'
+ testCompile group: 'org.hamcrest', name: 'hamcrest-library', version: '1.3'
testCompile group: 'com.squareup.okhttp3', name: 'mockwebserver', version: '3.8.1'
testCompile group: 'org.jmockit', name: 'jmockit', version: '1.34'
testCompile group: 'org.littleshoot', name: 'littleproxy', version: '1.1.0'
@@ -54,6 +57,12 @@ gradle.projectsEvaluated {
}
}
+// we need Java 1.8 features for JUnit 5 features, but our production code is 1.6
+compileTestJava {
+ sourceCompatibility = 1.8
+ targetCompatibility = 1.8
+}
+
tasks.withType(Test) {
def jMockit
doFirst {
@@ -65,35 +74,45 @@ tasks.withType(Test) {
}
}
-test {
- // Run tests for any DB
- useJUnit {
- excludeCategories 'com.cloudant.test.main.RequiresCloudant',
- 'com.cloudant.test.main.RequiresCouch'
+// hacky - see https://discuss.gradle.org/t/passing-arguments-to-a-task/8427/9
+def CustomJunitPlatformTask(include, exclude) {
+ return tasks.create(name: "exec_${include}_${exclude}", type: JavaExec, dependsOn: testClasses) {
+ classpath = sourceSets.main.runtimeClasspath + sourceSets.test.runtimeClasspath
+ main = 'org.junit.platform.console.ConsoleLauncher'
+ // arguments to pass to the application
+ args ('--reports-dir',testResultsDir,
+ '--scan-class-path')
+ // build up includes
+ if (include.size > 0) {
+ args += '--include-tag'
+ args += include.join("|")
+ }
+ // build up excludes
+ if (exclude.size > 0) {
+ args += '--exclude-tag'
+ args += exclude.join("|")
+ }
+ // inherit system properties
+ systemProperties System.properties
+ // some tests expect user.dir to be same as working dir, which
+ // defaults to project dir
+ systemProperty "user.dir", project.projectDir
}
}
-task noDBTest(type: Test, dependsOn: testClasses) {
- // Run unit tests that do not need a running database
- useJUnit {
- excludeCategories 'com.cloudant.test.main.RequiresDB'
- }
-}
+// Run tests which are compatible with all versions of Couch or
+// Cloudant.
+// This is the default test target.
+task test (dependsOn:CustomJunitPlatformTask([],['RequiresCouch','RequiresCloudant']), overwrite: true){}
-task cloudantTest(type: Test, dependsOn: testClasses) {
- // Run tests that can use any Cloudant
- useJUnit {
- excludeCategories 'com.cloudant.test.main.RequiresCloudantService'
- }
-}
+// Run 'unit' tests which do not require a database.
+task noDBTest(dependsOn: CustomJunitPlatformTask([],['RequiresDB'])) {}
-task cloudantServiceTest(type: Test, dependsOn: testClasses) {
- // Run all Cloudant service tests
- useJUnit {
- excludeCategories 'com.cloudant.test.main.RequiresCloudantLocal',
- 'com.cloudant.test.main.RequiresCouch'
- }
-}
+// Run tests that can use any Cloudant.
+task cloudantTest(dependsOn: CustomJunitPlatformTask([],['RequiresCloudantService'])) {}
+
+// Run all Cloudant service tests.
+task cloudantServiceTest(dependsOn: CustomJunitPlatformTask([],['RequiresCloudantLocal', 'RequiresCouch'])) {}
//task for generating a client properties file
class ClientProperties extends DefaultTask {
diff --git a/cloudant-client/src/test/java/com/cloudant/api/query/FieldAssertHelper.java b/cloudant-client/src/test/java/com/cloudant/api/query/FieldAssertHelper.java
index 100ad355d..ace2a2ade 100644
--- a/cloudant-client/src/test/java/com/cloudant/api/query/FieldAssertHelper.java
+++ b/cloudant-client/src/test/java/com/cloudant/api/query/FieldAssertHelper.java
@@ -1,5 +1,5 @@
/*
- * Copyright © 2017 IBM Corp. All rights reserved.
+ * Copyright © 2017, 2018 IBM Corp. All rights reserved.
*
* 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
@@ -14,8 +14,8 @@
package com.cloudant.api.query;
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertNotNull;
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertNotNull;
import com.cloudant.client.api.query.Field;
import com.cloudant.client.api.query.JsonIndex;
@@ -40,7 +40,7 @@ public static class Json extends FieldAssertHelper
@Override
protected void assertField(JsonIndex.Field field, Sort.Order order) {
- assertEquals("The order should be the same", order, field.getOrder());
+ assertEquals(order, field.getOrder(), "The order should be the same");
}
}
@@ -53,20 +53,20 @@ public static class Text extends FieldAssertHelper {
@Override
protected void assertField(TextIndex.Field field, Type type) {
- assertEquals("The type should be the same", type, field.getType());
+ assertEquals(type, field.getType(), "The type should be the same");
}
}
public void assertFields(List actualFields) {
- assertEquals("There should be the correct number of fields", expectedFields.size(),
- actualFields.size());
+ assertEquals(expectedFields.size(),
+ actualFields.size(), "There should be the correct number of fields");
for (F field : actualFields) {
assertNotNull("The field should have a name", field.getName());
T expected = expectedFields.remove(field.getName());
- assertNotNull("Unexpected field " + field.getName() + " found.", expected);
+ assertNotNull(expected, "Unexpected field " + field.getName() + " found.");
assertField(field, expected);
}
- assertEquals("All fields should be asserted.", 0, expectedFields.size());
+ assertEquals(0, expectedFields.size(), "All fields should be asserted.");
}
protected abstract void assertField(F field, T type);
diff --git a/cloudant-client/src/test/java/com/cloudant/api/query/IndexCreationTests.java b/cloudant-client/src/test/java/com/cloudant/api/query/IndexCreationTests.java
index f062f21d8..4d59f65d6 100644
--- a/cloudant-client/src/test/java/com/cloudant/api/query/IndexCreationTests.java
+++ b/cloudant-client/src/test/java/com/cloudant/api/query/IndexCreationTests.java
@@ -15,24 +15,24 @@
package com.cloudant.api.query;
import static com.cloudant.client.api.query.Expression.gt;
-import static org.junit.Assert.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertEquals;
import com.cloudant.client.api.query.JsonIndex;
import com.cloudant.client.api.query.Selector;
import com.cloudant.client.api.query.TextIndex;
import com.cloudant.client.internal.query.Helpers;
-import com.cloudant.tests.util.MockedServerTest;
+import com.cloudant.tests.base.TestWithMockedServer;
import com.google.gson.Gson;
import com.google.gson.JsonObject;
-import org.junit.Test;
+import org.junit.jupiter.api.Test;
import okhttp3.mockwebserver.MockResponse;
import okhttp3.mockwebserver.RecordedRequest;
import java.util.concurrent.TimeUnit;
-public class IndexCreationTests extends MockedServerTest {
+public class IndexCreationTests extends TestWithMockedServer {
private static MockResponse CREATED = new MockResponse().setBody("{\"result\": \"created\"}");
@@ -122,7 +122,7 @@ public void createNamedTextIndex() throws Exception {
@Test
public void createTextIndexInDesignDoc() throws Exception {
createIndexTest(TextIndex.builder()
- .designDocument("testddoc")
+ .designDocument("testddoc")
.definition(),
"{type: \"text\", ddoc: \"testddoc\", index: {}}");
}
@@ -216,6 +216,6 @@ private void createIndexTest(String definition, String expected) throws Exceptio
db.createIndex(definition);
RecordedRequest request = server.takeRequest(1, TimeUnit.SECONDS);
JsonObject actual = new Gson().fromJson(request.getBody().readUtf8(), JsonObject.class);
- assertEquals("The request body should match the expected", exp, actual);
+ assertEquals(exp, actual, "The request body should match the expected");
}
}
diff --git a/cloudant-client/src/test/java/com/cloudant/api/query/IndexDeletionTests.java b/cloudant-client/src/test/java/com/cloudant/api/query/IndexDeletionTests.java
index 237573df1..4fdb5fe4d 100644
--- a/cloudant-client/src/test/java/com/cloudant/api/query/IndexDeletionTests.java
+++ b/cloudant-client/src/test/java/com/cloudant/api/query/IndexDeletionTests.java
@@ -1,5 +1,5 @@
/*
- * Copyright © 2017 IBM Corp. All rights reserved.
+ * Copyright © 2017, 2018 IBM Corp. All rights reserved.
*
* 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
@@ -14,21 +14,21 @@
package com.cloudant.api.query;
-import static org.junit.Assert.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import com.cloudant.tests.base.TestWithMockedServer;
import com.cloudant.tests.util.MockWebServerResources;
-import com.cloudant.tests.util.MockedServerTest;
-import org.junit.Before;
-import org.junit.Test;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
import okhttp3.mockwebserver.RecordedRequest;
import java.util.concurrent.TimeUnit;
-public class IndexDeletionTests extends MockedServerTest {
+public class IndexDeletionTests extends TestWithMockedServer {
- @Before
+ @BeforeEach
public void enqueueOK() {
server.enqueue(MockWebServerResources.JSON_OK);
}
@@ -53,7 +53,7 @@ public void deleteTextIndex() throws Exception {
private void assertDelete(String name, String ddoc, String type) throws Exception {
RecordedRequest request = server.takeRequest(1, TimeUnit.SECONDS);
- assertEquals("The request body should match the expected", "/" + dbResource.getDatabaseName() +
- "/_index/_design/" + ddoc + "/" + type + "/" + name, request.getPath());
+ assertEquals("/" + dbResource.getDatabaseName() + "/_index/_design/" + ddoc + "/" + type
+ + "/" + name, request.getPath(), "The request body should match the expected");
}
}
diff --git a/cloudant-client/src/test/java/com/cloudant/api/query/IndexLifecycleTest.java b/cloudant-client/src/test/java/com/cloudant/api/query/IndexLifecycleTest.java
index 7e11454b4..90b95e7e7 100644
--- a/cloudant-client/src/test/java/com/cloudant/api/query/IndexLifecycleTest.java
+++ b/cloudant-client/src/test/java/com/cloudant/api/query/IndexLifecycleTest.java
@@ -1,5 +1,5 @@
/*
- * Copyright © 2017 IBM Corp. All rights reserved.
+ * Copyright © 2017, 2018 IBM Corp. All rights reserved.
*
* 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
@@ -14,9 +14,8 @@
package com.cloudant.api.query;
-import static org.junit.Assert.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertEquals;
-import com.cloudant.client.api.Database;
import com.cloudant.client.api.query.Field;
import com.cloudant.client.api.query.Index;
import com.cloudant.client.api.query.JsonIndex;
@@ -24,22 +23,18 @@
import com.cloudant.client.api.query.TextIndex;
import com.cloudant.client.api.query.Type;
import com.cloudant.test.main.RequiresCloudant;
-import com.cloudant.tests.util.CloudantClientResource;
-import com.cloudant.tests.util.DatabaseResource;
+import com.cloudant.tests.base.TestWithDbPerTest;
-import org.junit.After;
-import org.junit.Before;
-import org.junit.Rule;
-import org.junit.Test;
-import org.junit.experimental.categories.Category;
-import org.junit.rules.RuleChain;
+import org.junit.jupiter.api.AfterEach;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
import java.util.Collections;
import java.util.List;
// This really requires Couch2.0 + text index support, but we don't have a way of expressing that
-@Category(RequiresCloudant.class)
+@RequiresCloudant
/**
* Index lifecycle test.
@@ -47,18 +42,10 @@
* Test list indexes
* After delete indexes
*/
-public class IndexLifecycleTest {
+public class IndexLifecycleTest extends TestWithDbPerTest {
- private CloudantClientResource clientResource = new CloudantClientResource();
- private DatabaseResource dbResource = new DatabaseResource(clientResource);
- @Rule
- public RuleChain chain = RuleChain.outerRule(clientResource).around(dbResource);
-
- private Database db;
-
- @Before
+ @BeforeEach
public void createIndexes() throws Exception {
- db = dbResource.get();
// Create a JSON index
db.createIndex(JsonIndex.builder()
@@ -84,14 +71,14 @@ public void listIndexes() throws Exception {
{
// JSON index
List jIndexes = db.listIndexes().jsonIndexes();
- assertEquals("There should be one JSON index", 1, jIndexes.size());
+ assertEquals(1, jIndexes.size(), "There should be one JSON index");
JsonIndex jIndex = jIndexes.get(0);
- assertEquals("The ddoc should be correct", "_design/indexlifecycle", jIndex
- .getDesignDocumentID());
- assertEquals("The name should be correct", "testjson", jIndex.getName());
- assertEquals("The type should be correct", "json", jIndex.getType());
+ assertEquals("_design/indexlifecycle", jIndex
+ .getDesignDocumentID(), "The ddoc should be correct");
+ assertEquals("testjson", jIndex.getName(), "The name should be correct");
+ assertEquals("json", jIndex.getType(), "The type should be correct");
List fields = jIndex.getFields();
- assertEquals("There should be two fields", 2, fields.size());
+ assertEquals(2, fields.size(), "There should be two fields");
// Field assertions
new FieldAssertHelper.Json(Collections.singletonMap("testDefaultAsc", Sort.Order.ASC)
, Collections.singletonMap("testAsc", Sort.Order.ASC)).assertFields(fields);
@@ -100,14 +87,14 @@ public void listIndexes() throws Exception {
{
// Text index
List tIndexes = db.listIndexes().textIndexes();
- assertEquals("There should be one text index", 1, tIndexes.size());
+ assertEquals(1, tIndexes.size(), "There should be one text index");
TextIndex tIndex = tIndexes.get(0);
- assertEquals("The ddoc should be correct", "_design/indexlifecycle", tIndex
- .getDesignDocumentID());
- assertEquals("The name should be correct", "testtext", tIndex.getName());
- assertEquals("The type should be correct", "text", tIndex.getType());
+ assertEquals("_design/indexlifecycle", tIndex
+ .getDesignDocumentID(), "The ddoc should be correct");
+ assertEquals("testtext", tIndex.getName(), "The name should be correct");
+ assertEquals("text", tIndex.getType(), "The type should be correct");
List fields = tIndex.getFields();
- assertEquals("There should be three fields", 3, fields.size());
+ assertEquals(3, fields.size(), "There should be three fields");
// Field assertions
new FieldAssertHelper.Text(Collections.singletonMap("testString", Type.STRING),
Collections.singletonMap("testNumber", Type.NUMBER),
@@ -117,23 +104,23 @@ public void listIndexes() throws Exception {
{
// All indexes
List> allIndexes = db.listIndexes().allIndexes();
- assertEquals("There should be three total indexes", 3, allIndexes.size());
+ assertEquals(3, allIndexes.size(), "There should be three total indexes");
for (Index index : allIndexes) {
if (index.getType().equals("special")) {
- assertEquals("The name should be correct", "_all_docs", index.getName());
- assertEquals("There should be 1 field", 1, index.getFields().size());
- assertEquals("There field should be called _id", "_id", index.getFields().get(0)
- .getName());
+ assertEquals("_all_docs", index.getName(), "The name should be correct");
+ assertEquals(1, index.getFields().size(), "There should be 1 field");
+ assertEquals("_id", index.getFields().get(0)
+ .getName(), "There field should be called _id");
}
}
}
}
- @After
+ @AfterEach
public void deleteIndexes() throws Exception {
db.deleteIndex("testjson", "indexlifecycle", "json");
db.deleteIndex("testtext", "indexlifecycle", "text");
List> allIndexes = db.listIndexes().allIndexes();
- assertEquals("There should be one (special) index", 1, allIndexes.size());
+ assertEquals(1, allIndexes.size(), "There should be one (special) index");
}
}
diff --git a/cloudant-client/src/test/java/com/cloudant/api/query/IndexListTests.java b/cloudant-client/src/test/java/com/cloudant/api/query/IndexListTests.java
index 8f28f2061..9502b062b 100644
--- a/cloudant-client/src/test/java/com/cloudant/api/query/IndexListTests.java
+++ b/cloudant-client/src/test/java/com/cloudant/api/query/IndexListTests.java
@@ -1,5 +1,5 @@
/*
- * Copyright © 2017 IBM Corp. All rights reserved.
+ * Copyright © 2017, 2018 IBM Corp. All rights reserved.
*
* 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
@@ -14,8 +14,8 @@
package com.cloudant.api.query;
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.fail;
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.fail;
import com.cloudant.client.api.query.Field;
import com.cloudant.client.api.query.Index;
@@ -23,21 +23,20 @@
import com.cloudant.client.api.query.Sort;
import com.cloudant.client.api.query.TextIndex;
import com.cloudant.client.api.query.Type;
-import com.cloudant.tests.util.MockedServerTest;
+import com.cloudant.tests.base.TestWithMockedServer;
import org.apache.commons.io.IOUtils;
-import org.junit.Test;
+import org.junit.jupiter.api.Test;
import okhttp3.mockwebserver.MockResponse;
import java.io.BufferedInputStream;
-import java.io.File;
import java.io.FileInputStream;
import java.util.Collections;
import java.util.List;
import java.util.Map;
-public class IndexListTests extends MockedServerTest {
+public class IndexListTests extends TestWithMockedServer {
private static String SELECTOR_STRING = "{\"year\":{\"$gt\":2010}}";
@@ -57,12 +56,11 @@ public class IndexListTests extends MockedServerTest {
* @return
*/
private static String fromFile(String resourceFileName) {
- System.out.println(new File(".").getAbsolutePath());
try {
return IOUtils.toString(new BufferedInputStream(new FileInputStream("" +
"./src/test/resources/query-tests/" + resourceFileName + ".js")), "UTF-8");
} catch (Exception e) {
- fail("Error reading test resource: " + e.getMessage());
+ fail("Error reading test resource: " + e.getMessage());
}
return null;
}
@@ -92,12 +90,11 @@ private void assertIndex(Index index, String name, String type, String selector)
private void assertIndex(Index index, String name, String ddoc, String type, String selector)
throws Exception {
- assertEquals("The index should have the correct name", name, index.getName());
- assertEquals("The index should have the correct ddoc", ddoc, index
- .getDesignDocumentID());
- assertEquals("The index should have the correct type", type, index.getType());
- assertEquals("The index should have the correct selector", selector, index
- .getPartialFilterSelector());
+ assertEquals(name, index.getName(), "The index should have the correct name");
+ assertEquals(ddoc, index.getDesignDocumentID(), "The index should have the correct ddoc");
+ assertEquals(type, index.getType(), "The index should have the correct type");
+ assertEquals(selector, index.getPartialFilterSelector(), "The index should have the " +
+ "correct selector");
}
private void assertJsonIndex(JsonIndex index, String name, String selector, Map...
expectedFields) throws Exception {
assertIndex(index, name, "text", selector);
- assertEquals("The analyzer should be correct", analyzer, index.getAnalyzer());
- assertEquals("The default field should be correct", defaultField, index.getDefaultField());
+ assertEquals(analyzer, index.getAnalyzer(), "The analyzer should be correct");
+ assertEquals(defaultField, index.getDefaultField(), "The default field should be correct");
// Assert the fields
new FieldAssertHelper.Text(expectedFields).assertFields(index.getFields());
}
@@ -146,7 +143,7 @@ private void assertComplexText(TextIndex index) throws Exception {
public void listSimpleJsonIndex() throws Exception {
enqueueList(JSON_SIMPLE);
List indexes = db.listIndexes().jsonIndexes();
- assertEquals("There should be 1 JSON index", 1, indexes.size());
+ assertEquals(1, indexes.size(), "There should be 1 JSON index");
JsonIndex simple = indexes.get(0);
assertSimpleJson(simple);
}
@@ -155,7 +152,7 @@ public void listSimpleJsonIndex() throws Exception {
public void listComplexJsonIndex() throws Exception {
enqueueList(JSON_COMPLEX);
List indexes = db.listIndexes().jsonIndexes();
- assertEquals("There should be 1 JSON index", 1, indexes.size());
+ assertEquals(1, indexes.size(), "There should be 1 JSON index");
JsonIndex complex = indexes.get(0);
assertComplexJson(complex);
@@ -165,7 +162,7 @@ public void listComplexJsonIndex() throws Exception {
public void listMultipleJsonIndexes() throws Exception {
enqueueList(JSON_SIMPLE, JSON_COMPLEX);
List indexes = db.listIndexes().jsonIndexes();
- assertEquals("There should be 2 JSON indexes", 2, indexes.size());
+ assertEquals(2, indexes.size(), "There should be 2 JSON indexes");
JsonIndex simple = indexes.get(0);
assertSimpleJson(simple);
JsonIndex complex = indexes.get(1);
@@ -176,7 +173,7 @@ public void listMultipleJsonIndexes() throws Exception {
public void listSimpleTextIndex() throws Exception {
enqueueList(TEXT_SIMPLE);
List indexes = db.listIndexes().textIndexes();
- assertEquals("There should be 1 text index", 1, indexes.size());
+ assertEquals(1, indexes.size(), "There should be 1 text index");
TextIndex simple = indexes.get(0);
assertSimpleText(simple);
}
@@ -191,7 +188,7 @@ public void listSimpleTextIndex() throws Exception {
public void listSimpleTextIndexWithSelector() throws Exception {
enqueueList(TEXT_SIMPLE_SELECTOR);
List indexes = db.listIndexes().textIndexes();
- assertEquals("There should be 1 text index", 1, indexes.size());
+ assertEquals(1, indexes.size(), "There should be 1 text index");
TextIndex simple = indexes.get(0);
assertTextIndex(simple, "simpleselector", SELECTOR_STRING, "\"keyword\"", "{}",
Collections.singletonMap
@@ -202,7 +199,7 @@ public void listSimpleTextIndexWithSelector() throws Exception {
public void listComplexTextIndex() throws Exception {
enqueueList(TEXT_COMPLEX);
List indexes = db.listIndexes().textIndexes();
- assertEquals("There should be 1 text index", 1, indexes.size());
+ assertEquals(1, indexes.size(), "There should be 1 text index");
TextIndex complex = indexes.get(0);
assertComplexText(complex);
}
@@ -211,7 +208,7 @@ public void listComplexTextIndex() throws Exception {
public void listMultipleTextIndexes() throws Exception {
enqueueList(TEXT_SIMPLE, TEXT_COMPLEX, TEXT_ALL_FIELDS);
List indexes = db.listIndexes().textIndexes();
- assertEquals("There should be 3 text indexes", 3, indexes.size());
+ assertEquals(3, indexes.size(), "There should be 3 text indexes");
TextIndex simple = indexes.get(0);
assertSimpleText(simple);
TextIndex complex = indexes.get(1);
@@ -226,7 +223,7 @@ public void listAllIndexes() throws Exception {
enqueueList(JSON_SIMPLE, JSON_COMPLEX, TEXT_SIMPLE, TEXT_COMPLEX, TEXT_ALL_FIELDS);
List> indexes = db.listIndexes().allIndexes();
// Note 5 listed here, plus the special index that is always included
- assertEquals("There should be 6 indexes", 6, indexes.size());
+ assertEquals(6, indexes.size(), "There should be 6 indexes");
for (int i = 0; i < indexes.size(); i++) {
String name;
String type;
@@ -235,9 +232,9 @@ public void listAllIndexes() throws Exception {
case 0:
Index a = indexes.get(i);
assertIndex(a, "_all_docs", null, "special", null);
- assertEquals("There should be 1 field", 1, a.getFields().size());
- assertEquals("There field should be called _id", "_id", a.getFields().get(0)
- .getName());
+ assertEquals(1, a.getFields().size(), "There should be 1 field");
+ assertEquals("_id", a.getFields().get(0).getName(), "There field should be " +
+ "called _id");
return;
case 1:
name = "simplejson";
diff --git a/cloudant-client/src/test/java/com/cloudant/test/main/RequiresCloudant.java b/cloudant-client/src/test/java/com/cloudant/test/main/RequiresCloudant.java
index a750a3471..36a24e962 100644
--- a/cloudant-client/src/test/java/com/cloudant/test/main/RequiresCloudant.java
+++ b/cloudant-client/src/test/java/com/cloudant/test/main/RequiresCloudant.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2015 IBM Corp. All rights reserved.
+ * Copyright © 2015, 2018 IBM Corp. All rights reserved.
*
* 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
@@ -14,8 +14,19 @@
package com.cloudant.test.main;
+import org.junit.jupiter.api.Tag;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
/**
- * JUnit category to label tests which require Cloudant Service or Cloudant Local
+ * JUnit tag to label tests which require Cloudant Service or Cloudant Local
*/
-public class RequiresCloudant extends RequiresDB {
+@Target({ElementType.TYPE, ElementType.METHOD})
+@Retention(RetentionPolicy.RUNTIME)
+@Tag("RequiresCloudant")
+@Tag("RequiresDB")
+public @interface RequiresCloudant {
}
diff --git a/cloudant-client/src/test/java/com/cloudant/test/main/RequiresCloudantLocal.java b/cloudant-client/src/test/java/com/cloudant/test/main/RequiresCloudantLocal.java
index 5a55614d7..910435d9b 100644
--- a/cloudant-client/src/test/java/com/cloudant/test/main/RequiresCloudantLocal.java
+++ b/cloudant-client/src/test/java/com/cloudant/test/main/RequiresCloudantLocal.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2015 IBM Corp. All rights reserved.
+ * Copyright © 2015, 2018 IBM Corp. All rights reserved.
*
* 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
@@ -14,8 +14,20 @@
package com.cloudant.test.main;
+import org.junit.jupiter.api.Tag;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
/**
- * JUnit category to label tests which require Cloudant local
+ * JUnit tag to label tests which require Cloudant local
*/
-public class RequiresCloudantLocal extends RequiresCloudant {
+@Target({ElementType.TYPE, ElementType.METHOD})
+@Retention(RetentionPolicy.RUNTIME)
+@Tag("RequiresCloudantLocal")
+@Tag("RequiresCloudant")
+@Tag("RequiresDB")
+public @interface RequiresCloudantLocal {
}
diff --git a/cloudant-client/src/test/java/com/cloudant/test/main/RequiresCloudantService.java b/cloudant-client/src/test/java/com/cloudant/test/main/RequiresCloudantService.java
index b62243347..52bb5985d 100644
--- a/cloudant-client/src/test/java/com/cloudant/test/main/RequiresCloudantService.java
+++ b/cloudant-client/src/test/java/com/cloudant/test/main/RequiresCloudantService.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2015 IBM Corp. All rights reserved.
+ * Copyright © 2015, 2018 IBM Corp. All rights reserved.
*
* 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
@@ -14,8 +14,20 @@
package com.cloudant.test.main;
+import org.junit.jupiter.api.Tag;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
/**
- * JUnit category to label tests which require the Cloudant service
+ * JUnit tag to label tests which require the Cloudant service
*/
-public class RequiresCloudantService extends RequiresCloudant {
+@Target({ElementType.TYPE, ElementType.METHOD})
+@Retention(RetentionPolicy.RUNTIME)
+@Tag("RequiresCloudantService")
+@Tag("RequiresCloudant")
+@Tag("RequiresDB")
+public @interface RequiresCloudantService {
}
diff --git a/cloudant-client/src/test/java/com/cloudant/test/main/RequiresCouch.java b/cloudant-client/src/test/java/com/cloudant/test/main/RequiresCouch.java
index b36edcec4..c19a3fec6 100644
--- a/cloudant-client/src/test/java/com/cloudant/test/main/RequiresCouch.java
+++ b/cloudant-client/src/test/java/com/cloudant/test/main/RequiresCouch.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2015 IBM Corp. All rights reserved.
+ * Copyright © 2015, 2018 IBM Corp. All rights reserved.
*
* 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
@@ -14,8 +14,19 @@
package com.cloudant.test.main;
+import org.junit.jupiter.api.Tag;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
/**
- * JUnit category to label tests which require a running DB
+ * JUnit tag to label tests which require a running DB
*/
-public class RequiresCouch extends RequiresDB {
+@Target({ElementType.TYPE, ElementType.METHOD})
+@Retention(RetentionPolicy.RUNTIME)
+@Tag("RequiresCouch")
+@Tag("RequiresDB")
+public @interface RequiresCouch {
}
diff --git a/cloudant-client/src/test/java/com/cloudant/test/main/RequiresDB.java b/cloudant-client/src/test/java/com/cloudant/test/main/RequiresDB.java
index b706bd0df..7d45bb389 100644
--- a/cloudant-client/src/test/java/com/cloudant/test/main/RequiresDB.java
+++ b/cloudant-client/src/test/java/com/cloudant/test/main/RequiresDB.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2015 IBM Corp. All rights reserved.
+ * Copyright © 2015, 2018 IBM Corp. All rights reserved.
*
* 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
@@ -14,8 +14,18 @@
package com.cloudant.test.main;
+import org.junit.jupiter.api.Tag;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
/**
- * JUnit category to label tests which require a running DB
+ * JUnit tag to label tests which require a running DB
*/
-public class RequiresDB {
+@Target({ElementType.TYPE, ElementType.METHOD})
+@Retention(RetentionPolicy.RUNTIME)
+@Tag("RequiresDB")
+public @interface RequiresDB {
}
diff --git a/cloudant-client/src/test/java/com/cloudant/tests/AttachmentsTest.java b/cloudant-client/src/test/java/com/cloudant/tests/AttachmentsTest.java
index 0207ebac1..637093e0b 100644
--- a/cloudant-client/src/test/java/com/cloudant/tests/AttachmentsTest.java
+++ b/cloudant-client/src/test/java/com/cloudant/tests/AttachmentsTest.java
@@ -1,6 +1,6 @@
/*
* Copyright (C) 2011 lightcouch.org
- * Copyright © 2015, 2016 IBM Corp. All rights reserved.
+ * Copyright © 2015, 2018 IBM Corp. All rights reserved.
*
* 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
@@ -14,32 +14,25 @@
*/
package com.cloudant.tests;
-import static org.hamcrest.CoreMatchers.is;
-import static org.junit.Assert.assertArrayEquals;
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.assertNull;
-import static org.junit.Assert.assertTrue;
-import static org.junit.Assert.assertThat;
+import static org.junit.jupiter.api.Assertions.assertArrayEquals;
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertNotNull;
+import static org.junit.jupiter.api.Assertions.assertNull;
+import static org.junit.jupiter.api.Assertions.assertThrows;
+import static org.junit.jupiter.api.Assertions.assertTrue;
-import com.cloudant.client.api.Database;
import com.cloudant.client.api.model.Attachment;
import com.cloudant.client.api.model.Document;
import com.cloudant.client.api.model.Params;
import com.cloudant.client.api.model.Response;
-import com.cloudant.client.internal.DatabaseURIHelper;
import com.cloudant.test.main.RequiresDB;
-import com.cloudant.tests.util.CloudantClientResource;
-import com.cloudant.tests.util.DatabaseResource;
+import com.cloudant.tests.base.TestWithDbPerClass;
import com.cloudant.tests.util.Utils;
import org.apache.commons.codec.binary.Base64;
import org.apache.commons.io.IOUtils;
-import org.junit.BeforeClass;
-import org.junit.ClassRule;
-import org.junit.Test;
-import org.junit.experimental.categories.Category;
-import org.junit.rules.RuleChain;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.function.Executable;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
@@ -47,21 +40,8 @@
import java.io.InputStream;
import java.net.URISyntaxException;
-@Category(RequiresDB.class)
-public class AttachmentsTest {
-
- public static CloudantClientResource clientResource = new CloudantClientResource();
- public static DatabaseResource dbResource = new DatabaseResource(clientResource);
- @ClassRule
- public static RuleChain chain = RuleChain.outerRule(clientResource).around(dbResource);
-
- private static Database db;
-
- @BeforeClass
- public static void setUp() {
- db = dbResource.get();
- }
-
+@RequiresDB
+public class AttachmentsTest extends TestWithDbPerClass {
@Test
public void attachmentInline() {
@@ -177,9 +157,9 @@ public void addNewAttachmentToExistingDocument() throws Exception {
Response attResponse = db.saveAttachment(bytesIn, "foo.txt", "text/plain", response.getId
(), response.getRev());
- assertEquals("The document ID should be the same", response.getId(), attResponse.getId());
- assertTrue("The response code should be a 20x", attResponse.getStatusCode() / 100 == 2);
- assertNull("There should be no error saving the attachment", attResponse.getError());
+ assertEquals(response.getId(), attResponse.getId(), "The document ID should be the same");
+ assertTrue(attResponse.getStatusCode() / 100 == 2, "The response code should be a 20x");
+ assertNull(attResponse.getError(), "There should be no error saving the attachment");
// Assert the attachment is correct
Document doc = db.find(Document.class, response.getId(), attResponse.getRev());
@@ -227,7 +207,7 @@ public void attachmentStandaloneGivenId() throws IOException, URISyntaxException
// Save the attachment to a doc with the given ID
Response response = db.saveAttachment(bytesIn, "foo.txt", "text/plain", docId, null);
- assertEquals("The saved document ID should match", docId, response.getId());
+ assertEquals(docId, response.getId(), "The saved document ID should match");
InputStream in = db.getAttachment(docId, "foo.txt");
@@ -241,26 +221,43 @@ public void attachmentStandaloneGivenId() throws IOException, URISyntaxException
}
}
- @Test(expected = IllegalArgumentException.class)
+ @Test
public void attachmentStandaloneNullDocNonNullRev() {
- byte[] bytesToDB = "binary data".getBytes();
- ByteArrayInputStream bytesIn = new ByteArrayInputStream(bytesToDB);
- Response response = db.saveAttachment(bytesIn, "foo.txt", "text/plain", null, "1-abcdef");
+ assertThrows(IllegalArgumentException.class, new Executable() {
+ @Override
+ public void execute() throws Throwable {
+ byte[] bytesToDB = "binary data".getBytes();
+ ByteArrayInputStream bytesIn = new ByteArrayInputStream(bytesToDB);
+ Response response = db.saveAttachment(bytesIn, "foo.txt", "text/plain", null,
+ "1-abcdef");
+ }
+ });
}
- @Test(expected = IllegalArgumentException.class)
+ @Test
public void attachmentStandaloneEmptyDocId() {
- byte[] bytesToDB = "binary data".getBytes();
- ByteArrayInputStream bytesIn = new ByteArrayInputStream(bytesToDB);
- Response response = db.saveAttachment(bytesIn, "foo.txt", "text/plain", "", "1-abcdef");
+ assertThrows(IllegalArgumentException.class, new Executable() {
+ @Override
+ public void execute() throws Throwable {
+ byte[] bytesToDB = "binary data".getBytes();
+ ByteArrayInputStream bytesIn = new ByteArrayInputStream(bytesToDB);
+ Response response = db.saveAttachment(bytesIn, "foo.txt", "text/plain", "",
+ "1-abcdef");
+ }
+ });
}
- @Test(expected = IllegalArgumentException.class)
+ @Test
public void attachmentStandaloneDocIdEmptyRev() {
- String docId = Utils.generateUUID();
- byte[] bytesToDB = "binary data".getBytes();
- ByteArrayInputStream bytesIn = new ByteArrayInputStream(bytesToDB);
- Response response = db.saveAttachment(bytesIn, "foo.txt", "text/plain", docId, "");
+ assertThrows(IllegalArgumentException.class, new Executable() {
+ @Override
+ public void execute() throws Throwable {
+ String docId = Utils.generateUUID();
+ byte[] bytesToDB = "binary data".getBytes();
+ ByteArrayInputStream bytesIn = new ByteArrayInputStream(bytesToDB);
+ Response response = db.saveAttachment(bytesIn, "foo.txt", "text/plain", docId, "");
+ }
+ });
}
@Test
@@ -284,23 +281,38 @@ public void removeAttachment() {
assertNull(bar3.getAttachments());
}
- @Test(expected = IllegalArgumentException.class)
+ @Test
public void removeAttachmentNullIdNonNullRev() {
- String attachmentName = "txt_1.txt";
- Response response = db.removeAttachment(null, "1-abcdef", attachmentName);
+ assertThrows(IllegalArgumentException.class, new Executable() {
+ @Override
+ public void execute() throws Throwable {
+ String attachmentName = "txt_1.txt";
+ Response response = db.removeAttachment(null, "1-abcdef", attachmentName);
+ }
+ });
}
- @Test(expected = IllegalArgumentException.class)
+ @Test
public void removeAttachmentNonNullIdNullRev() {
- String docId = Utils.generateUUID();
- String attachmentName = "txt_1.txt";
- Response response = db.removeAttachment(docId, null, attachmentName);
+ assertThrows(IllegalArgumentException.class, new Executable() {
+ @Override
+ public void execute() throws Throwable {
+ String docId = Utils.generateUUID();
+ String attachmentName = "txt_1.txt";
+ Response response = db.removeAttachment(docId, null, attachmentName);
+ }
+ });
}
- @Test(expected = IllegalArgumentException.class)
+ @Test
public void removeAttachmentNonNullIdNonNullRevNullAttachmentName() {
- String docId = Utils.generateUUID();
- String rev = "1-abcdef";
- Response response = db.removeAttachment(docId, rev, null);
+ assertThrows(IllegalArgumentException.class, new Executable() {
+ @Override
+ public void execute() throws Throwable {
+ String docId = Utils.generateUUID();
+ String rev = "1-abcdef";
+ Response response = db.removeAttachment(docId, rev, null);
+ }
+ });
}
}
diff --git a/cloudant-client/src/test/java/com/cloudant/tests/BulkDocumentTest.java b/cloudant-client/src/test/java/com/cloudant/tests/BulkDocumentTest.java
index d704f8646..6fd1ac28f 100644
--- a/cloudant-client/src/test/java/com/cloudant/tests/BulkDocumentTest.java
+++ b/cloudant-client/src/test/java/com/cloudant/tests/BulkDocumentTest.java
@@ -1,6 +1,6 @@
/*
* Copyright (C) 2011 lightcouch.org
- * Copyright (c) 2015 IBM Corp. All rights reserved.
+ * Copyright © 2015, 2018 IBM Corp. All rights reserved.
*
* 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
@@ -15,39 +15,20 @@
package com.cloudant.tests;
import static org.hamcrest.CoreMatchers.is;
-import static org.junit.Assert.assertThat;
+import static org.hamcrest.MatcherAssert.assertThat;
-import com.cloudant.client.api.Database;
import com.cloudant.client.api.model.Response;
import com.cloudant.test.main.RequiresDB;
-import com.cloudant.tests.util.CloudantClientResource;
-import com.cloudant.tests.util.DatabaseResource;
+import com.cloudant.tests.base.TestWithDbPerClass;
import com.google.gson.JsonObject;
-import org.junit.BeforeClass;
-import org.junit.ClassRule;
-import org.junit.Test;
-import org.junit.experimental.categories.Category;
-import org.junit.rules.RuleChain;
+import org.junit.jupiter.api.Test;
import java.util.ArrayList;
import java.util.List;
-@Category(RequiresDB.class)
-public class BulkDocumentTest {
-
- public static CloudantClientResource clientResource = new CloudantClientResource();
- public static DatabaseResource dbResource = new DatabaseResource(clientResource);
- @ClassRule
- public static RuleChain chain = RuleChain.outerRule(clientResource).around(dbResource);
-
-
- private static Database db;
-
- @BeforeClass
- public static void setUp() {
- db = dbResource.get();
- }
+@RequiresDB
+public class BulkDocumentTest extends TestWithDbPerClass {
@Test
public void bulkModifyDocs() {
diff --git a/cloudant-client/src/test/java/com/cloudant/tests/ChangeNotificationsTest.java b/cloudant-client/src/test/java/com/cloudant/tests/ChangeNotificationsTest.java
index d05687ea1..60338d9dd 100644
--- a/cloudant-client/src/test/java/com/cloudant/tests/ChangeNotificationsTest.java
+++ b/cloudant-client/src/test/java/com/cloudant/tests/ChangeNotificationsTest.java
@@ -1,6 +1,6 @@
/*
* Copyright (C) 2011 lightcouch.org
- * Copyright © 2015, 2016 IBM Corp. All rights reserved.
+ * Copyright © 2015, 2018 IBM Corp. All rights reserved.
*
* 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
@@ -15,10 +15,10 @@
package com.cloudant.tests;
import static org.hamcrest.CoreMatchers.is;
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.assertThat;
-import static org.junit.Assert.assertTrue;
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertNotNull;
+import static org.junit.jupiter.api.Assertions.assertTrue;
import com.cloudant.client.api.Changes;
import com.cloudant.client.api.CloudantClient;
@@ -28,15 +28,13 @@
import com.cloudant.client.api.model.DbInfo;
import com.cloudant.client.api.model.Response;
import com.cloudant.test.main.RequiresDB;
-import com.cloudant.tests.util.CloudantClientResource;
-import com.cloudant.tests.util.DatabaseResource;
+import com.cloudant.tests.base.TestWithDbPerClass;
+import com.cloudant.tests.extensions.MockWebServerExtension;
import com.google.gson.JsonObject;
-import org.junit.Before;
-import org.junit.ClassRule;
-import org.junit.Rule;
-import org.junit.Test;
-import org.junit.experimental.categories.Category;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.extension.RegisterExtension;
import okhttp3.mockwebserver.MockResponse;
import okhttp3.mockwebserver.MockWebServer;
@@ -45,22 +43,16 @@
import java.util.List;
import java.util.concurrent.TimeUnit;
-@Category(RequiresDB.class)
-public class ChangeNotificationsTest {
+@RequiresDB
+public class ChangeNotificationsTest extends TestWithDbPerClass {
- @ClassRule
- public static CloudantClientResource clientResource = new CloudantClientResource();
- @ClassRule
- public static MockWebServer mockWebServer = new MockWebServer();
+ @RegisterExtension
+ public static MockWebServerExtension mockWebServerExt = new MockWebServerExtension();
+ private static MockWebServer mockWebServer;
- @Rule
- public DatabaseResource dbResource = new DatabaseResource(clientResource);
-
- private Database db;
-
- @Before
+ @BeforeEach
public void setup() {
- db = dbResource.get();
+ mockWebServer = mockWebServerExt.get();
}
@Test
@@ -129,9 +121,10 @@ public void changesDescending() throws Exception {
mockWebServer.enqueue(new MockResponse().setBody("{\"results\": []}"));
db.changes().descending(true).getChanges();
RecordedRequest request = mockWebServer.takeRequest(1, TimeUnit.SECONDS);
- assertNotNull("There should be a changes request", request);
- assertTrue("There should be a descending parameter on the request", request.getPath()
- .contains("descending=true"));
+ assertNotNull(request, "There should be a changes request");
+ assertTrue(request.getPath()
+ .contains("descending=true"), "There should be a descending parameter on the " +
+ "request");
}
/**
@@ -146,11 +139,12 @@ public void changesCustomParameter() throws Exception {
mockWebServer.enqueue(new MockResponse().setBody("{\"results\": []}"));
db.changes().filter("myFilter").parameter("myParam", "paramValue").getChanges();
RecordedRequest request = mockWebServer.takeRequest(1, TimeUnit.SECONDS);
- assertNotNull("There should be a changes request", request);
- assertTrue("There should be a filter parameter on the request", request.getPath()
- .contains("filter=myFilter"));
- assertTrue("There should be a custom parameter on the request", request.getPath()
- .contains("myParam=paramValue"));
+ assertNotNull(request, "There should be a changes request");
+ assertTrue(request.getPath()
+ .contains("filter=myFilter"), "There should be a filter parameter on the request");
+ assertTrue(request.getPath()
+ .contains("myParam=paramValue"), "There should be a custom parameter on the " +
+ "request");
}
/**
@@ -184,13 +178,13 @@ public void changesFeedLastSeq() throws Exception {
Changes c = db.changes().continuousChanges();
int nChanges = 0;
// check against regression where hasNext() will hang
- while(c.hasNext()) {
+ while (c.hasNext()) {
nChanges++;
c.next();
}
RecordedRequest request = mockWebServer.takeRequest(1, TimeUnit.SECONDS);
- assertNotNull("There should be a changes request", request);
- assertEquals("There should be 14 changes", 14, nChanges);
+ assertNotNull(request, "There should be a changes request");
+ assertEquals(14, nChanges, "There should be 14 changes");
}
}
diff --git a/cloudant-client/src/test/java/com/cloudant/tests/ClientLoadTest.java b/cloudant-client/src/test/java/com/cloudant/tests/ClientLoadTest.java
index 2b03e9975..b3a4de5b1 100644
--- a/cloudant-client/src/test/java/com/cloudant/tests/ClientLoadTest.java
+++ b/cloudant-client/src/test/java/com/cloudant/tests/ClientLoadTest.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2015 IBM Corp. All rights reserved.
+ * Copyright © 2015, 2018 IBM Corp. All rights reserved.
*
* 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
@@ -16,21 +16,19 @@
import com.cloudant.client.api.CloudantClient;
import com.cloudant.client.api.Database;
-import com.cloudant.tests.util.CloudantClientResource;
-import com.cloudant.tests.util.DatabaseResource;
-import com.cloudant.tests.util.TestLog;
+import com.cloudant.tests.extensions.CloudantClientExtension;
+import com.cloudant.tests.extensions.DatabaseExtension;
-import org.junit.After;
-import org.junit.BeforeClass;
-import org.junit.ClassRule;
-import org.junit.Ignore;
-import org.junit.Test;
-import org.junit.rules.RuleChain;
+import org.junit.jupiter.api.AfterEach;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Disabled;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.extension.RegisterExtension;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
-@Ignore
+@Disabled
public class ClientLoadTest {
/**
@@ -38,21 +36,18 @@ public class ClientLoadTest {
*/
private static final int MAX_CONNECTIONS = 20;
- @ClassRule
- public static final TestLog log = new TestLog();
-
- public static CloudantClientResource clientResource = new CloudantClientResource
- (CloudantClientHelper.getClientBuilder()
- .maxConnections(MAX_CONNECTIONS));
- public static DatabaseResource dbResource = new DatabaseResource(clientResource);
- @ClassRule
- public static RuleChain chain = RuleChain.outerRule(clientResource).around(dbResource);
+ @RegisterExtension
+ public static CloudantClientExtension clientResource = new CloudantClientExtension(
+ CloudantClientHelper.getClientBuilder().maxConnections(MAX_CONNECTIONS));
+ @RegisterExtension
+ public static DatabaseExtension.PerTest dbResource = new DatabaseExtension.PerTest
+ (clientResource);
private static CloudantClient dbClient;
private static Database db;
- @BeforeClass
- public static void setUp() {
+ @BeforeEach
+ public void setUp() {
dbClient = clientResource.get();
db = dbResource.get();
}
@@ -61,7 +56,7 @@ public static void setUp() {
private static final int DOCS_PER_THREAD = 10;
- @After
+ @AfterEach
public void tearDown() {
dbClient.shutdown();
}
diff --git a/cloudant-client/src/test/java/com/cloudant/tests/CloudFoundryServiceTest.java b/cloudant-client/src/test/java/com/cloudant/tests/CloudFoundryServiceTest.java
index c1969ca54..857c0ff6c 100644
--- a/cloudant-client/src/test/java/com/cloudant/tests/CloudFoundryServiceTest.java
+++ b/cloudant-client/src/test/java/com/cloudant/tests/CloudFoundryServiceTest.java
@@ -1,5 +1,5 @@
/*
- * Copyright © 2016 IBM Corp. All rights reserved.
+ * Copyright © 2016, 2018 IBM Corp. All rights reserved.
*
* 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
@@ -17,7 +17,9 @@
import com.cloudant.client.api.ClientBuilder;
import com.google.gson.GsonBuilder;
-import org.junit.Test;
+import org.junit.jupiter.api.Assertions;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.function.Executable;
import java.util.ArrayList;
import java.util.HashMap;
@@ -87,25 +89,37 @@ public void vcapValidServiceNameSpecified() {
vcap.createNewService("test_bluemix_service_1",
CloudantClientHelper.SERVER_URI_WITH_USER_INFO,
CloudantClientHelper.COUCH_USERNAME, CloudantClientHelper.COUCH_PASSWORD);
- ClientBuilder.bluemix(vcap.toJson(), serviceName, "test_bluemix_service_1").build().serverVersion();
+ ClientBuilder.bluemix(vcap.toJson(), serviceName, "test_bluemix_service_1").build()
+ .serverVersion();
}
- @Test(expected = IllegalArgumentException.class)
+ @Test
public void vcapMissingServiceNameSpecified() {
- VCAPGenerator vcap = new CloudFoundryServiceTest.VCAPGenerator();
- vcap.createNewService("test_bluemix_service_1",
- CloudantClientHelper.SERVER_URI_WITH_USER_INFO,
- CloudantClientHelper.COUCH_USERNAME, CloudantClientHelper.COUCH_PASSWORD);
- ClientBuilder.bluemix(vcap.toJson(), "missingService", "test_bluemix_service_1").build();
+ Assertions.assertThrows(IllegalArgumentException.class, new Executable() {
+ @Override
+ public void execute() throws Throwable {
+ VCAPGenerator vcap = new CloudFoundryServiceTest.VCAPGenerator();
+ vcap.createNewService("test_bluemix_service_1",
+ CloudantClientHelper.SERVER_URI_WITH_USER_INFO,
+ CloudantClientHelper.COUCH_USERNAME, CloudantClientHelper.COUCH_PASSWORD);
+ ClientBuilder.bluemix(vcap.toJson(), "missingService", "test_bluemix_service_1")
+ .build();
+ }
+ });
}
- @Test(expected = IllegalArgumentException.class)
+ @Test
public void vcapNullServiceNameSpecified() {
- VCAPGenerator vcap = new CloudFoundryServiceTest.VCAPGenerator();
- vcap.createNewService("test_bluemix_service_1",
- CloudantClientHelper.SERVER_URI_WITH_USER_INFO,
- CloudantClientHelper.COUCH_USERNAME, CloudantClientHelper.COUCH_PASSWORD);
- ClientBuilder.bluemix(vcap.toJson(), null, "test_bluemix_service_1").build();
+ Assertions.assertThrows(IllegalArgumentException.class, new Executable() {
+ @Override
+ public void execute() throws Throwable {
+ VCAPGenerator vcap = new CloudFoundryServiceTest.VCAPGenerator();
+ vcap.createNewService("test_bluemix_service_1",
+ CloudantClientHelper.SERVER_URI_WITH_USER_INFO,
+ CloudantClientHelper.COUCH_USERNAME, CloudantClientHelper.COUCH_PASSWORD);
+ ClientBuilder.bluemix(vcap.toJson(), null, "test_bluemix_service_1").build();
+ }
+ });
}
@Test
@@ -126,70 +140,119 @@ public void vcapSingleServiceNoNameSpecified() {
ClientBuilder.bluemix(vcap.toJson()).build().serverVersion();
}
- @Test(expected = IllegalArgumentException.class)
+ @Test
public void vcapSingleServiceMissingNamedService() {
- VCAPGenerator vcap = new CloudFoundryServiceTest.VCAPGenerator();
- vcap.createNewService("test_bluemix_service_1","http://foo1.bar", "admin1", "pass1");
- ClientBuilder.bluemix(vcap.toJson(), "test_bluemix_service_2");
+ Assertions.assertThrows(IllegalArgumentException.class, new Executable() {
+ @Override
+ public void execute() throws Throwable {
+ VCAPGenerator vcap = new CloudFoundryServiceTest.VCAPGenerator();
+ vcap.createNewService("test_bluemix_service_1", "http://foo1.bar", "admin1",
+ "pass1");
+ ClientBuilder.bluemix(vcap.toJson(), "test_bluemix_service_2");
+ }
+ });
}
- @Test(expected = IllegalArgumentException.class)
+ @Test
public void vcapSingleServiceEmptyCredentials() {
- VCAPGenerator vcap = new CloudFoundryServiceTest.VCAPGenerator();
- vcap.createNewServiceWithEmptyCredentials("test_bluemix_service_1");
- ClientBuilder.bluemix(vcap.toJson(), "test_bluemix_service_1");
+ Assertions.assertThrows(IllegalArgumentException.class, new Executable() {
+ @Override
+ public void execute() throws Throwable {
+ VCAPGenerator vcap = new CloudFoundryServiceTest.VCAPGenerator();
+ vcap.createNewServiceWithEmptyCredentials("test_bluemix_service_1");
+ ClientBuilder.bluemix(vcap.toJson(), "test_bluemix_service_1");
+ }
+ });
}
@Test
public void vcapMultiService() {
VCAPGenerator vcap = new CloudFoundryServiceTest.VCAPGenerator();
- vcap.createNewService("test_bluemix_service_1","http://foo1.bar", "admin1", "pass1");
- vcap.createNewService("test_bluemix_service_2","http://foo2.bar", "admin2", "pass2");
+ vcap.createNewService("test_bluemix_service_1", "http://foo1.bar", "admin1", "pass1");
+ vcap.createNewService("test_bluemix_service_2", "http://foo2.bar", "admin2", "pass2");
vcap.createNewService("test_bluemix_service_3",
CloudantClientHelper.SERVER_URI_WITH_USER_INFO,
CloudantClientHelper.COUCH_USERNAME, CloudantClientHelper.COUCH_PASSWORD);
ClientBuilder.bluemix(vcap.toJson(), "test_bluemix_service_3").build().serverVersion();
}
- @Test(expected = IllegalArgumentException.class)
+ @Test
public void vcapMultiServiceNoNameSpecified() {
- VCAPGenerator vcap = new CloudFoundryServiceTest.VCAPGenerator();
- vcap.createNewService("test_bluemix_service_1","http://foo1.bar", "admin1", "pass1");
- vcap.createNewService("test_bluemix_service_2","http://foo2.bar", "admin2", "pass2");
- vcap.createNewService("test_bluemix_service_3","http://foo3.bar", "admin3", "pass3");
- ClientBuilder.bluemix(vcap.toJson());
+ Assertions.assertThrows(IllegalArgumentException.class, new Executable() {
+ @Override
+ public void execute() throws Throwable {
+ VCAPGenerator vcap = new CloudFoundryServiceTest.VCAPGenerator();
+ vcap.createNewService("test_bluemix_service_1", "http://foo1.bar", "admin1",
+ "pass1");
+ vcap.createNewService("test_bluemix_service_2", "http://foo2.bar", "admin2",
+ "pass2");
+ vcap.createNewService("test_bluemix_service_3", "http://foo3.bar", "admin3",
+ "pass3");
+ ClientBuilder.bluemix(vcap.toJson());
+ }
+ });
}
- @Test(expected = IllegalArgumentException.class)
+ @Test
public void vcapMultiServiceMissingNamedService() {
- VCAPGenerator vcap = new CloudFoundryServiceTest.VCAPGenerator();
- vcap.createNewService("test_bluemix_service_1","http://foo1.bar", "admin1", "pass1");
- vcap.createNewService("test_bluemix_service_2","http://foo2.bar", "admin2", "pass2");
- vcap.createNewService("test_bluemix_service_3","http://foo3.bar", "admin3", "pass3");
- ClientBuilder.bluemix(vcap.toJson(), "test_bluemix_service_4");
+ Assertions.assertThrows(IllegalArgumentException.class, new Executable() {
+ @Override
+ public void execute() throws Throwable {
+ VCAPGenerator vcap = new CloudFoundryServiceTest.VCAPGenerator();
+ vcap.createNewService("test_bluemix_service_1", "http://foo1.bar", "admin1",
+ "pass1");
+ vcap.createNewService("test_bluemix_service_2", "http://foo2.bar", "admin2",
+ "pass2");
+ vcap.createNewService("test_bluemix_service_3", "http://foo3.bar", "admin3",
+ "pass3");
+ ClientBuilder.bluemix(vcap.toJson(), "test_bluemix_service_4");
+ }
+ });
}
- @Test(expected = IllegalArgumentException.class)
+ @Test
public void vcapMultiServiceEmptyCredentials() {
- VCAPGenerator vcap = new CloudFoundryServiceTest.VCAPGenerator();
- vcap.createNewService("test_bluemix_service_1","http://foo1.bar", "admin1", "pass1");
- vcap.createNewService("test_bluemix_service_2","http://foo2.bar", "admin2", "pass2");
- vcap.createNewServiceWithEmptyCredentials("test_bluemix_service_3");
- ClientBuilder.bluemix(vcap.toJson(), "test_bluemix_service_3");
+ Assertions.assertThrows(IllegalArgumentException.class, new Executable() {
+ @Override
+ public void execute() throws Throwable {
+ VCAPGenerator vcap = new CloudFoundryServiceTest.VCAPGenerator();
+ vcap.createNewService("test_bluemix_service_1", "http://foo1.bar", "admin1",
+ "pass1");
+ vcap.createNewService("test_bluemix_service_2", "http://foo2.bar", "admin2",
+ "pass2");
+ vcap.createNewServiceWithEmptyCredentials("test_bluemix_service_3");
+ ClientBuilder.bluemix(vcap.toJson(), "test_bluemix_service_3");
+ }
+ });
}
- @Test(expected = IllegalArgumentException.class)
+ @Test
public void vcapNoServicesPresent() {
- ClientBuilder.bluemix(new CloudFoundryServiceTest.VCAPGenerator().toJson());
+ Assertions.assertThrows(IllegalArgumentException.class, new Executable() {
+ @Override
+ public void execute() throws Throwable {
+ ClientBuilder.bluemix(new CloudFoundryServiceTest.VCAPGenerator().toJson());
+ }
+ });
}
- @Test(expected = IllegalArgumentException.class)
+ @Test
public void vcapInvalidJSON() {
- ClientBuilder.bluemix("{\"cloudantNoSQLDB\":[]"); // invalid JSON
+ Assertions.assertThrows(IllegalArgumentException.class, new Executable() {
+ @Override
+ public void execute() throws Throwable {
+ ClientBuilder.bluemix("{\"cloudantNoSQLDB\":[]"); // invalid JSON
+ }
+ });
}
- @Test(expected = IllegalArgumentException.class)
+ @Test
public void vcapNotPresent() {
- ClientBuilder.bluemix(null);
+ Assertions.assertThrows(IllegalArgumentException.class, new Executable() {
+ @Override
+ public void execute() throws Throwable {
+ ClientBuilder.bluemix(null);
+ }
+ });
}
}
diff --git a/cloudant-client/src/test/java/com/cloudant/tests/CloudantClientHelper.java b/cloudant-client/src/test/java/com/cloudant/tests/CloudantClientHelper.java
index 77912c75b..08b06df89 100644
--- a/cloudant-client/src/test/java/com/cloudant/tests/CloudantClientHelper.java
+++ b/cloudant-client/src/test/java/com/cloudant/tests/CloudantClientHelper.java
@@ -1,5 +1,5 @@
/*
- * Copyright © 2015, 2016 IBM Corp. All rights reserved.
+ * Copyright © 2015, 2018 IBM Corp. All rights reserved.
*
* 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
@@ -16,6 +16,7 @@
import com.cloudant.client.api.ClientBuilder;
import com.cloudant.client.api.CloudantClient;
+
import okhttp3.mockwebserver.MockWebServer;
import java.net.MalformedURLException;
diff --git a/cloudant-client/src/test/java/com/cloudant/tests/CloudantClientTests.java b/cloudant-client/src/test/java/com/cloudant/tests/CloudantClientTests.java
index ddad4e403..0c959fe67 100644
--- a/cloudant-client/src/test/java/com/cloudant/tests/CloudantClientTests.java
+++ b/cloudant-client/src/test/java/com/cloudant/tests/CloudantClientTests.java
@@ -1,534 +1,574 @@
-/*
- * Copyright © 2015, 2017 IBM Corp. All rights reserved.
- *
- * 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.cloudant.tests;
-
-import static com.cloudant.client.org.lightcouch.internal.CouchDbUtil.createPost;
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.assertTrue;
-
-import com.cloudant.client.api.ClientBuilder;
-import com.cloudant.client.api.CloudantClient;
-import com.cloudant.client.api.Database;
-import com.cloudant.client.api.model.ApiKey;
-import com.cloudant.client.api.model.Membership;
-import com.cloudant.client.api.model.Task;
-import com.cloudant.client.org.lightcouch.CouchDbException;
-import com.cloudant.client.org.lightcouch.NoDocumentException;
-import com.cloudant.client.org.lightcouch.PreconditionFailedException;
-import com.cloudant.http.Http;
-import com.cloudant.http.HttpConnection;
-import com.cloudant.http.interceptors.BasicAuthInterceptor;
-import com.cloudant.http.internal.interceptors.UserAgentInterceptor;
-import com.cloudant.test.main.RequiresCloudant;
-import com.cloudant.test.main.RequiresCloudantService;
-import com.cloudant.test.main.RequiresDB;
-import com.cloudant.tests.util.CloudantClientResource;
-import com.cloudant.tests.util.MockWebServerResources;
-import com.cloudant.tests.util.TestLog;
-import com.cloudant.tests.util.Utils;
-
-import org.apache.commons.io.IOUtils;
-import org.junit.ClassRule;
-import org.junit.Rule;
-import org.junit.Test;
-import org.junit.experimental.categories.Category;
-
-import okhttp3.mockwebserver.Dispatcher;
-import okhttp3.mockwebserver.MockResponse;
-import okhttp3.mockwebserver.MockWebServer;
-import okhttp3.mockwebserver.RecordedRequest;
-import okhttp3.mockwebserver.SocketPolicy;
-
-import java.io.ByteArrayInputStream;
-import java.io.File;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.UnsupportedEncodingException;
-import java.net.InetAddress;
-import java.net.ServerSocket;
-import java.net.Socket;
-import java.net.SocketTimeoutException;
-import java.net.URL;
-import java.net.URLClassLoader;
-import java.net.URLEncoder;
-import java.util.List;
-import java.util.concurrent.TimeUnit;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
-
-import javax.net.ServerSocketFactory;
-
-/**
- * Note some tests in this class use Java 1.7 features
- */
-public class CloudantClientTests {
-
- @ClassRule
- public static final TestLog TEST_LOG = new TestLog();
-
- @ClassRule
- public static CloudantClientResource clientResource = new CloudantClientResource();
- private CloudantClient account = clientResource.get();
-
- @Rule
- public MockWebServer server = new MockWebServer();
-
- @Test
- @Category(RequiresCloudantService.class)
- public void apiKey() {
- ApiKey key = account.generateApiKey();
- assertNotNull(key);
- assertNotNull(key.getKey());
- assertNotNull(key.getPassword());
- }
-
- @Test
- @Category(RequiresCloudant.class)
- public void activeTasks() {
- List tasks = account.getActiveTasks();
- assertNotNull(tasks);
- }
-
- @Test
- @Category(RequiresCloudant.class)
- public void membership() {
- Membership mship = account.getMembership();
- assertNotNull(mship);
- assertNotNull(mship.getClusterNodes());
- assertNotNull(mship.getClusterNodes().hasNext());
- assertNotNull(mship.getAllNodes());
- assertNotNull(mship.getAllNodes().hasNext());
- }
-
- @Test
- @Category(RequiresCloudant.class)
- public void cookieTest() {
-
- Membership membership = account.getMembership();
- assertNotNull(membership);
- }
-
- // java-cloudant/n.n.n or java-cloudant/unknown followed by 4 groups of /anything
- private final String userAgentRegex = "java-cloudant/(?:(?:\\d+.\\d+.\\d+))" +
- "(?:/{1}[^/]+){4}";
-
- private final String userAgentUnknownRegex = "cloudant-http/(?:(?:unknown))" +
- "(?:/{1}[^/]+){4}";
-
-
- private final String userAgentFormat = "java-cloudant/version/jvm.version/jvm.vendor/os" +
- ".name/os.arch";
-
- /**
- * Assert that the User-Agent header is of the expected form.
- */
- @Test
- public void testUserAgentHeaderString() throws Exception {
-
- // This doesn't read the a properties file, since the tests do not run from the published
- // jars.
- String userAgentHeader = new UserAgentInterceptor(UserAgentInterceptor.class
- .getClassLoader(),
- "META-INF/com.cloudant.client.properties").getUserAgent();
- assertTrue("The value of the User-Agent header: " + userAgentHeader + " should match the " +
- "format: " + userAgentFormat,
- userAgentHeader.matches(userAgentUnknownRegex));
- }
-
- @Test
- public void testUserAgentHeaderStringFromFile() throws Exception {
- // This doesn't read the a properties file, since the tests do not run from the published
- // jars.
- // Point to the built classes, it's a bit awkward but we need to load the class cleanly
- File f = new File("../cloudant-http/build/classes/main/");
- String userAgentHeader = new UserAgentInterceptor(new URLClassLoader(new URL[]{f.toURI()
- .toURL()}) {
-
- @Override
- public InputStream getResourceAsStream(String name) {
- if (name.equals("META-INF/com.cloudant.client.properties")) {
- try {
- return new ByteArrayInputStream(("user.agent.name=java-cloudant\nuser" +
- ".agent.version=1.6.1").getBytes("UTF-8"));
- } catch (UnsupportedEncodingException e) {
- throw new RuntimeException(e);
- }
- }
- return super.getResourceAsStream(name);
- }
- }, "META-INF/com.cloudant.client.properties").getUserAgent();
- assertTrue("The value of the User-Agent header: " + userAgentHeader + " should match the " +
- "format: " + userAgentFormat,
- userAgentHeader.matches(userAgentRegex));
- }
-
- /**
- * Assert that requests have the User-Agent header added. This test runs a local HTTP server
- * process that can handle a single request to receive the request and validate the header.
- */
- @Test
- public void testUserAgentHeaderIsAddedToRequest() throws Exception {
-
- //send back an OK 200
- server.enqueue(new MockResponse());
-
- //instantiating the client performs a single post request
- CloudantClient client = CloudantClientHelper.newMockWebServerClientBuilder(server)
- .build();
- String response = client.executeRequest(createPost(client.getBaseUri(), null,
- "application/json")).responseAsString();
- assertTrue("There should be no response body on the mock response", response.isEmpty());
-
- //assert that the request had the expected header
- String userAgentHeader = server.takeRequest(10, TimeUnit.SECONDS)
- .getHeader("User-Agent");
- assertNotNull("The User-Agent header should be present on the request",
- userAgentHeader);
- assertTrue("The value of the User-Agent header " + userAgentHeader + " on the request" +
- " should match the format " + userAgentFormat,
- userAgentHeader.matches(userAgentUnknownRegex));
- }
-
- /**
- * Test a NoDocumentException is thrown when trying an operation on a DB that doesn't exist
- */
- @Test(expected = NoDocumentException.class)
- @Category(RequiresDB.class)
- public void nonExistentDatabaseException() {
- //try and get a DB that doesn't exist
- Database db = account.database("not_really_there", false);
- //try an operation against the non-existant DB
- db.info();
- }
-
- /**
- * Validate that no exception bubbles up when trying to create a DB that already exists
- */
- @Test
- @Category(RequiresDB.class)
- public void existingDatabaseCreateException() {
- String id = Utils.generateUUID();
- String dbName = "existing" + id;
- try {
- //create a DB for this test
- account.createDB(dbName);
-
- // Get a database instance using create true for the already existing DB
- account.database(dbName, true);
- } finally {
- //clean up the DB created by this test
- account.deleteDB(dbName);
- }
- }
-
- /**
- * Validate that a PreconditionFailedException is thrown when using the createDB method to
- * create a database that already exists.
- */
- @Test(expected = PreconditionFailedException.class)
- @Category(RequiresDB.class)
- public void existingDatabaseCreateDBException() {
- String id = Utils.generateUUID();
- String dbName = "existing" + id;
- try {
- //create a DB for this test
- account.createDB(dbName);
-
- //do a get with create true for the already existing DB
- account.createDB(dbName);
-
- } finally {
- //clean up the DB created by this test
- account.deleteDB(dbName);
- }
- }
-
- @Test
- public void testDefaultPorts() throws Exception {
- CloudantClient c = null;
-
- c = CloudantClientHelper.newTestAddressClient().build();
-
- assertEquals("The http port should be 80", 80, c.getBaseUri().getPort());
-
-
- c = CloudantClientHelper.newHttpsTestAddressClient().build();
-
- assertEquals("The http port should be 443", 443, c.getBaseUri().getPort());
- }
-
- /**
- * Check that the connection timeout throws a SocketTimeoutException when it can't connect
- * within the timeout.
- */
- @Test(expected = SocketTimeoutException.class)
- public void connectionTimeout() throws Throwable {
- // Do this test on the loopback
- InetAddress loopback = InetAddress.getLoopbackAddress();
- ServerSocket serverSocket = ServerSocketFactory.getDefault().createServerSocket(0, 1,
- loopback);
-
- int port = serverSocket.getLocalPort();
- //block the single connection to our server
- Socket socket = new Socket(loopback.getHostAddress(), port);
-
- //now try to connect, but should timeout because there is no connection available
- try {
- CloudantClient c = ClientBuilder.url(new URL("http", loopback.getHostAddress(), port,
- "")).connectTimeout(100, TimeUnit.MILLISECONDS)
- // Unfortunately openjdk doesn't honour the connect timeout so we set the read
- // timeout as well so that the test doesn't take too long on that platform
- .readTimeout(250, TimeUnit.MILLISECONDS)
- .build();
-
- // Make a request
- c.getAllDbs();
- } catch (CouchDbException e) {
- //unwrap the CouchDbException
- if (e.getCause() != null) {
- //whilst it would be really nice to actually assert that this was a connect
- //exception and not some other SocketTimeoutException there are JVM differences in
- //this respect (i.e. OpenJDK does not appear to distinguish between read/connect)
- //in its exception messages
- throw e.getCause();
- } else {
- throw e;
- }
- } finally {
- //make sure we close the sockets
- IOUtils.closeQuietly(socket);
- IOUtils.closeQuietly(serverSocket);
- }
- }
-
- /**
- * Checks that the read timeout works. The test sets a read timeout of 0.25 s and the mock
- * server thread never sends a response. If things are working
- * correctly then the client should see a SocketTimeoutException for the read.
- */
- @Test(expected = SocketTimeoutException.class)
- public void readTimeout() throws Throwable {
- // Don't respond so the read will timeout
- server.enqueue(new MockResponse().setSocketPolicy(SocketPolicy.NO_RESPONSE));
-
- try {
- CloudantClient c = CloudantClientHelper.newMockWebServerClientBuilder(server)
- .readTimeout(25, TimeUnit.MILLISECONDS).build();
-
- //do a call that expects a response
- c.getAllDbs();
- } catch (CouchDbException e) {
- //unwrap the CouchDbException
- if (e.getCause() != null) {
- throw e.getCause();
- } else {
- throw e;
- }
- }
- }
-
- /**
- * This tests that a CouchDbException is thrown if the user is null, but the password is
- * supplied.
- */
- @Test(expected = CouchDbException.class)
- public void nullUser() throws Exception {
- CloudantClientHelper.newTestAddressClient()
- .password(":0-myPassword")
- .build();
-
- }
-
- /**
- * This tests that a CouchDbException is thrown if the user is supplied, but the password is
- * null.
- */
- @Test(expected = CouchDbException.class)
- public void nullPassword() throws Exception {
- CloudantClientHelper.newTestAddressClient()
- .username("user")
- .build();
- }
-
- /**
- * Test that user info provided in a url is correctly removed and made into user name and
- * password fields.
- */
- @Test
- public void testUserInfoInUrl() throws Exception {
- urlCheck("user", "password");
- }
-
- // A String of all the URI reserved and "unsafe" characters, plus © and an emoji. Encodes to:
- // %21*%27%28%29%3B%3A%40%26%3D%2B%24%2C%2F%3F%23%5B%5D+%22%25
- // -.%3C%3E%5C%5E_%60%7B%7C%7D%7E%C2%A9%F0%9F%94%92
- private static String SPECIALS = "!*'();:@&=+$,/?#[] \"%-.<>\\^_`{|}~©\uD83D\uDD12";
-
- /**
- * Test that user info provided in a url is correctly removed and made into user name and
- * password fields when the user info includes URL encoded characters.
- */
- @Test
- public void testUserInfoInUrlWithSpecials() throws Exception {
- String user = URLEncoder.encode("user" + SPECIALS, "UTF-8");
- String pw = URLEncoder.encode("password" + SPECIALS, "UTF-8");
- urlCheck(user, pw);
- }
-
- /**
- * Test that user info provided via the username and password methods including URL special
- * characters is encoded correctly.
- */
- @Test
- public void testUserInfoWithSpecials() throws Exception {
- String user = "user" + SPECIALS;
- String pw = "password" + SPECIALS;
- credentialsCheck(CloudantClientHelper.newMockWebServerClientBuilder(server).username
- (user).password(pw), URLEncoder.encode(user, "UTF-8"), URLEncoder.encode(pw,
- "UTF-8"));
- }
-
- private static Pattern CREDENTIALS = Pattern.compile("name=([^&]+)&password=(.+)");
-
- private void urlCheck(String encodedUser, String encodedPassword) throws Exception {
- ClientBuilder b = ClientBuilder.url(server.url("").newBuilder().encodedUsername
- (encodedUser).encodedPassword(encodedPassword).build().url());
- credentialsCheck(b, encodedUser, encodedPassword);
- }
-
- private void credentialsCheck(ClientBuilder b, String encodedUser, String encodedPassword)
- throws Exception {
- CloudantClient c = b.build();
-
- server.enqueue(MockWebServerResources.OK_COOKIE);
- server.enqueue(MockWebServerResources.JSON_OK);
-
- HttpConnection conn = c.executeRequest(Http.GET(c.getBaseUri()));
- // Consume response stream and assert ok: true
- String responseStr = conn.responseAsString();
- assertNotNull(responseStr);
-
- // One request to _session then one to get info
- assertEquals("There should be two requests", 2, server.getRequestCount());
-
- // Get the _session request
- RecordedRequest request = server.takeRequest();
- String body = request.getBody().readUtf8();
- // body should be of form:
- // name=YourUserName&password=YourPassword
- Matcher m = CREDENTIALS.matcher(body);
- assertTrue("The _session request should match the regex", m.matches());
- assertEquals("There should be a username group and a password group in the creds", 2, m
- .groupCount());
- assertEquals("The username should match", encodedUser, m.group(1));
- assertEquals("The password should match", encodedPassword, m.group(2));
-
- //ensure that building a URL from it does not throw any exceptions
- new URL(c.getBaseUri().toString());
- }
-
- @Test
- public void sessionDeleteOnShutdown() throws Exception {
- // Mock a 200 OK for the _session DELETE request
- server.enqueue(new MockResponse().setResponseCode(200).setBody("{\"ok\":\"true\"}"));
-
- CloudantClient c = CloudantClientHelper.newMockWebServerClientBuilder(server).build();
- c.shutdown();
-
- RecordedRequest request = server.takeRequest(10, TimeUnit.SECONDS);
- assertEquals("The request method should be DELETE", "DELETE", request.getMethod());
- assertEquals("The request should be to the _session path", "/_session", request.getPath());
- }
-
- /**
- * Test that adding the Basic Authentication interceptor to CloudantClient works.
- */
- @Test
- @Category(RequiresCloudant.class)
- public void testBasicAuth() throws IOException {
- BasicAuthInterceptor interceptor =
- new BasicAuthInterceptor(CloudantClientHelper.COUCH_USERNAME
- + ":" + CloudantClientHelper.COUCH_PASSWORD);
-
- CloudantClient client = ClientBuilder.account(CloudantClientHelper.COUCH_USERNAME)
- .interceptors(interceptor).build();
-
- // Test passes if there are no exceptions
- client.getAllDbs();
- }
-
- /**
- * Test that configuring the Basic Authentication interceptor from credentials and adding to
- * the CloudantClient works.
- */
- @Test
- public void testBasicAuthFromCredentials() throws Exception {
- BasicAuthInterceptor interceptor =
- BasicAuthInterceptor.createFromCredentials("username", "password");
-
- // send back a mock OK 200
- server.enqueue(new MockResponse());
-
- CloudantClient client = CloudantClientHelper.newMockWebServerClientBuilder(server)
- .interceptors(interceptor).build();
-
- client.getAllDbs();
-
- // expected 'username:password'
- assertEquals("Basic dXNlcm5hbWU6cGFzc3dvcmQ=", server.takeRequest().getHeader("Authorization"));
- }
-
- @Test
- public void gatewayStyleURL() throws Exception {
-
- final String gatewayPath = "/gateway";
-
- // Set a dispatcher that returns 200 if the requests have the correct path /gateway/_all_dbs
- // Otherwise return 400.
- server.setDispatcher(new Dispatcher() {
- @Override
- public MockResponse dispatch(RecordedRequest request) throws InterruptedException {
- if (request.getPath().equals(gatewayPath + "/_all_dbs")) {
- return new MockResponse();
- } else {
- return new MockResponse().setResponseCode(400);
- }
- }
- });
-
- // Build a client with a URL that includes a path
- CloudantClient c = ClientBuilder.url(new URL(server.url(gatewayPath).toString())).build();
- // If the request path is wrong this call will return 400 and throw an exception failing the
- // test.
- c.getAllDbs();
-
- // Build a client with a URL that includes a path with a trailing /
- c = ClientBuilder.url(new URL(server.url(gatewayPath + "/").toString())).build();
- // If the request path is wrong this call will return 400 and throw an exception failing the
- // test.
- c.getAllDbs();
- }
-
- /**
- * Assert that a {@code null} URL causes an IllegalArgumentException to be thrown.
- *
- * @throws Exception
- */
- @Test(expected = IllegalArgumentException.class)
- public void nullURLThrowsIAE() throws Exception {
- ClientBuilder.url(null);
- }
-}
+/*
+ * Copyright © 2015, 2018 IBM Corp. All rights reserved.
+ *
+ * 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.cloudant.tests;
+
+import static com.cloudant.client.org.lightcouch.internal.CouchDbUtil.createPost;
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertNotNull;
+import static org.junit.jupiter.api.Assertions.assertThrows;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+
+import com.cloudant.client.api.ClientBuilder;
+import com.cloudant.client.api.CloudantClient;
+import com.cloudant.client.api.Database;
+import com.cloudant.client.api.model.ApiKey;
+import com.cloudant.client.api.model.Membership;
+import com.cloudant.client.api.model.Task;
+import com.cloudant.client.org.lightcouch.CouchDbException;
+import com.cloudant.client.org.lightcouch.NoDocumentException;
+import com.cloudant.client.org.lightcouch.PreconditionFailedException;
+import com.cloudant.http.Http;
+import com.cloudant.http.HttpConnection;
+import com.cloudant.http.interceptors.BasicAuthInterceptor;
+import com.cloudant.http.internal.interceptors.UserAgentInterceptor;
+import com.cloudant.test.main.RequiresCloudant;
+import com.cloudant.test.main.RequiresCloudantService;
+import com.cloudant.test.main.RequiresDB;
+import com.cloudant.tests.base.TestWithDbPerClass;
+import com.cloudant.tests.extensions.MockWebServerExtension;
+import com.cloudant.tests.util.MockWebServerResources;
+import com.cloudant.tests.util.Utils;
+
+import org.apache.commons.io.IOUtils;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.extension.RegisterExtension;
+import org.junit.jupiter.api.function.Executable;
+
+import okhttp3.mockwebserver.Dispatcher;
+import okhttp3.mockwebserver.MockResponse;
+import okhttp3.mockwebserver.MockWebServer;
+import okhttp3.mockwebserver.RecordedRequest;
+import okhttp3.mockwebserver.SocketPolicy;
+
+import java.io.ByteArrayInputStream;
+import java.io.File;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.UnsupportedEncodingException;
+import java.net.InetAddress;
+import java.net.ServerSocket;
+import java.net.Socket;
+import java.net.SocketTimeoutException;
+import java.net.URL;
+import java.net.URLClassLoader;
+import java.net.URLEncoder;
+import java.util.List;
+import java.util.concurrent.TimeUnit;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+import javax.net.ServerSocketFactory;
+
+/**
+ * Note some tests in this class use Java 1.7 features
+ */
+public class CloudantClientTests extends TestWithDbPerClass {
+
+ @RegisterExtension
+ public MockWebServerExtension mockWebServerExt = new MockWebServerExtension();
+
+ public MockWebServer server;
+
+ @BeforeEach
+ public void beforeEach() {
+ server = mockWebServerExt.get();
+ }
+
+ @Test
+ @RequiresCloudantService
+ public void apiKey() {
+ ApiKey key = account.generateApiKey();
+ assertNotNull(key);
+ assertNotNull(key.getKey());
+ assertNotNull(key.getPassword());
+ }
+
+ @Test
+ @RequiresCloudant
+ public void activeTasks() {
+ List tasks = account.getActiveTasks();
+ assertNotNull(tasks);
+ }
+
+ @Test
+ @RequiresCloudant
+ public void membership() {
+ Membership mship = account.getMembership();
+ assertNotNull(mship);
+ assertNotNull(mship.getClusterNodes());
+ assertNotNull(mship.getClusterNodes().hasNext());
+ assertNotNull(mship.getAllNodes());
+ assertNotNull(mship.getAllNodes().hasNext());
+ }
+
+ @Test
+ @RequiresCloudant
+ public void cookieTest() {
+
+ Membership membership = account.getMembership();
+ assertNotNull(membership);
+ }
+
+ // java-cloudant/n.n.n or java-cloudant/unknown followed by 4 groups of /anything
+ private final String userAgentRegex = "java-cloudant/(?:(?:\\d+.\\d+.\\d+))" +
+ "(?:/{1}[^/]+){4}";
+
+ private final String userAgentUnknownRegex = "cloudant-http/(?:(?:unknown))" +
+ "(?:/{1}[^/]+){4}";
+
+
+ private final String userAgentFormat = "java-cloudant/version/jvm.version/jvm.vendor/os" +
+ ".name/os.arch";
+
+ /**
+ * Assert that the User-Agent header is of the expected form.
+ */
+ @Test
+ public void testUserAgentHeaderString() throws Exception {
+
+ // This doesn't read the a properties file, since the tests do not run from the published
+ // jars.
+ String userAgentHeader = new UserAgentInterceptor(UserAgentInterceptor.class
+ .getClassLoader(),
+ "META-INF/com.cloudant.client.properties").getUserAgent();
+ assertTrue(userAgentHeader.matches(userAgentUnknownRegex), "The value of the User-Agent " +
+ "header: " + userAgentHeader + " should match the " + "format: " + userAgentFormat);
+ }
+
+ @Test
+ public void testUserAgentHeaderStringFromFile() throws Exception {
+ // This doesn't read the a properties file, since the tests do not run from the published
+ // jars.
+ // Point to the built classes, it's a bit awkward but we need to load the class cleanly
+ File f = new File("../cloudant-http/build/classes/main/");
+ String userAgentHeader = new UserAgentInterceptor(new URLClassLoader(new URL[]{f.toURI()
+ .toURL()}) {
+
+ @Override
+ public InputStream getResourceAsStream(String name) {
+ if (name.equals("META-INF/com.cloudant.client.properties")) {
+ try {
+ return new ByteArrayInputStream(("user.agent.name=java-cloudant\nuser" +
+ ".agent.version=1.6.1").getBytes("UTF-8"));
+ } catch (UnsupportedEncodingException e) {
+ throw new RuntimeException(e);
+ }
+ }
+ return super.getResourceAsStream(name);
+ }
+ }, "META-INF/com.cloudant.client.properties").getUserAgent();
+ assertTrue(userAgentHeader.matches(userAgentRegex), "The value of the User-Agent header: " +
+ "" + userAgentHeader + " should match the " + "format: " + userAgentFormat);
+ }
+
+ /**
+ * Assert that requests have the User-Agent header added. This test runs a local HTTP server
+ * process that can handle a single request to receive the request and validate the header.
+ */
+ @Test
+ public void testUserAgentHeaderIsAddedToRequest() throws Exception {
+
+ //send back an OK 200
+ server.enqueue(new MockResponse());
+
+ //instantiating the client performs a single post request
+ CloudantClient client = CloudantClientHelper.newMockWebServerClientBuilder(server)
+ .build();
+ String response = client.executeRequest(createPost(client.getBaseUri(), null,
+ "application/json")).responseAsString();
+ assertTrue(response.isEmpty(), "There should be no response body on the mock response");
+
+ //assert that the request had the expected header
+ String userAgentHeader = server.takeRequest(10, TimeUnit.SECONDS)
+ .getHeader("User-Agent");
+ assertNotNull(userAgentHeader, "The User-Agent header should be present on the request");
+ assertTrue(userAgentHeader.matches(userAgentUnknownRegex), "The value of the User-Agent " +
+ "header " + userAgentHeader + " on the request" + " should match the format " +
+ userAgentFormat);
+ }
+
+ /**
+ * Test a NoDocumentException is thrown when trying an operation on a DB that doesn't exist
+ */
+ @Test
+ @RequiresDB
+ public void nonExistentDatabaseException() {
+ assertThrows(NoDocumentException.class, new Executable() {
+ @Override
+ public void execute() throws Throwable {
+ //try and get a DB that doesn't exist
+ Database db = account.database("not_really_there", false);
+ //try an operation against the non-existant DB
+ db.info();
+ }
+ });
+ }
+
+ /**
+ * Validate that no exception bubbles up when trying to create a DB that already exists
+ */
+ @Test
+ @RequiresDB
+ public void existingDatabaseCreateException() {
+ String id = Utils.generateUUID();
+ String dbName = "existing" + id;
+ try {
+ //create a DB for this test
+ account.createDB(dbName);
+
+ // Get a database instance using create true for the already existing DB
+ account.database(dbName, true);
+ } finally {
+ //clean up the DB created by this test
+ account.deleteDB(dbName);
+ }
+ }
+
+ /**
+ * Validate that a PreconditionFailedException is thrown when using the createDB method to
+ * create a database that already exists.
+ */
+ @Test
+ @RequiresDB
+ public void existingDatabaseCreateDBException() {
+ assertThrows(PreconditionFailedException.class, new Executable() {
+ @Override
+ public void execute() throws Throwable {
+
+ String id = Utils.generateUUID();
+ String dbName = "existing" + id;
+ try {
+ //create a DB for this test
+ account.createDB(dbName);
+
+ //do a get with create true for the already existing DB
+ account.createDB(dbName);
+
+ } finally {
+ //clean up the DB created by this test
+ account.deleteDB(dbName);
+ }
+ }
+ });
+ }
+
+ @Test
+ public void testDefaultPorts() throws Exception {
+ CloudantClient c = null;
+
+ c = CloudantClientHelper.newTestAddressClient().build();
+
+ assertEquals(80, c.getBaseUri().getPort(), "The http port should be 80");
+
+
+ c = CloudantClientHelper.newHttpsTestAddressClient().build();
+
+ assertEquals(443, c.getBaseUri().getPort(), "The http port should be 443");
+ }
+
+ /**
+ * Check that the connection timeout throws a SocketTimeoutException when it can't connect
+ * within the timeout.
+ */
+ @Test
+ public void connectionTimeout() throws Throwable {
+ assertThrows(SocketTimeoutException.class, new Executable() {
+ @Override
+ public void execute() throws Throwable {
+
+ // Do this test on the loopback
+ InetAddress loopback = InetAddress.getLoopbackAddress();
+ ServerSocket serverSocket = ServerSocketFactory.getDefault().createServerSocket
+ (0, 1,
+ loopback);
+
+ int port = serverSocket.getLocalPort();
+ //block the single connection to our server
+ Socket socket = new Socket(loopback.getHostAddress(), port);
+
+ //now try to connect, but should timeout because there is no connection available
+ try {
+ CloudantClient c = ClientBuilder.url(new URL("http", loopback.getHostAddress
+ (), port,
+ "")).connectTimeout(100, TimeUnit.MILLISECONDS)
+ // Unfortunately openjdk doesn't honour the connect timeout so we set
+ // the read
+ // timeout as well so that the test doesn't take too long on that
+ // platform
+ .readTimeout(250, TimeUnit.MILLISECONDS)
+ .build();
+
+ // Make a request
+ c.getAllDbs();
+ } catch (CouchDbException e) {
+ //unwrap the CouchDbException
+ if (e.getCause() != null) {
+ //whilst it would be really nice to actually assert that this was a connect
+ //exception and not some other SocketTimeoutException there are JVM
+ // differences in
+ //this respect (i.e. OpenJDK does not appear to distinguish between
+ // read/connect)
+ //in its exception messages
+ throw e.getCause();
+ } else {
+ throw e;
+ }
+ } finally {
+ //make sure we close the sockets
+ IOUtils.closeQuietly(socket);
+ IOUtils.closeQuietly(serverSocket);
+ }
+ }
+ });
+ }
+
+ /**
+ * Checks that the read timeout works. The test sets a read timeout of 0.25 s and the mock
+ * server thread never sends a response. If things are working
+ * correctly then the client should see a SocketTimeoutException for the read.
+ */
+ @Test
+ public void readTimeout() throws Throwable {
+ assertThrows(SocketTimeoutException.class, new Executable() {
+ @Override
+ public void execute() throws Throwable {
+ // Don't respond so the read will timeout
+ server.enqueue(new MockResponse().setSocketPolicy(SocketPolicy.NO_RESPONSE));
+ try {
+ CloudantClient c = CloudantClientHelper.newMockWebServerClientBuilder(server)
+ .readTimeout(25, TimeUnit.MILLISECONDS).build();
+
+ //do a call that expects a response
+ c.getAllDbs();
+ } catch (CouchDbException e) {
+ //unwrap the CouchDbException
+ if (e.getCause() != null) {
+ throw e.getCause();
+ } else {
+ throw e;
+ }
+ }
+ }
+ });
+ }
+
+ /**
+ * This tests that a CouchDbException is thrown if the user is null, but the password is
+ * supplied.
+ */
+ @Test
+ public void nullUser() throws Exception {
+ assertThrows(CouchDbException.class, new Executable() {
+ @Override
+ public void execute() throws Throwable {
+ CloudantClientHelper.newTestAddressClient()
+ .password(":0-myPassword")
+ .build();
+ }
+ });
+ }
+
+ /**
+ * This tests that a CouchDbException is thrown if the user is supplied, but the password is
+ * null.
+ */
+ @Test
+ public void nullPassword() throws Exception {
+ assertThrows(CouchDbException.class, new Executable() {
+ @Override
+ public void execute() throws Throwable {
+ CloudantClientHelper.newTestAddressClient()
+ .username("user")
+ .build();
+ }
+ });
+ }
+
+ /**
+ * Test that user info provided in a url is correctly removed and made into user name and
+ * password fields.
+ */
+ @Test
+ public void testUserInfoInUrl() throws Exception {
+ urlCheck("user", "password");
+ }
+
+ // A String of all the URI reserved and "unsafe" characters, plus © and an emoji. Encodes to:
+ // %21*%27%28%29%3B%3A%40%26%3D%2B%24%2C%2F%3F%23%5B%5D+%22%25
+ // -.%3C%3E%5C%5E_%60%7B%7C%7D%7E%C2%A9%F0%9F%94%92
+ private static String SPECIALS = "!*'();:@&=+$,/?#[] \"%-.<>\\^_`{|}~©\uD83D\uDD12";
+
+ /**
+ * Test that user info provided in a url is correctly removed and made into user name and
+ * password fields when the user info includes URL encoded characters.
+ */
+ @Test
+ public void testUserInfoInUrlWithSpecials() throws Exception {
+ String user = URLEncoder.encode("user" + SPECIALS, "UTF-8");
+ String pw = URLEncoder.encode("password" + SPECIALS, "UTF-8");
+ urlCheck(user, pw);
+ }
+
+ /**
+ * Test that user info provided via the username and password methods including URL special
+ * characters is encoded correctly.
+ */
+ @Test
+ public void testUserInfoWithSpecials() throws Exception {
+ String user = "user" + SPECIALS;
+ String pw = "password" + SPECIALS;
+ credentialsCheck(CloudantClientHelper.newMockWebServerClientBuilder(server).username
+ (user).password(pw), URLEncoder.encode(user, "UTF-8"), URLEncoder.encode(pw,
+ "UTF-8"));
+ }
+
+ private static Pattern CREDENTIALS = Pattern.compile("name=([^&]+)&password=(.+)");
+
+ private void urlCheck(String encodedUser, String encodedPassword) throws Exception {
+ ClientBuilder b = ClientBuilder.url(server.url("").newBuilder().encodedUsername
+ (encodedUser).encodedPassword(encodedPassword).build().url());
+ credentialsCheck(b, encodedUser, encodedPassword);
+ }
+
+ private void credentialsCheck(ClientBuilder b, String encodedUser, String encodedPassword)
+ throws Exception {
+ CloudantClient c = b.build();
+
+ server.enqueue(MockWebServerResources.OK_COOKIE);
+ server.enqueue(MockWebServerResources.JSON_OK);
+
+ HttpConnection conn = c.executeRequest(Http.GET(c.getBaseUri()));
+ // Consume response stream and assert ok: true
+ String responseStr = conn.responseAsString();
+ assertNotNull(responseStr);
+
+ // One request to _session then one to get info
+ assertEquals(2, server.getRequestCount(), "There should be two requests");
+
+ // Get the _session request
+ RecordedRequest request = server.takeRequest();
+ String body = request.getBody().readUtf8();
+ // body should be of form:
+ // name=YourUserName&password=YourPassword
+ Matcher m = CREDENTIALS.matcher(body);
+ assertTrue(m.matches(), "The _session request should match the regex");
+ assertEquals(2, m.groupCount(), "There should be a username group and a password group in" +
+ " the creds");
+ assertEquals(encodedUser, m.group(1), "The username should match");
+ assertEquals(encodedPassword, m.group(2), "The password should match");
+
+ //ensure that building a URL from it does not throw any exceptions
+ new URL(c.getBaseUri().toString());
+ }
+
+ @Test
+ public void sessionDeleteOnShutdown() throws Exception {
+ // Mock a 200 OK for the _session DELETE request
+ server.enqueue(new MockResponse().setResponseCode(200).setBody("{\"ok\":\"true\"}"));
+
+ CloudantClient c = CloudantClientHelper.newMockWebServerClientBuilder(server).build();
+ c.shutdown();
+
+ RecordedRequest request = server.takeRequest(10, TimeUnit.SECONDS);
+ assertEquals("DELETE", request.getMethod(), "The request method should be DELETE");
+ assertEquals("/_session", request.getPath(), "The request should be to the _session path");
+ }
+
+ /**
+ * Test that adding the Basic Authentication interceptor to CloudantClient works.
+ */
+ @Test
+ @RequiresCloudant
+ public void testBasicAuth() throws IOException {
+ BasicAuthInterceptor interceptor =
+ new BasicAuthInterceptor(CloudantClientHelper.COUCH_USERNAME
+ + ":" + CloudantClientHelper.COUCH_PASSWORD);
+
+ CloudantClient client = ClientBuilder.account(CloudantClientHelper.COUCH_USERNAME)
+ .interceptors(interceptor).build();
+
+ // Test passes if there are no exceptions
+ client.getAllDbs();
+ }
+
+ /**
+ * Test that configuring the Basic Authentication interceptor from credentials and adding to
+ * the CloudantClient works.
+ */
+ @Test
+ public void testBasicAuthFromCredentials() throws Exception {
+ BasicAuthInterceptor interceptor =
+ BasicAuthInterceptor.createFromCredentials("username", "password");
+
+ // send back a mock OK 200
+ server.enqueue(new MockResponse());
+
+ CloudantClient client = CloudantClientHelper.newMockWebServerClientBuilder(server)
+ .interceptors(interceptor).build();
+
+ client.getAllDbs();
+
+ // expected 'username:password'
+ assertEquals("Basic dXNlcm5hbWU6cGFzc3dvcmQ=", server.takeRequest().getHeader
+ ("Authorization"));
+ }
+
+ @Test
+ public void gatewayStyleURL() throws Exception {
+
+ final String gatewayPath = "/gateway";
+
+ // Set a dispatcher that returns 200 if the requests have the correct path /gateway/_all_dbs
+ // Otherwise return 400.
+ server.setDispatcher(new Dispatcher() {
+ @Override
+ public MockResponse dispatch(RecordedRequest request) throws InterruptedException {
+ if (request.getPath().equals(gatewayPath + "/_all_dbs")) {
+ return new MockResponse();
+ } else {
+ return new MockResponse().setResponseCode(400);
+ }
+ }
+ });
+
+ // Build a client with a URL that includes a path
+ CloudantClient c = ClientBuilder.url(new URL(server.url(gatewayPath).toString())).build();
+ // If the request path is wrong this call will return 400 and throw an exception failing the
+ // test.
+ c.getAllDbs();
+
+ // Build a client with a URL that includes a path with a trailing /
+ c = ClientBuilder.url(new URL(server.url(gatewayPath + "/").toString())).build();
+ // If the request path is wrong this call will return 400 and throw an exception failing the
+ // test.
+ c.getAllDbs();
+ }
+
+ /**
+ * Assert that a {@code null} URL causes an IllegalArgumentException to be thrown.
+ *
+ * @throws Exception
+ */
+ @Test
+ public void nullURLThrowsIAE() throws Exception {
+ assertThrows(IllegalArgumentException.class, new Executable() {
+ @Override
+ public void execute() throws Throwable {
+ ClientBuilder.url(null);
+ }
+ });
+ }
+}
diff --git a/cloudant-client/src/test/java/com/cloudant/tests/ComplexKeySerializationTest.java b/cloudant-client/src/test/java/com/cloudant/tests/ComplexKeySerializationTest.java
index 34adbc5ad..c7768e92c 100644
--- a/cloudant-client/src/test/java/com/cloudant/tests/ComplexKeySerializationTest.java
+++ b/cloudant-client/src/test/java/com/cloudant/tests/ComplexKeySerializationTest.java
@@ -1,8 +1,8 @@
/*
- * Copyright (c) 2015 IBM Corp. All rights reserved.
+ * Copyright © 2015, 2018 IBM Corp. All rights reserved.
*
* 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 key copy of the License at
+ * except in compliance with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
@@ -14,13 +14,13 @@
package com.cloudant.tests;
-import static org.junit.Assert.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertEquals;
import com.cloudant.client.api.views.Key;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
-import org.junit.Test;
+import org.junit.jupiter.api.Test;
public class ComplexKeySerializationTest {
diff --git a/cloudant-client/src/test/java/com/cloudant/tests/CouchDbUtilTest.java b/cloudant-client/src/test/java/com/cloudant/tests/CouchDbUtilTest.java
index c0a8c02bb..f1f374d24 100644
--- a/cloudant-client/src/test/java/com/cloudant/tests/CouchDbUtilTest.java
+++ b/cloudant-client/src/test/java/com/cloudant/tests/CouchDbUtilTest.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2015 IBM Corp. All rights reserved.
+ * Copyright © 2015, 2018 IBM Corp. All rights reserved.
*
* 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
@@ -15,14 +15,14 @@
package com.cloudant.tests;
-import static org.junit.Assert.assertEquals;
import static com.cloudant.client.org.lightcouch.internal.CouchDbUtil.jsonToObject;
+import static org.junit.jupiter.api.Assertions.assertEquals;
import com.google.gson.Gson;
import com.google.gson.JsonObject;
import com.google.gson.JsonParser;
-import org.junit.Test;
+import org.junit.jupiter.api.Test;
public class CouchDbUtilTest {
diff --git a/cloudant-client/src/test/java/com/cloudant/tests/DBServerTest.java b/cloudant-client/src/test/java/com/cloudant/tests/DBServerTest.java
index 1019859ef..c82e58b0f 100644
--- a/cloudant-client/src/test/java/com/cloudant/tests/DBServerTest.java
+++ b/cloudant-client/src/test/java/com/cloudant/tests/DBServerTest.java
@@ -16,42 +16,20 @@
import static org.hamcrest.CoreMatchers.is;
import static org.hamcrest.CoreMatchers.not;
-import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.assertThat;
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.junit.jupiter.api.Assertions.assertNotNull;
-import com.cloudant.client.api.CloudantClient;
-import com.cloudant.client.api.Database;
import com.cloudant.client.api.model.DbInfo;
import com.cloudant.client.api.model.MetaInformation;
import com.cloudant.test.main.RequiresDB;
-import com.cloudant.tests.util.CloudantClientResource;
-import com.cloudant.tests.util.DatabaseResource;
+import com.cloudant.tests.base.TestWithDbPerClass;
-import org.junit.BeforeClass;
-import org.junit.ClassRule;
-import org.junit.Test;
-import org.junit.experimental.categories.Category;
-import org.junit.rules.RuleChain;
+import org.junit.jupiter.api.Test;
import java.util.List;
-@Category(RequiresDB.class)
-public class DBServerTest {
-
- public static CloudantClientResource clientResource = new CloudantClientResource();
- public static DatabaseResource dbResource = new DatabaseResource(clientResource);
- @ClassRule
- public static RuleChain chain = RuleChain.outerRule(clientResource).around(dbResource);
-
- private static CloudantClient account;
- private static Database db;
-
- @BeforeClass
- public static void setUp() {
- account = clientResource.get();
- db = dbResource.get();
- }
-
+@RequiresDB
+public class DBServerTest extends TestWithDbPerClass {
@Test
public void dbInfo() {
diff --git a/cloudant-client/src/test/java/com/cloudant/tests/DatabaseTest.java b/cloudant-client/src/test/java/com/cloudant/tests/DatabaseTest.java
index aac8db689..5b7b21481 100644
--- a/cloudant-client/src/test/java/com/cloudant/tests/DatabaseTest.java
+++ b/cloudant-client/src/test/java/com/cloudant/tests/DatabaseTest.java
@@ -1,199 +1,201 @@
-/*
- * Copyright © 2015, 2016 IBM Corp. All rights reserved.
- *
- * 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.cloudant.tests;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertNotNull;
-
-import com.cloudant.client.api.CloudantClient;
-import com.cloudant.client.api.Database;
-import com.cloudant.client.api.model.ApiKey;
-import com.cloudant.client.api.model.Permissions;
-import com.cloudant.client.api.model.Shard;
-import com.cloudant.client.org.lightcouch.CouchDbException;
-import com.cloudant.test.main.RequiresCloudant;
-import com.cloudant.test.main.RequiresCloudantLocal;
-import com.cloudant.test.main.RequiresCloudantService;
-import com.cloudant.test.main.RequiresCouch;
-import com.cloudant.test.main.RequiresDB;
-import com.cloudant.tests.util.CloudantClientResource;
-import com.cloudant.tests.util.DatabaseResource;
-import com.cloudant.tests.util.MockWebServerResources;
-import com.google.gson.GsonBuilder;
-
-import org.junit.BeforeClass;
-import org.junit.ClassRule;
-import org.junit.Test;
-import org.junit.experimental.categories.Category;
-import org.junit.rules.RuleChain;
-
-import okhttp3.mockwebserver.MockResponse;
-import okhttp3.mockwebserver.MockWebServer;
-
-import java.net.MalformedURLException;
-import java.util.EnumSet;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-
-@Category(RequiresDB.class)
-public class DatabaseTest {
-
- public static CloudantClientResource clientResource = new CloudantClientResource();
- public static DatabaseResource dbResource = new DatabaseResource(clientResource);
-
- @ClassRule
- public static RuleChain chain = RuleChain.outerRule(clientResource).around(dbResource);
- @ClassRule
- public static MockWebServer mockWebServer = new MockWebServer();
-
- private static Database db;
- private static CloudantClient account;
-
- @BeforeClass
- public static void setUp() throws Exception {
- account = clientResource.get();
- db = dbResource.get();
-
- //replicate animaldb for tests
- com.cloudant.client.api.Replication r = account.replication();
- r.source("http://clientlibs-test.cloudant.com/animaldb");
- r.createTarget(true);
- r.target(dbResource.getDbURIWithUserInfo());
- r.trigger();
- }
-
- @Test
- @Category(RequiresCloudantService.class)
- public void permissions() {
- Map> userPerms = db.getPermissions();
- assertNotNull(userPerms);
- ApiKey key = account.generateApiKey();
- EnumSet p = EnumSet.of(Permissions._reader, Permissions._writer);
- db.setPermissions(key.getKey(), p);
- userPerms = db.getPermissions();
- assertNotNull(userPerms);
- assertEquals(1, userPerms.size());
- assertEquals(p, userPerms.get(key.getKey()));
-
- p = EnumSet.noneOf(Permissions.class);
- db.setPermissions(key.getKey(), p);
- userPerms = db.getPermissions();
- assertNotNull(userPerms);
- assertEquals(1, userPerms.size());
- assertEquals(p, userPerms.get(key.getKey()));
- }
-
- /**
- * Test that when called against a DB that is not a Cloudant service
- * an UnsupportedOperationException is thrown
- */
- @Test(expected = UnsupportedOperationException.class)
- @Category({RequiresCouch.class, RequiresCloudantLocal.class})
- public void testPermissionsException() {
- Map> userPerms = db.getPermissions();
- }
-
- @Test
- public void permissionsParsing() throws Exception {
- CloudantClient client = CloudantClientHelper.newMockWebServerClientBuilder(mockWebServer)
- .build();
- Database db = client.database("notarealdb", false);
-
- // Mock up a request of all permissions
- mockWebServer.enqueue(MockWebServerResources.PERMISSIONS); // for GET _security
- mockWebServer.enqueue(MockWebServerResources.JSON_OK); // for PUT _security
- db.setPermissions("testUsername", EnumSet.allOf(Permissions.class));
-
- // Mock up a failing request
- String testError = "test error";
- String testReason = "test reason";
- mockWebServer.enqueue(MockWebServerResources.PERMISSIONS); // for GET _security
- mockWebServer.enqueue(new MockResponse().setResponseCode(400).setBody("{\"reason\":\"" +
- testReason + "\", \"error\":\"" + testError + "\"}"));
- try {
- db.setPermissions("testUsername", EnumSet.allOf(Permissions.class));
- } catch (CouchDbException e) {
- assertEquals("", testError, e.getError());
- assertEquals("", testReason, e.getReason());
- }
- }
-
- @Test
- @Category(RequiresCloudant.class)
- public void shards() {
- List shards = db.getShards();
- assert (shards.size() > 0);
- for (Shard s : shards) {
- assertNotNull(s.getRange());
- assertNotNull(s.getNodes());
- assertNotNull(s.getNodes().hasNext());
- }
- }
-
- @Test
- @Category(RequiresCloudant.class)
- public void shard() {
- Shard s = db.getShard("snipe");
- assertNotNull(s);
- assertNotNull(s.getRange());
- assertNotNull(s.getNodes());
- assert (s.getNodes().hasNext());
- }
-
-
- @Test
- @Category(RequiresCloudant.class)
- public void QuorumTests() {
-
- db.save(new Animal("human"), 2);
- Animal h = db.find(Animal.class, "human", new com.cloudant.client.api.model.Params()
- .readQuorum(2));
- assertNotNull(h);
- assertEquals("human", h.getId());
-
- db.update(h.setClass("inhuman"), 2);
- h = db.find(Animal.class, "human", new com.cloudant.client.api.model.Params().readQuorum
- (2));
- assertEquals("inhuman", h.getclass());
-
- db.post(new Animal("test"), 2);
- h = db.find(Animal.class, "test", new com.cloudant.client.api.model.Params().readQuorum(3));
- assertEquals("test", h.getId());
-
-
- }
-
- //Test case for issue #31
- @Test
- public void customGsonDeserializerTest() throws MalformedURLException {
- GsonBuilder builder = new GsonBuilder();
- builder.setDateFormat("yyyy-MM-dd'T'HH:mm:ss");
-
- CloudantClient account = CloudantClientHelper.getClientBuilder()
- .gsonBuilder(builder)
- .build();
-
- Database db = account.database(dbResource.getDatabaseName(), false);
-
- Map h = new HashMap();
- h.put("_id", "serializertest");
- h.put("date", "2015-01-23T18:25:43.511Z");
- db.save(h);
-
- db.find(Foo.class, "serializertest"); // should not throw a JsonSyntaxException
-
- }
-}
+/*
+ * Copyright © 2015, 2018 IBM Corp. All rights reserved.
+ *
+ * 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.cloudant.tests;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertNotNull;
+import static org.junit.jupiter.api.Assertions.assertThrows;
+
+import com.cloudant.client.api.CloudantClient;
+import com.cloudant.client.api.Database;
+import com.cloudant.client.api.model.ApiKey;
+import com.cloudant.client.api.model.Permissions;
+import com.cloudant.client.api.model.Shard;
+import com.cloudant.client.org.lightcouch.CouchDbException;
+import com.cloudant.test.main.RequiresCloudant;
+import com.cloudant.test.main.RequiresCloudantLocal;
+import com.cloudant.test.main.RequiresCloudantService;
+import com.cloudant.test.main.RequiresCouch;
+import com.cloudant.test.main.RequiresDB;
+import com.cloudant.tests.base.TestWithDbPerClass;
+import com.cloudant.tests.extensions.MockWebServerExtension;
+import com.cloudant.tests.util.MockWebServerResources;
+import com.google.gson.GsonBuilder;
+
+import org.junit.jupiter.api.BeforeAll;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.extension.RegisterExtension;
+import org.junit.jupiter.api.function.Executable;
+
+import okhttp3.mockwebserver.MockResponse;
+import okhttp3.mockwebserver.MockWebServer;
+
+import java.net.MalformedURLException;
+import java.util.EnumSet;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+@RequiresDB
+public class DatabaseTest extends TestWithDbPerClass {
+
+ @RegisterExtension
+ public static MockWebServerExtension mockWebServerExt = new MockWebServerExtension();
+
+ private static MockWebServer mockWebServer;
+
+ @BeforeEach
+ public void beforeEach() {
+ mockWebServer = mockWebServerExt.get();
+ }
+
+ @BeforeAll
+ public static void beforeAll() throws Exception {
+ //replicate animaldb for tests
+ com.cloudant.client.api.Replication r = account.replication();
+ r.source("https://clientlibs-test.cloudant.com/animaldb");
+ r.createTarget(true);
+ r.target(dbResource.getDbURIWithUserInfo());
+ r.trigger();
+ }
+
+ @Test
+ @RequiresCloudantService
+ public void permissions() {
+ Map> userPerms = db.getPermissions();
+ assertNotNull(userPerms);
+ ApiKey key = account.generateApiKey();
+ EnumSet p = EnumSet.of(Permissions._reader, Permissions._writer);
+ db.setPermissions(key.getKey(), p);
+ userPerms = db.getPermissions();
+ assertNotNull(userPerms);
+ assertEquals(1, userPerms.size());
+ assertEquals(p, userPerms.get(key.getKey()));
+
+ p = EnumSet.noneOf(Permissions.class);
+ db.setPermissions(key.getKey(), p);
+ userPerms = db.getPermissions();
+ assertNotNull(userPerms);
+ assertEquals(1, userPerms.size());
+ assertEquals(p, userPerms.get(key.getKey()));
+ }
+
+ /**
+ * Test that when called against a DB that is not a Cloudant service
+ * an UnsupportedOperationException is thrown
+ */
+ @RequiresCouch
+ @RequiresCloudantLocal
+ public void testPermissionsException() {
+ assertThrows(UnsupportedOperationException.class, new Executable() {
+ @Override
+ public void execute() throws Throwable {
+ Map> userPerms = db.getPermissions();
+ }
+ });
+ }
+
+ @Test
+ public void permissionsParsing() throws Exception {
+ CloudantClient client = CloudantClientHelper.newMockWebServerClientBuilder(mockWebServer)
+ .build();
+ Database db = client.database("notarealdb", false);
+
+ // Mock up a request of all permissions
+ mockWebServer.enqueue(MockWebServerResources.PERMISSIONS); // for GET _security
+ mockWebServer.enqueue(MockWebServerResources.JSON_OK); // for PUT _security
+ db.setPermissions("testUsername", EnumSet.allOf(Permissions.class));
+
+ // Mock up a failing request
+ String testError = "test error";
+ String testReason = "test reason";
+ mockWebServer.enqueue(MockWebServerResources.PERMISSIONS); // for GET _security
+ mockWebServer.enqueue(new MockResponse().setResponseCode(400).setBody("{\"reason\":\"" +
+ testReason + "\", \"error\":\"" + testError + "\"}"));
+ try {
+ db.setPermissions("testUsername", EnumSet.allOf(Permissions.class));
+ } catch (CouchDbException e) {
+ assertEquals(testError, e.getError());
+ assertEquals(testReason, e.getReason());
+ }
+ }
+
+ @Test
+ @RequiresCloudant
+ public void shards() {
+ List shards = db.getShards();
+ assert (shards.size() > 0);
+ for (Shard s : shards) {
+ assertNotNull(s.getRange());
+ assertNotNull(s.getNodes());
+ assertNotNull(s.getNodes().hasNext());
+ }
+ }
+
+ @Test
+ @RequiresCloudant
+ public void shard() {
+ Shard s = db.getShard("snipe");
+ assertNotNull(s);
+ assertNotNull(s.getRange());
+ assertNotNull(s.getNodes());
+ assert (s.getNodes().hasNext());
+ }
+
+
+ @Test
+ @RequiresCloudant
+ public void QuorumTests() {
+
+ db.save(new Animal("human"), 2);
+ Animal h = db.find(Animal.class, "human", new com.cloudant.client.api.model.Params()
+ .readQuorum(2));
+ assertNotNull(h);
+ assertEquals("human", h.getId());
+
+ db.update(h.setClass("inhuman"), 2);
+ h = db.find(Animal.class, "human", new com.cloudant.client.api.model.Params().readQuorum
+ (2));
+ assertEquals("inhuman", h.getclass());
+
+ db.post(new Animal("test"), 2);
+ h = db.find(Animal.class, "test", new com.cloudant.client.api.model.Params().readQuorum(3));
+ assertEquals("test", h.getId());
+
+
+ }
+
+ //Test case for issue #31
+ @Test
+ public void customGsonDeserializerTest() throws MalformedURLException {
+ GsonBuilder builder = new GsonBuilder();
+ builder.setDateFormat("yyyy-MM-dd'T'HH:mm:ss");
+
+ CloudantClient account = CloudantClientHelper.getClientBuilder()
+ .gsonBuilder(builder)
+ .build();
+
+ Database db = account.database(dbResource.getDatabaseName(), false);
+
+ Map h = new HashMap();
+ h.put("_id", "serializertest");
+ h.put("date", "2015-01-23T18:25:43.511Z");
+ db.save(h);
+
+ db.find(Foo.class, "serializertest"); // should not throw a JsonSyntaxException
+
+ }
+}
diff --git a/cloudant-client/src/test/java/com/cloudant/tests/DatabaseURIHelperTest.java b/cloudant-client/src/test/java/com/cloudant/tests/DatabaseURIHelperTest.java
index d4cf83f95..1f732557c 100644
--- a/cloudant-client/src/test/java/com/cloudant/tests/DatabaseURIHelperTest.java
+++ b/cloudant-client/src/test/java/com/cloudant/tests/DatabaseURIHelperTest.java
@@ -1,5 +1,6 @@
-/**
+/*
* Copyright (c) 2015 Cloudant, Inc. All rights reserved.
+ * Copyright © 2018 IBM Corp. All rights reserved.
*
* 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
@@ -17,39 +18,85 @@
import com.cloudant.client.internal.DatabaseURIHelper;
-import org.junit.Assert;
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.junit.runners.Parameterized;
+import org.junit.jupiter.api.Assertions;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.TestTemplate;
+import org.junit.jupiter.api.extension.ExtendWith;
+import org.junit.jupiter.api.extension.Extension;
+import org.junit.jupiter.api.extension.ExtensionContext;
+import org.junit.jupiter.api.extension.ParameterContext;
+import org.junit.jupiter.api.extension.ParameterResolver;
+import org.junit.jupiter.api.extension.TestTemplateInvocationContext;
+import org.junit.jupiter.api.extension.TestTemplateInvocationContextProvider;
import java.net.URI;
import java.net.URISyntaxException;
-import java.util.Arrays;
-import java.util.Collection;
+import java.util.Collections;
import java.util.HashMap;
+import java.util.List;
import java.util.Map;
import java.util.TreeMap;
+import java.util.stream.Stream;
-@RunWith(Parameterized.class)
+@ExtendWith(DatabaseURIHelperTest.ParameterProvider.class)
public class DatabaseURIHelperTest {
- @Parameterized.Parameters
- public static Collection
*/
- @Category(RequiresCloudant.class)
+ @RequiresCloudant
@Test
public void testJsonErrorStreamFromLB() throws Exception {
final AtomicBoolean badHeaderEnabled = new AtomicBoolean(false);
@@ -165,7 +155,8 @@ public void testJsonErrorStreamFromLB() throws Exception {
// Make a good request, which will set up the session etc
HttpConnection d = c.executeRequest(Http.GET(c.getBaseUri()));
d.responseAsString();
- assertTrue("The first request should succeed", d.getConnection().getResponseCode() / 100 == 2);
+ assertTrue(d.getConnection().getResponseCode() / 100 == 2, "The first request should " +
+ "succeed");
// Enable the bad headers and expect the exception on the next request
badHeaderEnabled.set(true);
@@ -174,10 +165,10 @@ public void testJsonErrorStreamFromLB() throws Exception {
} catch (CouchDbException e) {
//we expect a CouchDbException
- assertEquals("The exception should be for a bad request", 400, e.getStatusCode());
+ assertEquals(400, e.getStatusCode(), "The exception should be for a bad request");
- assertNotNull("The exception should have an error set", e.getError());
- assertEquals("The exception error should be bad request", "bad_request", e.getError());
+ assertNotNull(e.getError(), "The exception should have an error set");
+ assertEquals("bad_request", e.getError(), "The exception error should be bad request");
} finally {
// Disable the bad header to allow a clean shutdown
badHeaderEnabled.set(false);
@@ -195,16 +186,16 @@ public void testJsonErrorStreamFromLB() throws Exception {
*/
private void exceptionAsserts(CouchDbException e, int expectedCode, String expectedReason) {
assertExceptionStatusCode(e, expectedCode);
- assertNotNull("The error should not be null", e.getError());
+ assertNotNull(e.getError(), "The error should not be null");
if ("".equals(expectedReason)) {
- assertNotNull("The reason should not be null", e.getReason());
+ assertNotNull(e.getReason(), "The reason should not be null");
} else {
- assertEquals("The reason should be " + expectedReason, expectedReason, e.getReason());
+ assertEquals(expectedReason, e.getReason(), "The reason should be " + expectedReason);
}
}
private void assertExceptionStatusCode(CouchDbException e, int expectedCode) {
- assertEquals("The HTTP status code should be " + expectedCode, expectedCode, e
- .getStatusCode());
+ assertEquals(expectedCode, e.getStatusCode(), "The HTTP status code should be " +
+ expectedCode);
}
}
diff --git a/cloudant-client/src/test/java/com/cloudant/tests/SearchTests.java b/cloudant-client/src/test/java/com/cloudant/tests/SearchTests.java
index d8f1ddfda..d3e1dc895 100644
--- a/cloudant-client/src/test/java/com/cloudant/tests/SearchTests.java
+++ b/cloudant-client/src/test/java/com/cloudant/tests/SearchTests.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2015 IBM Corp. All rights reserved.
+ * Copyright © 2015, 2018 IBM Corp. All rights reserved.
*
* 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
@@ -14,12 +14,10 @@
package com.cloudant.tests;
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.assertTrue;
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertNotNull;
+import static org.junit.jupiter.api.Assertions.assertTrue;
-import com.cloudant.client.api.CloudantClient;
-import com.cloudant.client.api.Database;
import com.cloudant.client.api.DesignDocumentManager;
import com.cloudant.client.api.Search;
import com.cloudant.client.api.model.DesignDocument;
@@ -27,14 +25,10 @@
import com.cloudant.client.api.model.SearchResult.SearchResultRow;
import com.cloudant.client.internal.URIBase;
import com.cloudant.test.main.RequiresCloudant;
-import com.cloudant.tests.util.CloudantClientResource;
-import com.cloudant.tests.util.DatabaseResource;
+import com.cloudant.tests.base.TestWithDbPerClass;
-import org.junit.BeforeClass;
-import org.junit.ClassRule;
-import org.junit.Test;
-import org.junit.experimental.categories.Category;
-import org.junit.rules.RuleChain;
+import org.junit.jupiter.api.BeforeAll;
+import org.junit.jupiter.api.Test;
import java.io.File;
import java.net.URI;
@@ -45,24 +39,12 @@
import java.util.Map;
import java.util.Map.Entry;
-@Category(RequiresCloudant.class)
-public class SearchTests {
+@RequiresCloudant
+public class SearchTests extends TestWithDbPerClass {
- public static CloudantClientResource clientResource = new CloudantClientResource();
- public static DatabaseResource dbResource = new DatabaseResource(clientResource);
-
- @ClassRule
- public static RuleChain chain = RuleChain.outerRule(clientResource).around(dbResource);
-
- private static Database db;
- private static CloudantClient account;
-
- @BeforeClass
+ @BeforeAll
public static void setUp() throws Exception {
- account = clientResource.get();
- db = dbResource.get();
-
- // replciate the animals db for search tests
+ // replicate the animals db for search tests
com.cloudant.client.api.Replication r = account.replication();
r.source("https://clientlibs-test.cloudant.com/animaldb");
r.createTarget(true);
@@ -269,7 +251,8 @@ private void escapingTest(String expectedResult, String query) {
String uriBaseString = account.getBaseUri().toASCIIString();
String expectedUriString = uriBaseString
- + "/animaldb/_design/views101/_search/animals?include_docs=true&q=" + expectedResult;
+ + "/animaldb/_design/views101/_search/animals?include_docs=true&q=" +
+ expectedResult;
String uriString = uri.toASCIIString();
assertEquals(expectedUriString, uriString);
diff --git a/cloudant-client/src/test/java/com/cloudant/tests/SessionInterceptorExpiryTests.java b/cloudant-client/src/test/java/com/cloudant/tests/SessionInterceptorExpiryTests.java
index 243e333c5..dc95cc97a 100644
--- a/cloudant-client/src/test/java/com/cloudant/tests/SessionInterceptorExpiryTests.java
+++ b/cloudant-client/src/test/java/com/cloudant/tests/SessionInterceptorExpiryTests.java
@@ -14,11 +14,11 @@
package com.cloudant.tests;
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.assertNull;
-import static org.junit.Assert.assertTrue;
-import static org.junit.Assert.fail;
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertNotNull;
+import static org.junit.jupiter.api.Assertions.assertNull;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+import static org.junit.jupiter.api.Assertions.fail;
import com.cloudant.http.Http;
import com.cloudant.http.HttpConnection;
@@ -28,47 +28,100 @@
import com.cloudant.http.internal.interceptors.CookieInterceptor;
import com.cloudant.http.internal.interceptors.IamCookieInterceptor;
import com.cloudant.http.internal.ok.OkHttpClientHttpUrlConnectionFactory;
+import com.cloudant.tests.extensions.MockWebServerExtension;
import com.cloudant.tests.util.HttpFactoryParameterizedTest;
import com.cloudant.tests.util.IamSystemPropertyMock;
import com.cloudant.tests.util.MockWebServerResources;
-import org.junit.Before;
-import org.junit.BeforeClass;
-import org.junit.Rule;
-import org.junit.Test;
-import org.junit.runners.Parameterized;
+import org.junit.jupiter.api.BeforeAll;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.TestTemplate;
+import org.junit.jupiter.api.extension.ExtendWith;
+import org.junit.jupiter.api.extension.Extension;
+import org.junit.jupiter.api.extension.ExtensionContext;
+import org.junit.jupiter.api.extension.ParameterContext;
+import org.junit.jupiter.api.extension.ParameterResolver;
+import org.junit.jupiter.api.extension.RegisterExtension;
+import org.junit.jupiter.api.extension.TestTemplateInvocationContext;
+import org.junit.jupiter.api.extension.TestTemplateInvocationContextProvider;
import okhttp3.mockwebserver.MockResponse;
import okhttp3.mockwebserver.MockWebServer;
import okhttp3.mockwebserver.RecordedRequest;
-import java.util.ArrayList;
+import java.util.Collections;
import java.util.List;
import java.util.regex.Pattern;
+import java.util.stream.Stream;
+@ExtendWith(SessionInterceptorExpiryTests.ParameterProvider.class)
public class SessionInterceptorExpiryTests extends HttpFactoryParameterizedTest {
- public static IamSystemPropertyMock iamSystemPropertyMock;
+ static class ParameterProvider implements TestTemplateInvocationContextProvider {
+ @Override
+ public boolean supportsTestTemplate(ExtensionContext context) {
+ return true;
+ }
- @Parameterized.Parameters(name = "Using okhttp: {0} for session path {1}")
- public static List testParams() {
- List tests = new ArrayList(4);
- tests.add(new Object[]{false, "/_session"});
- tests.add(new Object[]{true, "/_session"});
- tests.add(new Object[]{false, "/_iam_session"});
- tests.add(new Object[]{true, "/_iam_session"});
- return tests;
- }
+ @Override
+ public Stream provideTestTemplateInvocationContexts
+ (ExtensionContext context) {
+ return Stream.of(invocationContext(false, "/_iam_session"),
+ invocationContext(false, "/_session"),
+ invocationContext(true, "/_iam_session"),
+ invocationContext(true, "/_session"));
+ }
- // Note Parameter(0) okUsable is inherited
+ public static TestTemplateInvocationContext invocationContext(final boolean okUsable,
+ final String sessionPath) {
+ return new TestTemplateInvocationContext() {
+ @Override
+ public String getDisplayName(int invocationIndex) {
+ return String.format("path:%s,okUsable:%s", sessionPath, okUsable);
+ }
- @Parameterized.Parameter(1)
- public String sessionPath;
+ @Override
+ public List getAdditionalExtensions() {
+ return Collections.singletonList(new ParameterResolver() {
+ @Override
+ public boolean supportsParameter(ParameterContext parameterContext,
+ ExtensionContext extensionContext) {
+ switch (parameterContext.getIndex()) {
+ case 0:
+ return parameterContext.getParameter().getType().equals
+ (boolean.class);
+ case 1:
+ return parameterContext.getParameter().getType().equals
+ (String.class);
+ }
+ return false;
+ }
- @Rule
- public MockWebServer mockWebServer = new MockWebServer();
- @Rule
- public MockWebServer mockIamServer = new MockWebServer();
+ @Override
+ public Object resolveParameter(ParameterContext parameterContext,
+ ExtensionContext extensionContext) {
+ switch (parameterContext.getIndex()) {
+ case 0:
+ return okUsable;
+ case 1:
+ return sessionPath;
+ }
+ return null;
+ }
+ });
+ }
+ };
+ }
+ }
+
+ public static IamSystemPropertyMock iamSystemPropertyMock;
+
+ @RegisterExtension
+ public MockWebServerExtension mockWebServerExt = new MockWebServerExtension();
+ public MockWebServer mockWebServer;
+ @RegisterExtension
+ public MockWebServerExtension mockIamServerExt = new MockWebServerExtension();
+ public MockWebServer mockIamServer;
private HttpConnectionRequestInterceptor rqInterceptor;
private HttpConnectionResponseInterceptor rpInterceptor;
@@ -76,13 +129,16 @@ public static List testParams() {
/**
* Before running this test class setup the property mock.
*/
- @BeforeClass
+ @BeforeAll
public static void setupIamSystemPropertyMock() {
iamSystemPropertyMock = new IamSystemPropertyMock();
}
- @Before
- public void setupSessionInterceptor() {
+ @BeforeEach
+ public void setupSessionInterceptor(boolean okUsable, String sessionPath) {
+ this.mockWebServer = mockWebServerExt.get();
+ this.mockIamServer = mockIamServerExt.get();
+
String baseUrl = mockWebServer.url("").toString();
if (sessionPath.equals("/_session")) {
@@ -102,7 +158,10 @@ public void setupSessionInterceptor() {
}
- private void queueResponses(Long expiry, String cookieValue) {
+ private void queueResponses(boolean okUsable,
+ String sessionPath,
+ Long expiry,
+ String cookieValue) {
// Queue up the session response
String cookieString;
if (sessionPath.equals("/_session")) {
@@ -123,10 +182,13 @@ private void queueResponses(Long expiry, String cookieValue) {
mockWebServer.enqueue(MockWebServerResources.JSON_OK);
}
- private void executeTest(Long expiryTime, String cookieValue) throws Exception {
- queueResponses(expiryTime, cookieValue);
+ private void executeTest(boolean okUsable,
+ String sessionPath,
+ Long expiryTime,
+ String cookieValue) throws Exception {
+ queueResponses(okUsable, sessionPath, expiryTime, cookieValue);
HttpConnection conn = Http.GET(mockWebServer.url("/").url());
- conn.connectionFactory = (okUsable) ? new OkHttpClientHttpUrlConnectionFactory() :
+ conn.connectionFactory = (isOkUsable) ? new OkHttpClientHttpUrlConnectionFactory() :
new DefaultHttpUrlConnectionFactory();
conn.requestInterceptors.add(rqInterceptor);
conn.responseInterceptors.add(rpInterceptor);
@@ -135,36 +197,38 @@ private void executeTest(Long expiryTime, String cookieValue) throws Exception {
// Consume response stream and assert ok: true
String responseStr = conn.responseAsString();
String okPattern = ".*\"ok\"\\s*:\\s*true.*";
- assertTrue("There should be an ok response: " + responseStr, Pattern.compile(okPattern,
- Pattern.DOTALL).matcher(responseStr).matches());
+ assertTrue(Pattern.compile(okPattern, Pattern.DOTALL).matcher(responseStr).matches(),
+ "There should be an ok response: " + responseStr);
// Assert the _session request
RecordedRequest sessionRequest = mockWebServer.takeRequest(MockWebServerResources
.TIMEOUT, MockWebServerResources.TIMEOUT_UNIT);
- assertEquals("The interceptor should make a session request", sessionPath,
- sessionRequest.getPath());
- assertNull("There should be no existing cookie on the session request", sessionRequest
- .getHeader("Cookie"));
+ assertEquals(sessionPath, sessionRequest.getPath(), "The interceptor should make a " +
+ "session request");
+ assertNull(sessionRequest.getHeader("Cookie"), "There should be no existing cookie on the" +
+ " session request");
// Assert the GET request
RecordedRequest getRequest = mockWebServer.takeRequest(MockWebServerResources.TIMEOUT,
MockWebServerResources.TIMEOUT_UNIT);
- assertEquals("The request path should be correct", "/", getRequest.getPath());
- assertNotNull("There should be a cookie on the request", getRequest.getHeader("Cookie"));
- String expectedCookie = ((sessionPath.equals("/_session")) ? MockWebServerResources.AUTH_COOKIE_NAME :
+ assertEquals("/", getRequest.getPath(), "The request path should be correct");
+ assertNotNull(getRequest.getHeader("Cookie"), "There should be a cookie on the request");
+ String expectedCookie = ((sessionPath.equals("/_session")) ? MockWebServerResources
+ .AUTH_COOKIE_NAME :
MockWebServerResources.IAM_COOKIE_NAME) + "=" + cookieValue;
- assertEquals("The cookie should be the correct session type", expectedCookie,
- getRequest.getHeader("Cookie"));
+ assertEquals(expectedCookie, getRequest.getHeader("Cookie"), "The cookie should be the " +
+ "correct session type");
}
/**
* Test the non-expiry case just to validate that things work normally
+ *
* @throws Exception
*/
- @Test
- public void testMakesCookieRequest() throws Exception {
- executeTest(null, MockWebServerResources.EXPECTED_OK_COOKIE);
+ @TestTemplate
+ public void testMakesCookieRequest(boolean okUsable, String sessionPath) throws Exception {
+ executeTest(okUsable, sessionPath, null, MockWebServerResources.EXPECTED_OK_COOKIE);
}
/**
@@ -174,10 +238,12 @@ public void testMakesCookieRequest() throws Exception {
*
* @throws Exception
*/
- @Test
- public void testNewCookieRequestMadeAfterExpiry() throws Exception {
+ @TestTemplate
+ public void testNewCookieRequestMadeAfterExpiry(boolean okUsable, String sessionPath) throws
+ Exception {
// Make a GET request and get a cookie valid for 2 seconds
- executeTest(System.currentTimeMillis() + 2000, MockWebServerResources.EXPECTED_OK_COOKIE);
+ executeTest(okUsable, sessionPath, System.currentTimeMillis() + 2000,
+ MockWebServerResources.EXPECTED_OK_COOKIE);
// Sleep 2 seconds and make another request
// Note 1 second appears to be insufficient probably due to rounding to the nearest second
@@ -186,7 +252,7 @@ public void testNewCookieRequestMadeAfterExpiry() throws Exception {
// Since the Cookie is expired it should follow the same sequence of POST /_session GET /
// If the expired Cookie was retrieved it would only do GET / and the test would fail.
- executeTest(null, MockWebServerResources.EXPECTED_OK_COOKIE_2);
+ executeTest(okUsable, sessionPath, null, MockWebServerResources.EXPECTED_OK_COOKIE_2);
}
}
diff --git a/cloudant-client/src/test/java/com/cloudant/tests/SslAuthenticationTest.java b/cloudant-client/src/test/java/com/cloudant/tests/SslAuthenticationTest.java
index 40651323e..302dc86c3 100644
--- a/cloudant-client/src/test/java/com/cloudant/tests/SslAuthenticationTest.java
+++ b/cloudant-client/src/test/java/com/cloudant/tests/SslAuthenticationTest.java
@@ -1,5 +1,5 @@
/*
- * Copyright © 2015, 2016 IBM Corp. All rights reserved.
+ * Copyright © 2015, 2018 IBM Corp. All rights reserved.
*
* 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
@@ -14,46 +14,101 @@
package com.cloudant.tests;
-import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.assertTrue;
-import static org.junit.Assert.fail;
+import static org.junit.jupiter.api.Assertions.assertNotNull;
+import static org.junit.jupiter.api.Assertions.assertThrows;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+import static org.junit.jupiter.api.Assertions.fail;
import com.cloudant.client.api.CloudantClient;
import com.cloudant.client.org.lightcouch.CouchDbException;
import com.cloudant.test.main.RequiresCloudantService;
-import com.cloudant.tests.util.CloudantClientResource;
-import com.cloudant.tests.util.MockWebServerResources;
+import com.cloudant.tests.extensions.MockWebServerExtension;
import com.cloudant.tests.util.HttpFactoryParameterizedTest;
+import com.cloudant.tests.util.MockWebServerResources;
-import org.junit.Before;
-import org.junit.ClassRule;
-import org.junit.Rule;
-import org.junit.Test;
-import org.junit.experimental.categories.Category;
-import org.junit.runners.Parameterized;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.TestTemplate;
+import org.junit.jupiter.api.extension.ExtendWith;
+import org.junit.jupiter.api.extension.Extension;
+import org.junit.jupiter.api.extension.ExtensionContext;
+import org.junit.jupiter.api.extension.ParameterContext;
+import org.junit.jupiter.api.extension.ParameterResolver;
+import org.junit.jupiter.api.extension.RegisterExtension;
+import org.junit.jupiter.api.extension.TestTemplateInvocationContext;
+import org.junit.jupiter.api.extension.TestTemplateInvocationContextProvider;
+import org.junit.jupiter.api.function.Executable;
import okhttp3.mockwebserver.MockResponse;
import okhttp3.mockwebserver.MockWebServer;
+import java.util.Collections;
+import java.util.List;
+import java.util.stream.Stream;
+
import javax.net.ssl.SSLHandshakeException;
import javax.net.ssl.SSLSocketFactory;
+@ExtendWith(SslAuthenticationTest.ParameterProvider.class)
public class SslAuthenticationTest extends HttpFactoryParameterizedTest {
- @ClassRule
- public static CloudantClientResource dbClientResource = new CloudantClientResource();
- private static CloudantClient dbClient = dbClientResource.get();
+ static class ParameterProvider implements TestTemplateInvocationContextProvider {
+ @Override
+ public boolean supportsTestTemplate(ExtensionContext context) {
+ return true;
+ }
- @Rule
- public MockWebServer server = new MockWebServer();
+ @Override
+ public Stream provideTestTemplateInvocationContexts
+ (ExtensionContext context) {
+ return Stream.of(invocationContext(false),
+ invocationContext(true));
+ }
- @Parameterized.Parameters(name = "Using okhttp: {0}")
- public static Object[] okUsable() {
- return new Object[]{true, false};
+ public static TestTemplateInvocationContext invocationContext(final boolean okUsable) {
+ return new TestTemplateInvocationContext() {
+ @Override
+ public String getDisplayName(int invocationIndex) {
+ return String.format("okUsable:%s", okUsable);
+ }
+
+ @Override
+ public List getAdditionalExtensions() {
+ return Collections.singletonList(new ParameterResolver() {
+ @Override
+ public boolean supportsParameter(ParameterContext parameterContext,
+ ExtensionContext extensionContext) {
+ switch (parameterContext.getIndex()) {
+ case 0:
+ return parameterContext.getParameter().getType().equals
+ (boolean.class);
+ }
+ return false;
+ }
+
+ @Override
+ public Object resolveParameter(ParameterContext parameterContext,
+ ExtensionContext extensionContext) {
+ switch (parameterContext.getIndex()) {
+ case 0:
+ return okUsable;
+ }
+ return null;
+ }
+ });
+ }
+ };
+ }
}
- @Before
- public void getMockWebServer() {
+
+ @RegisterExtension
+ public static MockWebServerExtension mockWebServerExt = new MockWebServerExtension();
+
+ protected MockWebServer server;
+
+ @BeforeEach
+ public void beforeEach() {
+ server = mockWebServerExt.get();
server.useHttps(MockWebServerResources.getSSLSocketFactory(), false);
}
@@ -64,21 +119,20 @@ public void getMockWebServer() {
* @param e the exception.
*/
private static void validateClientAuthenticationException(CouchDbException e) {
- assertNotNull("Expected CouchDbException but got null", e);
+ assertNotNull(e, "Expected CouchDbException but got null");
Throwable t = e.getCause();
- assertTrue("Expected SSLHandshakeException caused by client certificate check but got " +
- t.getClass(),
- t instanceof SSLHandshakeException);
+ assertTrue(t instanceof SSLHandshakeException, "Expected SSLHandshakeException caused by " +
+ "client certificate check but got " + t.getClass());
}
/**
* Connect to the local simple https server with SSL authentication disabled.
*/
- @Test
+ @TestTemplate
public void localSslAuthenticationDisabled() throws Exception {
// Build a client that connects to the mock server with SSL authentication disabled
- dbClient = CloudantClientHelper.newMockWebServerClientBuilder(server)
+ CloudantClient dbClient = CloudantClientHelper.newMockWebServerClientBuilder(server)
.disableSSLAuthentication()
.build();
@@ -95,12 +149,12 @@ public void localSslAuthenticationDisabled() throws Exception {
* Connect to the local simple https server with SSL authentication enabled explicitly.
* This should throw an exception because the SSL authentication fails.
*/
- @Test
+ @TestTemplate
public void localSslAuthenticationEnabled() throws Exception {
CouchDbException thrownException = null;
try {
- dbClient = CloudantClientHelper.newMockWebServerClientBuilder(server)
+ CloudantClient dbClient = CloudantClientHelper.newMockWebServerClientBuilder(server)
.build();
// Queue a 200 OK response
@@ -119,11 +173,11 @@ public void localSslAuthenticationEnabled() throws Exception {
* This shouldn't throw an exception as the Cloudant server has a valid
* SSL certificate, so should be authenticated.
*/
- @Test
- @Category(RequiresCloudantService.class)
+ @TestTemplate
+ @RequiresCloudantService
public void remoteSslAuthenticationEnabledTest() {
- dbClient = CloudantClientHelper.getClientBuilder().build();
+ CloudantClient dbClient = CloudantClientHelper.getClientBuilder().build();
// Make an arbitrary connection to the DB.
dbClient.getAllDbs();
@@ -134,11 +188,11 @@ public void remoteSslAuthenticationEnabledTest() {
/**
* Connect to the remote Cloudant server with SSL Authentication disabled.
*/
- @Test
- @Category(RequiresCloudantService.class)
+ @TestTemplate
+ @RequiresCloudantService
public void remoteSslAuthenticationDisabledTest() {
- dbClient = CloudantClientHelper.getClientBuilder()
+ CloudantClient dbClient = CloudantClientHelper.getClientBuilder()
.disableSSLAuthentication()
.build();
@@ -152,34 +206,44 @@ public void remoteSslAuthenticationDisabledTest() {
* Assert that building a client with a custom SSL factory first, then setting the
* SSL Authentication disabled will throw an IllegalStateException.
*/
- @Test(expected = IllegalStateException.class)
+ @TestTemplate
public void testCustomSSLFactorySSLAuthDisabled() {
+ assertThrows(IllegalStateException.class, new Executable() {
+ @Override
+ public void execute() throws Throwable {
- dbClient = CloudantClientHelper.getClientBuilder()
- .customSSLSocketFactory((SSLSocketFactory) SSLSocketFactory.getDefault())
- .disableSSLAuthentication()
- .build();
+ CloudantClient dbClient = CloudantClientHelper.getClientBuilder()
+ .customSSLSocketFactory((SSLSocketFactory) SSLSocketFactory.getDefault())
+
+ .disableSSLAuthentication()
+ .build();
+ }
+ });
}
/**
* Assert that building a client with SSL Authentication disabled first, then setting
* a custom SSL factory will throw an IllegalStateException.
*/
- @Test(expected = IllegalStateException.class)
+ @TestTemplate
public void testSSLAuthDisabledWithCustomSSLFactory() {
-
- dbClient = CloudantClientHelper.getClientBuilder()
- .disableSSLAuthentication()
- .customSSLSocketFactory((SSLSocketFactory) SSLSocketFactory.getDefault())
- .build();
-
+ assertThrows(IllegalStateException.class, new Executable() {
+ @Override
+ public void execute() throws Throwable {
+
+ CloudantClient dbClient = CloudantClientHelper.getClientBuilder()
+ .disableSSLAuthentication()
+ .customSSLSocketFactory((SSLSocketFactory) SSLSocketFactory.getDefault())
+ .build();
+ }
+ });
}
/**
* Repeat the localSSLAuthenticationDisabled, but with the cookie auth enabled.
* This test validates that the SSL settings also get applied to the cookie interceptor.
*/
- @Test
+ @TestTemplate
public void localSSLAuthenticationDisabledWithCookieAuth() throws Exception {
// Mock up an OK cookie response then an OK response for the getAllDbs()
@@ -187,7 +251,8 @@ public void localSSLAuthenticationDisabledWithCookieAuth() throws Exception {
server.enqueue(new MockResponse()); //OK 200
// Use a username and password to enable the cookie auth interceptor
- dbClient = CloudantClientHelper.newMockWebServerClientBuilder(server).username("user")
+ CloudantClient dbClient = CloudantClientHelper.newMockWebServerClientBuilder(server)
+ .username("user")
.password("password")
.disableSSLAuthentication()
.build();
@@ -199,7 +264,7 @@ public void localSSLAuthenticationDisabledWithCookieAuth() throws Exception {
* Repeat the localSSLAuthenticationEnabled, but with the cookie auth enabled.
* This test validates that the SSL settings also get applied to the cookie interceptor.
*/
- @Test
+ @TestTemplate
public void localSSLAuthenticationEnabledWithCookieAuth() throws Exception {
// Mock up an OK cookie response then an OK response for the getAllDbs()
@@ -207,16 +272,18 @@ public void localSSLAuthenticationEnabledWithCookieAuth() throws Exception {
server.enqueue(new MockResponse()); //OK 200
// Use a username and password to enable the cookie auth interceptor
- dbClient = CloudantClientHelper.newMockWebServerClientBuilder(server).username("user")
+ CloudantClient dbClient = CloudantClientHelper.newMockWebServerClientBuilder(server)
+ .username("user")
.password("password")
.build();
try {
dbClient.getAllDbs();
fail("The SSL authentication failure should result in a CouchDbException");
- } catch(CouchDbException e) {
+ } catch (CouchDbException e) {
validateClientAuthenticationException(e);
}
}
+
}
diff --git a/cloudant-client/src/test/java/com/cloudant/tests/URIBaseTest.java b/cloudant-client/src/test/java/com/cloudant/tests/URIBaseTest.java
index 5b6338ce8..add92b3c4 100644
--- a/cloudant-client/src/test/java/com/cloudant/tests/URIBaseTest.java
+++ b/cloudant-client/src/test/java/com/cloudant/tests/URIBaseTest.java
@@ -1,36 +1,48 @@
+/*
+ * Copyright © 2018 IBM Corp. All rights reserved.
+ *
+ * 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.cloudant.tests;
import com.cloudant.client.api.ClientBuilder;
import com.cloudant.client.api.CloudantClient;
import com.cloudant.client.internal.URIBase;
import com.cloudant.test.main.RequiresDB;
-import com.cloudant.tests.util.CloudantClientResource;
+import com.cloudant.tests.extensions.CloudantClientExtension;
-import org.junit.Assert;
-import org.junit.ClassRule;
-import org.junit.Test;
-import org.junit.experimental.categories.Category;
+import org.junit.jupiter.api.Assertions;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.extension.RegisterExtension;
import java.net.URI;
-@Category(RequiresDB.class)
+@RequiresDB
public class URIBaseTest {
- @ClassRule
- public static CloudantClientResource clientResource = new CloudantClientResource();
+ @RegisterExtension
+ public static CloudantClientExtension clientResource = new CloudantClientExtension();
@Test
public void buildAccountUri_noTrailingPathSeparator() throws Exception {
CloudantClient client = ClientBuilder.url(clientResource.get().getBaseUri().toURL())
.build();
- Assert.assertFalse(client.getBaseUri().toString().endsWith("/"));
+ Assertions.assertFalse(client.getBaseUri().toString().endsWith("/"));
URI clientUri = new URIBase(client.getBaseUri()).build();
- Assert.assertFalse(clientUri.toString().endsWith("/"));
+ Assertions.assertFalse(clientUri.toString().endsWith("/"));
//Check that path is not missing / separators
clientUri = new URIBase(client.getBaseUri()).path("").path("api").path("couch").build();
URI expectedAccountUri = new URI(clientResource.get().getBaseUri().toString()
+ "/api/couch");
- Assert.assertEquals(expectedAccountUri, clientUri);
+ Assertions.assertEquals(expectedAccountUri, clientUri);
}
}
diff --git a/cloudant-client/src/test/java/com/cloudant/tests/UnicodeTest.java b/cloudant-client/src/test/java/com/cloudant/tests/UnicodeTest.java
index c328e8b85..9881ba469 100644
--- a/cloudant-client/src/test/java/com/cloudant/tests/UnicodeTest.java
+++ b/cloudant-client/src/test/java/com/cloudant/tests/UnicodeTest.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2015 IBM Corp. All rights reserved.
+ * Copyright © 2015, 2018 IBM Corp. All rights reserved.
*
* 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
@@ -14,11 +14,8 @@
package com.cloudant.tests;
-import static org.junit.Assert.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertEquals;
-import com.cloudant.client.api.Database;
-import com.cloudant.client.api.query.Field;
-import com.cloudant.client.api.query.Index;
import com.cloudant.client.api.query.JsonIndex;
import com.cloudant.client.api.views.Key;
import com.cloudant.client.internal.DatabaseURIHelper;
@@ -26,18 +23,12 @@
import com.cloudant.http.HttpConnection;
import com.cloudant.test.main.RequiresCloudant;
import com.cloudant.test.main.RequiresDB;
-import com.cloudant.tests.util.CloudantClientResource;
-import com.cloudant.tests.util.DatabaseResource;
-import com.cloudant.tests.util.TestLog;
+import com.cloudant.tests.base.TestWithDbPerTest;
import com.google.gson.JsonObject;
import com.google.gson.JsonParser;
import org.apache.commons.io.IOUtils;
-import org.junit.Before;
-import org.junit.ClassRule;
-import org.junit.Rule;
-import org.junit.Test;
-import org.junit.experimental.categories.Category;
+import org.junit.jupiter.api.Test;
import java.io.BufferedInputStream;
import java.io.IOException;
@@ -52,31 +43,21 @@
import java.util.regex.Matcher;
import java.util.regex.Pattern;
-@Category(RequiresDB.class)
-public class UnicodeTest {
-
- @ClassRule
- public static final TestLog TEST_LOG = new TestLog();
- @ClassRule
- public static final CloudantClientResource clientResource = new CloudantClientResource();
- @Rule
- public final DatabaseResource dbResource = new DatabaseResource(clientResource);
+@RequiresDB
+public class UnicodeTest extends TestWithDbPerTest {
// According to JSON (ECMA-404, section 9 "Strings"):
// - All Unicode characters except those that must be escaped
// (U+0000..U+001F, U+0022, U+005C) may be placed in a string.
// - All Unicode characters may be included as Unicode escapes
// (after conversion to UTF-16).
+ private static final String TESTSTRING_KEY = "teststring";
private static final String TESTSTRING = "Gr\u00fc\u00dfe \u65e5\u672c\u8a9e \uD834\uDD1E.";
private static final String TESTSTRING_ESCAPED = "Gr\\u00fc\\u00dfe \\u65e5\\u672c\\u8a9e " +
"\\uD834\\uDD1E.";
-
- private Database db;
-
- @Before
- public void setup() {
- db = dbResource.get();
- }
+ private static final String EXPECTED_JSON = "{\"_id\":\"" + TESTSTRING_KEY + "\"," +
+ "\"_rev\":\"1-39933759c7250133b6039d94ea09134f\",\"foo\":\"Gr\u00fc\u00dfe " +
+ "\u65e5\u672c\u8a9e \uD834\uDD1E.\"}\n";
// ========================================================================
// REST request utilities.
@@ -262,7 +243,7 @@ private static void closeResponse(HttpConnection response) throws Exception {
*/
@Test
public void testLiteralUnicode() throws Exception {
- URI uri = new DatabaseURIHelper(db.getDBUri()).path("literal").build();
+ URI uri = new DatabaseURIHelper(db.getDBUri()).path(TESTSTRING_KEY).build();
{
HttpConnection conn = Http.PUT(uri, "application/json");
conn.requestProperties.put("Accept", "application/json");
@@ -277,7 +258,7 @@ public void testLiteralUnicode() throws Exception {
clientResource.get().executeRequest(conn);
assertEquals(200, conn.getConnection().getResponseCode());
String result = getPlainTextEntityAsString(conn, uri);
- TEST_LOG.logger.info("testLiteralUnicode: Result as returned in entity: " + result);
+ assertEquals(EXPECTED_JSON, result);
closeResponse(conn);
}
{
@@ -297,7 +278,7 @@ public void testLiteralUnicode() throws Exception {
*/
@Test
public void testEscapedUnicode() throws Exception {
- URI uri = new DatabaseURIHelper(db.getDBUri()).path("escaped").build();
+ URI uri = new DatabaseURIHelper(db.getDBUri()).path(TESTSTRING_KEY).build();
{
HttpConnection conn = Http.PUT(uri, "application/json");
conn.requestProperties.put("Accept", "application/json");
@@ -312,7 +293,7 @@ public void testEscapedUnicode() throws Exception {
clientResource.get().executeRequest(conn);
assertEquals(200, conn.getConnection().getResponseCode());
String result = getPlainTextEntityAsString(conn, uri);
- TEST_LOG.logger.info("testEscapedUnicode: Result as returned in entity: " + result);
+ assertEquals(EXPECTED_JSON, result);
closeResponse(conn);
}
{
@@ -338,7 +319,7 @@ public static class MyObject {
// To reproduce: In Eclipse, use "Run > Run Configurations...", tab "Common",
// panel "Encoding", set the encoding to ISO-8859-1.
@Test
- @Category(RequiresCloudant.class)
+ @RequiresCloudant
public void testUnicodeInObject() throws Exception {
db.createIndex(JsonIndex.builder()
.name("myview")
@@ -346,10 +327,6 @@ public void testUnicodeInObject() throws Exception {
.asc("foo")
.definition());
- // Show the indices.
- for (Index index : db.listIndexes().allIndexes()) {
- TEST_LOG.logger.info(index.toString());
- }
// Create an object.
MyObject object = new MyObject();
object.foo = TESTSTRING;
diff --git a/cloudant-client/src/test/java/com/cloudant/tests/UpdateHandlerTest.java b/cloudant-client/src/test/java/com/cloudant/tests/UpdateHandlerTest.java
index 890a714cd..3e3ec4de3 100644
--- a/cloudant-client/src/test/java/com/cloudant/tests/UpdateHandlerTest.java
+++ b/cloudant-client/src/test/java/com/cloudant/tests/UpdateHandlerTest.java
@@ -1,6 +1,6 @@
/*
* Copyright (C) 2011 lightcouch.org
- * Copyright (c) 2015 IBM Corp. All rights reserved.
+ * Copyright © 2015, 2018 IBM Corp. All rights reserved.
*
* 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
@@ -14,37 +14,24 @@
*/
package com.cloudant.tests;
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.assertTrue;
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertNotNull;
+import static org.junit.jupiter.api.Assertions.assertTrue;
-import com.cloudant.client.api.Database;
import com.cloudant.client.api.model.Params;
import com.cloudant.client.api.model.Response;
import com.cloudant.test.main.RequiresDB;
-import com.cloudant.tests.util.CloudantClientResource;
-import com.cloudant.tests.util.DatabaseResource;
+import com.cloudant.tests.base.TestWithDbPerClass;
import com.cloudant.tests.util.Utils;
-import org.junit.BeforeClass;
-import org.junit.ClassRule;
-import org.junit.Test;
-import org.junit.experimental.categories.Category;
-import org.junit.rules.RuleChain;
+import org.junit.jupiter.api.BeforeAll;
+import org.junit.jupiter.api.Test;
-@Category(RequiresDB.class)
-public class UpdateHandlerTest {
+@RequiresDB
+public class UpdateHandlerTest extends TestWithDbPerClass {
- public static CloudantClientResource clientResource = new CloudantClientResource();
- public static DatabaseResource dbResource = new DatabaseResource(clientResource);
- @ClassRule
- public static RuleChain chain = RuleChain.outerRule(clientResource).around(dbResource);
-
- private static Database db;
-
- @BeforeClass
- public static void setUp() throws Exception {
- db = dbResource.get();
+ @BeforeAll
+ public static void beforeAll() throws Exception {
Utils.putDesignDocs(db);
}
diff --git a/cloudant-client/src/test/java/com/cloudant/tests/ViewPaginationTests.java b/cloudant-client/src/test/java/com/cloudant/tests/ViewPaginationTests.java
index 7275d6091..52529ec37 100644
--- a/cloudant-client/src/test/java/com/cloudant/tests/ViewPaginationTests.java
+++ b/cloudant-client/src/test/java/com/cloudant/tests/ViewPaginationTests.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2015 IBM Corp. All rights reserved.
+ * Copyright © 2015, 2018 IBM Corp. All rights reserved.
*
* 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
@@ -14,68 +14,115 @@
package com.cloudant.tests;
-import static org.junit.Assert.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertEquals;
-import com.cloudant.client.api.Database;
import com.cloudant.client.api.views.Key;
import com.cloudant.client.api.views.ViewRequest;
import com.cloudant.client.api.views.ViewResponse;
+import com.cloudant.test.main.RequiresDB;
+import com.cloudant.tests.base.TestWithDbPerTest;
import com.cloudant.tests.util.CheckPagination;
-import com.cloudant.tests.util.CloudantClientResource;
-import com.cloudant.tests.util.DatabaseResource;
import com.cloudant.tests.util.Utils;
-import org.junit.Before;
-import org.junit.ClassRule;
-import org.junit.Rule;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.junit.runners.Parameterized;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.TestTemplate;
+import org.junit.jupiter.api.extension.ExtendWith;
+import org.junit.jupiter.api.extension.Extension;
+import org.junit.jupiter.api.extension.ExtensionContext;
+import org.junit.jupiter.api.extension.ParameterContext;
+import org.junit.jupiter.api.extension.ParameterResolver;
+import org.junit.jupiter.api.extension.TestTemplateInvocationContext;
+import org.junit.jupiter.api.extension.TestTemplateInvocationContextProvider;
import java.util.ArrayList;
+import java.util.Collections;
import java.util.List;
+import java.util.stream.Stream;
+import java.util.stream.StreamSupport;
-@RunWith(Parameterized.class)
-public class ViewPaginationTests {
+@RequiresDB
+@ExtendWith(ViewPaginationTests.ParameterProvider.class)
+public class ViewPaginationTests extends TestWithDbPerTest {
- /**
- * Parameters for these tests so we run each test multiple times.
- * We run with a single key or a complex key and both ascending and descending.
- */
- @Parameterized.Parameters(name = "Key:{0},Descending:{1},Stateless:{2}")
- public static Iterable data() {
+ static class ParameterProvider implements TestTemplateInvocationContextProvider {
+ @Override
+ public boolean supportsTestTemplate(ExtensionContext context) {
+ return true;
+ }
+
+ @Override
+ public Stream provideTestTemplateInvocationContexts
+ (ExtensionContext context) {
+ return StreamSupport.stream(data().spliterator(), false);
+ }
+
+ public static TestTemplateInvocationContext invocationContext(final CheckPagination.Type
+ type,
+ final boolean descending,
+ final boolean stateless) {
+ return new TestTemplateInvocationContext() {
+ @Override
+ public String getDisplayName(int invocationIndex) {
+ return String.format("Key:%s,Descending:%s,Stateless:%s", type,
+ descending, stateless);
+ }
+
+ @Override
+ public List getAdditionalExtensions() {
+ return Collections.singletonList(new ParameterResolver() {
+ @Override
+ public boolean supportsParameter(ParameterContext parameterContext,
+ ExtensionContext extensionContext) {
+ switch (parameterContext.getIndex()) {
+ case 0:
+ return parameterContext.getParameter().getType().equals
+ (CheckPagination.Type.class);
+ case 1:
+ return parameterContext.getParameter().getType().equals
+ (boolean.class);
+ case 2:
+ return parameterContext.getParameter().getType().equals
+ (boolean.class);
+ }
+ return false;
+ }
+
+ @Override
+ public Object resolveParameter(ParameterContext parameterContext,
+ ExtensionContext extensionContext) {
+ switch (parameterContext.getIndex()) {
+ case 0:
+ return type;
+ case 1:
+ return descending;
+ case 2:
+ return stateless;
+ }
+ return null;
+ }
+ });
+ }
+ };
+ }
+ }
+ public static Iterable data() {
+
+ List contexts = new
+ ArrayList();
boolean[] tf = new boolean[]{true, false};
- List parameters = new ArrayList();
for (CheckPagination.Type type : CheckPagination.Type.values()) {
for (boolean descending : tf) {
for (boolean stateless : tf) {
- parameters.add(new Object[]{type, descending, stateless});
+ contexts.add(ParameterProvider.invocationContext(type, descending, stateless));
}
}
}
- return parameters;
+ return contexts;
}
- @Parameterized.Parameter
- public CheckPagination.Type type;
-
- @Parameterized.Parameter(value = 1)
- public boolean descending;
-
- @Parameterized.Parameter(value = 2)
- public boolean stateless;
-
- @ClassRule
- public static CloudantClientResource clientResource = new CloudantClientResource();
- @Rule
- public DatabaseResource dbResource = new DatabaseResource(clientResource);
-
- private Database db;
-
- @Before
+ @BeforeEach
public void setUp() throws Exception {
- db = dbResource.get();
Utils.putDesignDocs(db);
}
@@ -87,8 +134,10 @@ public void setUp() throws Exception {
* Page forward to the last page, back to the first page, forward to the last page and back to
* the first page.
*/
- @Test
- public void allTheWayInEachDirectionTwice() throws Exception {
+ @TestTemplate
+ public void allTheWayInEachDirectionTwice(CheckPagination.Type type,
+ boolean descending,
+ boolean stateless) throws Exception {
CheckPagination.newTest(type)
.descending(descending)
.docCount(6)
@@ -106,8 +155,10 @@ public void allTheWayInEachDirectionTwice() throws Exception {
* Page forward to the last page, back to the first page, forward to the last page and back to
* the first page.
*/
- @Test
- public void partialLastPageAllTheWayInEachDirectionTwice() throws Exception {
+ @TestTemplate
+ public void partialLastPageAllTheWayInEachDirectionTwice(CheckPagination.Type type,
+ boolean descending,
+ boolean stateless) throws Exception {
CheckPagination.newTest(type)
.descending(descending)
.docCount(5)
@@ -124,8 +175,10 @@ public void partialLastPageAllTheWayInEachDirectionTwice() throws Exception {
*
* Page part way forward, and part way back a few times before paging to the last page.
*/
- @Test
- public void partWayInEachDirection() throws Exception {
+ @TestTemplate
+ public void partWayInEachDirection(CheckPagination.Type type,
+ boolean descending,
+ boolean stateless) throws Exception {
CheckPagination.newTest(type)
.descending(descending)
.docCount(30)
@@ -142,8 +195,10 @@ public void partWayInEachDirection() throws Exception {
*
* Page part way forward, and part way back a few times before paging to the last page.
*/
- @Test
- public void partialLastPagePartWayInEachDirection() throws Exception {
+ @TestTemplate
+ public void partialLastPagePartWayInEachDirection(CheckPagination.Type type,
+ boolean descending,
+ boolean stateless) throws Exception {
CheckPagination.newTest(type)
.descending(descending)
.docCount(28)
@@ -157,21 +212,28 @@ public void partialLastPagePartWayInEachDirection() throws Exception {
* Check that we can page through a view where we use start and end keys.
* Assert that we don't exceed the limits of those keys.
*/
- @Test
- public void startAndEndKeyLimits() throws Exception {
- startAndEndKeyLimits(true);
+ @TestTemplate
+ public void startAndEndKeyLimits(CheckPagination.Type type,
+ boolean descending,
+ boolean stateless) throws Exception {
+ startAndEndKeyLimits(type, descending, stateless, true);
}
/**
* Check that we can page through a view where we use start and end keys.
* Assert that we don't exceed the limits of those keys.
*/
- @Test
- public void startAndEndKeyLimitsExclusiveEnd() throws Exception {
- startAndEndKeyLimits(false);
+ @TestTemplate
+ public void startAndEndKeyLimitsExclusiveEnd(CheckPagination.Type type,
+ boolean descending,
+ boolean stateless) throws Exception {
+ startAndEndKeyLimits(type, descending, stateless, false);
}
- private void startAndEndKeyLimits(boolean inclusiveEnd) throws Exception {
+ private void startAndEndKeyLimits(CheckPagination.Type type,
+ boolean descending,
+ boolean stateless,
+ boolean inclusiveEnd) throws Exception {
//use the CheckPagination to set-up for this test, but we need to do running differently
//since this page is not just simple paging
CheckPagination cp = CheckPagination.newTest(type)
@@ -193,7 +255,7 @@ private void startAndEndKeyLimits(boolean inclusiveEnd) throws Exception {
.newPaginatedRequest(Key.Type.STRING, String.class).reduce(false).descending
(descending).inclusiveEnd(inclusiveEnd).rowsPerPage(4).startKey
(startKey).endKey(endKey).build();
- runStartAndEndKeyLimits(request, startKey, expectedEndKey);
+ runStartAndEndKeyLimits(stateless, request, startKey, expectedEndKey);
} else {
//for multi we will use the creator_created view
Key.ComplexKey startKey = (descending) ? Key.complex("uuid").add(1011) : Key.complex
@@ -207,19 +269,21 @@ private void startAndEndKeyLimits(boolean inclusiveEnd) throws Exception {
.newPaginatedRequest(Key.Type.COMPLEX, String.class).reduce(false).descending
(descending).inclusiveEnd(inclusiveEnd).rowsPerPage(4).startKey
(startKey).endKey(endKey).build();
- runStartAndEndKeyLimits(request, startKey, expectedEndKey);
+ runStartAndEndKeyLimits(stateless, request, startKey, expectedEndKey);
}
}
- private void runStartAndEndKeyLimits(ViewRequest request, T expectedStartKey,
+ private void runStartAndEndKeyLimits(boolean stateless,
+ ViewRequest request,
+ T expectedStartKey,
T expectedEndKey)
throws Exception {
ViewResponse page = request.getResponse();
//check the start key is as expected
- assertEquals("The start key should be " + expectedStartKey, expectedStartKey, page
- .getKeys().get(0));
+ assertEquals(expectedStartKey, page.getKeys().get(0), "The start key should be " +
+ expectedStartKey);
//get the last page
while (page.hasNextPage()) {
@@ -230,10 +294,8 @@ private void runStartAndEndKeyLimits(ViewRequest request, T expec
}
}
//check the end key is as expected
- assertEquals("The end key should be " + expectedEndKey, expectedEndKey, page.getKeys()
- .get(page.getKeys()
- .size()
- - 1));
+ assertEquals(expectedEndKey, page.getKeys().get(page.getKeys().size() - 1), "The end key " +
+ "should be " + expectedEndKey);
//now page backwards and ensure the last key we get is the start key
while (page.hasPreviousPage()) {
@@ -244,7 +306,7 @@ private void runStartAndEndKeyLimits(ViewRequest request, T expec
}
}
//check the start key is as expected
- assertEquals("The start key should be " + expectedStartKey, expectedStartKey, page
- .getKeys().get(0));
+ assertEquals(expectedStartKey, page.getKeys().get(0), "The start key should be " +
+ expectedStartKey);
}
}
diff --git a/cloudant-client/src/test/java/com/cloudant/tests/ViewsTest.java b/cloudant-client/src/test/java/com/cloudant/tests/ViewsTest.java
index 1f4f89f44..d9150d09e 100644
--- a/cloudant-client/src/test/java/com/cloudant/tests/ViewsTest.java
+++ b/cloudant-client/src/test/java/com/cloudant/tests/ViewsTest.java
@@ -1,6 +1,6 @@
/*
* Copyright (C) 2011 lightcouch.org
- * Copyright © 2015, 2016 IBM Corp. All rights reserved.
+ * Copyright © 2015, 2018 IBM Corp. All rights reserved.
*
* 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
@@ -16,13 +16,14 @@
import static org.hamcrest.CoreMatchers.is;
import static org.hamcrest.CoreMatchers.not;
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.assertNull;
-import static org.junit.Assert.assertThat;
-import static org.junit.Assert.assertTrue;
-import static org.junit.Assert.fail;
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertFalse;
+import static org.junit.jupiter.api.Assertions.assertNotNull;
+import static org.junit.jupiter.api.Assertions.assertNull;
+import static org.junit.jupiter.api.Assertions.assertThrows;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+import static org.junit.jupiter.api.Assertions.fail;
import com.cloudant.client.api.CloudantClient;
import com.cloudant.client.api.Database;
@@ -38,21 +39,22 @@
import com.cloudant.http.HttpConnectionInterceptorContext;
import com.cloudant.test.main.RequiresCloudant;
import com.cloudant.test.main.RequiresDB;
-import com.cloudant.tests.util.CloudantClientResource;
+import com.cloudant.tests.base.TestWithDbPerTest;
+import com.cloudant.tests.extensions.CloudantClientExtension;
+import com.cloudant.tests.extensions.DatabaseExtension;
+import com.cloudant.tests.extensions.MockWebServerExtension;
+import com.cloudant.tests.extensions.MultiExtension;
import com.cloudant.tests.util.ContextCollectingInterceptor;
-import com.cloudant.tests.util.DatabaseResource;
import com.cloudant.tests.util.Utils;
import com.google.gson.Gson;
import com.google.gson.JsonArray;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
-import org.junit.Before;
-import org.junit.ClassRule;
-import org.junit.Rule;
-import org.junit.Test;
-import org.junit.experimental.categories.Category;
-import org.junit.rules.RuleChain;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.extension.RegisterExtension;
+import org.junit.jupiter.api.function.Executable;
import okhttp3.mockwebserver.MockResponse;
import okhttp3.mockwebserver.MockWebServer;
@@ -69,30 +71,29 @@
import java.util.concurrent.TimeUnit;
import java.util.regex.Pattern;
-@Category(RequiresDB.class)
-public class ViewsTest {
-
- @ClassRule
- public static CloudantClientResource clientResource = new CloudantClientResource();
- @ClassRule
- public static MockWebServer mockWebServer = new MockWebServer();
-
- @Rule
- public DatabaseResource dbResource = new DatabaseResource(clientResource);
-
-
- private static ContextCollectingInterceptor cci = new ContextCollectingInterceptor();
- public static CloudantClientResource interceptedClient = new CloudantClientResource
- (CloudantClientHelper.getClientBuilder().interceptors(cci));
- public static DatabaseResource interceptedDB = new DatabaseResource(interceptedClient);
- @ClassRule
- public static RuleChain intercepted = RuleChain.outerRule(interceptedClient).around
- (interceptedDB);
- private Database db;
-
- @Before
- public void setUp() throws Exception {
- db = dbResource.get();
+@RequiresDB
+public class ViewsTest extends TestWithDbPerTest {
+
+ public static MockWebServerExtension mockWebServerExt = new MockWebServerExtension();
+ public static ContextCollectingInterceptor cci = new ContextCollectingInterceptor();
+ public static CloudantClientExtension interceptedClient = new CloudantClientExtension
+ (CloudantClientHelper.getClientBuilder()
+ .interceptors(cci));
+ public static DatabaseExtension.PerClass interceptedDB = new DatabaseExtension.PerClass
+ (interceptedClient);
+
+ @RegisterExtension
+ public static MultiExtension extensions = new MultiExtension(
+ mockWebServerExt,
+ interceptedClient,
+ interceptedDB
+ );
+
+ protected MockWebServer mockWebServer;
+
+ @BeforeEach
+ public void beforeEach() throws Exception {
+ mockWebServer = mockWebServerExt.get();
Utils.putDesignDocs(db);
}
@@ -126,10 +127,11 @@ public void byKeys() throws Exception {
public void byNonExistentAndExistingKey() throws Exception {
init();
List> foos = db.getViewRequestBuilder("example", "foo")
- .newRequest(Key.Type.STRING, Object.class).includeDocs(true).keys("key-1", "non-existent")
+ .newRequest(Key.Type.STRING, Object.class).includeDocs(true).keys("key-1",
+ "non-existent")
.build().getResponse().getRows();
assertThat(foos.size(), is(1));
- for (ViewResponse.Row row: foos) {
+ for (ViewResponse.Row row : foos) {
if (row.getError() == null) {
assertThat(row.getKey().toString(), is("key-1"));
} else {
@@ -623,19 +625,18 @@ public void scalarValues() throws Exception {
@Test
public void viewWithNoResult_emptyList() throws IOException {
init();
- assertEquals("The results list should be of length 0", 0, db.getViewRequestBuilder
- ("example", "by_tag").newRequest(Key.Type.STRING, Object.class).keys
- ("javax").build().getResponse().getKeys().size());
+ assertEquals(0, db.getViewRequestBuilder("example", "by_tag").newRequest(Key.Type.STRING,
+ Object.class).keys("javax").build().getResponse().getKeys().size(), "The results " +
+ "list should be of length 0");
}
@Test
public void viewWithNoResult_nullSingleResult() throws IOException {
init();
- assertNull("The single result should be null", db.getViewRequestBuilder("example",
- "by_tag").newRequest(Key.Type.STRING,
- Object.class).keys
- ("javax").build().getSingleValue());
+ assertNull(db.getViewRequestBuilder("example", "by_tag").newRequest(Key.Type.STRING,
+ Object.class).keys("javax").build().getSingleValue(), "The single result should " +
+ "be null");
}
@@ -657,7 +658,7 @@ public void allDocs() throws Exception {
.getIdsAndRevs();
assertThat(idsAndRevs.size(), not(0));
for (Map.Entry doc : idsAndRevs.entrySet()) {
- assertNotNull("The document _rev value should not be null", doc.getValue());
+ assertNotNull(doc.getValue(), "The document _rev value should not be null");
}
}
@@ -694,7 +695,7 @@ public void allDocsWithOneNonExistingKey() throws Exception {
Map idsAndRevs = response.getIdsAndRevs();
assertThat(idsAndRevs.size(), is(1));
for (Map.Entry doc : idsAndRevs.entrySet()) {
- assertNotNull("The document _rev value should not be null", doc.getValue());
+ assertNotNull(doc.getValue(), "The document _rev value should not be null");
}
assertThat(errors.size(), is(1));
@@ -867,7 +868,7 @@ private void assertJsonArrayKeysAndValues(ArrayList expectedJson,
* @throws IOException
*/
@Test
- @Category(RequiresCloudant.class)
+ @RequiresCloudant
public void multiRequest() throws IOException {
init();
ViewMultipleRequest multi = db.getViewRequestBuilder("example", "foo")
@@ -878,11 +879,11 @@ public void multiRequest() throws IOException {
.build();
int i = 1;
List> responses = multi.getViewResponses();
- assertEquals("There should be 3 respones for 3 requests", 3, responses.size());
+ assertEquals(3, responses.size(), "There should be 3 responses for 3 requests");
for (ViewResponse response : responses) {
- assertEquals("There should be 1 row in each response", 1, response.getRows().size());
- assertEquals("The returned key should be key-" + i, "key-" + i, response.getKeys()
- .get(0));
+ assertEquals(1, response.getRows().size(), "There should be 1 row in each response");
+ assertEquals("key-" + i, response.getKeys().get(0), "The returned key should be key-"
+ + i);
i++;
}
}
@@ -949,24 +950,38 @@ public void multiRequestBuildParametersSecond() {
* Validate that an IllegalStateException is thrown if an attempt is made to build a multi
* request without calling add() before build() with two requests.
*/
- @Test(expected = IllegalStateException.class)
+ @Test
public void multiRequestBuildOnlyAfterAdd() {
- ViewMultipleRequest multi = db.getViewRequestBuilder("example", "foo")
- .newMultipleRequest(Key.Type.STRING, Object.class)
- .keys("key-1").add()
- .keys("key-2").build();
+ assertThrows(IllegalStateException.class,
+ new Executable() {
+ @Override
+ public void execute() throws Throwable {
+ ViewMultipleRequest multi = db.getViewRequestBuilder
+ ("example", "foo")
+ .newMultipleRequest(Key.Type.STRING, Object.class)
+ .keys("key-1").add()
+ .keys("key-2").build();
+ }
+ });
}
/**
* Validate that an IllegalStateException is thrown if an attempt is made to build a multi
* request without calling add() before build() with a single request with parameters.
*/
- @Test(expected = IllegalStateException.class)
+ @Test
public void multiRequestBuildOnlyAfterAddSingle() {
- ViewMultipleRequest multi = db.getViewRequestBuilder("example", "foo")
- .newMultipleRequest(Key.Type.STRING, Object.class)
- .keys("key-1")
- .build();
+ assertThrows(IllegalStateException.class,
+ new Executable() {
+ @Override
+ public void execute() throws Throwable {
+ ViewMultipleRequest multi = db.getViewRequestBuilder
+ ("example", "foo")
+ .newMultipleRequest(Key.Type.STRING, Object.class)
+ .keys("key-1")
+ .build();
+ }
+ });
}
/**
@@ -974,11 +989,18 @@ public void multiRequestBuildOnlyAfterAddSingle() {
* request without calling add() before build() with a single request with no view request
* parameter calls.
*/
- @Test(expected = IllegalStateException.class)
+ @Test
public void multiRequestBuildOnlyAfterAddNoParams() {
- ViewMultipleRequest multi = db.getViewRequestBuilder("example", "foo")
- .newMultipleRequest(Key.Type.STRING, Object.class)
- .build();
+ assertThrows(IllegalStateException.class,
+ new Executable() {
+ @Override
+ public void execute() throws Throwable {
+ ViewMultipleRequest multi = db.getViewRequestBuilder
+ ("example", "foo")
+ .newMultipleRequest(Key.Type.STRING, Object.class)
+ .build();
+ }
+ });
}
/**
@@ -988,7 +1010,7 @@ public void multiRequestBuildOnlyAfterAddNoParams() {
* @throws IOException
*/
@Test
- @Category(RequiresCloudant.class)
+ @RequiresCloudant
public void multiRequestMixedReduced() throws IOException {
init();
ViewMultipleRequest multi = db.getViewRequestBuilder("example", "by_tag")
@@ -999,15 +1021,15 @@ public void multiRequestMixedReduced() throws IOException {
.build();
List> responses = multi.getViewResponses();
- assertEquals("There should be 2 respones for 2 requests", 2, responses.size());
+ assertEquals(2, responses.size(), "There should be 2 responses for 2 requests");
List javaTagKeys = responses.get(0).getKeys();
- assertEquals("There should be 1 java tag result", 1, javaTagKeys.size());
- assertEquals("The key should be java", "java", javaTagKeys.get(0));
+ assertEquals(1, javaTagKeys.size(), "There should be 1 java tag result");
+ assertEquals("java", javaTagKeys.get(0), "The key should be java");
List allTagsReduced = responses.get(1).getValues();
- assertEquals("There should be 1 reduced result", 1, allTagsReduced.size());
- assertEquals("The result should be 4", 4, ((Number) allTagsReduced.get(0)).intValue());
+ assertEquals(1, allTagsReduced.size(), "There should be 1 reduced result");
+ assertEquals(4, ((Number) allTagsReduced.get(0)).intValue(), "The result should be 4");
}
/**
@@ -1022,9 +1044,9 @@ public void assertNoPagesOnUnpaginated() throws Exception {
ViewResponse response = db.getViewRequestBuilder("example", "foo")
.newRequest(Key.Type.STRING,
Object.class).limit(2).build().getResponse();
- assertEquals("There should be 2 keys returned", 2, response.getKeys().size());
- assertFalse("There should be no additional pages", response.hasNextPage());
- assertNull("The next page should be null", response.nextPage());
+ assertEquals(2, response.getKeys().size(), "There should be 2 keys returned");
+ assertFalse(response.hasNextPage(), "There should be no additional pages");
+ assertNull(response.nextPage(), "The next page should be null");
}
/**
@@ -1041,8 +1063,8 @@ public void enhancedForPagination() throws Exception {
Object.class).rowsPerPage(1).build();
int i = 1;
for (ViewResponse page : paginatedQuery.getResponse()) {
- assertEquals("There should be one key on each page", 1, page.getKeys().size());
- assertEquals("The key should be key-" + i, "key-" + i, page.getKeys().get(0));
+ assertEquals(1, page.getKeys().size(), "There should be one key on each page");
+ assertEquals("key-" + i, page.getKeys().get(0), "The key should be key-" + i);
i++;
}
}
@@ -1052,11 +1074,18 @@ public void enhancedForPagination() throws Exception {
*
* @throws Exception
*/
- @Test(expected = IllegalArgumentException.class)
+ @Test
public void rowsPerPageValidationMax() throws Exception {
- ViewRequest paginatedQuery = db.getViewRequestBuilder("example", "foo")
- .newPaginatedRequest(Key.Type.STRING,
- Object.class).rowsPerPage(Integer.MAX_VALUE).build();
+ assertThrows(IllegalArgumentException.class,
+ new Executable() {
+ @Override
+ public void execute() throws Throwable {
+ ViewRequest paginatedQuery = db.getViewRequestBuilder
+ ("example", "foo")
+ .newPaginatedRequest(Key.Type.STRING,
+ Object.class).rowsPerPage(Integer.MAX_VALUE).build();
+ }
+ });
}
/**
@@ -1064,11 +1093,18 @@ public void rowsPerPageValidationMax() throws Exception {
*
* @throws Exception
*/
- @Test(expected = IllegalArgumentException.class)
+ @Test
public void rowsPerPageValidationZero() throws Exception {
- ViewRequest paginatedQuery = db.getViewRequestBuilder("example", "foo")
- .newPaginatedRequest(Key.Type.STRING,
- Object.class).rowsPerPage(0).build();
+ assertThrows(IllegalArgumentException.class,
+ new Executable() {
+ @Override
+ public void execute() throws Throwable {
+ ViewRequest paginatedQuery = db.getViewRequestBuilder
+ ("example", "foo")
+ .newPaginatedRequest(Key.Type.STRING,
+ Object.class).rowsPerPage(0).build();
+ }
+ });
}
/**
@@ -1076,11 +1112,18 @@ public void rowsPerPageValidationZero() throws Exception {
*
* @throws Exception
*/
- @Test(expected = IllegalArgumentException.class)
+ @Test
public void rowsPerPageValidationMin() throws Exception {
- ViewRequest paginatedQuery = db.getViewRequestBuilder("example", "foo")
- .newPaginatedRequest(Key.Type.STRING,
- Object.class).rowsPerPage(-25).build();
+ assertThrows(IllegalArgumentException.class,
+ new Executable() {
+ @Override
+ public void execute() throws Throwable {
+ ViewRequest paginatedQuery = db.getViewRequestBuilder
+ ("example", "foo")
+ .newPaginatedRequest(Key.Type.STRING,
+ Object.class).rowsPerPage(-25).build();
+ }
+ });
}
/**
@@ -1089,11 +1132,18 @@ public void rowsPerPageValidationMin() throws Exception {
*
* @throws Exception
*/
- @Test(expected = IllegalArgumentException.class)
+ @Test
public void validationIncludeDocsReduceView() throws Exception {
- ViewRequest paginatedQuery = db.getViewRequestBuilder("example", "foo")
- .newRequest(Key.Type.STRING,
- Object.class).includeDocs(true).reduce(true).build();
+ assertThrows(IllegalArgumentException.class,
+ new Executable() {
+ @Override
+ public void execute() throws Throwable {
+ ViewRequest paginatedQuery = db.getViewRequestBuilder
+ ("example", "foo")
+ .newRequest(Key.Type.STRING,
+ Object.class).includeDocs(true).reduce(true).build();
+ }
+ });
}
/**
@@ -1117,11 +1167,18 @@ public void noExceptionWhenReduceTrueByDefault() throws Exception {
*
* @throws Exception
*/
- @Test(expected = IllegalArgumentException.class)
+ @Test
public void validationGroupLevelWithSimpleKey() throws Exception {
- ViewRequest paginatedQuery = db.getViewRequestBuilder("example", "foo")
- .newRequest(Key.Type.STRING,
- Object.class).groupLevel(1).build();
+ assertThrows(IllegalArgumentException.class,
+ new Executable() {
+ @Override
+ public void execute() throws Throwable {
+ ViewRequest paginatedQuery = db.getViewRequestBuilder
+ ("example", "foo")
+ .newRequest(Key.Type.STRING,
+ Object.class).groupLevel(1).build();
+ }
+ });
}
/**
@@ -1130,11 +1187,18 @@ public void validationGroupLevelWithSimpleKey() throws Exception {
*
* @throws Exception
*/
- @Test(expected = IllegalArgumentException.class)
+ @Test
public void validationGroupLevelWithNonReduce() throws Exception {
- ViewRequest paginatedQuery = db.getViewRequestBuilder("example", "foo")
- .newRequest(Key.Type.STRING,
- Object.class).reduce(false).groupLevel(1).build();
+ assertThrows(IllegalArgumentException.class,
+ new Executable() {
+ @Override
+ public void execute() throws Throwable {
+ ViewRequest paginatedQuery = db.getViewRequestBuilder
+ ("example", "foo")
+ .newRequest(Key.Type.STRING,
+ Object.class).reduce(false).groupLevel(1).build();
+ }
+ });
}
/**
@@ -1143,11 +1207,18 @@ public void validationGroupLevelWithNonReduce() throws Exception {
*
* @throws Exception
*/
- @Test(expected = IllegalArgumentException.class)
+ @Test
public void validationGroupWithNonReduce() throws Exception {
- ViewRequest paginatedQuery = db.getViewRequestBuilder("example", "foo")
- .newRequest(Key.Type.STRING,
- Object.class).reduce(false).group(true).build();
+ assertThrows(IllegalArgumentException.class,
+ new Executable() {
+ @Override
+ public void execute() throws Throwable {
+ ViewRequest paginatedQuery = db.getViewRequestBuilder
+ ("example", "foo")
+ .newRequest(Key.Type.STRING,
+ Object.class).reduce(false).group(true).build();
+ }
+ });
}
/**
@@ -1195,8 +1266,8 @@ public void testComplexKeyContainingIntTokenPagination() throws Exception {
// We want the last context
HttpConnectionInterceptorContext context = cci.contexts.get(cci.contexts.size() - 1);
String query = context.connection.url.getQuery();
- assertTrue("The query startkey should match.", query.contains("startkey=%5B%22uuid%22," +
- "1005%5D"));
+ assertTrue(query.contains("startkey=%5B%22uuid%22," + "1005%5D"), "The query startkey " +
+ "should match.");
}
/**
@@ -1258,13 +1329,16 @@ public void staleParameterValues() throws Exception {
assertStaleParameter(viewBuilder.build(), noStaleParameter);
// Test the OK stale argument supplied case
- assertStaleParameter(viewBuilder.stale(SettableViewParameters.STALE_OK).build(), staleParameterOK);
+ assertStaleParameter(viewBuilder.stale(SettableViewParameters.STALE_OK).build(),
+ staleParameterOK);
// Test the update_after stale argument supplied case
- assertStaleParameter(viewBuilder.stale(SettableViewParameters.STALE_UPDATE_AFTER).build(), staleParameterUpdate);
+ assertStaleParameter(viewBuilder.stale(SettableViewParameters.STALE_UPDATE_AFTER).build()
+ , staleParameterUpdate);
// Test the NO stale argument supplied case
- assertStaleParameter(viewBuilder.stale(SettableViewParameters.STALE_NO).build(), noStaleParameter);
+ assertStaleParameter(viewBuilder.stale(SettableViewParameters.STALE_NO).build(),
+ noStaleParameter);
}
/**
@@ -1283,9 +1357,9 @@ private void assertStaleParameter(ViewRequest viewRequest, Patt
mockWebServer.enqueue(mockResponse);
viewRequest.getSingleValue();
RecordedRequest request = mockWebServer.takeRequest(1, TimeUnit.SECONDS);
- assertNotNull("There should have been a view request", request);
- assertTrue("There request URL should match the pattern " + p.toString(), p.matcher
- (request.getPath()).matches());
+ assertNotNull(request, "There should have been a view request");
+ assertTrue(p.matcher(request.getPath()).matches(), "There request URL should match the " +
+ "pattern " + p.toString());
}
/**
@@ -1350,6 +1424,6 @@ public void getIdsAndRevsForDeletedIDsWithAllDocs() throws Exception {
// Do an _all_docs request using the 4 _ids of the generated docs.
Map allDocsIdsAndRevs = database.getAllDocsRequestBuilder().keys(idsAndRevs
.keySet().toArray(new String[4])).build().getResponse().getIdsAndRevs();
- assertEquals("The ids and revs should be equal", idsAndRevs, allDocsIdsAndRevs);
+ assertEquals(idsAndRevs, allDocsIdsAndRevs, "The ids and revs should be equal");
}
}
diff --git a/cloudant-client/src/test/java/com/cloudant/tests/base/TestWithDb.java b/cloudant-client/src/test/java/com/cloudant/tests/base/TestWithDb.java
new file mode 100644
index 000000000..b701fa502
--- /dev/null
+++ b/cloudant-client/src/test/java/com/cloudant/tests/base/TestWithDb.java
@@ -0,0 +1,28 @@
+/*
+ * Copyright © 2018 IBM Corp. All rights reserved.
+ *
+ * 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.cloudant.tests.base;
+
+import com.cloudant.client.api.CloudantClient;
+import com.cloudant.client.api.Database;
+import com.cloudant.tests.extensions.CloudantClientExtension;
+
+public abstract class TestWithDb {
+
+ protected static CloudantClientExtension clientResource = new CloudantClientExtension();
+
+ protected static CloudantClient account;
+
+ protected static Database db;
+
+}
diff --git a/cloudant-client/src/test/java/com/cloudant/tests/base/TestWithDbPerClass.java b/cloudant-client/src/test/java/com/cloudant/tests/base/TestWithDbPerClass.java
new file mode 100644
index 000000000..7d0a000d7
--- /dev/null
+++ b/cloudant-client/src/test/java/com/cloudant/tests/base/TestWithDbPerClass.java
@@ -0,0 +1,38 @@
+/*
+ * Copyright © 2018 IBM Corp. All rights reserved.
+ *
+ * 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.cloudant.tests.base;
+
+import com.cloudant.tests.extensions.DatabaseExtension;
+import com.cloudant.tests.extensions.MultiExtension;
+
+import org.junit.jupiter.api.BeforeAll;
+import org.junit.jupiter.api.extension.RegisterExtension;
+
+// Base class for tests which require a DB which is used throughout the lifetime of the test class
+public class TestWithDbPerClass extends TestWithDb {
+
+ protected static DatabaseExtension.PerClass dbResource = new DatabaseExtension.PerClass
+ (clientResource);
+
+ @RegisterExtension
+ protected static MultiExtension perClassExtensions = new MultiExtension(clientResource,
+ dbResource);
+
+ @BeforeAll
+ public static void testWithDbBeforeAll() {
+ account = clientResource.get();
+ db = dbResource.get();
+ }
+
+}
diff --git a/cloudant-client/src/test/java/com/cloudant/tests/base/TestWithDbPerTest.java b/cloudant-client/src/test/java/com/cloudant/tests/base/TestWithDbPerTest.java
new file mode 100644
index 000000000..3f7965dd4
--- /dev/null
+++ b/cloudant-client/src/test/java/com/cloudant/tests/base/TestWithDbPerTest.java
@@ -0,0 +1,43 @@
+/*
+ * Copyright © 2018 IBM Corp. All rights reserved.
+ *
+ * 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.cloudant.tests.base;
+
+import com.cloudant.tests.extensions.DatabaseExtension;
+import com.cloudant.tests.extensions.MultiExtension;
+
+import org.junit.jupiter.api.BeforeAll;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.extension.RegisterExtension;
+
+// Base class for tests which require a new DB for each test method
+public class TestWithDbPerTest extends TestWithDb {
+
+ protected static DatabaseExtension.PerTest dbResource = new DatabaseExtension.PerTest
+ (clientResource);
+
+ @RegisterExtension
+ protected static MultiExtension perTestExtensions = new MultiExtension(clientResource,
+ dbResource);
+
+ @BeforeEach
+ public void testWithDbBeforeEach() {
+ db = dbResource.get();
+ }
+
+ @BeforeAll
+ public static void testWithDbBeforeAll() {
+ account = clientResource.get();
+ }
+
+}
diff --git a/cloudant-client/src/test/java/com/cloudant/tests/base/TestWithMockedServer.java b/cloudant-client/src/test/java/com/cloudant/tests/base/TestWithMockedServer.java
new file mode 100644
index 000000000..c53b28ce3
--- /dev/null
+++ b/cloudant-client/src/test/java/com/cloudant/tests/base/TestWithMockedServer.java
@@ -0,0 +1,58 @@
+/*
+ * Copyright © 2017, 2018 IBM Corp. All rights reserved.
+ *
+ * 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.cloudant.tests.base;
+
+import com.cloudant.client.api.CloudantClient;
+import com.cloudant.client.api.Database;
+import com.cloudant.tests.extensions.CloudantClientMockServerExtension;
+import com.cloudant.tests.extensions.DatabaseExtension;
+import com.cloudant.tests.extensions.MockWebServerExtension;
+import com.cloudant.tests.extensions.MultiExtension;
+
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.extension.RegisterExtension;
+
+import okhttp3.mockwebserver.MockWebServer;
+
+/**
+ * Class of tests that run against a MockWebServer. This class handles set up and tear down of the
+ * mock server and associated client and db objects before/after each test.
+ */
+public abstract class TestWithMockedServer {
+
+ public static MockWebServerExtension mockWebServerExt = new MockWebServerExtension();
+ public static CloudantClientMockServerExtension clientResource = new
+ CloudantClientMockServerExtension(mockWebServerExt);
+ public static DatabaseExtension.PerTest dbResource = new DatabaseExtension.PerTest
+ (clientResource);
+ @RegisterExtension
+ public static MultiExtension extensions = new MultiExtension(
+ mockWebServerExt,
+ clientResource,
+ dbResource
+ );
+
+ protected MockWebServer server;
+ protected CloudantClient client;
+ protected Database db;
+
+ @BeforeEach
+ public void beforeEach() {
+ server = mockWebServerExt.get();
+ client = clientResource.get();
+ db = dbResource.get();
+ }
+
+}
diff --git a/cloudant-client/src/test/java/com/cloudant/tests/ReplicateBaseTest.java b/cloudant-client/src/test/java/com/cloudant/tests/base/TestWithReplication.java
similarity index 53%
rename from cloudant-client/src/test/java/com/cloudant/tests/ReplicateBaseTest.java
rename to cloudant-client/src/test/java/com/cloudant/tests/base/TestWithReplication.java
index 227e697a9..ad1ba61f9 100644
--- a/cloudant-client/src/test/java/com/cloudant/tests/ReplicateBaseTest.java
+++ b/cloudant-client/src/test/java/com/cloudant/tests/base/TestWithReplication.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2015 IBM Corp. All rights reserved.
+ * Copyright © 2015, 2018 IBM Corp. All rights reserved.
*
* 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
@@ -12,42 +12,45 @@
* and limitations under the License.
*/
-package com.cloudant.tests;
+package com.cloudant.tests.base;
-import static org.junit.Assert.assertTrue;
+import static org.junit.jupiter.api.Assertions.assertTrue;
import com.cloudant.client.api.CloudantClient;
import com.cloudant.client.api.Database;
import com.cloudant.client.api.views.Key;
import com.cloudant.client.api.views.ViewResponse;
-import com.cloudant.tests.util.CloudantClientResource;
-import com.cloudant.tests.util.DatabaseResource;
+import com.cloudant.tests.extensions.CloudantClientExtension;
+import com.cloudant.tests.extensions.DatabaseExtension;
+import com.cloudant.tests.extensions.MultiExtension;
import com.cloudant.tests.util.Utils;
-import org.junit.Before;
-import org.junit.ClassRule;
-import org.junit.Rule;
+import org.junit.jupiter.api.BeforeAll;
+import org.junit.jupiter.api.extension.RegisterExtension;
-public class ReplicateBaseTest {
+public class TestWithReplication {
- @ClassRule
- public static CloudantClientResource clientResource = new CloudantClientResource();
- protected CloudantClient account = clientResource.get();
+ protected static CloudantClientExtension clientResource = new CloudantClientExtension();
+ protected static CloudantClient account;
- @Rule
- public DatabaseResource db1Resource = new DatabaseResource(clientResource);
- @Rule
- public DatabaseResource db2Resource = new DatabaseResource(clientResource);
+ protected static DatabaseExtension.PerClass db1Resource = new DatabaseExtension.PerClass
+ (clientResource);
+ protected static DatabaseExtension.PerClass db2Resource = new DatabaseExtension.PerClass
+ (clientResource);
- protected Database db1;
+ @RegisterExtension
+ public static MultiExtension extensions = new MultiExtension(clientResource, db1Resource,
+ db2Resource);
- protected Database db2;
+ protected static Database db1;
+ protected static Database db2;
protected static String db1URI;
protected static String db2URI;
- @Before
- public void setUp() throws Exception {
+ @BeforeAll
+ public static void setUp() throws Exception {
+ account = clientResource.get();
db1 = db1Resource.get();
db1URI = db1Resource.getDbURIWithUserInfo();
@@ -56,6 +59,7 @@ public void setUp() throws Exception {
db2 = db2Resource.get();
db2URI = db2Resource.getDbURIWithUserInfo();
Utils.putDesignDocs(db2);
+
}
protected void assertConflictsNotZero(Database db) throws Exception {
@@ -63,7 +67,7 @@ protected void assertConflictsNotZero(Database db) throws Exception {
("conflicts", "conflict").newRequest(Key.Type.COMPLEX, String.class).build()
.getResponse();
int conflictCount = conflicts.getRows().size();
- assertTrue("There should be at least 1 conflict, there were " + conflictCount,
- conflictCount > 0);
+ assertTrue(conflictCount > 0, "There should be at least 1 conflict, there were " +
+ conflictCount);
}
}
diff --git a/cloudant-client/src/test/java/com/cloudant/tests/extensions/AbstractClientExtension.java b/cloudant-client/src/test/java/com/cloudant/tests/extensions/AbstractClientExtension.java
new file mode 100644
index 000000000..160c34548
--- /dev/null
+++ b/cloudant-client/src/test/java/com/cloudant/tests/extensions/AbstractClientExtension.java
@@ -0,0 +1,24 @@
+/*
+ * Copyright © 2018 IBM Corp. All rights reserved.
+ *
+ * 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.cloudant.tests.extensions;
+
+import com.cloudant.client.api.CloudantClient;
+
+public abstract class AbstractClientExtension {
+
+ public abstract CloudantClient get();
+
+ public abstract String getBaseURIWithUserInfo();
+
+}
diff --git a/cloudant-client/src/test/java/com/cloudant/tests/util/CloudantClientResource.java b/cloudant-client/src/test/java/com/cloudant/tests/extensions/CloudantClientExtension.java
similarity index 67%
rename from cloudant-client/src/test/java/com/cloudant/tests/util/CloudantClientResource.java
rename to cloudant-client/src/test/java/com/cloudant/tests/extensions/CloudantClientExtension.java
index 375d16fb2..4083ac700 100644
--- a/cloudant-client/src/test/java/com/cloudant/tests/util/CloudantClientResource.java
+++ b/cloudant-client/src/test/java/com/cloudant/tests/extensions/CloudantClientExtension.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2015 IBM Corp. All rights reserved.
+ * Copyright © 2015, 2018 IBM Corp. All rights reserved.
*
* 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
@@ -12,38 +12,44 @@
* and limitations under the License.
*/
-package com.cloudant.tests.util;
+package com.cloudant.tests.extensions;
import com.cloudant.client.api.ClientBuilder;
import com.cloudant.client.api.CloudantClient;
import com.cloudant.tests.CloudantClientHelper;
-import org.junit.rules.ExternalResource;
+import org.junit.jupiter.api.extension.AfterAllCallback;
+import org.junit.jupiter.api.extension.BeforeAllCallback;
+import org.junit.jupiter.api.extension.ExtensionContext;
+
+public class CloudantClientExtension extends AbstractClientExtension implements
+ BeforeAllCallback, AfterAllCallback {
-public class CloudantClientResource extends ExternalResource {
private ClientBuilder clientBuilder;
+
private CloudantClient client;
- public CloudantClientResource() {
+ public CloudantClientExtension() {
this.clientBuilder = CloudantClientHelper.getClientBuilder();
}
- public CloudantClientResource(ClientBuilder clientBuilder) {
+ public CloudantClientExtension(ClientBuilder clientBuilder) {
this.clientBuilder = clientBuilder;
}
@Override
- public void before() {
- client = clientBuilder.build();
+ public CloudantClient get() {
+ return this.client;
}
@Override
- public void after() {
+ public void afterAll(ExtensionContext context) throws Exception {
client.shutdown();
}
- public CloudantClient get() {
- return this.client;
+ @Override
+ public void beforeAll(ExtensionContext context) throws Exception {
+ client = clientBuilder.build();
}
/**
@@ -52,6 +58,7 @@ public CloudantClient get() {
*
* @return String representation of the URI
*/
+ @Override
public String getBaseURIWithUserInfo() {
return CloudantClientHelper.SERVER_URI_WITH_USER_INFO;
}
diff --git a/cloudant-client/src/test/java/com/cloudant/tests/extensions/CloudantClientMockServerExtension.java b/cloudant-client/src/test/java/com/cloudant/tests/extensions/CloudantClientMockServerExtension.java
new file mode 100644
index 000000000..a3270d7e5
--- /dev/null
+++ b/cloudant-client/src/test/java/com/cloudant/tests/extensions/CloudantClientMockServerExtension.java
@@ -0,0 +1,62 @@
+/*
+ * Copyright © 2017, 2018 IBM Corp. All rights reserved.
+ *
+ * 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.cloudant.tests.extensions;
+
+import com.cloudant.client.api.CloudantClient;
+import com.cloudant.tests.CloudantClientHelper;
+import com.cloudant.tests.util.MockWebServerResources;
+
+import org.junit.jupiter.api.extension.AfterEachCallback;
+import org.junit.jupiter.api.extension.BeforeEachCallback;
+import org.junit.jupiter.api.extension.ExtensionContext;
+
+import okhttp3.mockwebserver.MockWebServer;
+
+public class CloudantClientMockServerExtension extends AbstractClientExtension implements
+ BeforeEachCallback, AfterEachCallback {
+
+ private final MockWebServerExtension mockWebServerExt;
+ private MockWebServer mockWebServer;
+ private CloudantClient client;
+
+ public CloudantClientMockServerExtension(MockWebServerExtension mockWebServerExt) {
+ this.mockWebServerExt = mockWebServerExt;
+ }
+
+ @Override
+ public void beforeEach(ExtensionContext ctx) {
+ this.mockWebServer = this.mockWebServerExt.get();
+ this.client = CloudantClientHelper.newMockWebServerClientBuilder(this.mockWebServer)
+ .build();
+ }
+
+ @Override
+ public void afterEach(ExtensionContext ctx) {
+ // Queue a 200 for the _session DELETE that is called on shutdown.
+ mockWebServer.enqueue(MockWebServerResources.JSON_OK);
+ }
+
+ @Override
+ public CloudantClient get() {
+ return client;
+ }
+
+ @Override
+ public String getBaseURIWithUserInfo() {
+ return CloudantClientHelper.SERVER_URI_WITH_USER_INFO;
+ }
+
+
+}
diff --git a/cloudant-client/src/test/java/com/cloudant/tests/util/DatabaseResource.java b/cloudant-client/src/test/java/com/cloudant/tests/extensions/DatabaseExtension.java
similarity index 59%
rename from cloudant-client/src/test/java/com/cloudant/tests/util/DatabaseResource.java
rename to cloudant-client/src/test/java/com/cloudant/tests/extensions/DatabaseExtension.java
index 553369090..da30a0490 100644
--- a/cloudant-client/src/test/java/com/cloudant/tests/util/DatabaseResource.java
+++ b/cloudant-client/src/test/java/com/cloudant/tests/extensions/DatabaseExtension.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2015 IBM Corp. All rights reserved.
+ * Copyright © 2015, 2018 IBM Corp. All rights reserved.
*
* 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
@@ -12,25 +12,29 @@
* and limitations under the License.
*/
-package com.cloudant.tests.util;
+package com.cloudant.tests.extensions;
import com.cloudant.client.api.CloudantClient;
import com.cloudant.client.api.Database;
+import com.cloudant.tests.util.Utils;
-import org.junit.rules.ExternalResource;
-import org.junit.runner.Description;
-import org.junit.runners.model.Statement;
+import org.junit.jupiter.api.extension.AfterAllCallback;
+import org.junit.jupiter.api.extension.AfterEachCallback;
+import org.junit.jupiter.api.extension.BeforeAllCallback;
+import org.junit.jupiter.api.extension.BeforeEachCallback;
+import org.junit.jupiter.api.extension.ExtensionContext;
import java.util.Locale;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
-public class DatabaseResource extends ExternalResource {
+public class DatabaseExtension {
// Get the maximum length for a database name, defaults to 128 chars
private static final int DB_NAME_SIZE = Integer.parseInt(System.getProperty("test.db.name" +
".length", "128"));
- private final CloudantClientResource clientResource;
+ private final AbstractClientExtension clientResource;
+
private CloudantClient client;
private String databaseName = Utils.generateUUID();
private Database database;
@@ -52,25 +56,16 @@ public class DatabaseResource extends ExternalResource {
*
* @param clientResource
*/
- public DatabaseResource(CloudantClientResource clientResource) {
+
+ protected DatabaseExtension(CloudantClientExtension clientResource) {
this.clientResource = clientResource;
}
- public DatabaseResource(CloudantClientMockServerResource mockServerResource) {
+ protected DatabaseExtension(CloudantClientMockServerExtension mockServerResource) {
this.clientResource = mockServerResource;
this.mock = true;
}
- @Override
- public Statement apply(Statement base, Description description) {
- String testClassName = description.getClassName();
- String testMethodName = description.getMethodName();
- String uniqueSuffix = Utils.generateUUID();
- databaseName = sanitizeDbName(testClassName + "-" + (testMethodName == null ? "" :
- testMethodName + "-") + uniqueSuffix);
- return super.apply(base, description);
- }
-
/**
* The database must start with a letter and can only contain lowercase letters (a-z), digits
* (0-9) and the following characters _, $, (, ), +, -, and /.
@@ -79,6 +74,14 @@ public Statement apply(Statement base, Description description) {
* @return sanitized name
*/
private static String sanitizeDbName(String name) {
+ //lowercase to remove any caps that will not be permitted
+ name = name.toLowerCase(Locale.ENGLISH);
+ //replace any non alphanum with underscores
+ name = name.replaceAll("[^a-z0-9]", "_");
+ //squash multiple underscores
+ name = name.replaceAll("(_){2,}", "_");
+ //remove leading underscore as it is reserved for internal couch use
+ name = name.replaceAll("^_", "");
//database name is limited to 128 characters on the Cloudant service
//forego the package name in favour of test details and UUID
int excess;
@@ -90,15 +93,12 @@ private static String sanitizeDbName(String name) {
name = m.group(1);
}
}
- //lowercase to remove any caps that will not be permitted
- name = name.toLowerCase(Locale.ENGLISH);
- //replace any characters that are not permitted with underscores
- name = name.replaceAll("[^a-z0-9_\\$\\(\\)\\+\\-/]", "_");
return name;
}
- @Override
- public void before() {
+ public void before(ExtensionContext context) {
+ String uniqueSuffix = Utils.generateUUID();
+ databaseName = sanitizeDbName(String.format("%s-%s", context.getUniqueId(), uniqueSuffix));
client = clientResource.get();
if (!mock) {
database = client.database(databaseName, true);
@@ -107,8 +107,7 @@ public void before() {
}
}
- @Override
- public void after() {
+ public void after(ExtensionContext context) {
if (!mock) {
client.deleteDB(databaseName);
}
@@ -130,6 +129,47 @@ public String getDatabaseName() {
* @return the URI for the DB with creds
*/
public String getDbURIWithUserInfo() throws Exception {
- return clientResource.getBaseURIWithUserInfo() + "/" + getDatabaseName();
+ String info = clientResource.getBaseURIWithUserInfo() + "/" + getDatabaseName();
+ return info;
+ }
+
+ public static class PerClass extends DatabaseExtension implements BeforeAllCallback,
+ AfterAllCallback {
+
+ public PerClass(CloudantClientExtension clientResource) {
+ super(clientResource);
+ }
+
+ @Override
+ public void afterAll(ExtensionContext extensionContext) throws Exception {
+ super.after(extensionContext);
+ }
+
+ @Override
+ public void beforeAll(ExtensionContext extensionContext) throws Exception {
+ super.before(extensionContext);
+ }
+ }
+
+ public static class PerTest extends DatabaseExtension implements BeforeEachCallback,
+ AfterEachCallback {
+
+ public PerTest(CloudantClientExtension clientResource) {
+ super(clientResource);
+ }
+
+ public PerTest(CloudantClientMockServerExtension mockServerResource) {
+ super(mockServerResource);
+ }
+
+ @Override
+ public void afterEach(ExtensionContext extensionContext) throws Exception {
+ super.after(extensionContext);
+ }
+
+ @Override
+ public void beforeEach(ExtensionContext extensionContext) throws Exception {
+ super.before(extensionContext);
+ }
}
}
diff --git a/cloudant-client/src/test/java/com/cloudant/tests/extensions/MockWebServerExtension.java b/cloudant-client/src/test/java/com/cloudant/tests/extensions/MockWebServerExtension.java
new file mode 100644
index 000000000..0ea96dfb6
--- /dev/null
+++ b/cloudant-client/src/test/java/com/cloudant/tests/extensions/MockWebServerExtension.java
@@ -0,0 +1,54 @@
+/*
+ * Copyright © 2018 IBM Corp. All rights reserved.
+ *
+ * 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.cloudant.tests.extensions;
+
+import org.junit.jupiter.api.extension.AfterEachCallback;
+import org.junit.jupiter.api.extension.BeforeEachCallback;
+import org.junit.jupiter.api.extension.ExtensionContext;
+
+import okhttp3.mockwebserver.MockWebServer;
+
+public class MockWebServerExtension implements BeforeEachCallback, AfterEachCallback {
+
+ private MockWebServer mockWebServer;
+ private boolean started = false;
+
+ public MockWebServerExtension() {
+ }
+
+ public MockWebServer get() {
+ return this.mockWebServer;
+ }
+
+ // NB beforeEach/afterEach emulate before and after in the actual mock, because we can't call
+ // these directly as they are marked as protected
+
+ @Override
+ public synchronized void beforeEach(ExtensionContext context) throws Exception {
+ this.mockWebServer = new MockWebServer();
+ if (started) {
+ System.err.println("*** WARNING: MockWebServer already started");
+ return;
+ }
+ this.mockWebServer.start();
+ started = true;
+ }
+
+ @Override
+ public synchronized void afterEach(ExtensionContext context) throws Exception {
+ this.mockWebServer.shutdown();
+ started = false;
+ }
+
+}
diff --git a/cloudant-client/src/test/java/com/cloudant/tests/extensions/MultiExtension.java b/cloudant-client/src/test/java/com/cloudant/tests/extensions/MultiExtension.java
new file mode 100644
index 000000000..feb051cb6
--- /dev/null
+++ b/cloudant-client/src/test/java/com/cloudant/tests/extensions/MultiExtension.java
@@ -0,0 +1,88 @@
+/*
+ * Copyright © 2018 IBM Corp. All rights reserved.
+ *
+ * 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.cloudant.tests.extensions;
+
+import org.junit.jupiter.api.extension.AfterAllCallback;
+import org.junit.jupiter.api.extension.AfterEachCallback;
+import org.junit.jupiter.api.extension.AfterTestExecutionCallback;
+import org.junit.jupiter.api.extension.BeforeAllCallback;
+import org.junit.jupiter.api.extension.BeforeEachCallback;
+import org.junit.jupiter.api.extension.BeforeTestExecutionCallback;
+import org.junit.jupiter.api.extension.Extension;
+import org.junit.jupiter.api.extension.ExtensionContext;
+
+public class MultiExtension implements Extension, AfterAllCallback, AfterEachCallback,
+ AfterTestExecutionCallback, BeforeAllCallback, BeforeEachCallback,
+ BeforeTestExecutionCallback {
+
+ private final Extension[] extensions;
+
+ public MultiExtension(Extension... extensions) {
+ this.extensions = extensions;
+ }
+
+ @Override
+ public void afterAll(ExtensionContext extensionContext) throws Exception {
+ for (Extension extension : extensions) {
+ if (extension instanceof AfterAllCallback) {
+ ((AfterAllCallback) extension).afterAll(extensionContext);
+ }
+ }
+ }
+
+ @Override
+ public void afterEach(ExtensionContext extensionContext) throws Exception {
+ for (Extension extension : extensions) {
+ if (extension instanceof AfterEachCallback) {
+ ((AfterEachCallback) extension).afterEach(extensionContext);
+ }
+ }
+ }
+
+ @Override
+ public void afterTestExecution(ExtensionContext extensionContext) throws Exception {
+ for (Extension extension : extensions) {
+ if (extension instanceof AfterTestExecutionCallback) {
+ ((AfterTestExecutionCallback) extension).afterTestExecution(extensionContext);
+ }
+ }
+ }
+
+ @Override
+ public void beforeAll(ExtensionContext extensionContext) throws Exception {
+ for (Extension extension : extensions) {
+ if (extension instanceof BeforeAllCallback) {
+ ((BeforeAllCallback) extension).beforeAll(extensionContext);
+ }
+ }
+ }
+
+ @Override
+ public void beforeEach(ExtensionContext extensionContext) throws Exception {
+ for (Extension extension : extensions) {
+ if (extension instanceof BeforeEachCallback) {
+ ((BeforeEachCallback) extension).beforeEach(extensionContext);
+ }
+ }
+ }
+
+ @Override
+ public void beforeTestExecution(ExtensionContext extensionContext) throws Exception {
+ for (Extension extension : extensions) {
+ if (extension instanceof BeforeTestExecutionCallback) {
+ ((BeforeTestExecutionCallback) extension).beforeTestExecution(extensionContext);
+ }
+ }
+ }
+}
diff --git a/cloudant-client/src/test/java/com/cloudant/tests/util/CheckPagination.java b/cloudant-client/src/test/java/com/cloudant/tests/util/CheckPagination.java
index 949d02127..ff4e94de1 100644
--- a/cloudant-client/src/test/java/com/cloudant/tests/util/CheckPagination.java
+++ b/cloudant-client/src/test/java/com/cloudant/tests/util/CheckPagination.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2015 IBM Corp. All rights reserved.
+ * Copyright © 2015, 2018 IBM Corp. All rights reserved.
*
* 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
@@ -15,10 +15,10 @@
package com.cloudant.tests.util;
import static org.hamcrest.CoreMatchers.is;
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertThat;
-import static org.junit.Assert.assertTrue;
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertFalse;
+import static org.junit.jupiter.api.Assertions.assertTrue;
import com.cloudant.client.api.Database;
import com.cloudant.client.api.views.Key;
@@ -116,9 +116,9 @@ public CheckPagination stateless(boolean stateless) {
* @return the last page in the view.
*/
private void checkPagesForward(int currentPage,
- int numberOfPages,
- int docCount,
- int docsPerPage) throws IOException {
+ int numberOfPages,
+ int docCount,
+ int docsPerPage) throws IOException {
for (int i = 0; i < numberOfPages; ++i) {
nextPage();
checkPage(page, docCount, docsPerPage, currentPage + i + 1, descending);
@@ -135,9 +135,9 @@ private void checkPagesForward(int currentPage,
* @return the first page in the view
*/
private void checkPagesBackward(int currentPage,
- int numberOfPages,
- int docCount,
- int docsPerPage) throws IOException {
+ int numberOfPages,
+ int docCount,
+ int docsPerPage) throws IOException {
for (int i = 0; i < numberOfPages; ++i) {
previousPage();
checkPage(page, docCount, docsPerPage, currentPage - i - 1, descending);
@@ -198,8 +198,8 @@ private void checkDocumentTitles(ViewResponse page, int docCount, int docsPerPag
}
List resultList = page.getDocsAs(Foo.class);
for (int i = 0; i < resultList.size(); ++i) {
- assertEquals("Document titles do not match", ViewsTest.docTitle(descending ? offset-- :
- offset++), resultList.get(i).getTitle());
+ assertEquals(ViewsTest.docTitle(descending ? offset-- :
+ offset++), resultList.get(i).getTitle(), "Document titles do not match");
}
}
diff --git a/cloudant-client/src/test/java/com/cloudant/tests/util/CloudantClientMockServerResource.java b/cloudant-client/src/test/java/com/cloudant/tests/util/CloudantClientMockServerResource.java
deleted file mode 100644
index 0141a3c44..000000000
--- a/cloudant-client/src/test/java/com/cloudant/tests/util/CloudantClientMockServerResource.java
+++ /dev/null
@@ -1,36 +0,0 @@
-/*
- * Copyright © 2017 IBM Corp. All rights reserved.
- *
- * 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.cloudant.tests.util;
-
-import com.cloudant.tests.CloudantClientHelper;
-
-import okhttp3.mockwebserver.MockWebServer;
-
-public class CloudantClientMockServerResource extends CloudantClientResource {
-
- private final MockWebServer server;
-
- public CloudantClientMockServerResource(MockWebServer mockWebServer) {
- super(CloudantClientHelper.newMockWebServerClientBuilder(mockWebServer));
- this.server = mockWebServer;
- }
-
- @Override
- public void after() {
- // Queue a 200 for the _session DELETE that is called on shutdown.
- server.enqueue(MockWebServerResources.JSON_OK);
- super.after();
- }
-}
diff --git a/cloudant-client/src/test/java/com/cloudant/tests/util/HttpFactoryParameterizedTest.java b/cloudant-client/src/test/java/com/cloudant/tests/util/HttpFactoryParameterizedTest.java
index 19c11921e..ae1cb50d1 100644
--- a/cloudant-client/src/test/java/com/cloudant/tests/util/HttpFactoryParameterizedTest.java
+++ b/cloudant-client/src/test/java/com/cloudant/tests/util/HttpFactoryParameterizedTest.java
@@ -1,5 +1,5 @@
/*
- * Copyright © 2016 IBM Corp. All rights reserved.
+ * Copyright © 2016, 2018 IBM Corp. All rights reserved.
*
* 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
@@ -14,27 +14,24 @@
package com.cloudant.tests.util;
-import static org.junit.Assert.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertEquals;
import com.cloudant.http.internal.DefaultHttpUrlConnectionFactory;
import com.cloudant.http.internal.ok.OkHelper;
+import com.cloudant.tests.base.TestWithDbPerClass;
-import org.junit.Before;
-import org.junit.runner.RunWith;
-import org.junit.runners.Parameterized;
+import org.junit.jupiter.api.BeforeEach;
import mockit.Mock;
import mockit.MockUp;
-@RunWith(Parameterized.class)
-public abstract class HttpFactoryParameterizedTest {
+public abstract class HttpFactoryParameterizedTest extends TestWithDbPerClass {
/**
* A parameter governing whether to allow okhttp or not. This lets us exercise both
* HttpURLConnection types in these tests.
*/
- @Parameterized.Parameter
- public boolean okUsable;
+ public boolean isOkUsable;
/**
* A mock OkHelper that always returns false to force use of the JVM HttpURLConnection
@@ -47,14 +44,16 @@ public static boolean isOkUsable() {
}
}
- @Before
- public void changeHttpConnectionFactory() throws Exception {
- if (!okUsable) {
+ @BeforeEach
+ public void changeHttpConnectionFactory(boolean isOkUsable) throws Exception {
+ this.isOkUsable = isOkUsable;
+ if (!isOkUsable) {
// New up the mock that will stop okhttp's factory being used
new OkHelperMock();
}
// Verify that we are getting the behaviour we expect.
- assertEquals("The OK usable value was not what was expected for the test parameter.",
- okUsable, OkHelper.isOkUsable());
+ assertEquals(
+ isOkUsable, OkHelper.isOkUsable(), "The OK usable value was not what was expected" +
+ " for the test parameter.");
}
}
diff --git a/cloudant-client/src/test/java/com/cloudant/tests/util/IamSystemPropertyMock.java b/cloudant-client/src/test/java/com/cloudant/tests/util/IamSystemPropertyMock.java
index 734457610..51585704b 100644
--- a/cloudant-client/src/test/java/com/cloudant/tests/util/IamSystemPropertyMock.java
+++ b/cloudant-client/src/test/java/com/cloudant/tests/util/IamSystemPropertyMock.java
@@ -32,7 +32,7 @@ public class IamSystemPropertyMock extends MockUp {
public void setMockIamTokenEndpointUrl(String mockIamTokenEndpointUrl) {
this.mockIamTokenEndpointUrl.set(mockIamTokenEndpointUrl);
}
-
+
@Mock
public String getProperty(Invocation inv, String key) {
if (key.equals("com.cloudant.client.iamserver")) {
diff --git a/cloudant-client/src/test/java/com/cloudant/tests/util/MockedServerTest.java b/cloudant-client/src/test/java/com/cloudant/tests/util/MockedServerTest.java
deleted file mode 100644
index 020097b4a..000000000
--- a/cloudant-client/src/test/java/com/cloudant/tests/util/MockedServerTest.java
+++ /dev/null
@@ -1,47 +0,0 @@
-/*
- * Copyright © 2017 IBM Corp. All rights reserved.
- *
- * 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.cloudant.tests.util;
-
-import com.cloudant.client.api.CloudantClient;
-import com.cloudant.client.api.Database;
-
-import org.junit.Before;
-import org.junit.Rule;
-import org.junit.rules.RuleChain;
-
-import okhttp3.mockwebserver.MockWebServer;
-
-/**
- * Class of tests that run against a MockWebServer. This class handles set up and tear down of the
- * mock server and associated client and db objects before/after each test.
- */
-public abstract class MockedServerTest {
-
- protected MockWebServer server = new MockWebServer();
- protected CloudantClient client;
- protected Database db;
-
- protected CloudantClientMockServerResource clientResource = new
- CloudantClientMockServerResource(server);
- protected DatabaseResource dbResource = new DatabaseResource(clientResource);
- @Rule
- public RuleChain chain = RuleChain.outerRule(server).around(clientResource).around(dbResource);
-
- @Before
- public void setup() throws Exception {
- client = clientResource.get();
- db = dbResource.get();
- }
-}
diff --git a/cloudant-client/src/test/java/com/cloudant/tests/util/TestLog.java b/cloudant-client/src/test/java/com/cloudant/tests/util/TestLog.java
deleted file mode 100644
index 0759afcb2..000000000
--- a/cloudant-client/src/test/java/com/cloudant/tests/util/TestLog.java
+++ /dev/null
@@ -1,35 +0,0 @@
-/*
- * Copyright (c) 2015 IBM Corp. All rights reserved.
- *
- * 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.cloudant.tests.util;
-
-import org.junit.rules.TestRule;
-import org.junit.runner.Description;
-import org.junit.runners.model.Statement;
-
-import java.util.logging.Logger;
-
-public class TestLog implements TestRule {
-
- //default to a logger name for this class, but replace when the rule is applied
- public Logger logger = Logger.getLogger(TestLog.class.getName());
-
- @Override
- public Statement apply(final Statement base, Description description) {
- //set a logger for the name of the test class
- logger = Logger.getLogger(description.getClassName());
- return base;
- }
-
-}
diff --git a/cloudant-client/src/test/java/com/cloudant/tests/util/Utils.java b/cloudant-client/src/test/java/com/cloudant/tests/util/Utils.java
index a274ab000..687aab4da 100644
--- a/cloudant-client/src/test/java/com/cloudant/tests/util/Utils.java
+++ b/cloudant-client/src/test/java/com/cloudant/tests/util/Utils.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2015 IBM Corp. All rights reserved.
+ * Copyright © 2015, 2018 IBM Corp. All rights reserved.
*
* 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
@@ -16,10 +16,10 @@
import static org.hamcrest.CoreMatchers.is;
import static org.hamcrest.CoreMatchers.nullValue;
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.assertThat;
-import static org.junit.Assert.assertTrue;
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertNotNull;
+import static org.junit.jupiter.api.Assertions.assertTrue;
import com.cloudant.client.api.CloudantClient;
import com.cloudant.client.api.Database;
@@ -186,14 +186,16 @@ public static T findDocumentWithRetries(Database db, String docId, Class
*/
public static String[] splitAndAssert(String toSplit, String splitOn, int expectedNumber) {
String[] parts = toSplit.split(splitOn);
- assertEquals("There should be " + expectedNumber + " instances of " + splitOn + " in the " +
- "content", expectedNumber + 1, parts.length);
+ assertEquals(expectedNumber + 1, parts.length, "There should be " + expectedNumber + " " +
+ "instances of " + splitOn + " in the " +
+ "content");
return parts;
}
/**
* Test utility to put design documents under the testing resource folder in to the database.
- * @param db database to put the design docs
+ *
+ * @param db database to put the design docs
* @param directory location of design docs
*/
public static void putDesignDocs(Database db, File directory) throws FileNotFoundException {
@@ -212,7 +214,7 @@ public static void putDesignDocs(Database db) throws FileNotFoundException {
}
public static void assertOKResponse(Response r) throws Exception {
- assertTrue("The response code should be 2XX was " + r.getStatusCode(), r.getStatusCode()
- / 100 == 2);
+ assertTrue(r.getStatusCode()
+ / 100 == 2, "The response code should be 2XX was " + r.getStatusCode());
}
}
diff --git a/gradle/wrapper/gradle-wrapper.jar b/gradle/wrapper/gradle-wrapper.jar
index d3b83982b..8252d7e25 100644
Binary files a/gradle/wrapper/gradle-wrapper.jar and b/gradle/wrapper/gradle-wrapper.jar differ
diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties
index 7e36e6166..bf3de2183 100644
--- a/gradle/wrapper/gradle-wrapper.properties
+++ b/gradle/wrapper/gradle-wrapper.properties
@@ -1,6 +1,5 @@
-#Thu Oct 06 15:51:02 MSK 2016
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
+distributionUrl=https\://services.gradle.org/distributions/gradle-4.6-bin.zip
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
-distributionUrl=https\://services.gradle.org/distributions/gradle-2.14.1-bin.zip
diff --git a/gradlew b/gradlew
index 27309d923..cccdd3d51 100755
--- a/gradlew
+++ b/gradlew
@@ -1,4 +1,4 @@
-#!/usr/bin/env bash
+#!/usr/bin/env sh
##############################################################################
##
@@ -33,11 +33,11 @@ DEFAULT_JVM_OPTS=""
# Use the maximum available, or set MAX_FD != -1 to use that value.
MAX_FD="maximum"
-warn ( ) {
+warn () {
echo "$*"
}
-die ( ) {
+die () {
echo
echo "$*"
echo
@@ -154,11 +154,19 @@ if $cygwin ; then
esac
fi
-# Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules
-function splitJvmOpts() {
- JVM_OPTS=("$@")
+# Escape application args
+save () {
+ for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done
+ echo " "
}
-eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS
-JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME"
+APP_ARGS=$(save "$@")
-exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@"
+# Collect all arguments for the java command, following the shell quoting and substitution rules
+eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS"
+
+# by default we should be in the correct project dir, but when run from Finder on Mac, the cwd is wrong
+if [ "$(uname)" = "Darwin" ] && [ "$HOME" = "$PWD" ]; then
+ cd "$(dirname "$0")"
+fi
+
+exec "$JAVACMD" "$@"
diff --git a/gradlew.bat b/gradlew.bat
index f6d5974e7..e95643d6a 100644
--- a/gradlew.bat
+++ b/gradlew.bat
@@ -49,7 +49,6 @@ goto fail
@rem Get command-line arguments, handling Windows variants
if not "%OS%" == "Windows_NT" goto win9xME_args
-if "%@eval[2+2]" == "4" goto 4NT_args
:win9xME_args
@rem Slurp the command line arguments.
@@ -60,11 +59,6 @@ set _SKIP=2
if "x%~1" == "x" goto execute
set CMD_LINE_ARGS=%*
-goto execute
-
-:4NT_args
-@rem Get arguments from the 4NT Shell from JP Software
-set CMD_LINE_ARGS=%$
:execute
@rem Setup the command line