Skip to content

Commit e5f7d52

Browse files
committed
API integration test refactoring
Signed-off-by: Nils Bandener <nils.bandener@eliatra.com>
1 parent 6fdab03 commit e5f7d52

23 files changed

+1313
-1201
lines changed

src/integrationTest/java/org/opensearch/security/ConfigurationFiles.java

Lines changed: 0 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -11,13 +11,10 @@
1111

1212
import java.io.IOException;
1313
import java.io.InputStream;
14-
import java.nio.charset.StandardCharsets;
1514
import java.nio.file.Files;
1615
import java.nio.file.Path;
17-
import java.nio.file.StandardOpenOption;
1816
import java.util.Objects;
1917

20-
import org.opensearch.core.common.Strings;
2118
import org.opensearch.security.securityconf.impl.CType;
2219

2320
public class ConfigurationFiles {
@@ -43,14 +40,6 @@ public static Path createConfigurationDirectory() {
4340
}
4441
}
4542

46-
public static void writeToConfig(final CType cType, final Path configFolder, final String content) throws IOException {
47-
if (Strings.isNullOrEmpty(content)) return;
48-
try (final var out = Files.newOutputStream(cType.configFile(configFolder), StandardOpenOption.APPEND)) {
49-
out.write(content.getBytes(StandardCharsets.UTF_8));
50-
out.flush();
51-
}
52-
}
53-
5443
public static void copyResourceToFile(String resource, Path destination) {
5544
try (InputStream input = ConfigurationFiles.class.getClassLoader().getResourceAsStream(resource)) {
5645
Objects.requireNonNull(input, "Cannot find source resource " + resource);

src/integrationTest/java/org/opensearch/security/api/AbstractApiIntegrationTest.java

Lines changed: 25 additions & 219 deletions
Large diffs are not rendered by default.

src/integrationTest/java/org/opensearch/security/api/AbstractConfigEntityApiIntegrationTest.java

Lines changed: 80 additions & 84 deletions
Original file line numberDiff line numberDiff line change
@@ -16,37 +16,34 @@
1616
import java.util.StringJoiner;
1717

1818
import org.hamcrest.Matcher;
19-
import org.junit.Test;
2019

2120
import org.opensearch.common.CheckedSupplier;
2221
import org.opensearch.core.xcontent.ToXContentObject;
22+
import org.opensearch.test.framework.cluster.LocalCluster;
2323
import org.opensearch.test.framework.cluster.TestRestClient;
2424

2525
import com.nimbusds.jose.util.Pair;
2626

2727
import static org.hamcrest.CoreMatchers.is;
2828
import static org.hamcrest.CoreMatchers.not;
2929
import static org.hamcrest.MatcherAssert.assertThat;
30-
import static org.hamcrest.Matchers.containsString;
3130
import static org.hamcrest.Matchers.equalTo;
3231
import static org.hamcrest.Matchers.oneOf;
3332
import static org.opensearch.security.api.PatchPayloadHelper.addOp;
3433
import static org.opensearch.security.api.PatchPayloadHelper.patch;
3534
import static org.opensearch.security.api.PatchPayloadHelper.removeOp;
3635
import static org.opensearch.security.api.PatchPayloadHelper.replaceOp;
3736
import static org.opensearch.security.support.ConfigConstants.SECURITY_RESTAPI_ADMIN_ENABLED;
37+
import static org.opensearch.test.framework.matcher.RestMatchers.isBadRequest;
38+
import static org.opensearch.test.framework.matcher.RestMatchers.isCreated;
39+
import static org.opensearch.test.framework.matcher.RestMatchers.isForbidden;
40+
import static org.opensearch.test.framework.matcher.RestMatchers.isNotFound;
41+
import static org.opensearch.test.framework.matcher.RestMatchers.isOk;
3842

3943
public abstract class AbstractConfigEntityApiIntegrationTest extends AbstractApiIntegrationTest {
4044

41-
static {
42-
testSecurityConfig.withRestAdminUser(REST_ADMIN_USER, allRestAdminPermissions());
43-
}
44-
45-
@Override
46-
protected Map<String, Object> getClusterSettings() {
47-
Map<String, Object> clusterSettings = super.getClusterSettings();
48-
clusterSettings.put(SECURITY_RESTAPI_ADMIN_ENABLED, true);
49-
return clusterSettings;
45+
protected static LocalCluster.Builder clusterBuilder() {
46+
return AbstractApiIntegrationTest.clusterBuilder().nodeSetting(SECURITY_RESTAPI_ADMIN_ENABLED, true);
5047
}
5148

5249
interface TestDescriptor {
@@ -99,26 +96,24 @@ protected String apiPath(String... paths) {
9996
return fullPath.toString();
10097
}
10198

102-
@Test
103-
public void forbiddenForRegularUsers() throws Exception {
104-
withUser(NEW_USER, client -> {
105-
forbidden(() -> client.putJson(apiPath("some_entity"), EMPTY_BODY));
106-
forbidden(() -> client.get(apiPath()));
107-
forbidden(() -> client.get(apiPath("some_entity")));
108-
forbidden(() -> client.putJson(apiPath("some_entity"), EMPTY_BODY));
109-
forbidden(() -> client.patch(apiPath(), EMPTY_BODY));
110-
forbidden(() -> client.patch(apiPath("some_entity"), EMPTY_BODY));
111-
forbidden(() -> client.delete(apiPath("some_entity")));
112-
});
99+
public void forbiddenForRegularUsers(LocalCluster localCluster) throws Exception {
100+
try (TestRestClient client = localCluster.getRestClient(NEW_USER)) {
101+
assertThat(client.putJson(apiPath("some_entity"), EMPTY_BODY), isForbidden());
102+
assertThat(client.get(apiPath()), isForbidden());
103+
assertThat(client.get(apiPath("some_entity")), isForbidden());
104+
assertThat(client.putJson(apiPath("some_entity"), EMPTY_BODY), isForbidden());
105+
assertThat(client.patch(apiPath(), EMPTY_BODY), isForbidden());
106+
assertThat(client.patch(apiPath("some_entity"), EMPTY_BODY), isForbidden());
107+
assertThat(client.delete(apiPath("some_entity")), isForbidden());
108+
}
113109
}
114110

115-
@Test
116-
public void availableForAdminUser() throws Exception {
117-
final var entitiesNames = predefinedHiddenAndReservedConfigEntities();
111+
public void availableForAdminUser(LocalCluster localCluster) throws Exception {
112+
final var entitiesNames = predefinedHiddenAndReservedConfigEntities(localCluster);
118113
final var hiddenEntityName = entitiesNames.getLeft();
119114
final var reservedEntityName = entitiesNames.getRight();
120115
// can't see hidden resources
121-
withUser(ADMIN_USER_NAME, client -> {
116+
try (TestRestClient client = localCluster.getRestClient(ADMIN_USER)) {
122117
verifyNoHiddenEntities(() -> client.get(apiPath()));
123118
creationOfReadOnlyEntityForbidden(
124119
randomAsciiAlphanumOfLength(10),
@@ -131,35 +126,28 @@ public void availableForAdminUser() throws Exception {
131126
verifyUpdateAndDeleteReservedConfigEntityForbidden(reservedEntityName, client);
132127
verifyCrudOperations(null, null, client);
133128
verifyBadRequestOperations(client);
134-
});
129+
}
135130
}
136131

137-
Pair<String, String> predefinedHiddenAndReservedConfigEntities() throws Exception {
132+
Pair<String, String> predefinedHiddenAndReservedConfigEntities(LocalCluster localCluster) throws Exception {
138133
final var hiddenEntityName = randomAsciiAlphanumOfLength(10);
139134
final var reservedEntityName = randomAsciiAlphanumOfLength(10);
140-
withUser(
141-
ADMIN_USER_NAME,
142-
localCluster.getAdminCertificate(),
143-
client -> created(() -> client.putJson(apiPath(hiddenEntityName), testDescriptor.hiddenEntityPayload()))
144-
);
145-
withUser(
146-
ADMIN_USER_NAME,
147-
localCluster.getAdminCertificate(),
148-
client -> created(() -> client.putJson(apiPath(reservedEntityName), testDescriptor.reservedEntityPayload()))
149-
);
135+
try (TestRestClient client = localCluster.getAdminCertRestClient()) {
136+
assertThat(client.putJson(apiPath(hiddenEntityName), testDescriptor.hiddenEntityPayload()), isCreated());
137+
assertThat(client.putJson(apiPath(reservedEntityName), testDescriptor.reservedEntityPayload()), isCreated());
138+
}
150139
return Pair.of(hiddenEntityName, reservedEntityName);
151140
}
152141

153-
@Test
154-
public void availableForTLSAdminUser() throws Exception {
155-
withUser(ADMIN_USER_NAME, localCluster.getAdminCertificate(), this::availableForSuperAdminUser);
142+
public void availableForTLSAdminUser(LocalCluster localCluster) throws Exception {
143+
try (TestRestClient client = localCluster.getAdminCertRestClient()) {
144+
availableForSuperAdminUser(client);
145+
}
156146
}
157147

158-
@Test
159-
public void availableForRESTAdminUser() throws Exception {
160-
withUser(REST_ADMIN_USER, this::availableForSuperAdminUser);
161-
if (testDescriptor.restAdminLimitedUser().isPresent()) {
162-
withUser(testDescriptor.restAdminLimitedUser().get(), this::availableForSuperAdminUser);
148+
public void availableForRESTAdminUser(LocalCluster localCluster) throws Exception {
149+
try (TestRestClient client = localCluster.getRestClient(REST_ADMIN_USER)) {
150+
availableForSuperAdminUser(client);
163151
}
164152
}
165153

@@ -178,7 +166,9 @@ void availableForSuperAdminUser(final TestRestClient client) throws Exception {
178166
}
179167

180168
void verifyNoHiddenEntities(final CheckedSupplier<TestRestClient.HttpResponse, Exception> endpointCallback) throws Exception {
181-
final var body = ok(endpointCallback).bodyAsJsonNode();
169+
final var resp = endpointCallback.get();
170+
assertThat(resp, isOk());
171+
final var body = resp.bodyAsJsonNode();
182172
final var pretty = body.toPrettyString();
183173
final var it = body.elements();
184174
while (it.hasNext()) {
@@ -190,11 +180,11 @@ void verifyNoHiddenEntities(final CheckedSupplier<TestRestClient.HttpResponse, E
190180
void creationOfReadOnlyEntityForbidden(final String entityName, final TestRestClient client, final ToXContentObject... entities)
191181
throws Exception {
192182
for (final var configEntity : entities) {
193-
assertInvalidKeys(
194-
badRequest(() -> client.putJson(apiPath(entityName), configEntity)),
195-
is(oneOf("static", "hidden", "reserved"))
196-
);
197-
badRequest(() -> client.patch(apiPath(), patch(addOp(randomAsciiAlphanumOfLength(10), configEntity))));
183+
final var resp = client.putJson(apiPath(entityName), configEntity);
184+
assertThat(resp, isBadRequest());
185+
assertInvalidKeys(resp, is(oneOf("static", "hidden", "reserved")));
186+
final var resp2 = client.patch(apiPath(), patch(addOp(randomAsciiAlphanumOfLength(10), configEntity)));
187+
assertThat(resp2, isBadRequest());
198188
}
199189
}
200190

@@ -222,54 +212,60 @@ void assertWrongDataType(final TestRestClient.HttpResponse response, final Map<S
222212
assertThat(response.getBody(), response.getTextFromJsonBody("/" + p.getKey()), is(p.getValue()));
223213
}
224214

225-
void assertSpecifyOneOf(final TestRestClient.HttpResponse response, final String expectedSpecifyOneOfKeys) {
226-
assertThat(response.getBody(), response.getTextFromJsonBody("/status"), is("error"));
227-
assertThat(response.getBody(), response.getTextFromJsonBody("/reason"), equalTo("Invalid configuration"));
228-
assertThat(response.getBody(), response.getTextFromJsonBody("/specify_one_of/keys"), containsString(expectedSpecifyOneOfKeys));
229-
}
230-
231-
void assertMissingMandatoryKeys(final TestRestClient.HttpResponse response, final String expectedKeys) {
232-
assertThat(response.getBody(), response.getTextFromJsonBody("/status"), is("error"));
233-
assertThat(response.getBody(), response.getTextFromJsonBody("/reason"), equalTo("Invalid configuration"));
234-
assertThat(response.getBody(), response.getTextFromJsonBody("/missing_mandatory_keys/keys"), containsString(expectedKeys));
235-
}
236-
237215
void verifyUpdateAndDeleteHiddenConfigEntityForbidden(final String hiddenEntityName, final TestRestClient client) throws Exception {
238216
final var expectedErrorMessage = "Resource '" + hiddenEntityName + "' is not available.";
239-
notFound(() -> client.putJson(apiPath(hiddenEntityName), testDescriptor.entityPayload()), expectedErrorMessage);
240-
notFound(
241-
() -> client.patch(
217+
assertThat(
218+
client.putJson(apiPath(hiddenEntityName), testDescriptor.entityPayload()),
219+
isNotFound().withAttribute("/message", expectedErrorMessage)
220+
);
221+
assertThat(
222+
client.patch(
242223
apiPath(hiddenEntityName),
243224
patch(replaceOp(testDescriptor.entityJsonProperty(), testDescriptor.jsonPropertyPayload()))
244225
),
245-
expectedErrorMessage
226+
isNotFound().withAttribute("/message", expectedErrorMessage)
246227
);
247-
notFound(() -> client.patch(apiPath(), patch(replaceOp(hiddenEntityName, testDescriptor.entityPayload()))), expectedErrorMessage);
248-
notFound(() -> client.patch(apiPath(hiddenEntityName), patch(removeOp(testDescriptor.entityJsonProperty()))), expectedErrorMessage);
249-
notFound(() -> client.patch(apiPath(), patch(removeOp(hiddenEntityName))), expectedErrorMessage);
250-
notFound(() -> client.delete(apiPath(hiddenEntityName)), expectedErrorMessage);
228+
assertThat(
229+
client.patch(apiPath(), patch(replaceOp(hiddenEntityName, testDescriptor.entityPayload()))),
230+
isNotFound().withAttribute("/message", expectedErrorMessage)
231+
);
232+
assertThat(
233+
client.patch(apiPath(hiddenEntityName), patch(removeOp(testDescriptor.entityJsonProperty()))),
234+
isNotFound().withAttribute("/message", expectedErrorMessage)
235+
);
236+
assertThat(
237+
client.patch(apiPath(), patch(removeOp(hiddenEntityName))),
238+
isNotFound().withAttribute("/message", expectedErrorMessage)
239+
);
240+
assertThat(client.delete(apiPath(hiddenEntityName)), isNotFound().withAttribute("/message", expectedErrorMessage));
251241
}
252242

253243
void verifyUpdateAndDeleteReservedConfigEntityForbidden(final String reservedEntityName, final TestRestClient client) throws Exception {
254244
final var expectedErrorMessage = "Resource '" + reservedEntityName + "' is reserved.";
255-
forbidden(() -> client.putJson(apiPath(reservedEntityName), testDescriptor.entityPayload()), expectedErrorMessage);
256-
forbidden(
257-
() -> client.patch(
245+
assertThat(
246+
client.putJson(apiPath(reservedEntityName), testDescriptor.entityPayload()),
247+
isForbidden().withAttribute("/message", expectedErrorMessage)
248+
);
249+
assertThat(
250+
client.patch(
258251
apiPath(reservedEntityName),
259252
patch(replaceOp(testDescriptor.entityJsonProperty(), testDescriptor.entityJsonProperty()))
260253
),
261-
expectedErrorMessage
254+
isForbidden().withAttribute("/message", expectedErrorMessage)
262255
);
263-
forbidden(
264-
() -> client.patch(apiPath(), patch(replaceOp(reservedEntityName, testDescriptor.entityPayload()))),
265-
expectedErrorMessage
256+
assertThat(
257+
client.patch(apiPath(), patch(replaceOp(reservedEntityName, testDescriptor.entityPayload()))),
258+
isForbidden().withAttribute("/message", expectedErrorMessage)
259+
);
260+
assertThat(
261+
client.patch(apiPath(), patch(removeOp(reservedEntityName))),
262+
isForbidden().withAttribute("/message", expectedErrorMessage)
266263
);
267-
forbidden(() -> client.patch(apiPath(), patch(removeOp(reservedEntityName))), expectedErrorMessage);
268-
forbidden(
269-
() -> client.patch(apiPath(reservedEntityName), patch(removeOp(testDescriptor.entityJsonProperty()))),
270-
expectedErrorMessage
264+
assertThat(
265+
client.patch(apiPath(reservedEntityName), patch(removeOp(testDescriptor.entityJsonProperty()))),
266+
isForbidden().withAttribute("/message", expectedErrorMessage)
271267
);
272-
forbidden(() -> client.delete(apiPath(reservedEntityName)), expectedErrorMessage);
268+
assertThat(client.delete(apiPath(reservedEntityName)), isForbidden().withAttribute("/message", expectedErrorMessage));
273269
}
274270

275271
void forbiddenToCreateEntityWithRestAdminPermissions(final TestRestClient client) throws Exception {}

0 commit comments

Comments
 (0)