Skip to content
This repository was archived by the owner on Mar 11, 2022. It is now read-only.

Commit d36d95e

Browse files
authored
Merge pull request #483 from cloudant/iam-testing
Enabled IAM auth for testing
2 parents 699f683 + 8f015c3 commit d36d95e

16 files changed

+208
-82
lines changed

CONTRIBUTING.md

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -112,11 +112,11 @@ CouchDB. To run tests with a remote CouchDB or Cloudant, you need set the
112112
details of this CouchDB server, including access credentials:
113113

114114
```
115-
systemProp.test.couch.username=yourUsername
116-
systemProp.test.couch.password=yourPassword
117-
systemProp.test.couch.host=couchdbHost # default localhost
118-
systemProp.test.couch.port=couchdbPort # default 5984
119-
systemProp.test.couch.http=[http|https] # default http
115+
systemProp.test.server.user=yourUsername
116+
systemProp.test.server.password=yourPassword
117+
systemProp.test.server.host=couchdborcloudanthost # default localhost
118+
systemProp.test.server.port=5984 # default 5984
119+
systemProp.test.server.protocol=[http|https] # default http
120120
```
121121
Alternatively, provide a URL containing all the above information:
122122
```

Jenkinsfile

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -27,10 +27,9 @@ def runTests(testEnv, isServiceTests) {
2727

2828
//Set up the environment and run the tests
2929
withEnv(testEnv) {
30-
withCredentials([usernamePassword(credentialsId: env.CREDS_ID, usernameVariable: 'DB_USER', passwordVariable: 'DB_PASSWORD'),
31-
string(credentialsId: 'clientlibs-test-iam', variable: 'DB_IAM_API_KEY')]) {
30+
withCredentials([(env.CREDS_ID.contains('iam')) ? string(credentialsId: env.CREDS_ID, variable: 'IAM_API_KEY') : usernamePassword(credentialsId: env.CREDS_ID, usernameVariable: 'DB_USER', passwordVariable: 'DB_PASSWORD')]) {
3231
try {
33-
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'
32+
sh "./gradlew ${(env.DB_USER?.trim()) ? '-Dtest.server.user=$DB_USER -Dtest.server.password=$DB_PASSWORD' : ''} -Dtest.server.host=\$DB_HOST -Dtest.server.port=\$DB_PORT -Dtest.server.protocol=\$DB_HTTP \$GRADLE_TARGET"
3433
} finally {
3534
junit '**/build/test-results/**/*.xml'
3635
}
@@ -51,6 +50,7 @@ stage('Build') {
5150
stage('QA') {
5251
// Define the matrix environments
5352
def CLOUDANT_ENV = ['DB_HTTP=https', 'DB_HOST=clientlibs-test.cloudant.com', 'DB_PORT=443', 'DB_IGNORE_COMPACTION=true', 'CREDS_ID=clientlibs-test']
53+
def CLOUDANT_IAM_ENV = ['DB_HTTP=https', 'DB_HOST=clientlibs-test.cloudant.com', 'DB_PORT=443', 'DB_IGNORE_COMPACTION=true', 'CREDS_ID=clientlibs-test-iam']
5454
def COUCH1_6_ENV = ['DB_HTTP=http', 'DB_HOST=cloudantsync002.bristol.uk.ibm.com', 'DB_PORT=5984', 'DB_IGNORE_COMPACTION=false', 'CREDS_ID=couchdb']
5555
def COUCH2_0_ENV = ['DB_HTTP=http', 'DB_HOST=cloudantsync002.bristol.uk.ibm.com', 'DB_PORT=5985', 'DB_IGNORE_COMPACTION=true', 'CREDS_ID=couchdb']
5656
def CLOUDANT_LOCAL_ENV = ['DB_HTTP=http', 'DB_HOST=cloudantsync002.bristol.uk.ibm.com', 'DB_PORT=8081', 'DB_IGNORE_COMPACTION=true', 'CREDS_ID=couchdb']
@@ -86,6 +86,9 @@ stage('QA') {
8686
},
8787
CloudantLocal: {
8888
runTests(CLOUDANT_LOCAL_ENV, false)
89+
},
90+
CloudantIam: {
91+
runTests(CLOUDANT_IAM_ENV, true)
8992
}
9093
)
9194
}

cloudant-client/build.gradle

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -110,9 +110,9 @@ task cloudantServiceTest(type: Test) {
110110

111111
task integrationTest(type: Test) {
112112
// Special environment variables for integration tests
113-
[SERVER_URL:'test.couch.url',
114-
SERVER_USER:'test.couch.username',
115-
SERVER_PASSWORD:'test.couch.password',
113+
[SERVER_URL:'test.server.url',
114+
SERVER_USER:'test.server.user',
115+
SERVER_PASSWORD:'test.server.password',
116116
TEST_REPLICATION_SOURCE_URL:'test.replication.source.url'].each { k,v ->
117117
def e = System.getenv(k)
118118
if (e) {

cloudant-client/src/test/java/com/cloudant/tests/CloudFoundryServiceTest.java

Lines changed: 12 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright © 2016, 2018 IBM Corp. All rights reserved.
2+
* Copyright © 2016, 2019 IBM Corp. All rights reserved.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file
55
* except in compliance with the License. You may obtain a copy of the License at
@@ -14,18 +14,14 @@
1414

1515
package com.cloudant.tests;
1616

17+
import static com.cloudant.tests.util.MockWebServerResources.IAM_API_KEY;
1718
import static com.cloudant.tests.util.MockWebServerResources.IAM_TOKEN;
1819
import static com.cloudant.tests.util.MockWebServerResources.OK_IAM_COOKIE;
19-
import static com.cloudant.tests.util.MockWebServerResources.IAM_API_KEY;
2020
import static com.cloudant.tests.util.MockWebServerResources.iamTokenEndpoint;
2121
import static org.junit.jupiter.api.Assertions.assertEquals;
22-
import static org.junit.jupiter.api.Assertions.assertNotNull;
23-
import static org.junit.jupiter.api.Assertions.assertTrue;
2422

2523
import com.cloudant.client.api.ClientBuilder;
2624
import com.cloudant.client.api.CloudantClient;
27-
import com.cloudant.http.Http;
28-
import com.cloudant.http.HttpConnection;
2925
import com.cloudant.tests.extensions.MockWebServerExtension;
3026
import com.cloudant.tests.util.IamSystemPropertyMock;
3127
import com.cloudant.tests.util.MockWebServerResources;
@@ -52,6 +48,10 @@ public class CloudFoundryServiceTest {
5248

5349
public static IamSystemPropertyMock iamSystemPropertyMock;
5450

51+
private static String TEST_HOST = "https://cloudant.example";
52+
private static String TEST_USER = "user";
53+
private static String TEST_PASSWORD = "pass";
54+
5555
private String mockServerHostPort;
5656

5757
@RegisterExtension
@@ -167,8 +167,7 @@ public void vcapMissingServiceNameSpecified() {
167167
public void execute() throws Throwable {
168168
VCAPGenerator vcap = new CloudFoundryServiceTest.VCAPGenerator();
169169
vcap.createNewLegacyService("test_bluemix_service_1",
170-
CloudantClientHelper.COUCH_HOST,
171-
CloudantClientHelper.COUCH_USERNAME, CloudantClientHelper.COUCH_PASSWORD);
170+
TEST_HOST, TEST_USER, TEST_PASSWORD);
172171
ClientBuilder.bluemix(vcap.toJson(), "missingService", "test_bluemix_service_1")
173172
.build();
174173
}
@@ -182,8 +181,7 @@ public void vcapNullServiceNameSpecified() {
182181
public void execute() throws Throwable {
183182
VCAPGenerator vcap = new CloudFoundryServiceTest.VCAPGenerator();
184183
vcap.createNewLegacyService("test_bluemix_service_1",
185-
CloudantClientHelper.COUCH_HOST,
186-
CloudantClientHelper.COUCH_USERNAME, CloudantClientHelper.COUCH_PASSWORD);
184+
TEST_HOST, TEST_USER, TEST_PASSWORD);
187185
ClientBuilder.bluemix(vcap.toJson(), null, "test_bluemix_service_1").build();
188186
}
189187
});
@@ -254,7 +252,7 @@ public void vcapSingleServiceEmptyCredentials() {
254252
public void execute() throws Throwable {
255253
VCAPGenerator vcap = new CloudFoundryServiceTest.VCAPGenerator();
256254
vcap.createNewLegacyServiceWithEmptyCredentials("test_bluemix_service_1",
257-
CloudantClientHelper.COUCH_HOST);
255+
CloudantClientHelper.SERVER_HOST);
258256
ClientBuilder.bluemix(vcap.toJson(), "test_bluemix_service_1");
259257
}
260258
});
@@ -279,7 +277,7 @@ public void vcapSingleServiceEmptyIAM() {
279277
public void execute() throws Throwable {
280278
VCAPGenerator vcap = new CloudFoundryServiceTest.VCAPGenerator();
281279
vcap.createNewServiceWithEmptyIAM("test_bluemix_service_1",
282-
CloudantClientHelper.COUCH_HOST);
280+
CloudantClientHelper.SERVER_HOST);
283281
ClientBuilder.bluemix(vcap.toJson(), "test_bluemix_service_1");
284282
}
285283
});
@@ -384,7 +382,7 @@ public void execute() throws Throwable {
384382
vcap.createNewLegacyService("test_bluemix_service_2", "foo2.bar", "admin2",
385383
"pass2");
386384
vcap.createNewLegacyServiceWithEmptyCredentials("test_bluemix_service_3",
387-
CloudantClientHelper.COUCH_HOST);
385+
CloudantClientHelper.SERVER_HOST);
388386
ClientBuilder.bluemix(vcap.toJson(), "test_bluemix_service_3");
389387
}
390388
});
@@ -399,7 +397,7 @@ public void execute() throws Throwable {
399397
vcap.createNewService("test_bluemix_service_1", "admin1", "apikey1");
400398
vcap.createNewService("test_bluemix_service_2", "admin2", "apikey2");
401399
vcap.createNewServiceWithEmptyIAM("test_bluemix_service_3",
402-
CloudantClientHelper.COUCH_HOST);
400+
CloudantClientHelper.SERVER_HOST);
403401
ClientBuilder.bluemix(vcap.toJson(), "test_bluemix_service_3");
404402
}
405403
});

cloudant-client/src/test/java/com/cloudant/tests/CloudantClientHelper.java

Lines changed: 37 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright © 2015, 2018 IBM Corp. All rights reserved.
2+
* Copyright © 2015, 2019 IBM Corp. All rights reserved.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file
55
* except in compliance with the License. You may obtain a copy of the License at
@@ -16,6 +16,7 @@
1616

1717
import com.cloudant.client.api.ClientBuilder;
1818
import com.cloudant.client.api.CloudantClient;
19+
import com.cloudant.tests.extensions.IamAuthCondition;
1920

2021
import okhttp3.mockwebserver.MockWebServer;
2122

@@ -32,53 +33,54 @@ public abstract class CloudantClientHelper {
3233
//some tests need access to the URI with user info (e.g. replication)
3334
public static final String SERVER_URI_WITH_USER_INFO;
3435
//some tests need access to the credentials (e.g. auth interceptors, vcap)
35-
public static final String COUCH_USERNAME;
36-
public static final String COUCH_PASSWORD;
37-
public static final String COUCH_HOST;
36+
static final String SERVER_USER;
37+
static final String SERVER_PASSWORD;
38+
static final String SERVER_HOST;
3839

39-
protected static final CloudantClient CLIENT_INSTANCE;
40+
private static final CloudantClient CLIENT_INSTANCE;
4041

41-
private static final String COUCH_PORT;
42-
private static final String HTTP_PROTOCOL;
42+
private static final String SERVER_PORT;
43+
private static final String SERVER_PROTOCOL;
4344
private static final URL SERVER_URL;
4445

4546
static {
4647

4748
try {
4849
//a URL might be supplied, otherwise use the separate properties
49-
String URL = System.getProperty("test.couch.url");
50+
String URL = System.getProperty("test.server.url");
5051
if (URL != null) {
5152
URL couch = new URL(URL);
52-
HTTP_PROTOCOL = couch.getProtocol();
53-
COUCH_HOST = couch.getHost();
54-
COUCH_PORT = (couch.getPort() < 0) ? null : Integer.toString(couch.getPort());
53+
SERVER_PROTOCOL = couch.getProtocol();
54+
SERVER_HOST = couch.getHost();
55+
SERVER_PORT = (couch.getPort() < 0) ? null : Integer.toString(couch.getPort());
5556
String userInfo = couch.getUserInfo();
5657
if (userInfo != null) {
57-
COUCH_USERNAME = userInfo.substring(0, userInfo.indexOf(":"));
58-
COUCH_PASSWORD = userInfo.substring(userInfo.indexOf(":") + 1);
58+
SERVER_USER = userInfo.substring(0, userInfo.indexOf(":"));
59+
SERVER_PASSWORD = userInfo.substring(userInfo.indexOf(":") + 1);
5960
} else {
60-
COUCH_USERNAME = System.getProperty("test.couch.username");
61-
COUCH_PASSWORD = System.getProperty("test.couch.password");
61+
SERVER_USER = System.getProperty("test.server.user");
62+
SERVER_PASSWORD = System.getProperty("test.server.password");
6263
}
6364
} else {
64-
COUCH_USERNAME = System.getProperty("test.couch.username");
65-
COUCH_PASSWORD = System.getProperty("test.couch.password");
66-
COUCH_HOST = System.getProperty("test.couch.host", "localhost");
67-
COUCH_PORT = System.getProperty("test.couch.port", "5984");
68-
HTTP_PROTOCOL = System.getProperty("test.couch.http", "http"); //should either be
65+
SERVER_USER = System.getProperty("test.server.user");
66+
SERVER_PASSWORD = System.getProperty("test.server.password");
67+
SERVER_HOST = System.getProperty("test.server.host", "localhost");
68+
SERVER_PORT = System.getProperty("test.server.port", "5984");
69+
SERVER_PROTOCOL = System.getProperty("test.server.protocol", "http"); //should either be
6970
// http or https
7071
}
7172

7273
//now build the URLs
73-
SERVER_URL = new URL(HTTP_PROTOCOL + "://"
74-
+ COUCH_HOST
75-
+ ((COUCH_PORT != null) ? ":" + COUCH_PORT : "")); //port if supplied
74+
SERVER_URL = new URL(SERVER_PROTOCOL + "://"
75+
+ SERVER_HOST
76+
+ ((SERVER_PORT != null) ? ":" + SERVER_PORT : "")); //port if supplied
7677

7778
// Ensure username and password are correctly URL encoded when included in the URI
78-
SERVER_URI_WITH_USER_INFO = HTTP_PROTOCOL + "://"
79-
+ ((COUCH_USERNAME != null) ? URLEncoder.encode(COUCH_USERNAME, "UTF-8") +
80-
":" + URLEncoder.encode(COUCH_PASSWORD, "UTF-8") + "@" : "") + COUCH_HOST + (
81-
(COUCH_PORT != null) ? ":" + COUCH_PORT : ""); //port if supplied
79+
SERVER_URI_WITH_USER_INFO = SERVER_PROTOCOL + "://"
80+
+ ((!IamAuthCondition.IS_IAM_ENABLED && SERVER_USER != null) ?
81+
URLEncoder.encode(SERVER_USER, "UTF-8") +
82+
":" + URLEncoder.encode(SERVER_PASSWORD, "UTF-8") + "@" : "") + SERVER_HOST + (
83+
(SERVER_PORT != null) ? ":" + SERVER_PORT : ""); //port if supplied
8284
} catch (Throwable t) {
8385
throw new RuntimeException(t);
8486
}
@@ -116,9 +118,14 @@ public static ClientBuilder newMockWebServerClientBuilder(MockWebServer mockServ
116118
}
117119

118120
public static ClientBuilder getClientBuilder() {
119-
return ClientBuilder.url(SERVER_URL)
120-
.username(COUCH_USERNAME)
121-
.password(COUCH_PASSWORD);
121+
ClientBuilder builder = ClientBuilder.url(SERVER_URL);
122+
if (IamAuthCondition.IS_IAM_ENABLED) {
123+
builder.iamApiKey(IamAuthCondition.IAM_API_KEY);
124+
} else {
125+
builder.username(SERVER_USER)
126+
.password(SERVER_PASSWORD);
127+
}
128+
return builder;
122129
}
123130

124131
static String REP_SOURCE = null;

cloudant-client/src/test/java/com/cloudant/tests/CloudantClientTests.java

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright © 2015, 2018 IBM Corp. All rights reserved.
2+
* Copyright © 2015, 2019 IBM Corp. All rights reserved.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file
55
* except in compliance with the License. You may obtain a copy of the License at
@@ -37,6 +37,7 @@
3737
import com.cloudant.test.main.RequiresCloudantService;
3838
import com.cloudant.test.main.RequiresDB;
3939
import com.cloudant.tests.base.TestWithDbPerClass;
40+
import com.cloudant.tests.extensions.DisabledWithIam;
4041
import com.cloudant.tests.extensions.MockWebServerExtension;
4142
import com.cloudant.tests.util.MockWebServerResources;
4243
import com.cloudant.tests.util.Utils;
@@ -88,6 +89,7 @@ public void beforeEach() {
8889
}
8990

9091
@Test
92+
@DisabledWithIam
9193
@RequiresCloudantService
9294
public void apiKey() {
9395
ApiKey key = account.generateApiKey();
@@ -491,13 +493,14 @@ public void sessionDeleteOnShutdown() throws Exception {
491493
* Test that adding the Basic Authentication interceptor to CloudantClient works.
492494
*/
493495
@Test
496+
@DisabledWithIam
494497
@RequiresCloudant
495498
public void testBasicAuth() throws IOException {
496499
BasicAuthInterceptor interceptor =
497-
new BasicAuthInterceptor(CloudantClientHelper.COUCH_USERNAME
498-
+ ":" + CloudantClientHelper.COUCH_PASSWORD);
500+
new BasicAuthInterceptor(CloudantClientHelper.SERVER_USER
501+
+ ":" + CloudantClientHelper.SERVER_PASSWORD);
499502

500-
CloudantClient client = ClientBuilder.account(CloudantClientHelper.COUCH_USERNAME)
503+
CloudantClient client = ClientBuilder.account(CloudantClientHelper.SERVER_USER)
501504
.interceptors(interceptor).build();
502505

503506
// Test passes if there are no exceptions

cloudant-client/src/test/java/com/cloudant/tests/DatabaseTest.java

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright © 2015, 2018 IBM Corp. All rights reserved.
2+
* Copyright © 2015, 2019 IBM Corp. All rights reserved.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file
55
* except in compliance with the License. You may obtain a copy of the License at
@@ -31,6 +31,7 @@
3131
import com.cloudant.test.main.RequiresCouch;
3232
import com.cloudant.test.main.RequiresDB;
3333
import com.cloudant.tests.base.TestWithDbPerClass;
34+
import com.cloudant.tests.extensions.DisabledWithIam;
3435
import com.cloudant.tests.extensions.MockWebServerExtension;
3536
import com.cloudant.tests.util.MockWebServerResources;
3637
import com.google.gson.GsonBuilder;
@@ -70,10 +71,12 @@ public static void beforeAll() throws Exception {
7071
r.source(getReplicationSourceUrl("animaldb"));
7172
r.createTarget(true);
7273
r.target(dbResource.getDbURIWithUserInfo());
74+
dbResource.appendReplicationAuth(r);
7375
r.trigger();
7476
}
7577

7678
@Test
79+
@DisabledWithIam
7780
@RequiresCloudantService
7881
public void permissions() {
7982
Map<String, EnumSet<Permissions>> userPerms = db.getPermissions();

cloudant-client/src/test/java/com/cloudant/tests/HttpTest.java

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright © 2017, 2018 IBM Corp. All rights reserved.
2+
* Copyright © 2017, 2019 IBM Corp. All rights reserved.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file
55
* except in compliance with the License. You may obtain a copy of the License at
@@ -41,6 +41,7 @@
4141
import com.cloudant.test.main.RequiresCloudant;
4242
import com.cloudant.tests.extensions.CloudantClientExtension;
4343
import com.cloudant.tests.extensions.DatabaseExtension;
44+
import com.cloudant.tests.extensions.DisabledWithIam;
4445
import com.cloudant.tests.extensions.MockWebServerExtension;
4546
import com.cloudant.tests.extensions.MultiExtension;
4647
import com.cloudant.tests.util.HttpFactoryParameterizedTest;
@@ -163,6 +164,7 @@ public void beforeEach() {
163164
* Basic test that we can write a document body by POSTing to a known database
164165
*/
165166
@TestTemplate
167+
@DisabledWithIam
166168
public void testWriteToServerOk() throws Exception {
167169
HttpConnection conn = new HttpConnection("POST", new URL(dbResource.getDbURIWithUserInfo()),
168170
"application/json");
@@ -221,10 +223,11 @@ public void testReadBeforeExecute() throws Exception {
221223
// be named cookie_test
222224
//
223225
@TestTemplate
226+
@DisabledWithIam
224227
@RequiresCloudant
225228
public void testCookieAuthWithoutRetry() throws IOException {
226-
CookieInterceptor interceptor = new CookieInterceptor(CloudantClientHelper.COUCH_USERNAME,
227-
CloudantClientHelper.COUCH_PASSWORD, clientResource.get().getBaseUri().toString());
229+
CookieInterceptor interceptor = new CookieInterceptor(CloudantClientHelper.SERVER_USER,
230+
CloudantClientHelper.SERVER_PASSWORD, clientResource.get().getBaseUri().toString());
228231

229232
HttpConnection conn = new HttpConnection("POST", dbResource.get().getDBUri().toURL(),
230233
"application/json");
@@ -278,11 +281,12 @@ public void testCookieAuthWithPath() throws Exception {
278281
* is expected to hold the newly created document's id and rev.
279282
*/
280283
@TestTemplate
284+
@DisabledWithIam
281285
@RequiresCloudant
282286
public void testBasicAuth() throws IOException {
283287
BasicAuthInterceptor interceptor =
284-
new BasicAuthInterceptor(CloudantClientHelper.COUCH_USERNAME
285-
+ ":" + CloudantClientHelper.COUCH_PASSWORD);
288+
new BasicAuthInterceptor(CloudantClientHelper.SERVER_USER
289+
+ ":" + CloudantClientHelper.SERVER_PASSWORD);
286290

287291
HttpConnection conn = new HttpConnection("POST", dbResource.get().getDBUri().toURL(),
288292
"application/json");

0 commit comments

Comments
 (0)