TraceIT: Use mock and await log calls

TraceIT is flaky because it requires calls in RestApiServlet to
happen in a certain order (return result after writing performance
logs).

However, this depends on inner works of the webserver implementation.
For example, in RestApiServlet, we call HttpResponse#sendError and
only then return and invoke the performance logger.

If the webserver decides to return the response to the client at that
point, the test becomes flaky because it then depends on the execution
order of the thread on the server and the thread that runs the test.

Change-Id: I297384d3998d23b4f826cf0a81e363570998c57a
This commit is contained in:
Patrick Hiesel
2020-12-08 13:56:24 +01:00
parent 595e6db974
commit af691dee64

View File

@@ -18,6 +18,13 @@ import static com.google.common.truth.Truth.assertThat;
import static org.apache.http.HttpStatus.SC_CREATED;
import static org.apache.http.HttpStatus.SC_INTERNAL_SERVER_ERROR;
import static org.apache.http.HttpStatus.SC_OK;
import static org.mockito.ArgumentMatchers.anyLong;
import static org.mockito.ArgumentMatchers.anyString;
import static org.mockito.Mockito.any;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.timeout;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.verifyZeroInteractions;
import com.google.auto.value.AutoValue;
import com.google.common.collect.ImmutableList;
@@ -52,7 +59,6 @@ import com.google.gerrit.server.rules.SubmitRule;
import com.google.gerrit.server.validators.ProjectCreationValidationListener;
import com.google.gerrit.server.validators.ValidationException;
import com.google.inject.Inject;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Optional;
@@ -370,37 +376,31 @@ public class TraceIT extends AbstractDaemonTest {
@Test
public void performanceLoggingForRestCall() throws Exception {
TestPerformanceLogger testPerformanceLogger = new TestPerformanceLogger();
PerformanceLogger testPerformanceLogger = mock(PerformanceLogger.class);
try (Registration registration =
extensionRegistry.newRegistration().add(testPerformanceLogger)) {
RestResponse response = adminRestSession.put("/projects/new10");
assertThat(response.getStatusCode()).isEqualTo(SC_CREATED);
// This assertion assumes that the server invokes the PerformanceLogger plugins before it
// sends
// the response to the client. If this assertion gets flaky it's likely that this got changed
// on
// server-side.
assertThat(testPerformanceLogger.logEntries()).isNotEmpty();
verify(testPerformanceLogger, timeout(5000).atLeastOnce()).log(anyString(), anyLong(), any());
}
}
@Test
public void performanceLoggingForPush() throws Exception {
TestPerformanceLogger testPerformanceLogger = new TestPerformanceLogger();
PerformanceLogger testPerformanceLogger = mock(PerformanceLogger.class);
try (Registration registration =
extensionRegistry.newRegistration().add(testPerformanceLogger)) {
PushOneCommit push = pushFactory.create(admin.newIdent(), testRepo);
PushOneCommit.Result r = push.to("refs/heads/master");
r.assertOkStatus();
assertThat(testPerformanceLogger.logEntries()).isNotEmpty();
verify(testPerformanceLogger, timeout(5000).atLeastOnce()).log(anyString(), anyLong(), any());
}
}
@Test
@GerritConfig(name = "tracing.performanceLogging", value = "false")
public void noPerformanceLoggingIfDisabled() throws Exception {
TestPerformanceLogger testPerformanceLogger = new TestPerformanceLogger();
PerformanceLogger testPerformanceLogger = mock(PerformanceLogger.class);
try (Registration registration =
extensionRegistry.newRegistration().add(testPerformanceLogger)) {
RestResponse response = adminRestSession.put("/projects/new11");
@@ -410,7 +410,7 @@ public class TraceIT extends AbstractDaemonTest {
PushOneCommit.Result r = push.to("refs/heads/master");
r.assertOkStatus();
assertThat(testPerformanceLogger.logEntries()).isEmpty();
verifyZeroInteractions(testPerformanceLogger);
}
}
@@ -844,19 +844,6 @@ public class TraceIT extends AbstractDaemonTest {
}
}
private static class TestPerformanceLogger implements PerformanceLogger {
private List<PerformanceLogEntry> logEntries = new ArrayList<>();
@Override
public void log(String operation, long durationMs, Metadata metadata) {
logEntries.add(PerformanceLogEntry.create(operation, metadata));
}
ImmutableList<PerformanceLogEntry> logEntries() {
return ImmutableList.copyOf(logEntries);
}
}
@AutoValue
abstract static class PerformanceLogEntry {
static PerformanceLogEntry create(String operation, Metadata metadata) {