Skip to content

Commit 7fcb594

Browse files
committed
Add unit-tests for json-based snapshottakers
1 parent ba52f6e commit 7fcb594

File tree

5 files changed

+216
-2
lines changed

5 files changed

+216
-2
lines changed
Lines changed: 168 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,168 @@
1+
package io.jenkins.plugins.credentials.secretsmanager.factory;
2+
3+
import static org.assertj.core.api.Assertions.assertThat;
4+
5+
import java.lang.reflect.Constructor;
6+
import java.lang.reflect.InvocationTargetException;
7+
import java.lang.reflect.Method;
8+
import java.util.IdentityHashMap;
9+
import java.util.Map;
10+
import java.util.function.Supplier;
11+
12+
import org.junit.Before;
13+
import org.junit.Test;
14+
15+
import com.cloudbees.plugins.credentials.CredentialsSnapshotTaker;
16+
17+
import hudson.Extension;
18+
19+
public abstract class BaseAwsJsonCredentialsSnapshotTakerTest<C extends BaseAwsJsonCredentials, ST extends CredentialsSnapshotTaker<C>> {
20+
protected final Class<ST> classUnderTest;
21+
protected final Class<C> credentialBeingSnapshotted;
22+
23+
protected BaseAwsJsonCredentialsSnapshotTakerTest(Class<ST> classUnderTest, Class<C> credentialBeingSnapshotted) {
24+
this.classUnderTest = classUnderTest;
25+
this.credentialBeingSnapshotted = credentialBeingSnapshotted;
26+
}
27+
28+
protected abstract C makeCredential();
29+
30+
private LimitedUseSupplier<?> limitedUseSupplier;
31+
32+
@Before
33+
public void beforeTest() {
34+
limitedUseSupplier = null;
35+
}
36+
37+
protected <T> Supplier<T> mkSupplier(T supplied) {
38+
final LimitedUseSupplier<T> result = new LimitedUseSupplier<>(supplied);
39+
limitedUseSupplier = result;
40+
return result;
41+
}
42+
43+
private ST makeInstanceOrThrow() throws NoSuchMethodException, SecurityException, InstantiationException,
44+
IllegalAccessException, IllegalArgumentException, InvocationTargetException {
45+
final Constructor<ST> noArgsConstructor = classUnderTest.getConstructor();
46+
return noArgsConstructor.newInstance();
47+
}
48+
49+
@Test
50+
public void hasNoArgsConstructor() {
51+
// Given
52+
53+
// When
54+
Exception actual = null;
55+
try {
56+
makeInstanceOrThrow();
57+
} catch (Exception ex) {
58+
actual = ex;
59+
}
60+
61+
// Then
62+
assertThat(actual).isNull();
63+
}
64+
65+
@Test
66+
public void hasExtensionAnnotation() {
67+
// Given
68+
69+
// When
70+
final Extension actual = classUnderTest.getAnnotation(Extension.class);
71+
72+
// Then
73+
assertThat(actual).isNotNull();
74+
}
75+
76+
@Test
77+
public void typeTest() throws Exception {
78+
// Given
79+
final Class<C> expected = credentialBeingSnapshotted;
80+
final ST instance = makeInstanceOrThrow();
81+
82+
// When
83+
final Class<C> actual = instance.type();
84+
85+
// Then
86+
assertThat(actual).isEqualTo(expected);
87+
}
88+
89+
@Test
90+
public void snapshotGivenNullThenThrows() throws Exception {
91+
// Given
92+
final ST instance = makeInstanceOrThrow();
93+
94+
// When
95+
Exception actual = null;
96+
try {
97+
instance.snapshot(null);
98+
} catch (Exception ex) {
99+
actual = ex;
100+
}
101+
102+
// Then
103+
assertThat(actual).isNotNull();
104+
}
105+
106+
@Test
107+
public void snapshotGivenInstanceThenCreatesSnapshot() throws Exception {
108+
// Given
109+
final ST instance = makeInstanceOrThrow();
110+
final C credential = makeCredential();
111+
final Method[] allMethods = credentialBeingSnapshotted.getDeclaredMethods();
112+
final Map<Method, Object> expectedResults = new IdentityHashMap<>();
113+
for (final Method m : allMethods) {
114+
if (m.getParameterCount() != 0) {
115+
continue;
116+
}
117+
final Object expectedValue = m.invoke(credential);
118+
expectedResults.put(m, expectedValue);
119+
}
120+
final String expectedId = credential.getId();
121+
final String expectedDescription = credential.getDescription();
122+
123+
// When
124+
final C actual = instance.snapshot(credential);
125+
limitedUseSupplier.noFurtherUsePermitted();
126+
final String actualId = actual.getId();
127+
final String actualDescription = actual.getDescription();
128+
final Map<Method, Object> actualResults = new IdentityHashMap<>();
129+
for (final Method m : expectedResults.keySet()) {
130+
final Object actualValue = m.invoke(actual);
131+
actualResults.put(m, actualValue);
132+
}
133+
134+
// Then
135+
assertThat(actual).isNotNull();
136+
assertThat(actual).isNotSameAs(credential);
137+
assertThat(actual).isInstanceOf(credentialBeingSnapshotted);
138+
assertThat(actualId).as("getId()").isEqualTo(expectedId);
139+
assertThat(actualDescription).as("getDescription").isEqualTo(expectedDescription);
140+
for (final Method m : expectedResults.keySet()) {
141+
final Object expectedValue = expectedResults.get(m);
142+
final Object actualValue = actualResults.get(m);
143+
assertThat(actualValue).as(m.toGenericString()).isEqualTo(expectedValue);
144+
}
145+
}
146+
147+
private static class LimitedUseSupplier<T> implements Supplier<T> {
148+
private final T supplied;
149+
private boolean noFurtherUsePermitted = false;
150+
151+
public LimitedUseSupplier(T supplied) {
152+
this.supplied = supplied;
153+
}
154+
155+
public void noFurtherUsePermitted() {
156+
noFurtherUsePermitted = true;
157+
}
158+
159+
@Override
160+
public T get() {
161+
if (noFurtherUsePermitted) {
162+
throw new IllegalStateException(
163+
"Illegal access to non-snapshotted data. This data should have been copied and only the copy accessed.");
164+
}
165+
return supplied;
166+
}
167+
}
168+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
package io.jenkins.plugins.credentials.secretsmanager.factory.ssh_user_private_key;
2+
3+
import java.util.function.Supplier;
4+
5+
import hudson.util.Secret;
6+
import io.jenkins.plugins.credentials.secretsmanager.factory.BaseAwsJsonCredentialsSnapshotTakerTest;
7+
8+
public class AwsJsonSshUserPrivateKeySnapshotTakerTest extends
9+
BaseAwsJsonCredentialsSnapshotTakerTest<AwsJsonSshUserPrivateKey, AwsJsonSshUserPrivateKeySnapshotTaker> {
10+
11+
public AwsJsonSshUserPrivateKeySnapshotTakerTest() {
12+
super(AwsJsonSshUserPrivateKeySnapshotTaker.class, AwsJsonSshUserPrivateKey.class);
13+
}
14+
15+
@Override
16+
protected AwsJsonSshUserPrivateKey makeCredential() {
17+
final String json = AwsJsonSshUserPrivateKeyTest.mkUsernameKeyAndPassphraseJson("someUsername", "someKey",
18+
"somePassphrase");
19+
final Secret secret = Secret.fromString(json);
20+
final Supplier<Secret> s = super.mkSupplier(secret);
21+
return new AwsJsonSshUserPrivateKey("someId", "someDescription", s);
22+
}
23+
}

src/test/java/io/jenkins/plugins/credentials/secretsmanager/factory/ssh_user_private_key/AwsJsonSshUserPrivateKeyTest.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -179,7 +179,7 @@ public void ourDescriptorIsTheSameAsDescriptorForNonJsonCredentials() {
179179
assertThatJsonCredentialsDescriptorIsTheSameAsTheDescriptorForNonJsonCredentials(instance, expected);
180180
}
181181

182-
private static String mkUsernameKeyAndPassphraseJson(String username, String key, String passphrase) {
182+
static String mkUsernameKeyAndPassphraseJson(String username, String key, String passphrase) {
183183
return mkJson(AwsJsonSshUserPrivateKey.JSON_FIELDNAME_FOR_USERNAME, username,
184184
AwsJsonSshUserPrivateKey.JSON_FIELDNAME_FOR_PASSPHRASE, passphrase,
185185
AwsJsonSshUserPrivateKey.JSON_FIELDNAME_FOR_PRIVATE_KEY, key);
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
package io.jenkins.plugins.credentials.secretsmanager.factory.username_password;
2+
3+
import java.util.function.Supplier;
4+
5+
import hudson.util.Secret;
6+
import io.jenkins.plugins.credentials.secretsmanager.factory.BaseAwsJsonCredentialsSnapshotTakerTest;
7+
8+
public class AwsJsonUsernamePasswordCredentialsSnapshotTakerTest extends
9+
BaseAwsJsonCredentialsSnapshotTakerTest<AwsJsonUsernamePasswordCredentials, AwsJsonUsernamePasswordCredentialsSnapshotTaker> {
10+
11+
public AwsJsonUsernamePasswordCredentialsSnapshotTakerTest() {
12+
super(AwsJsonUsernamePasswordCredentialsSnapshotTaker.class, AwsJsonUsernamePasswordCredentials.class);
13+
}
14+
15+
@Override
16+
protected AwsJsonUsernamePasswordCredentials makeCredential() {
17+
final String json = AwsJsonUsernamePasswordCredentialsTest.mkUsernameAndPasswordJson("someUsername",
18+
"somePassword");
19+
final Secret secret = Secret.fromString(json);
20+
final Supplier<Secret> s = super.mkSupplier(secret);
21+
return new AwsJsonUsernamePasswordCredentials("someId", "someDescription", s);
22+
}
23+
}

src/test/java/io/jenkins/plugins/credentials/secretsmanager/factory/username_password/AwsJsonUsernamePasswordCredentialsTest.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -142,7 +142,7 @@ public void ourDescriptorIsTheSameAsDescriptorForNonJsonCredentials() {
142142
assertThatJsonCredentialsDescriptorIsTheSameAsTheDescriptorForNonJsonCredentials(instance, expected);
143143
}
144144

145-
private static String mkUsernameAndPasswordJson(String username, String password) {
145+
static String mkUsernameAndPasswordJson(String username, String password) {
146146
return mkJson(AwsJsonUsernamePasswordCredentials.JSON_FIELDNAME_FOR_USERNAME, username,
147147
AwsJsonUsernamePasswordCredentials.JSON_FIELDNAME_FOR_PASSWORD, password);
148148
}

0 commit comments

Comments
 (0)