Skip to content

Commit

Permalink
Add tests to node endpoints. (#5434)
Browse files Browse the repository at this point in the history
Signed-off-by: Paul Harris <[email protected]>
  • Loading branch information
rolfyone authored May 5, 2022
1 parent d3b9cca commit 162a1a1
Show file tree
Hide file tree
Showing 13 changed files with 385 additions and 134 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -15,10 +15,6 @@
}
}
},
"500" : {
"description" : "Server Error",
"content" : { }
},
"400" : {
"description" : "The request could not be processed, check the response for more information.",
"content" : {
Expand All @@ -28,6 +24,16 @@
}
}
}
},
"500" : {
"description" : "Internal server error",
"content" : {
"application/json" : {
"schema" : {
"$ref" : "#/components/schemas/HttpErrorResponse"
}
}
}
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@
import io.javalin.plugin.openapi.annotations.OpenApiContent;
import io.javalin.plugin.openapi.annotations.OpenApiResponse;
import java.util.List;
import java.util.Objects;
import java.util.Optional;
import java.util.function.Function;
import tech.pegasys.teku.api.DataProvider;
Expand Down Expand Up @@ -199,5 +200,26 @@ public List<String> getDiscoveryAddresses() {
public MetadataMessage getMetadata() {
return metadata;
}

@Override
public boolean equals(final Object o) {
if (this == o) {
return true;
}
if (o == null || getClass() != o.getClass()) {
return false;
}
final IdentityData that = (IdentityData) o;
return Objects.equals(peerId, that.peerId)
&& Objects.equals(enr, that.enr)
&& Objects.equals(listeningAddresses, that.listeningAddresses)
&& Objects.equals(discoveryAddresses, that.discoveryAddresses)
&& Objects.equals(metadata, that.metadata);
}

@Override
public int hashCode() {
return Objects.hash(peerId, enr, listeningAddresses, discoveryAddresses, metadata);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
import io.javalin.plugin.openapi.annotations.OpenApiContent;
import io.javalin.plugin.openapi.annotations.OpenApiResponse;
import java.util.List;
import java.util.Objects;
import java.util.function.Function;
import org.jetbrains.annotations.NotNull;
import tech.pegasys.teku.api.DataProvider;
Expand Down Expand Up @@ -126,5 +127,23 @@ UInt64 getDisconnected() {
UInt64 getConnected() {
return connected;
}

@Override
public boolean equals(final Object o) {
if (this == o) {
return true;
}
if (o == null || getClass() != o.getClass()) {
return false;
}
final ResponseData that = (ResponseData) o;
return Objects.equals(disconnected, that.disconnected)
&& Objects.equals(connected, that.connected);
}

@Override
public int hashCode() {
return Objects.hash(disconnected, connected);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@
import io.javalin.plugin.openapi.annotations.OpenApiContent;
import io.javalin.plugin.openapi.annotations.OpenApiResponse;
import java.util.List;
import java.util.Objects;
import java.util.Optional;
import java.util.function.Function;
import org.jetbrains.annotations.NotNull;
Expand Down Expand Up @@ -160,5 +161,22 @@ public List<Eth2Peer> getPeers() {
public Integer getCount() {
return count;
}

@Override
public boolean equals(final Object o) {
if (this == o) {
return true;
}
if (o == null || getClass() != o.getClass()) {
return false;
}
final PeersData peersData = (PeersData) o;
return Objects.equals(peers, peersData.peers) && Objects.equals(count, peersData.count);
}

@Override
public int hashCode() {
return Objects.hash(peers, count);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@

package tech.pegasys.teku.beaconrestapi.handlers.v1.node;

import static tech.pegasys.teku.infrastructure.http.HttpStatusCodes.SC_INTERNAL_SERVER_ERROR;
import static tech.pegasys.teku.infrastructure.http.HttpStatusCodes.SC_OK;
import static tech.pegasys.teku.infrastructure.http.RestApiConstants.CACHE_NONE;
import static tech.pegasys.teku.infrastructure.http.RestApiConstants.RES_INTERNAL_ERROR;
Expand All @@ -24,12 +23,14 @@
import static tech.pegasys.teku.infrastructure.json.types.CoreTypes.UINT64_TYPE;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.google.common.base.MoreObjects;
import io.javalin.core.util.Header;
import io.javalin.http.Context;
import io.javalin.plugin.openapi.annotations.HttpMethod;
import io.javalin.plugin.openapi.annotations.OpenApi;
import io.javalin.plugin.openapi.annotations.OpenApiContent;
import io.javalin.plugin.openapi.annotations.OpenApiResponse;
import java.util.Objects;
import java.util.Optional;
import java.util.function.Function;
import org.jetbrains.annotations.NotNull;
Expand Down Expand Up @@ -77,7 +78,6 @@ public GetSyncing(final DataProvider provider) {
+ "and if it is, what block it is up to.")
.tags(TAG_NODE, TAG_VALIDATOR_REQUIRED)
.response(SC_OK, "Request successful", SYNCING_RESPONSE_TYPE)
.response(SC_INTERNAL_SERVER_ERROR, "Server Error")
.build());
this.syncProvider = syncProvider;
}
Expand Down Expand Up @@ -121,6 +121,17 @@ public SyncStatusData(final SyncDataProvider syncProvider) {
this.slotsBehind = calculateSlotsBehind(status);
}

SyncStatusData(
final boolean isSyncing,
final Boolean isOptimistic,
final int currentSlot,
final int slotsBehind) {
this.isSyncing = isSyncing;
this.isOptimistic = Optional.ofNullable(isOptimistic);
this.currentSlot = UInt64.valueOf(currentSlot);
this.slotsBehind = UInt64.valueOf(slotsBehind);
}

public boolean isSyncing() {
return isSyncing;
}
Expand All @@ -144,5 +155,35 @@ private UInt64 calculateSlotsBehind(final SyncingStatus syncingStatus) {
}
return UInt64.ZERO;
}

@Override
public boolean equals(final Object o) {
if (this == o) {
return true;
}
if (o == null || getClass() != o.getClass()) {
return false;
}
final SyncStatusData that = (SyncStatusData) o;
return isSyncing == that.isSyncing
&& Objects.equals(isOptimistic, that.isOptimistic)
&& Objects.equals(currentSlot, that.currentSlot)
&& Objects.equals(slotsBehind, that.slotsBehind);
}

@Override
public int hashCode() {
return Objects.hash(isSyncing, isOptimistic, currentSlot, slotsBehind);
}

@Override
public String toString() {
return MoreObjects.toStringHelper(this)
.add("isSyncing", isSyncing)
.add("isOptimistic", isOptimistic)
.add("currentSlot", currentSlot)
.add("slotsBehind", slotsBehind)
.toString();
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -17,111 +17,98 @@
import static javax.servlet.http.HttpServletResponse.SC_OK;
import static javax.servlet.http.HttpServletResponse.SC_PARTIAL_CONTENT;
import static javax.servlet.http.HttpServletResponse.SC_SERVICE_UNAVAILABLE;
import static org.mockito.ArgumentMatchers.anyString;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.verify;
import static org.assertj.core.api.Assertions.assertThat;
import static org.mockito.Mockito.when;
import static tech.pegasys.teku.infrastructure.http.HttpStatusCodes.SC_BAD_REQUEST;
import static tech.pegasys.teku.infrastructure.http.HttpStatusCodes.SC_INTERNAL_SERVER_ERROR;
import static tech.pegasys.teku.infrastructure.http.RestApiConstants.SYNCING_STATUS;

import java.util.List;
import java.util.Map;
import com.fasterxml.jackson.core.JsonProcessingException;
import org.junit.jupiter.api.Test;
import tech.pegasys.teku.beacon.sync.events.SyncState;
import tech.pegasys.teku.beaconrestapi.AbstractMigratedBeaconHandlerTest;
import tech.pegasys.teku.infrastructure.restapi.endpoints.JavalinRestApiRequest;
import tech.pegasys.teku.infrastructure.restapi.endpoints.RestApiRequest;
import tech.pegasys.teku.infrastructure.restapi.StubRestApiRequest;

public class GetHealthTest extends AbstractMigratedBeaconHandlerTest {
private final GetHealth handler = new GetHealth(syncDataProvider, chainDataProvider);
private StubRestApiRequest request = new StubRestApiRequest();

@Test
public void shouldReturnSyncingStatusWhenSyncing() throws Exception {
when(chainDataProvider.isStoreAvailable()).thenReturn(true);
when(syncService.getCurrentSyncState()).thenReturn(SyncState.SYNCING);

final GetHealth handler = new GetHealth(syncDataProvider, chainDataProvider);
final JavalinRestApiRequest request = new JavalinRestApiRequest(context, handler.getMetadata());

handler.handleRequest(request);
checkResponseWithoutBody(SC_PARTIAL_CONTENT);
assertThat(request.getResponseCode()).isEqualTo(SC_PARTIAL_CONTENT);
}

@Test
public void shouldReturnSyncingStatusWhenStartingUp() throws Exception {
when(chainDataProvider.isStoreAvailable()).thenReturn(true);
when(syncService.getCurrentSyncState()).thenReturn(SyncState.START_UP);

final GetHealth handler = new GetHealth(syncDataProvider, chainDataProvider);
final JavalinRestApiRequest request = new JavalinRestApiRequest(context, handler.getMetadata());

handler.handleRequest(request);
checkResponseWithoutBody(SC_PARTIAL_CONTENT);
assertThat(request.getResponseCode()).isEqualTo(SC_PARTIAL_CONTENT);
}

@Test
public void shouldReturnCustomSyncingStatusWhenSyncing() throws Exception {
when(context.queryParamMap()).thenReturn(Map.of(SYNCING_STATUS, List.of("100")));
when(chainDataProvider.isStoreAvailable()).thenReturn(true);
when(syncService.getCurrentSyncState()).thenReturn(SyncState.SYNCING);

final GetHealth handler = new GetHealth(syncDataProvider, chainDataProvider);
final RestApiRequest request = new JavalinRestApiRequest(context, handler.getMetadata());
request = StubRestApiRequest.builder().optionalQueryParameter(SYNCING_STATUS, "100").build();

handler.handleRequest(request);
checkResponseWithoutBody(SC_CONTINUE);
assertThat(request.getResponseCode()).isEqualTo(SC_CONTINUE);
}

@Test
public void shouldReturnDefaultSyncingStatusWhenSyncingWrongParam() throws Exception {
when(chainDataProvider.isStoreAvailable()).thenReturn(true);
when(syncService.getCurrentSyncState()).thenReturn(SyncState.SYNCING);
when(context.queryParamMap()).thenReturn(Map.of(SYNCING_STATUS, List.of("a")));

final GetHealth handler = new GetHealth(syncDataProvider, chainDataProvider);
final RestApiRequest request = new JavalinRestApiRequest(context, handler.getMetadata());

request = StubRestApiRequest.builder().optionalQueryParameter(SYNCING_STATUS, "a").build();
handler.handleRequest(request);
checkResponseWithoutBody(SC_PARTIAL_CONTENT);
assertThat(request.getResponseCode()).isEqualTo(SC_PARTIAL_CONTENT);
}

@Test
public void shouldReturnDefaultSyncingStatusWhenSyncingMultipleParams() throws Exception {
when(chainDataProvider.isStoreAvailable()).thenReturn(true);
when(syncService.getCurrentSyncState()).thenReturn(SyncState.SYNCING);
when(context.queryParamMap()).thenReturn(Map.of(SYNCING_STATUS, List.of("1", "2")));

final GetHealth handler = new GetHealth(syncDataProvider, chainDataProvider);
final RestApiRequest request = new JavalinRestApiRequest(context, handler.getMetadata());
request = StubRestApiRequest.builder().optionalQueryParameter(SYNCING_STATUS, "1,2").build();

handler.handleRequest(request);
checkResponseWithoutBody(SC_PARTIAL_CONTENT);
assertThat(request.getResponseCode()).isEqualTo(SC_PARTIAL_CONTENT);
}

@Test
public void shouldReturnOkWhenInSyncAndReady() throws Exception {
when(chainDataProvider.isStoreAvailable()).thenReturn(true);
when(syncService.getCurrentSyncState()).thenReturn(SyncState.IN_SYNC);

final GetHealth handler = new GetHealth(syncDataProvider, chainDataProvider);
final RestApiRequest request = new JavalinRestApiRequest(context, handler.getMetadata());

handler.handleRequest(request);
checkResponseWithoutBody(SC_OK);
assertThat(request.getResponseCode()).isEqualTo(SC_OK);
}

@Test
public void shouldReturnUnavailableWhenStoreNotAvailable() throws Exception {
when(chainDataProvider.isStoreAvailable()).thenReturn(false);

final GetHealth handler = new GetHealth(syncDataProvider, chainDataProvider);
final RestApiRequest request = new JavalinRestApiRequest(context, handler.getMetadata());

handler.handleRequest(request);
checkResponseWithoutBody(SC_SERVICE_UNAVAILABLE);
assertThat(request.getResponseCode()).isEqualTo(SC_SERVICE_UNAVAILABLE);
}

private void checkResponseWithoutBody(final int statusCode) {
verify(context).status(eq(statusCode));
verify(context, never()).result(anyString());
@Test
void metadata_shouldHandle400() throws JsonProcessingException {
verifyMetadataErrorResponse(handler, SC_BAD_REQUEST);
}

@Test
void metadata_shouldHandle500() throws JsonProcessingException {
verifyMetadataErrorResponse(handler, SC_INTERNAL_SERVER_ERROR);
}

@Test
void metadata_shouldHandle200() {
verifyMetadataEmptyResponse(handler, SC_OK);
}
}
Loading

0 comments on commit 162a1a1

Please sign in to comment.