Skip to content

Commit f6c678b

Browse files
committed
AJ-1234: Add WsmPactTest
This is the first of several test suites verifying interaction with WSM; this one focuses specifically on `createDataRepoSnapshotReference`.
1 parent 5c759cd commit f6c678b

File tree

1 file changed

+178
-0
lines changed
  • service/src/test/java/org/databiosphere/workspacedataservice/pact

1 file changed

+178
-0
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,178 @@
1+
package org.databiosphere.workspacedataservice.pact;
2+
3+
import static au.com.dius.pact.consumer.dsl.LambdaDsl.newJsonBody;
4+
import static org.junit.jupiter.api.Assertions.assertDoesNotThrow;
5+
import static org.junit.jupiter.api.Assertions.assertThrows;
6+
7+
import au.com.dius.pact.consumer.MockServer;
8+
import au.com.dius.pact.consumer.dsl.DslPart;
9+
import au.com.dius.pact.consumer.dsl.PactBuilder;
10+
import au.com.dius.pact.consumer.junit5.PactConsumerTestExt;
11+
import au.com.dius.pact.consumer.junit5.PactTestFor;
12+
import au.com.dius.pact.core.model.PactSpecVersion;
13+
import au.com.dius.pact.core.model.V4Pact;
14+
import au.com.dius.pact.core.model.annotations.Pact;
15+
import bio.terra.datarepo.model.SnapshotModel;
16+
import bio.terra.workspace.model.CloningInstructionsEnum;
17+
import java.util.HashMap;
18+
import java.util.Map;
19+
import java.util.UUID;
20+
import org.databiosphere.workspacedataservice.workspacemanager.HttpWorkspaceManagerClientFactory;
21+
import org.databiosphere.workspacedataservice.workspacemanager.WorkspaceManagerClientFactory;
22+
import org.databiosphere.workspacedataservice.workspacemanager.WorkspaceManagerDao;
23+
import org.databiosphere.workspacedataservice.workspacemanager.WorkspaceManagerException;
24+
import org.junit.jupiter.api.BeforeEach;
25+
import org.junit.jupiter.api.Tag;
26+
import org.junit.jupiter.api.Test;
27+
import org.junit.jupiter.api.extension.ExtendWith;
28+
import org.springframework.mock.web.MockHttpServletRequest;
29+
import org.springframework.web.context.request.RequestContextHolder;
30+
import org.springframework.web.context.request.ServletRequestAttributes;
31+
32+
@Tag("pact-test")
33+
@ExtendWith(PactConsumerTestExt.class)
34+
public class WsmPactTest {
35+
// copied from DslPart.UUID_REGEX, used to configure Pact to accept a wildcard UUID as the
36+
// workspaceId path param
37+
private static final String UUID_REGEX_PATTERN =
38+
"[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}";
39+
40+
// hardcoded to something vaguely human-readable to prevent churn in pactfiles
41+
private static final UUID WORKSPACE_UUID =
42+
UUID.fromString("facade00-0000-4000-a000-000000000000");
43+
44+
// hardcoded to something vaguely human-readable to prevent churn in pactfiles
45+
private static final UUID SNAPSHOT_UUID = UUID.fromString("decade00-0000-4000-a000-000000000000");
46+
private static final String SNAPSHOT_NAME = "hardcodedSnapshotName";
47+
private static final String SNAPSHOT_CREATOR_EMAIL = "[email protected]";
48+
49+
@BeforeEach
50+
void setUp() {
51+
// Without this setup, the HttpClient throws a "No thread-bound request found" error
52+
RequestContextHolder.setRequestAttributes(
53+
new ServletRequestAttributes(new MockHttpServletRequest()));
54+
}
55+
56+
private String snapshotPath(String workspaceIdPart) {
57+
return String.format(
58+
"/api/workspaces/v1/%s/resources/referenced/datarepo/snapshots", workspaceIdPart);
59+
}
60+
61+
@Pact(consumer = "wds", provider = "workspacemanager")
62+
V4Pact createDataRepoSnapshotReferenceSuccess(PactBuilder builder) {
63+
return builder
64+
.usingLegacyDsl()
65+
.given("a workspace with the given id exists", Map.of("id", WORKSPACE_UUID.toString()))
66+
.given("authenticated with the given email", Map.of("email", SNAPSHOT_CREATOR_EMAIL))
67+
.given("policies allowing snapshot reference creation")
68+
.uponReceiving("a request to create a snapshot reference")
69+
.matchPath(snapshotPath(UUID_REGEX_PATTERN), snapshotPath(WORKSPACE_UUID.toString()))
70+
.method("POST")
71+
.headers(contentTypeJson())
72+
.body(createSnapshotReferenceBody(SNAPSHOT_NAME))
73+
.willRespondWith()
74+
.status(200) // ok
75+
.headers(contentTypeJson())
76+
.body(
77+
newJsonBody(
78+
body -> {
79+
// put expectations here if we ever start reading fields in the code under
80+
// test
81+
})
82+
.build())
83+
.toPact(V4Pact.class);
84+
}
85+
86+
private String conditions(String... conditions) {
87+
return String.join(" and ", conditions);
88+
}
89+
90+
@Pact(consumer = "wds", provider = "workspacemanager")
91+
V4Pact createDataRepoSnapshotReferencePolicyConflict(PactBuilder builder) {
92+
return builder
93+
.usingLegacyDsl()
94+
.given("a workspace with the given id exists", Map.of("id", WORKSPACE_UUID.toString()))
95+
.given("authenticated with the given email", Map.of("email", SNAPSHOT_CREATOR_EMAIL))
96+
.given("policies preventing snapshot reference creation")
97+
.uponReceiving("a request to create a snapshot reference")
98+
.matchPath(snapshotPath(UUID_REGEX_PATTERN), snapshotPath(WORKSPACE_UUID.toString()))
99+
.method("POST")
100+
.headers(contentTypeJson())
101+
.body(createSnapshotReferenceBody(SNAPSHOT_NAME))
102+
.willRespondWith()
103+
.status(409) // conflict
104+
.headers(contentTypeJson())
105+
.body(
106+
newJsonBody(
107+
body ->
108+
body.stringMatcher(
109+
"message", "^(.*)policy conflict(.*)$", "unexpected policy conflict"))
110+
.build())
111+
.toPact(V4Pact.class);
112+
}
113+
114+
@Test
115+
@PactTestFor(
116+
pactMethod = "createDataRepoSnapshotReferenceSuccess",
117+
pactVersion = PactSpecVersion.V3)
118+
void testCreateDataRepoSnapshotReferenceSuccess(MockServer mockServer) {
119+
var wsmDao = buildWsmDao(mockServer);
120+
var snapshotModel = buildSnapshotModel();
121+
122+
assertDoesNotThrow(() -> wsmDao.createDataRepoSnapshotReference(snapshotModel));
123+
}
124+
125+
@Test
126+
@PactTestFor(
127+
pactMethod = "createDataRepoSnapshotReferencePolicyConflict",
128+
pactVersion = PactSpecVersion.V3)
129+
void testCreateDataRepoSnapshotReferenceConflict(MockServer mockServer) {
130+
var wsmDao = buildWsmDao(mockServer);
131+
var snapshotModel = buildSnapshotModel();
132+
133+
assertThrows(
134+
WorkspaceManagerException.class,
135+
() -> wsmDao.createDataRepoSnapshotReference(snapshotModel));
136+
}
137+
138+
private SnapshotModel buildSnapshotModel() {
139+
return new SnapshotModel().id(SNAPSHOT_UUID).name(SNAPSHOT_NAME);
140+
}
141+
142+
private WorkspaceManagerDao buildWsmDao(MockServer mockServer) {
143+
WorkspaceManagerClientFactory clientFactory =
144+
new HttpWorkspaceManagerClientFactory(mockServer.getUrl());
145+
return new WorkspaceManagerDao(clientFactory, WORKSPACE_UUID.toString());
146+
}
147+
148+
private DslPart createSnapshotReferenceBody(String snapshotName) {
149+
// metadata.name is a composite of <snapshotName>_<timestamp>
150+
String nameFormatString = String.format("'%s'_yyyyMMddHHmmss", snapshotName);
151+
152+
return newJsonBody(
153+
body -> {
154+
body.object(
155+
"snapshot",
156+
snapshot -> {
157+
snapshot.stringValue("instanceName", "terra");
158+
snapshot.uuid("snapshot");
159+
});
160+
body.object(
161+
"metadata",
162+
metadata -> {
163+
metadata.stringValue(
164+
"cloningInstructions", CloningInstructionsEnum.REFERENCE.toString());
165+
metadata.datetime("name", nameFormatString);
166+
});
167+
})
168+
.build();
169+
}
170+
171+
private Map<String, String> contentTypeJson() {
172+
Map<String, String> headers = new HashMap<>();
173+
// pact will automatically assume an expected Content-Type of "application/json; charset=UTF-8"
174+
// unless we explicitly tell it otherwise
175+
headers.put("Content-Type", "application/json");
176+
return headers;
177+
}
178+
}

0 commit comments

Comments
 (0)