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

Commit 35abe19

Browse files
committed
Enabled majority of tests to run with IAM credentials
Jenkinsfile changes for IAM matrix entry and API key. Added different credential blocks for different cred IDs. Updated test helper to provide IAM based ClientBuilder or CloudantClient when IAM API key is configured. Updated replication tests to use IAM auth when needed. Used mock host and credentials for CloudFoundaryServiceTest.
1 parent 699f683 commit 35abe19

14 files changed

Lines changed: 168 additions & 42 deletions

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.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"
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/src/test/java/com/cloudant/tests/CloudFoundryServiceTest.java

Lines changed: 8 additions & 10 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
});

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

Lines changed: 16 additions & 9 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,11 +33,11 @@ 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 COUCH_USERNAME;
37+
static final String COUCH_PASSWORD;
38+
static final String COUCH_HOST;
3839

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

4142
private static final String COUCH_PORT;
4243
private static final String HTTP_PROTOCOL;
@@ -76,7 +77,8 @@ public abstract class CloudantClientHelper {
7677

7778
// Ensure username and password are correctly URL encoded when included in the URI
7879
SERVER_URI_WITH_USER_INFO = HTTP_PROTOCOL + "://"
79-
+ ((COUCH_USERNAME != null) ? URLEncoder.encode(COUCH_USERNAME, "UTF-8") +
80+
+ ((!IamAuthCondition.IS_IAM_ENABLED && COUCH_USERNAME != null) ?
81+
URLEncoder.encode(COUCH_USERNAME, "UTF-8") +
8082
":" + URLEncoder.encode(COUCH_PASSWORD, "UTF-8") + "@" : "") + COUCH_HOST + (
8183
(COUCH_PORT != null) ? ":" + COUCH_PORT : ""); //port if supplied
8284
} catch (Throwable t) {
@@ -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(COUCH_USERNAME)
126+
.password(COUCH_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: 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
@@ -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,6 +493,7 @@ 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 =

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: 5 additions & 1 deletion
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,6 +223,7 @@ public void testReadBeforeExecute() throws Exception {
221223
// be named cookie_test
222224
//
223225
@TestTemplate
226+
@DisabledWithIam
224227
@RequiresCloudant
225228
public void testCookieAuthWithoutRetry() throws IOException {
226229
CookieInterceptor interceptor = new CookieInterceptor(CloudantClientHelper.COUCH_USERNAME,
@@ -278,6 +281,7 @@ 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 =

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

Lines changed: 2 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
@@ -64,6 +64,7 @@ public static void setUp() throws Exception {
6464
r.source(getReplicationSourceUrl("movies-demo"));
6565
r.createTarget(true);
6666
r.target(dbResource.getDbURIWithUserInfo());
67+
dbResource.appendReplicationAuth(r);
6768
r.trigger();
6869

6970
//Create indexes

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

Lines changed: 11 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
/*
22
* Copyright (C) 2011 lightcouch.org
3-
* Copyright © 2015, 2018 IBM Corp. All rights reserved.
3+
* Copyright © 2015, 2019 IBM Corp. All rights reserved.
44
*
55
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file
66
* except in compliance with the License. You may obtain a copy of the License at
@@ -36,10 +36,11 @@ public class ReplicationTest extends TestWithReplication {
3636

3737
@Test
3838
public void replication() {
39-
ReplicationResult result = account.replication()
39+
ReplicationResult result = db1Resource.appendReplicationAuth(account.replication()
4040
.createTarget(true)
4141
.source(db1URI)
4242
.target(db2URI)
43+
)
4344
.trigger();
4445

4546
assertTrue(result.isOk(), "The replication should complete ok");
@@ -53,12 +54,13 @@ public void replication_filteredWithQueryParams() {
5354
Map<String, Object> queryParams = new HashMap<String, Object>();
5455
queryParams.put("somekey1", "value 1");
5556

56-
ReplicationResult result = account.replication()
57+
ReplicationResult result = db1Resource.appendReplicationAuth(account.replication()
5758
.createTarget(true)
5859
.source(db1URI)
5960
.target(db2URI)
6061
.filter("example/example_filter")
6162
.queryParams(queryParams)
63+
)
6264
.trigger();
6365

6466
assertTrue(result.isOk(), "The replication should complete ok");
@@ -72,8 +74,9 @@ public void replicateDatabaseUsingReplicationTrigger() throws Exception {
7274
db1.save(fooOnDb1);
7375

7476
// trigger a replication
75-
ReplicationResult result = account.replication().source(db1URI)
76-
.target(db2URI).createTarget(true).trigger();
77+
ReplicationResult result =
78+
db1Resource.appendReplicationAuth(account.replication().source(db1URI)
79+
.target(db2URI).createTarget(true)).trigger();
7780

7881
assertTrue(result.isOk(), "The replication should complete ok");
7982

@@ -93,8 +96,9 @@ public void replication_conflict() throws Exception {
9396
db2.save(foodb2);
9497

9598
//replicate with DB1 with DB2
96-
ReplicationResult result = account.replication().source(db1URI)
97-
.target(db2URI).trigger();
99+
ReplicationResult result =
100+
db1Resource.appendReplicationAuth(account.replication().source(db1URI)
101+
.target(db2URI)).trigger();
98102

99103
assertTrue(result.isOk(), "The replication should complete ok");
100104

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

Lines changed: 9 additions & 5 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
@@ -50,11 +50,12 @@ public void cleanUpReplicatorDoc() throws Exception {
5050

5151
@Test
5252
public void replication() throws Exception {
53-
Response response = account.replicator()
53+
Response response = db1Resource.appendReplicatorAuth(account.replicator()
5454
.replicatorDocId(repDocId)
5555
.createTarget(true)
5656
.source(db1URI)
5757
.target(db2URI)
58+
)
5859
.save();
5960

6061
// find and remove replicator doc
@@ -68,13 +69,14 @@ public void replication_filteredWithQueryParams() throws Exception {
6869
Map<String, Object> queryParams = new HashMap<String, Object>();
6970
queryParams.put("somekey1", "value 1");
7071

71-
Response response = account.replicator()
72+
Response response = db1Resource.appendReplicatorAuth(account.replicator()
7273
.createTarget(true)
7374
.replicatorDocId(repDocId)
7475
.source(db1URI)
7576
.target(db2URI)
7677
.filter("example/example_filter")
7778
.queryParams(queryParams)
79+
)
7880
.save();
7981

8082
// find and remove replicator doc
@@ -87,11 +89,12 @@ public void replication_filteredWithQueryParams() throws Exception {
8789
public void replicatorDB() throws Exception {
8890

8991
// trigger a replication
90-
Response response = account.replicator()
92+
Response response = db1Resource.appendReplicatorAuth(account.replicator()
9193
.replicatorDocId(repDocId)
9294
.source(db1URI)
9395
.target(db2URI).continuous(true)
9496
.createTarget(true)
97+
)
9598
.save();
9699

97100
// we need the replication to start before continuing
@@ -116,8 +119,9 @@ public void replication_conflict() throws Exception {
116119
db2.save(foodb2);
117120

118121
//replicate with DB1 with DB2
119-
Response response = account.replicator().source(db1URI)
122+
Response response = db1Resource.appendReplicatorAuth(account.replicator().source(db1URI)
120123
.target(db2URI).replicatorDocId(repDocId)
124+
)
121125
.save();
122126

123127
// we need the replication to finish before continuing

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

Lines changed: 2 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
@@ -50,6 +50,7 @@ public static void setUp() throws Exception {
5050
r.source(getReplicationSourceUrl("animaldb"));
5151
r.createTarget(true);
5252
r.target(dbResource.getDbURIWithUserInfo());
53+
dbResource.appendReplicationAuth(r);
5354
r.trigger();
5455

5556
// sync the design doc for faceted search

0 commit comments

Comments
 (0)