Skip to content

Commit f12dcbd

Browse files
committed
iam: add conformance tests for IAM Identity Management APIs for GCP
1 parent 4482882 commit f12dcbd

25 files changed

+1147
-139
lines changed

iam/iam-client/src/test/java/com/salesforce/multicloudj/iam/client/AbstractIamIT.java

Lines changed: 263 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@
44
import com.salesforce.multicloudj.iam.driver.AbstractIam;
55
import com.salesforce.multicloudj.iam.model.PolicyDocument;
66
import com.salesforce.multicloudj.iam.model.Statement;
7+
import com.salesforce.multicloudj.iam.model.CreateOptions;
8+
import com.salesforce.multicloudj.iam.model.TrustConfiguration;
79
import org.junit.jupiter.api.AfterAll;
810
import org.junit.jupiter.api.AfterEach;
911
import org.junit.jupiter.api.Assertions;
@@ -13,6 +15,7 @@
1315
import org.junit.jupiter.api.TestInstance;
1416

1517
import java.util.List;
18+
import java.util.Optional;
1619

1720
@TestInstance(TestInstance.Lifecycle.PER_CLASS)
1821
public abstract class AbstractIamIT {
@@ -33,6 +36,10 @@ public interface Harness extends AutoCloseable {
3336

3437
String getIamEndpoint();
3538

39+
String getTrustedPrincipal();
40+
41+
String getTestIdentityName();
42+
3643
default String getPolicyVersion() {
3744
return "";
3845
}
@@ -41,12 +48,14 @@ default String getPolicyVersion() {
4148

4249
List<String> getTestPolicyActions();
4350

44-
String getTestPolicyName();
45-
}
51+
String getTestPolicyName();
52+
}
4653

4754
protected abstract Harness createHarness();
4855

4956
private Harness harness;
57+
private AbstractIam iam;
58+
private IamClient iamClient;
5059

5160
/**
5261
* Initializes the WireMock server before all tests.
@@ -73,27 +82,29 @@ public void shutdownWireMockServer() throws Exception {
7382
@BeforeEach
7483
public void setupTestEnvironment() {
7584
TestsUtil.startWireMockRecording(harness.getIamEndpoint());
85+
iam = harness.createIamDriver(true);
86+
iamClient = new IamClient(iam);
7687
}
7788

7889
/**
7990
* Cleans up the test environment after each test.
8091
*/
8192
@AfterEach
82-
public void cleanupTestEnvironment() {
93+
public void cleanupTestEnvironment() throws Exception {
8394
TestsUtil.stopWireMockRecording();
95+
if (iamClient != null) {
96+
iamClient.close(); // closes underlying AbstractIam
97+
}
8498
}
8599

86100
@Test
87101
public void testAttachInlinePolicy() {
88-
AbstractIam iam = harness.createIamDriver(true);
89-
IamClient iamClient = new IamClient(iam);
90-
91-
Statement.StatementBuilder statementBuilder = Statement.builder()
102+
Statement.StatementBuilder statementBuilder = Statement.builder()
92103
.effect(harness.getTestPolicyEffect());
93104
for (String action : harness.getTestPolicyActions()) {
94105
statementBuilder.action(action);
95106
}
96-
107+
97108
PolicyDocument policyDocument = PolicyDocument.builder()
98109
.version(harness.getPolicyVersion())
99110
.statement(statementBuilder.build())
@@ -109,10 +120,7 @@ public void testAttachInlinePolicy() {
109120

110121
@Test
111122
public void testGetInlinePolicyDetails() {
112-
AbstractIam iam = harness.createIamDriver(true);
113-
IamClient iamClient = new IamClient(iam);
114-
115-
PolicyDocument policyDocument = PolicyDocument.builder()
123+
PolicyDocument policyDocument = PolicyDocument.builder()
116124
.version(harness.getPolicyVersion())
117125
.statement(Statement.builder()
118126
.effect(harness.getTestPolicyEffect())
@@ -139,15 +147,12 @@ public void testGetInlinePolicyDetails() {
139147

140148
@Test
141149
public void testGetAttachedPolicies() {
142-
AbstractIam iam = harness.createIamDriver(true);
143-
IamClient iamClient = new IamClient(iam);
144-
145-
Statement.StatementBuilder statementBuilder = Statement.builder()
150+
Statement.StatementBuilder statementBuilder = Statement.builder()
146151
.effect(harness.getTestPolicyEffect());
147152
for (String action : harness.getTestPolicyActions()) {
148153
statementBuilder.action(action);
149154
}
150-
155+
151156
PolicyDocument policyDocument = PolicyDocument.builder()
152157
.version(harness.getPolicyVersion())
153158
.statement(statementBuilder.build())
@@ -171,10 +176,7 @@ public void testGetAttachedPolicies() {
171176

172177
@Test
173178
public void testRemovePolicy() {
174-
AbstractIam iam = harness.createIamDriver(true);
175-
IamClient iamClient = new IamClient(iam);
176-
177-
PolicyDocument policyDocument = PolicyDocument.builder()
179+
PolicyDocument policyDocument = PolicyDocument.builder()
178180
.version(harness.getPolicyVersion())
179181
.statement(Statement.builder()
180182
.effect(harness.getTestPolicyEffect())
@@ -189,11 +191,244 @@ public void testRemovePolicy() {
189191
harness.getIdentityName()
190192
);
191193

192-
iamClient.removePolicy(
193-
harness.getIdentityName(),
194-
harness.getTestPolicyName(),
195-
harness.getTenantId(),
196-
harness.getRegion()
197-
);
198-
}
194+
iamClient.removePolicy(
195+
harness.getIdentityName(),
196+
harness.getTestPolicyName(),
197+
harness.getTenantId(),
198+
harness.getRegion()
199+
);
200+
}
201+
202+
private void cleanUpIdentity(String identity) {
203+
try {
204+
iamClient.deleteIdentity(
205+
identity,
206+
harness.getTenantId(),
207+
harness.getRegion()
208+
);
209+
} catch (Exception e) {
210+
// Ignore
211+
}
212+
}
213+
214+
/**
215+
* Tests creating an identity without trust configuration.
216+
*/
217+
@Test
218+
public void testCreateIdentityWithoutTrustConfig() {
219+
String identityName = harness.getTestIdentityName();
220+
String identityId = iamClient.createIdentity(
221+
identityName,
222+
"Test identity for MultiCloudJ integration tests",
223+
harness.getTenantId(),
224+
harness.getRegion(),
225+
Optional.empty(),
226+
Optional.empty()
227+
);
228+
229+
Assertions.assertNotNull(identityId, "Identity ID should not be null");
230+
Assertions.assertFalse(identityId.isEmpty(), "Identity ID should not be empty");
231+
232+
cleanUpIdentity(identityName);
233+
}
234+
235+
/**
236+
* Tests creating an identity with trust configuration.
237+
*/
238+
@Test
239+
public void testCreateIdentityWithTrustConfig() {
240+
String identityName = harness.getTestIdentityName() + "Trusted";
241+
TrustConfiguration trustConfig = TrustConfiguration.builder()
242+
.addTrustedPrincipal(harness.getTrustedPrincipal())
243+
.build();
244+
245+
String identityId = iamClient.createIdentity(
246+
identityName,
247+
"Test identity with trust configuration",
248+
harness.getTenantId(),
249+
harness.getRegion(),
250+
Optional.of(trustConfig),
251+
Optional.empty()
252+
);
253+
254+
Assertions.assertNotNull(identityId, "Identity ID should not be null");
255+
Assertions.assertFalse(identityId.isEmpty(), "Identity ID should not be empty");
256+
257+
cleanUpIdentity(identityName);
258+
}
259+
260+
/**
261+
* Tests creating an identity with CreateOptions.
262+
*/
263+
@Test
264+
public void testCreateIdentityWithOptions() {
265+
String identityName = harness.getTestIdentityName() + "Options";
266+
CreateOptions options = CreateOptions.builder().build();
267+
268+
String identityId = iamClient.createIdentity(
269+
identityName,
270+
"Test identity with options",
271+
harness.getTenantId(),
272+
harness.getRegion(),
273+
Optional.empty(),
274+
Optional.of(options)
275+
);
276+
277+
Assertions.assertNotNull(identityId, "Identity ID should not be null");
278+
Assertions.assertFalse(identityId.isEmpty(), "Identity ID should not be empty");
279+
280+
cleanUpIdentity(identityName);
281+
}
282+
283+
/**
284+
* Tests creating an identity with null description.
285+
*/
286+
@Test
287+
public void testCreateIdentityWithNullDescription() {
288+
String identityName = harness.getTestIdentityName() + "NoDesc";
289+
290+
String identityId = iamClient.createIdentity(
291+
identityName,
292+
null,
293+
harness.getTenantId(),
294+
harness.getRegion(),
295+
Optional.empty(),
296+
Optional.empty()
297+
);
298+
299+
Assertions.assertNotNull(identityId, "Identity ID should not be null");
300+
Assertions.assertFalse(identityId.isEmpty(), "Identity ID should not be empty");
301+
302+
cleanUpIdentity(identityName);
303+
}
304+
305+
/**
306+
* Tests getting an identity by name.
307+
*/
308+
@Test
309+
public void testGetIdentity() throws InterruptedException {
310+
String identityName = harness.getTestIdentityName() + "Get";
311+
// First create an identity
312+
String identityId = iamClient.createIdentity(
313+
identityName,
314+
"Test identity for get operation",
315+
harness.getTenantId(),
316+
harness.getRegion(),
317+
Optional.empty(),
318+
Optional.empty()
319+
);
320+
321+
// sleep for 500ms
322+
Thread.sleep(500);
323+
324+
// Then retrieve it
325+
String retrievedIdentity = iamClient.getIdentity(
326+
harness.getTestIdentityName() + "Get",
327+
harness.getTenantId(),
328+
harness.getRegion()
329+
);
330+
331+
Assertions.assertNotNull(retrievedIdentity, "Retrieved identity should not be null");
332+
Assertions.assertFalse(retrievedIdentity.isEmpty(), "Retrieved identity should not be empty");
333+
334+
cleanUpIdentity(identityName);
335+
}
336+
337+
/**
338+
* Tests that the provider ID is correctly set.
339+
*/
340+
@Test
341+
public void testProviderId() {
342+
Assertions.assertNotNull(iam.getProviderId(), "Provider ID should not be null");
343+
Assertions.assertEquals(harness.getProviderId(), iam.getProviderId(),
344+
"Provider ID should match the expected value");
345+
}
346+
347+
/**
348+
* Tests exception mapping for provider-specific exceptions.
349+
*/
350+
@Test
351+
public void testExceptionMapping() {
352+
// Test with a generic exception
353+
Throwable genericException = new RuntimeException("Generic error");
354+
Class<? extends com.salesforce.multicloudj.common.exceptions.SubstrateSdkException> exceptionClass =
355+
iam.getException(genericException);
356+
357+
Assertions.assertNotNull(exceptionClass, "Exception class should not be null");
358+
Assertions.assertEquals(
359+
com.salesforce.multicloudj.common.exceptions.UnknownException.class,
360+
exceptionClass,
361+
"Generic exceptions should map to UnknownException"
362+
);
363+
}
364+
365+
/**
366+
* Tests deleting an identity.
367+
*/
368+
@Test
369+
public void testDeleteIdentity() {
370+
// First create an identity
371+
String identityId = iamClient.createIdentity(
372+
harness.getTestIdentityName() + "Delete",
373+
"Test identity for delete operation",
374+
harness.getTenantId(),
375+
harness.getRegion(),
376+
Optional.empty(),
377+
Optional.empty()
378+
);
379+
380+
Assertions.assertNotNull(identityId, "Identity ID should not be null");
381+
382+
// Then delete it - should not throw any exception
383+
Assertions.assertDoesNotThrow(() ->
384+
iamClient.deleteIdentity(
385+
harness.getTestIdentityName() + "Delete",
386+
harness.getTenantId(),
387+
harness.getRegion()
388+
)
389+
);
390+
}
391+
392+
/**
393+
* Tests the complete lifecycle: create, get, and delete an identity.
394+
*/
395+
@Test
396+
public void testIdentityLifecycle() throws InterruptedException {
397+
String testIdentityName = harness.getTestIdentityName() + "LifeCycle";
398+
399+
// Step 1: Create an identity
400+
String identityId = iamClient.createIdentity(
401+
testIdentityName,
402+
"Test identity for lifecycle test",
403+
harness.getTenantId(),
404+
harness.getRegion(),
405+
Optional.empty(),
406+
Optional.empty()
407+
);
408+
409+
Assertions.assertNotNull(identityId, "Identity ID should not be null after creation");
410+
Assertions.assertFalse(identityId.isEmpty(), "Identity ID should not be empty after creation");
411+
412+
// Step 2: Get the identity to verify it exists
413+
Thread.sleep(500);
414+
415+
String retrievedIdentity = iamClient.getIdentity(
416+
testIdentityName,
417+
harness.getTenantId(),
418+
harness.getRegion()
419+
);
420+
421+
Assertions.assertNotNull(retrievedIdentity, "Retrieved identity should not be null");
422+
Assertions.assertFalse(retrievedIdentity.isEmpty(), "Retrieved identity should not be empty");
423+
424+
// Step 3: Delete the identity
425+
Assertions.assertDoesNotThrow(() ->
426+
iamClient.deleteIdentity(
427+
testIdentityName,
428+
harness.getTenantId(),
429+
harness.getRegion()
430+
),
431+
"Deleting identity should not throw an exception"
432+
);
433+
}
199434
}

iam/iam-gcp/pom.xml

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,12 @@
5858
<version>3.12.1</version>
5959
<scope>test</scope>
6060
</dependency>
61+
<dependency>
62+
<groupId>org.wiremock</groupId>
63+
<artifactId>wiremock-grpc-extension</artifactId>
64+
<version>0.11.0</version>
65+
<scope>test</scope>
66+
</dependency>
6167
<dependency>
6268
<groupId>com.salesforce.multicloudj</groupId>
6369
<artifactId>iam-client</artifactId>

0 commit comments

Comments
 (0)