package info.frostfs.sdk.services; import frostfs.apemanager.APEManagerServiceGrpc; import frostfs.apemanager.Service; import info.frostfs.sdk.FileUtils; import info.frostfs.sdk.dto.chain.Chain; import info.frostfs.sdk.dto.chain.ChainTarget; import info.frostfs.sdk.enums.TargetType; import info.frostfs.sdk.exceptions.ValidationFrostFSException; import info.frostfs.sdk.jdo.ClientEnvironment; import info.frostfs.sdk.services.impl.ApeManagerClientImpl; import info.frostfs.sdk.testgenerator.ApeManagerGenerator; import info.frostfs.sdk.tools.RequestConstructor; import info.frostfs.sdk.tools.RequestSigner; import info.frostfs.sdk.tools.Verifier; import io.grpc.Channel; import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; import org.junit.platform.commons.util.ReflectionUtils; import org.mockito.ArgumentCaptor; import org.mockito.Mock; import org.mockito.MockedStatic; import org.mockito.Mockito; import org.mockito.junit.jupiter.MockitoExtension; import java.lang.reflect.Field; import java.util.stream.Collectors; import static org.assertj.core.api.Assertions.assertThat; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertThrows; import static org.mockito.Mockito.*; @ExtendWith(MockitoExtension.class) class ApeManagerClientTest { private ApeManagerClientImpl apeManagerClient; @Mock private APEManagerServiceGrpc.APEManagerServiceBlockingStub apeManagerServiceClient; @Mock private ClientEnvironment clientEnvironment; @Mock private Channel channel; private MockedStatic verifierMock; private MockedStatic requestConstructorMock; private MockedStatic requestSignerMock; @BeforeEach void setUp() throws IllegalAccessException { when(clientEnvironment.getChannel()).thenReturn(channel); apeManagerClient = new ApeManagerClientImpl(clientEnvironment); Field field = ReflectionUtils.findFields(ApeManagerClientImpl.class, f -> f.getName().equals("apeManagerServiceClient"), ReflectionUtils.HierarchyTraversalMode.TOP_DOWN) .get(0); field.setAccessible(true); field.set(apeManagerClient, apeManagerServiceClient); verifierMock = Mockito.mockStatic(Verifier.class); requestConstructorMock = Mockito.mockStatic(RequestConstructor.class); requestSignerMock = Mockito.mockStatic(RequestSigner.class); } @AfterEach void cleanUp() { verifierMock.close(); requestConstructorMock.close(); requestSignerMock.close(); } @Test void addChain_success() { //Given Chain chain = generateChain(); ChainTarget chainTarget = generateChainTarget(); var response = ApeManagerGenerator.generateAddChainResponse(); var captor = ArgumentCaptor.forClass(Service.AddChainRequest.class); when(apeManagerServiceClient.addChain(captor.capture())).thenReturn(response); //When var result = apeManagerClient.addChain(chain, chainTarget); //Then requestConstructorMock.verify( () -> RequestConstructor.addMetaHeader(any(Service.AddChainRequest.Builder.class), eq(null)), times(1) ); requestSignerMock.verify( () -> RequestSigner.sign(any(Service.AddChainRequest.Builder.class), eq(null)), times(1) ); verifierMock.verify(() -> Verifier.checkResponse(response), times(1)); assertThat(result).containsOnly(response.getBody().getChainId().toByteArray()); var request = captor.getValue(); assertThat(request.getBody().getChain().getRaw().toByteArray()).containsOnly(chain.getRaw()); assertEquals(chainTarget.getName(), request.getBody().getTarget().getName()); assertEquals(chainTarget.getType().value, request.getBody().getTarget().getType().getNumber()); } @Test void addChain_wrongParams() { //Given Chain chain = generateChain(); ChainTarget chainTarget = generateChainTarget(); //When + Then assertThrows(ValidationFrostFSException.class, () -> apeManagerClient.addChain(null, chainTarget)); assertThrows(ValidationFrostFSException.class, () -> apeManagerClient.addChain(chain, null)); assertThrows(ValidationFrostFSException.class, () -> apeManagerClient.addChain(null, null)); } @Test void removeChain_success() { //Given Chain chain = generateChain(); ChainTarget chainTarget = generateChainTarget(); var response = ApeManagerGenerator.generateRemoveChainResponse(); var captor = ArgumentCaptor.forClass(Service.RemoveChainRequest.class); when(apeManagerServiceClient.removeChain(captor.capture())).thenReturn(response); //When apeManagerClient.removeChain(chain, chainTarget); //Then requestConstructorMock.verify( () -> RequestConstructor.addMetaHeader(any(Service.RemoveChainRequest.Builder.class), eq(null)), times(1) ); requestSignerMock.verify( () -> RequestSigner.sign(any(Service.RemoveChainRequest.Builder.class), eq(null)), times(1) ); verifierMock.verify(() -> Verifier.checkResponse(response), times(1)); var request = captor.getValue(); assertThat(request.getBody().getChainId().toByteArray()).containsOnly(chain.getRaw()); assertEquals(chainTarget.getName(), request.getBody().getTarget().getName()); assertEquals(chainTarget.getType().value, request.getBody().getTarget().getType().getNumber()); } @Test void removeChain_wrongParams() { //Given Chain chain = generateChain(); ChainTarget chainTarget = generateChainTarget(); //When + Then assertThrows(ValidationFrostFSException.class, () -> apeManagerClient.removeChain(null, chainTarget)); assertThrows(ValidationFrostFSException.class, () -> apeManagerClient.removeChain(chain, null)); assertThrows(ValidationFrostFSException.class, () -> apeManagerClient.removeChain(null, null)); } @Test void listChain_success() { //Given ChainTarget chainTarget = generateChainTarget(); var response = ApeManagerGenerator.generateListChainsResponse(); var captor = ArgumentCaptor.forClass(Service.ListChainsRequest.class); when(apeManagerServiceClient.listChains(captor.capture())).thenReturn(response); //When var result = apeManagerClient.listChains(chainTarget); //Then requestConstructorMock.verify( () -> RequestConstructor.addMetaHeader(any(Service.ListChainsRequest.Builder.class), eq(null)), times(1) ); requestSignerMock.verify( () -> RequestSigner.sign(any(Service.ListChainsRequest.Builder.class), eq(null)), times(1) ); verifierMock.verify(() -> Verifier.checkResponse(response), times(1)); var actual = result.stream().map(Chain::getRaw).collect(Collectors.toList()); var expected = response.getBody().getChainsList().stream() .map(chain -> chain.getRaw().toByteArray()) .collect(Collectors.toList()); assertThat(actual).hasSize(10).containsAll(expected); var request = captor.getValue(); assertEquals(chainTarget.getName(), request.getBody().getTarget().getName()); assertEquals(chainTarget.getType().value, request.getBody().getTarget().getType().getNumber()); } @Test void listChain_wrongParams() { //When + Then assertThrows(ValidationFrostFSException.class, () -> apeManagerClient.listChains(null)); } private Chain generateChain() { byte[] chainRaw = FileUtils.resourceToBytes("test_chain_raw.json"); return new Chain(chainRaw); } private ChainTarget generateChainTarget() { return new ChainTarget("BzQw5HH3feoxFDD5tCT87Y1726qzgLfxEE7wgtoRzB3R", TargetType.NAMESPACE); } }