Skip to content

Commit 8ae263e

Browse files
peterniedgithub-actions[bot]
authored andcommitted
testComplianceEnable supports variable number of audit messages (#1920)
We were seeing test failures where on higher end computers there would be duplicate audit messages for the index mapping creation. Then when run inside GitHub Actions there would only be 2 messages. This doesn't look like an overt product issue, overlogging of requests, but the test case was not handling it well. Also improved the failure message response for faster future debugging. Signed-off-by: Peter Nied <petern@amazon.com> (cherry picked from commit 1904db5)
1 parent ee225b7 commit 8ae263e

2 files changed

Lines changed: 47 additions & 10 deletions

File tree

src/test/java/org/opensearch/security/auditlog/compliance/ComplianceAuditlogTest.java

Lines changed: 24 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
import java.io.IOException;
1515
import java.util.Collections;
1616
import java.util.List;
17+
import java.util.stream.Collectors;
1718

1819
import com.google.common.collect.ImmutableMap;
1920
import org.apache.http.Header;
@@ -32,6 +33,7 @@
3233
import org.opensearch.security.auditlog.AbstractAuditlogiUnitTest;
3334
import org.opensearch.security.auditlog.AuditTestUtils;
3435
import org.opensearch.security.auditlog.config.AuditConfig;
36+
import org.opensearch.security.auditlog.impl.AuditCategory;
3537
import org.opensearch.security.auditlog.impl.AuditMessage;
3638
import org.opensearch.security.auditlog.integration.TestAuditlogImpl;
3739
import org.opensearch.security.auditlog.integration.TestAuditlogImpl.MessagesNotFoundException;
@@ -41,9 +43,9 @@
4143
import org.opensearch.security.test.helper.rest.RestHelper.HttpResponse;
4244

4345
import static org.hamcrest.MatcherAssert.assertThat;
46+
import static org.hamcrest.core.AnyOf.anyOf;
4447
import static org.hamcrest.core.IsEqual.equalTo;
4548
import static org.junit.Assert.assertThrows;
46-
import static org.junit.Assert.assertTrue;
4749

4850
public class ComplianceAuditlogTest extends AbstractAuditlogiUnitTest {
4951

@@ -111,10 +113,27 @@ public void testComplianceEnable() throws Exception {
111113
updateAuditConfig(AuditTestUtils.createAuditPayload(auditConfig));
112114

113115
// make an event happen
114-
TestAuditlogImpl.doThenWaitForMessages(() -> {
115-
rh.executePutRequest("emp/_doc/0?refresh", "{\"Designation\" : \"CEO\", \"Gender\" : \"female\", \"Salary\" : 100}");
116-
}, 7);
117-
assertTrue(TestAuditlogImpl.messages.toString().contains("COMPLIANCE_DOC_WRITE"));
116+
List<AuditMessage> messages;
117+
try {
118+
messages = TestAuditlogImpl.doThenWaitForMessages(() -> {
119+
rh.executePutRequest("emp/_doc/0?refresh", "{\"Designation\" : \"CEO\", \"Gender\" : \"female\", \"Salary\" : 100}");
120+
System.out.println(rh.executeGetRequest("_cat/shards?v"));
121+
}, 7);
122+
} catch (final MessagesNotFoundException ex) {
123+
// indices:admin/mapping/auto_put can be logged twice, this handles if they were not found
124+
assertThat("Too many missing audit log messages", ex.getMissingCount(), equalTo(2));
125+
messages = ex.getFoundMessages();
126+
}
127+
128+
messages.stream().filter(msg -> msg.getCategory().equals(AuditCategory.COMPLIANCE_DOC_WRITE))
129+
.findFirst().orElseThrow(() -> new RuntimeException("Missing COMPLIANCE message"));
130+
131+
final List<AuditMessage> indexCreation = messages.stream().filter(msg -> "indices:admin/auto_create".equals(msg.getPrivilege())).collect(Collectors.toList());
132+
assertThat(indexCreation.size(), equalTo(2));
133+
134+
final List<AuditMessage> mappingCreation = messages.stream().filter(msg -> "indices:admin/mapping/auto_put".equals(msg.getPrivilege())).collect(Collectors.toList());
135+
assertThat(mappingCreation.size(), anyOf(equalTo(4), equalTo(2)));
136+
118137
// disable compliance
119138
auditConfig = new AuditConfig(true, AuditConfig.Filter.DEFAULT , ComplianceConfig.from(ImmutableMap.of("enabled", false, "write_watched_indices", Collections.singletonList("emp")), additionalSettings));
120139
updateAuditConfig(AuditTestUtils.createAuditPayload(auditConfig));

src/test/java/org/opensearch/security/auditlog/integration/TestAuditlogImpl.java

Lines changed: 23 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
import java.util.concurrent.CountDownLatch;
1717
import java.util.concurrent.TimeUnit;
1818
import java.util.concurrent.atomic.AtomicReference;
19+
import java.util.stream.Collectors;
1920

2021
import org.opensearch.common.settings.Settings;
2122
import org.opensearch.security.auditlog.impl.AuditMessage;
@@ -67,10 +68,10 @@ public static List<AuditMessage> doThenWaitForMessages(final Runnable action, fi
6768

6869
try {
6970
action.run();
70-
final int maxSecondsToWaitForMessages = 1;
71+
final int maxSecondsToWaitForMessages = 1;
7172
final boolean foundAll = latch.await(maxSecondsToWaitForMessages, TimeUnit.SECONDS);
7273
if (!foundAll) {
73-
throw new MessagesNotFoundException(expectedCount, (int)latch.getCount());
74+
throw new MessagesNotFoundException(expectedCount, messages);
7475
}
7576
if (messages.size() != expectedCount) {
7677
throw new RuntimeException("Unexpected number of messages, was expecting " + expectedCount + ", recieved " + messages.size());
@@ -96,10 +97,12 @@ public boolean isHandlingBackpressure() {
9697
public static class MessagesNotFoundException extends RuntimeException {
9798
private final int expectedCount;
9899
private final int missingCount;
99-
public MessagesNotFoundException(final int expectedCount, final int missingCount) {
100-
super("Did not recieve all " + expectedCount +" audit messages after a short wait, missing " + missingCount + " messages");
100+
private final List<AuditMessage> foundMessages;
101+
public MessagesNotFoundException(final int expectedCount, List<AuditMessage> foundMessages) {
102+
super(MessagesNotFoundException.createDetailMessage(expectedCount, foundMessages));
101103
this.expectedCount = expectedCount;
102-
this.missingCount = missingCount;
104+
this.missingCount = expectedCount - foundMessages.size();
105+
this.foundMessages = foundMessages;
103106
}
104107

105108
public int getExpectedCount() {
@@ -109,5 +112,20 @@ public int getExpectedCount() {
109112
public int getMissingCount() {
110113
return missingCount;
111114
}
115+
116+
public List<AuditMessage> getFoundMessages() {
117+
return foundMessages;
118+
}
119+
120+
private static String createDetailMessage(final int expectedCount, final List<AuditMessage> foundMessages) {
121+
return new StringBuilder()
122+
.append("Did not recieve all " + expectedCount + " audit messages after a short wait. ")
123+
.append("Missing " + (expectedCount - foundMessages.size()) + " messages.")
124+
.append("Messages found during this time: \n\n")
125+
.append(foundMessages.stream()
126+
.map(AuditMessage::toString)
127+
.collect(Collectors.joining("\n")))
128+
.toString();
129+
}
112130
}
113131
}

0 commit comments

Comments
 (0)