diff --git a/validator/api/src/main/java/tech/pegasys/teku/validator/api/UpdatableGraffitiProvider.java b/validator/api/src/main/java/tech/pegasys/teku/validator/api/UpdatableGraffitiProvider.java index d70b08d03d1..955a888808a 100644 --- a/validator/api/src/main/java/tech/pegasys/teku/validator/api/UpdatableGraffitiProvider.java +++ b/validator/api/src/main/java/tech/pegasys/teku/validator/api/UpdatableGraffitiProvider.java @@ -41,7 +41,7 @@ private Optional getFromStorage() { } } - public Optional getGraffitiWithThrowable() throws Throwable { + public Optional getWithThrowable() throws Throwable { return storageProvider.get().or(defaultProvider::get); } } diff --git a/validator/api/src/test/java/tech/pegasys/teku/validator/api/GraffitiManagerTest.java b/validator/api/src/test/java/tech/pegasys/teku/validator/api/GraffitiManagerTest.java index 941d4222b8d..0a5155bebbb 100644 --- a/validator/api/src/test/java/tech/pegasys/teku/validator/api/GraffitiManagerTest.java +++ b/validator/api/src/test/java/tech/pegasys/teku/validator/api/GraffitiManagerTest.java @@ -90,7 +90,8 @@ void setGraffiti_shouldReturnErrorMessageWhenUnableToWriteFile(@TempDir final Pa assertThat(file.setWritable(false)).isTrue(); assertThatThrownBy(() -> manager.setGraffiti(publicKey, graffiti)) - .isInstanceOf(IOException.class); + .isInstanceOf(GraffitiManagementException.class) + .hasMessage("Unable to update graffiti for validator " + publicKey); } @Test diff --git a/validator/api/src/test/java/tech/pegasys/teku/validator/api/UpdatableGraffitiProviderTest.java b/validator/api/src/test/java/tech/pegasys/teku/validator/api/UpdatableGraffitiProviderTest.java index a0c4e51295d..51c40fbcb70 100644 --- a/validator/api/src/test/java/tech/pegasys/teku/validator/api/UpdatableGraffitiProviderTest.java +++ b/validator/api/src/test/java/tech/pegasys/teku/validator/api/UpdatableGraffitiProviderTest.java @@ -14,10 +14,14 @@ package tech.pegasys.teku.validator.api; import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatThrownBy; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; import java.util.Optional; import org.apache.tuweni.bytes.Bytes32; import org.junit.jupiter.api.Test; +import tech.pegasys.teku.infrastructure.async.ExceptionThrowingSupplier; import tech.pegasys.teku.spec.TestSpecFactory; import tech.pegasys.teku.spec.util.DataStructureUtil; @@ -29,13 +33,13 @@ class UpdatableGraffitiProviderTest { private UpdatableGraffitiProvider provider; @Test - void shouldGetStorageGraffitiWhenAvailable() { + void get_shouldGetStorageGraffitiWhenAvailable() { provider = new UpdatableGraffitiProvider(() -> Optional.of(storageGraffiti), Optional::empty); assertThat(provider.get()).hasValue(storageGraffiti); } @Test - void shouldGetStorageGraffitiWhenBothAvailable() { + void get_shouldGetStorageGraffitiWhenBothAvailable() { provider = new UpdatableGraffitiProvider( () -> Optional.of(storageGraffiti), () -> Optional.of(defaultGraffiti)); @@ -43,14 +47,63 @@ void shouldGetStorageGraffitiWhenBothAvailable() { } @Test - void shouldGetDefaultGraffitiWhenStorageEmpty() { + void get_shouldGetDefaultGraffitiWhenStorageEmpty() { provider = new UpdatableGraffitiProvider(Optional::empty, () -> Optional.of(defaultGraffiti)); assertThat(provider.get()).hasValue(defaultGraffiti); } @Test - void shouldBeEmptyWhenBothEmpty() { + void get_shouldBeEmptyWhenBothEmpty() { provider = new UpdatableGraffitiProvider(Optional::empty, Optional::empty); assertThat(provider.get()).isEmpty(); } + + @Test + @SuppressWarnings("unchecked") + public void get_shouldDelegateToDefaultProviderWhenStorageProviderFails() throws Throwable { + final ExceptionThrowingSupplier> storageProvider = + mock(ExceptionThrowingSupplier.class); + when(storageProvider.get()).thenThrow(new RuntimeException("Error")); + + provider = new UpdatableGraffitiProvider(storageProvider, () -> Optional.of(defaultGraffiti)); + assertThat(provider.get()).hasValue(defaultGraffiti); + } + + @Test + void getWithThrowable_shouldGetStorageGraffitiWhenAvailable() { + provider = new UpdatableGraffitiProvider(() -> Optional.of(storageGraffiti), Optional::empty); + assertThat(provider.get()).hasValue(storageGraffiti); + } + + @Test + void getWithThrowable_shouldGetStorageGraffitiWhenBothAvailable() { + provider = + new UpdatableGraffitiProvider( + () -> Optional.of(storageGraffiti), () -> Optional.of(defaultGraffiti)); + assertThat(provider.get()).hasValue(storageGraffiti); + } + + @Test + void getWithThrowable_shouldGetDefaultGraffitiWhenStorageEmpty() { + provider = new UpdatableGraffitiProvider(Optional::empty, () -> Optional.of(defaultGraffiti)); + assertThat(provider.get()).hasValue(defaultGraffiti); + } + + @Test + void getWithThrowable_shouldBeEmptyWhenBothEmpty() { + provider = new UpdatableGraffitiProvider(Optional::empty, Optional::empty); + assertThat(provider.get()).isEmpty(); + } + + @Test + @SuppressWarnings("unchecked") + public void getWithThrowable_shouldThrowExceptionWhenStorageProviderFails() throws Throwable { + final RuntimeException exception = new RuntimeException("Error"); + final ExceptionThrowingSupplier> storageProvider = + mock(ExceptionThrowingSupplier.class); + when(storageProvider.get()).thenThrow(exception); + + provider = new UpdatableGraffitiProvider(storageProvider, () -> Optional.of(defaultGraffiti)); + assertThatThrownBy(() -> provider.getWithThrowable()).isEqualTo(exception); + } } diff --git a/validator/client/src/main/java/tech/pegasys/teku/validator/client/restapi/apis/GetGraffiti.java b/validator/client/src/main/java/tech/pegasys/teku/validator/client/restapi/apis/GetGraffiti.java index 816354edd47..2ddcf6a8b21 100644 --- a/validator/client/src/main/java/tech/pegasys/teku/validator/client/restapi/apis/GetGraffiti.java +++ b/validator/client/src/main/java/tech/pegasys/teku/validator/client/restapi/apis/GetGraffiti.java @@ -93,7 +93,7 @@ public void handleRequest(final RestApiRequest request) throws JsonProcessingExc try { final UpdatableGraffitiProvider provider = (UpdatableGraffitiProvider) maybeValidator.get().getGraffitiProvider(); - request.respondOk(new GraffitiResponse(publicKey, provider.getGraffitiWithThrowable())); + request.respondOk(new GraffitiResponse(publicKey, provider.getWithThrowable())); } catch (Throwable e) { request.respondError(SC_INTERNAL_SERVER_ERROR, e.getMessage()); } diff --git a/validator/client/src/test/java/tech/pegasys/teku/validator/client/restapi/apis/DeleteGraffitiTest.java b/validator/client/src/test/java/tech/pegasys/teku/validator/client/restapi/apis/DeleteGraffitiTest.java index d57bb769ddd..f3aa4c39fd4 100644 --- a/validator/client/src/test/java/tech/pegasys/teku/validator/client/restapi/apis/DeleteGraffitiTest.java +++ b/validator/client/src/test/java/tech/pegasys/teku/validator/client/restapi/apis/DeleteGraffitiTest.java @@ -60,7 +60,7 @@ class DeleteGraffitiTest { .build(); @Test - void shouldSuccessfullyDeleteGraffiti() throws IOException { + void shouldSuccessfullyDeleteGraffiti() throws IOException, GraffitiManagementException { final Validator validator = new Validator(publicKey, NO_OP_SIGNER, Optional::empty); when(keyManager.getValidatorByPublicKey(any())).thenReturn(Optional.of(validator)); @@ -72,7 +72,8 @@ void shouldSuccessfullyDeleteGraffiti() throws IOException { } @Test - void shouldReturnErrorWhenIssueDeletingGraffiti() throws IOException { + void shouldReturnErrorWhenIssueDeletingGraffiti() + throws IOException, GraffitiManagementException { final String errorMessage = "Unable to delete graffiti for validator " + publicKey; final Validator validator = new Validator(publicKey, NO_OP_SIGNER, Optional::empty); when(keyManager.getValidatorByPublicKey(any())).thenReturn(Optional.of(validator)); diff --git a/validator/client/src/test/java/tech/pegasys/teku/validator/client/restapi/apis/GetGraffitiTest.java b/validator/client/src/test/java/tech/pegasys/teku/validator/client/restapi/apis/GetGraffitiTest.java index 4e048c687bb..b120b7e30c0 100644 --- a/validator/client/src/test/java/tech/pegasys/teku/validator/client/restapi/apis/GetGraffitiTest.java +++ b/validator/client/src/test/java/tech/pegasys/teku/validator/client/restapi/apis/GetGraffitiTest.java @@ -136,7 +136,7 @@ void metadata_shouldHandle500() throws JsonProcessingException { private void checkGraffiti(final Optional graffiti) throws Throwable { final UpdatableGraffitiProvider provider = mock(UpdatableGraffitiProvider.class); - when(provider.getGraffitiWithThrowable()).thenReturn(graffiti); + when(provider.getWithThrowable()).thenReturn(graffiti); final Validator validator = new Validator(publicKey, NO_OP_SIGNER, provider); when(keyManager.getValidatorByPublicKey(eq(publicKey))).thenReturn(Optional.of(validator)); @@ -146,6 +146,6 @@ private void checkGraffiti(final Optional graffiti) throws Throwable { new GetGraffiti.GraffitiResponse(publicKey, graffiti); assertThat(request.getResponseCode()).isEqualTo(SC_OK); assertThat(request.getResponseBody()).isEqualTo(expectedResponse); - verify(provider).getGraffitiWithThrowable(); + verify(provider).getWithThrowable(); } } diff --git a/validator/client/src/test/java/tech/pegasys/teku/validator/client/restapi/apis/SetGraffitiTest.java b/validator/client/src/test/java/tech/pegasys/teku/validator/client/restapi/apis/SetGraffitiTest.java index f035042d80c..213acea7c47 100644 --- a/validator/client/src/test/java/tech/pegasys/teku/validator/client/restapi/apis/SetGraffitiTest.java +++ b/validator/client/src/test/java/tech/pegasys/teku/validator/client/restapi/apis/SetGraffitiTest.java @@ -62,7 +62,7 @@ class SetGraffitiTest { .build(); @Test - void shouldSuccessfullySetGraffiti() throws IOException { + void shouldSuccessfullySetGraffiti() throws IOException, GraffitiManagementException { request.setRequestBody(graffiti); final Validator validator = new Validator(publicKey, NO_OP_SIGNER, Optional::empty); @@ -76,7 +76,7 @@ void shouldSuccessfullySetGraffiti() throws IOException { } @Test - void shouldReturnErrorWhenIssueSettingGraffiti() throws IOException { + void shouldReturnErrorWhenIssueSettingGraffiti() throws IOException, GraffitiManagementException { final String errorMessage = "Unable to update graffiti for validator " + publicKey; request.setRequestBody(graffiti); @@ -95,7 +95,7 @@ void shouldReturnErrorWhenIssueSettingGraffiti() throws IOException { } @Test - void shouldThrowExceptionWhenInvalidGraffitiInput() throws IOException { + void shouldThrowExceptionWhenInvalidGraffitiInput() throws GraffitiManagementException { final String invalidGraffiti = "This graffiti is a bit too long!!"; final String errorMessage = String.format(