From c9a6805df30f6282ace0285df26107b5518d4e2b Mon Sep 17 00:00:00 2001 From: elinuxhenrik Date: Wed, 27 May 2020 11:18:46 +0200 Subject: [PATCH] Add tests to increase code coverage Change-Id: I675e1d8995affa820ccd07aa8d29b9386a078bcb Issue-ID: NONRTRIC-116 Signed-off-by: elinuxhenrik --- .../policyagent/clients/SdncOscA1Client.java | 47 +++--- .../configuration/ApplicationConfigParser.java | 4 + .../policyagent/tasks/RefreshConfigTask.java | 9 +- .../oransc/policyagent/aspect/LogAspectTest.java | 78 ++++++++++ .../policyagent/clients/SdncOscA1ClientTest.java | 162 ++++++++++++++------- .../policyagent/tasks/RefreshConfigTaskTest.java | 59 ++++++-- .../tasks/RicSynchronizationTaskTest.java | 8 +- 7 files changed, 266 insertions(+), 101 deletions(-) create mode 100644 policy-agent/src/test/java/org/oransc/policyagent/aspect/LogAspectTest.java diff --git a/policy-agent/src/main/java/org/oransc/policyagent/clients/SdncOscA1Client.java b/policy-agent/src/main/java/org/oransc/policyagent/clients/SdncOscA1Client.java index a5735f7d..2763ab9b 100644 --- a/policy-agent/src/main/java/org/oransc/policyagent/clients/SdncOscA1Client.java +++ b/policy-agent/src/main/java/org/oransc/policyagent/clients/SdncOscA1Client.java @@ -80,10 +80,12 @@ public class SdncOscA1Client implements A1Client { /** * Constructor that creates the REST client to use. * - * @param protocolType the southbound protocol of the controller. Supported - * protocols are SDNC_OSC_STD_V1_1 and SDNC_OSC_OSC_V1 + * @param protocolType the southbound protocol of the controller. Supported protocols are SDNC_OSC_STD_V1_1 and + * SDNC_OSC_OSC_V1 * @param ricConfig the configuration of the Ric to communicate with * @param controllerConfig the configuration of the SDNC controller to use + * + * @throws IllegalArgumentException when the protocolType is wrong. */ public SdncOscA1Client(A1ProtocolType protocolType, RicConfig ricConfig, ControllerConfig controllerConfig) { this(protocolType, ricConfig, controllerConfig, @@ -94,14 +96,21 @@ public class SdncOscA1Client implements A1Client { /** * Constructor where the REST client to use is provided. * - * @param protocolType the southbound protocol of the controller. Supported - * protocols are SDNC_OSC_STD_V1_1 and SDNC_OSC_OSC_V1 + * @param protocolType the southbound protocol of the controller. Supported protocols are SDNC_OSC_STD_V1_1 and + * SDNC_OSC_OSC_V1 * @param ricConfig the configuration of the Ric to communicate with * @param controllerConfig the configuration of the SDNC controller to use * @param restClient the REST client to use + * + * @throws IllegalArgumentException when the protocolType is wrong. */ public SdncOscA1Client(A1ProtocolType protocolType, RicConfig ricConfig, ControllerConfig controllerConfig, AsyncRestClient restClient) { + if (!(A1ProtocolType.SDNC_OSC_STD_V1_1.equals(protocolType) + || A1ProtocolType.SDNC_OSC_OSC_V1.equals(protocolType))) { + throw new IllegalArgumentException("Protocol type must be " + A1ProtocolType.SDNC_OSC_STD_V1_1 + " or " + + A1ProtocolType.SDNC_OSC_OSC_V1 + ", was: " + protocolType); + } this.restClient = restClient; this.ricConfig = ricConfig; this.protocolType = protocolType; @@ -112,22 +121,16 @@ public class SdncOscA1Client implements A1Client { public Mono> getPolicyTypeIdentities() { if (this.protocolType == A1ProtocolType.SDNC_OSC_STD_V1_1) { return Mono.just(Arrays.asList("")); - } else if (this.protocolType == A1ProtocolType.SDNC_OSC_OSC_V1) { + } else { OscA1Client.UriBuilder uri = new OscA1Client.UriBuilder(ricConfig); final String ricUrl = uri.createPolicyTypesUri(); return post(GET_POLICY_RPC, ricUrl, Optional.empty()) // .flatMapMany(SdncJsonHelper::parseJsonArrayOfString) // .collectList(); - } else { - return Mono.error(createIllegalProtocolException()); } } - private Exception createIllegalProtocolException() { - return new NullPointerException("Bug, unhandeled protocoltype: " + this.protocolType); - } - @Override public Mono> getPolicyIdentities() { return getPolicyIds() // @@ -138,13 +141,11 @@ public class SdncOscA1Client implements A1Client { public Mono getPolicyTypeSchema(String policyTypeId) { if (this.protocolType == A1ProtocolType.SDNC_OSC_STD_V1_1) { return Mono.just("{}"); - } else if (this.protocolType == A1ProtocolType.SDNC_OSC_OSC_V1) { + } else { OscA1Client.UriBuilder uri = new OscA1Client.UriBuilder(ricConfig); final String ricUrl = uri.createGetSchemaUri(policyTypeId); return post(GET_POLICY_RPC, ricUrl, Optional.empty()) // .flatMap(response -> OscA1Client.extractCreateSchema(response, policyTypeId)); - } else { - return Mono.error(createIllegalProtocolException()); } } @@ -167,13 +168,11 @@ public class SdncOscA1Client implements A1Client { if (this.protocolType == A1ProtocolType.SDNC_OSC_STD_V1_1) { return getPolicyIds() // .flatMap(policyId -> deletePolicyById("", policyId), CONCURRENCY_RIC); // - } else if (this.protocolType == A1ProtocolType.SDNC_OSC_OSC_V1) { + } else { OscA1Client.UriBuilder uriBuilder = new OscA1Client.UriBuilder(ricConfig); return getPolicyTypeIdentities() // .flatMapMany(Flux::fromIterable) // .flatMap(type -> oscDeleteInstancesForType(uriBuilder, type), CONCURRENCY_RIC); - } else { - return Flux.error(createIllegalProtocolException()); } } @@ -205,10 +204,8 @@ public class SdncOscA1Client implements A1Client { private Mono getUriBuilder() { if (protocolType == A1ProtocolType.SDNC_OSC_STD_V1_1) { return Mono.just(new StdA1ClientVersion1.UriBuilder(ricConfig)); - } else if (this.protocolType == A1ProtocolType.SDNC_OSC_OSC_V1) { - return Mono.just(new OscA1Client.UriBuilder(ricConfig)); } else { - return Mono.error(createIllegalProtocolException()); + return Mono.just(new OscA1Client.UriBuilder(ricConfig)); } } @@ -230,14 +227,12 @@ public class SdncOscA1Client implements A1Client { final String ricUrl = uri.createGetPolicyIdsUri(); return post(GET_POLICY_RPC, ricUrl, Optional.empty()) // .flatMapMany(SdncJsonHelper::parseJsonArrayOfString); - } else if (this.protocolType == A1ProtocolType.SDNC_OSC_OSC_V1) { + } else { OscA1Client.UriBuilder uri = new OscA1Client.UriBuilder(ricConfig); return getPolicyTypeIdentities() // .flatMapMany(Flux::fromIterable) .flatMap(type -> post(GET_POLICY_RPC, uri.createGetPolicyIdsUri(type), Optional.empty())) // .flatMap(SdncJsonHelper::parseJsonArrayOfString); - } else { - return Flux.error(createIllegalProtocolException()); } } @@ -272,10 +267,10 @@ public class SdncOscA1Client implements A1Client { } else { logger.debug("Error response: {} {}", output.httpStatus(), body); byte[] responseBodyBytes = body.getBytes(StandardCharsets.UTF_8); - WebClientResponseException e = new WebClientResponseException(output.httpStatus(), "statusText", null, - responseBodyBytes, StandardCharsets.UTF_8, null); + WebClientResponseException responseException = new WebClientResponseException(output.httpStatus(), + "statusText", null, responseBodyBytes, StandardCharsets.UTF_8, null); - return Mono.error(e); + return Mono.error(responseException); } } diff --git a/policy-agent/src/main/java/org/oransc/policyagent/configuration/ApplicationConfigParser.java b/policy-agent/src/main/java/org/oransc/policyagent/configuration/ApplicationConfigParser.java index 54957107..a76f964c 100644 --- a/policy-agent/src/main/java/org/oransc/policyagent/configuration/ApplicationConfigParser.java +++ b/policy-agent/src/main/java/org/oransc/policyagent/configuration/ApplicationConfigParser.java @@ -71,6 +71,10 @@ public class ApplicationConfigParser { JsonObject agentConfigJson = root.getAsJsonObject(CONFIG); + if (agentConfigJson == null) { + throw new ServiceException("Missing root configuration \"" + CONFIG + "\" in JSON: " + root); + } + JsonObject json = agentConfigJson.getAsJsonObject("streams_publishes"); if (json != null) { dmaapPublisherConfig = parseDmaapConfig(json); diff --git a/policy-agent/src/main/java/org/oransc/policyagent/tasks/RefreshConfigTask.java b/policy-agent/src/main/java/org/oransc/policyagent/tasks/RefreshConfigTask.java index 89c8d638..f44c8d5c 100644 --- a/policy-agent/src/main/java/org/oransc/policyagent/tasks/RefreshConfigTask.java +++ b/policy-agent/src/main/java/org/oransc/policyagent/tasks/RefreshConfigTask.java @@ -22,8 +22,10 @@ package org.oransc.policyagent.tasks; import com.google.gson.GsonBuilder; import com.google.gson.JsonElement; +import com.google.gson.JsonIOException; import com.google.gson.JsonObject; import com.google.gson.JsonParser; +import com.google.gson.JsonSyntaxException; import com.google.gson.TypeAdapterFactory; import java.io.BufferedInputStream; @@ -69,8 +71,7 @@ import reactor.core.publisher.Flux; import reactor.core.publisher.Mono; /** - * Regularly refreshes the configuration from Consul or from a local - * configuration file. + * Regularly refreshes the configuration from Consul or from a local configuration file. */ @Component public class RefreshConfigTask { @@ -158,8 +159,8 @@ public class RefreshConfigTask { } private Mono getFromCbs(CbsClient cbsClient) { - final CbsRequest getConfigRequest = CbsRequests.getAll(RequestDiagnosticContext.create()); try { + final CbsRequest getConfigRequest = CbsRequests.getAll(RequestDiagnosticContext.create()); return cbsClient.get(getConfigRequest) // .onErrorResume(this::ignoreErrorMono); } catch (Exception e) { @@ -249,7 +250,7 @@ public class RefreshConfigTask { appParser.parse(rootObject); logger.debug("Local configuration file loaded: {}", filepath); return Flux.just(rootObject); - } catch (IOException | ServiceException e) { + } catch (Exception e) { logger.error("Local configuration file not loaded: {}, {}", filepath, e.getMessage()); return Flux.empty(); } diff --git a/policy-agent/src/test/java/org/oransc/policyagent/aspect/LogAspectTest.java b/policy-agent/src/test/java/org/oransc/policyagent/aspect/LogAspectTest.java new file mode 100644 index 00000000..7930e5c7 --- /dev/null +++ b/policy-agent/src/test/java/org/oransc/policyagent/aspect/LogAspectTest.java @@ -0,0 +1,78 @@ +package org.oransc.policyagent.aspect; + +import static ch.qos.logback.classic.Level.TRACE; +import static org.assertj.core.api.Assertions.assertThat; +import static org.mockito.Mockito.never; +import static org.mockito.Mockito.times; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; + +import ch.qos.logback.classic.spi.ILoggingEvent; +import ch.qos.logback.core.read.ListAppender; + +import org.aspectj.lang.ProceedingJoinPoint; +import org.aspectj.lang.reflect.MethodSignature; +import org.junit.Rule; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.mockito.Mock; +import org.mockito.junit.MockitoJUnit; +import org.mockito.junit.MockitoRule; +import org.mockito.junit.jupiter.MockitoExtension; +import org.oransc.policyagent.utils.LoggingUtils; + +@ExtendWith(MockitoExtension.class) +class LogAspectTest { + @Rule + MockitoRule mockitoRule = MockitoJUnit.rule(); + + @Mock + private ProceedingJoinPoint proceedingJoinPoint; + + @Mock + private MethodSignature methodSignature; + + private LogAspect sampleAspect = new LogAspect(); + + @Test + void testExecutetimeTime_shouldLogTime() throws Throwable { + when(proceedingJoinPoint.getSignature()).thenReturn(methodSignature); + when(methodSignature.getDeclaringType()).thenReturn(this.getClass()); + + final ListAppender logAppender = LoggingUtils.getLogListAppender(LogAspect.class, TRACE); + + sampleAspect.executimeTime(proceedingJoinPoint); + // 'proceed()' is called exactly once + verify(proceedingJoinPoint, times(1)).proceed(); + // 'proceed(Object[])' is never called + verify(proceedingJoinPoint, never()).proceed(null); + + assertThat(logAppender.list.toString().contains("Execution time of")).isTrue(); + } + + @Test + void testEntryLog_shouldLogEntry() throws Throwable { + when(proceedingJoinPoint.getSignature()).thenReturn(methodSignature); + String signature = "signature"; + when(methodSignature.getName()).thenReturn(signature); + + final ListAppender logAppender = LoggingUtils.getLogListAppender(LogAspect.class, TRACE); + + sampleAspect.entryLog(proceedingJoinPoint); + + assertThat(logAppender.list.toString().contains("Entering method: " + signature)).isTrue(); + } + + @Test + void testExitLog_shouldLogExit() throws Throwable { + when(proceedingJoinPoint.getSignature()).thenReturn(methodSignature); + String signature = "signature"; + when(methodSignature.getName()).thenReturn(signature); + + final ListAppender logAppender = LoggingUtils.getLogListAppender(LogAspect.class, TRACE); + + sampleAspect.exitLog(proceedingJoinPoint); + + assertThat(logAppender.list.toString().contains("Exiting method: " + signature)).isTrue(); + } +} diff --git a/policy-agent/src/test/java/org/oransc/policyagent/clients/SdncOscA1ClientTest.java b/policy-agent/src/test/java/org/oransc/policyagent/clients/SdncOscA1ClientTest.java index 7a1daad5..d63974ea 100644 --- a/policy-agent/src/test/java/org/oransc/policyagent/clients/SdncOscA1ClientTest.java +++ b/policy-agent/src/test/java/org/oransc/policyagent/clients/SdncOscA1ClientTest.java @@ -20,9 +20,9 @@ package org.oransc.policyagent.clients; +import static org.junit.Assert.fail; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.mockito.ArgumentMatchers.anyString; -import static org.mockito.Mockito.mock; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; @@ -40,15 +40,18 @@ import java.util.Optional; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; +import org.mockito.Mock; import org.mockito.junit.jupiter.MockitoExtension; import org.mockito.stubbing.OngoingStubbing; import org.oransc.policyagent.clients.A1Client.A1ProtocolType; +import org.oransc.policyagent.clients.ImmutableAdapterOutput.Builder; import org.oransc.policyagent.clients.SdncOscA1Client.AdapterOutput; import org.oransc.policyagent.clients.SdncOscA1Client.AdapterRequest; import org.oransc.policyagent.configuration.ControllerConfig; import org.oransc.policyagent.configuration.ImmutableControllerConfig; import org.oransc.policyagent.repository.Policy; import org.oransc.policyagent.repository.Ric; +import org.springframework.http.HttpStatus; import org.springframework.web.reactive.function.client.WebClientResponseException; import reactor.core.publisher.Mono; @@ -70,6 +73,7 @@ class SdncOscA1ClientTest { SdncOscA1Client clientUnderTest; + @Mock AsyncRestClient asyncRestClientMock; private ControllerConfig controllerConfig() { @@ -83,7 +87,6 @@ class SdncOscA1ClientTest { @BeforeEach void init() { - asyncRestClientMock = mock(AsyncRestClient.class); Ric ric = A1ClientHelper.createRic(RIC_1_URL); clientUnderTest = new SdncOscA1Client(A1ProtocolType.SDNC_OSC_STD_V1_1, ric.getConfig(), controllerConfig(), @@ -91,22 +94,33 @@ class SdncOscA1ClientTest { } @Test - void testGetPolicyTypeIdentities_STD() { + void createClientWithWrongProtocol_thenErrorIsThrown() { + try { + new SdncOscA1Client(A1ProtocolType.STD_V1_1, null, null, null); + fail("Should have thrown exception."); + } catch (IllegalArgumentException e) { + return; + } + } + + @Test + void getPolicyTypeIdentities_STD() { List policyTypeIds = clientUnderTest.getPolicyTypeIdentities().block(); assertEquals(1, policyTypeIds.size(), "should hardcoded to one"); assertEquals("", policyTypeIds.get(0), "should hardcoded to empty"); } @Test - void testGetPolicyTypeIdentities_OSC() { + void getPolicyTypeIdentities_OSC() { clientUnderTest = new SdncOscA1Client(A1ProtocolType.SDNC_OSC_OSC_V1, // A1ClientHelper.createRic(RIC_1_URL).getConfig(), // controllerConfig(), asyncRestClientMock); - String response = createResponse(Arrays.asList(POLICY_TYPE_1_ID)); + String response = createOkResponseWithBody(Arrays.asList(POLICY_TYPE_1_ID)); whenAsyncPostThenReturn(Mono.just(response)); List policyTypeIds = clientUnderTest.getPolicyTypeIdentities().block(); + assertEquals(1, policyTypeIds.size(), ""); assertEquals(POLICY_TYPE_1_ID, policyTypeIds.get(0), ""); @@ -119,25 +133,26 @@ class SdncOscA1ClientTest { CONTROLLER_PASSWORD); } - private String loadFile(String fileName) throws IOException { - ClassLoader loader = Thread.currentThread().getContextClassLoader(); - URL url = loader.getResource(fileName); - File file = new File(url.getFile()); - return new String(Files.readAllBytes(file.toPath())); + @Test + void getTypeSchema_STD() { + String policyType = clientUnderTest.getPolicyTypeSchema("").block(); + + assertEquals("{}", policyType, ""); } @Test - void testGetTypeSchema_OSC() throws IOException { + void getTypeSchema_OSC() throws IOException { clientUnderTest = new SdncOscA1Client(A1ProtocolType.SDNC_OSC_OSC_V1, // A1ClientHelper.createRic(RIC_1_URL).getConfig(), // controllerConfig(), asyncRestClientMock); String ricResponse = loadFile("test_osc_get_schema_response.json"); JsonElement elem = gson().fromJson(ricResponse, JsonElement.class); - String responseFromController = createResponse(elem); + String responseFromController = createOkResponseWithBody(elem); whenAsyncPostThenReturn(Mono.just(responseFromController)); String response = clientUnderTest.getPolicyTypeSchema("policyTypeId").block(); + JsonElement respJson = gson().fromJson(response, JsonElement.class); assertEquals("policyTypeId", respJson.getAsJsonObject().get("title").getAsString(), "title should be updated to contain policyType ID"); @@ -154,29 +169,14 @@ class SdncOscA1ClientTest { assertEquals("1", result.get(1), ""); } - private String policiesUrl() { - return RIC_1_URL + "/A1-P/v1/policies"; - } - - private Gson gson() { - return SdncOscA1Client.gson; - } - - private String createResponse(Object body) { - AdapterOutput output = ImmutableAdapterOutput.builder() // - .body(gson().toJson(body)) // - .httpStatus(200) // - .build(); - return SdncJsonHelper.createOutputJsonString(output); - } - @Test - void testGetPolicyIdentities() { + void getPolicyIdentities_STD() { - String policyIdsResp = createResponse(Arrays.asList(POLICY_1_ID, POLICY_2_ID)); + String policyIdsResp = createOkResponseWithBody(Arrays.asList(POLICY_1_ID, POLICY_2_ID)); whenAsyncPostThenReturn(Mono.just(policyIdsResp)); List returned = clientUnderTest.getPolicyIdentities().block(); + assertEquals(2, returned.size(), ""); ImmutableAdapterRequest expectedParams = ImmutableAdapterRequest.builder() // @@ -189,18 +189,35 @@ class SdncOscA1ClientTest { } @Test - void testGetValidPolicyType() { - String policyType = clientUnderTest.getPolicyTypeSchema("").block(); - assertEquals("{}", policyType, ""); + void getPolicyIdentities_OSC() { + clientUnderTest = new SdncOscA1Client(A1ProtocolType.SDNC_OSC_OSC_V1, // + A1ClientHelper.createRic(RIC_1_URL).getConfig(), // + controllerConfig(), asyncRestClientMock); + + String policytypeIdsResp = createOkResponseWithBody(Arrays.asList(POLICY_TYPE_1_ID)); + String policyIdsResp = createOkResponseWithBody(Arrays.asList(POLICY_1_ID, POLICY_2_ID)); + whenAsyncPostThenReturn(Mono.just(policytypeIdsResp)).thenReturn(Mono.just(policyIdsResp)); + + List returned = clientUnderTest.getPolicyIdentities().block(); + + assertEquals(2, returned.size(), ""); + + ImmutableAdapterRequest expectedParams = ImmutableAdapterRequest.builder() // + .nearRtRicUrl(RIC_1_URL + "/a1-p/policytypes/type1/policies") // + .build(); + String expInput = SdncJsonHelper.createInputJsonString(expectedParams); + verify(asyncRestClientMock).postWithAuthHeader(GET_A1_POLICY_URL, expInput, CONTROLLER_USERNAME, + CONTROLLER_PASSWORD); } @Test - void testPutPolicyValidResponse() { + void putPolicyValidResponse() { whenPostReturnOkResponse(); String returned = clientUnderTest .putPolicy(A1ClientHelper.createPolicy(RIC_1_URL, POLICY_1_ID, POLICY_JSON_VALID, POLICY_TYPE_1_ID)) .block(); + assertEquals("OK", returned, ""); final String expUrl = policiesUrl() + "/" + POLICY_1_ID; AdapterRequest expectedInputParams = ImmutableAdapterRequest.builder() // @@ -213,11 +230,11 @@ class SdncOscA1ClientTest { } @Test - void testPutPolicyRejected() { + void putPolicyRejected() { final String policyJson = "{}"; AdapterOutput adapterOutput = ImmutableAdapterOutput.builder() // .body("NOK") // - .httpStatus(400) // ERROR + .httpStatus(HttpStatus.BAD_REQUEST.value()) // ERROR .build(); String resp = SdncJsonHelper.createOutputJsonString(adapterOutput); @@ -243,12 +260,13 @@ class SdncOscA1ClientTest { } @Test - void testDeletePolicy() { + void deletePolicy() { whenPostReturnOkResponse(); String returned = clientUnderTest .deletePolicy(A1ClientHelper.createPolicy(RIC_1_URL, POLICY_1_ID, POLICY_JSON_VALID, POLICY_TYPE_1_ID)) .block(); + assertEquals("OK", returned, ""); final String expUrl = policiesUrl() + "/" + POLICY_1_ID; AdapterRequest expectedInputParams = ImmutableAdapterRequest.builder() // @@ -261,7 +279,7 @@ class SdncOscA1ClientTest { } @Test - void testGetStatus() { + void getStatus() { whenPostReturnOkResponse(); Policy policy = A1ClientHelper.createPolicy(RIC_1_URL, POLICY_1_ID, POLICY_JSON_VALID, POLICY_TYPE_1_ID); @@ -281,34 +299,72 @@ class SdncOscA1ClientTest { } @Test - void testGetVersion() { + void getVersion_STD() { whenPostReturnOkResponse(); + A1ProtocolType returnedVersion = clientUnderTest.getProtocolVersion().block(); - assertEquals(A1ProtocolType.SDNC_OSC_STD_V1_1, returnedVersion, ""); + + assertEquals(A1ProtocolType.SDNC_OSC_STD_V1_1, returnedVersion); whenPostReturnOkResponseNoBody(); + returnedVersion = clientUnderTest.getProtocolVersion().block(); - assertEquals(A1ProtocolType.SDNC_OSC_STD_V1_1, returnedVersion, ""); + + assertEquals(A1ProtocolType.SDNC_OSC_STD_V1_1, returnedVersion); } - private void whenPostReturnOkResponse() { - AdapterOutput adapterOutput = ImmutableAdapterOutput.builder() // - .body("OK") // - .httpStatus(200) // - .build(); + @Test + void getVersion_OSC() { + clientUnderTest = new SdncOscA1Client(A1ProtocolType.SDNC_OSC_OSC_V1, // + A1ClientHelper.createRic(RIC_1_URL).getConfig(), // + controllerConfig(), asyncRestClientMock); - String resp = SdncJsonHelper.createOutputJsonString(adapterOutput); - whenAsyncPostThenReturn(Mono.just(resp)); + whenAsyncPostThenReturn(Mono.error(new Exception("Error"))).thenReturn(Mono.just(createOkResponseString(true))); + + A1ProtocolType returnedVersion = clientUnderTest.getProtocolVersion().block(); + + assertEquals(A1ProtocolType.SDNC_OSC_OSC_V1, returnedVersion); + } + + private String policiesUrl() { + return RIC_1_URL + "/A1-P/v1/policies"; + } + + private Gson gson() { + return SdncOscA1Client.gson; + } + + private String loadFile(String fileName) throws IOException { + ClassLoader loader = Thread.currentThread().getContextClassLoader(); + URL url = loader.getResource(fileName); + File file = new File(url.getFile()); + return new String(Files.readAllBytes(file.toPath())); + } + + private void whenPostReturnOkResponse() { + whenAsyncPostThenReturn(Mono.just(createOkResponseString(true))); } private void whenPostReturnOkResponseNoBody() { - AdapterOutput adapterOutput = ImmutableAdapterOutput.builder() // - .httpStatus(200) // - .body(Optional.empty()) // + whenAsyncPostThenReturn(Mono.just(createOkResponseString(false))); + } + + private String createOkResponseWithBody(Object body) { + AdapterOutput output = ImmutableAdapterOutput.builder() // + .body(gson().toJson(body)) // + .httpStatus(HttpStatus.OK.value()) // .build(); + return SdncJsonHelper.createOutputJsonString(output); + } - String resp = SdncJsonHelper.createOutputJsonString(adapterOutput); - whenAsyncPostThenReturn(Mono.just(resp)); + private String createOkResponseString(boolean withBody) { + Builder responseBuilder = ImmutableAdapterOutput.builder().httpStatus(HttpStatus.OK.value()); + if (withBody) { + responseBuilder.body(HttpStatus.OK.name()); + } else { + responseBuilder.body(Optional.empty()); + } + return SdncJsonHelper.createOutputJsonString(responseBuilder.build()); } private OngoingStubbing> whenAsyncPostThenReturn(Mono response) { diff --git a/policy-agent/src/test/java/org/oransc/policyagent/tasks/RefreshConfigTaskTest.java b/policy-agent/src/test/java/org/oransc/policyagent/tasks/RefreshConfigTaskTest.java index 4823a448..c7b913be 100644 --- a/policy-agent/src/test/java/org/oransc/policyagent/tasks/RefreshConfigTaskTest.java +++ b/policy-agent/src/test/java/org/oransc/policyagent/tasks/RefreshConfigTaskTest.java @@ -174,7 +174,8 @@ class RefreshConfigTaskTest { doReturn(getCorrectJson()).when(refreshTaskUnderTest).createInputStream(any()); doReturn("fileName").when(appConfig).getLocalConfigurationFilePath(); - StepVerifier.create(refreshTaskUnderTest.createRefreshTask()) // + StepVerifier // + .create(refreshTaskUnderTest.createRefreshTask()) // .expectSubscription() // .expectNext(Type.ADDED) // .expectNext(Type.ADDED) // @@ -193,7 +194,7 @@ class RefreshConfigTaskTest { } @Test - void whenFileExistsButJsonIsIncorrect_thenNoRicsArePutInRepository() throws Exception { + void whenFileExistsButJsonIsIncorrect_thenNoRicsArePutInRepositoryAndErrorIsLogged() throws Exception { refreshTaskUnderTest = this.createTestObject(CONFIG_FILE_EXISTS); refreshTaskUnderTest.systemEnvironment = new Properties(); @@ -201,7 +202,10 @@ class RefreshConfigTaskTest { doReturn(getIncorrectJson()).when(refreshTaskUnderTest).createInputStream(any()); doReturn("fileName").when(appConfig).getLocalConfigurationFilePath(); - StepVerifier.create(refreshTaskUnderTest.createRefreshTask()) // + final ListAppender logAppender = LoggingUtils.getLogListAppender(RefreshConfigTask.class, ERROR); + + StepVerifier // + .create(refreshTaskUnderTest.createRefreshTask()) // .expectSubscription() // .expectNoEvent(Duration.ofMillis(100)) // .thenCancel() // @@ -210,6 +214,8 @@ class RefreshConfigTaskTest { // Then verify(refreshTaskUnderTest).loadConfigurationFromFile(); assertThat(appConfig.getRicConfigs().size()).isEqualTo(0); + + assertThat(logAppender.list.toString().contains("Local configuration file not loaded: fileName, ")).isTrue(); } @Test @@ -224,10 +230,9 @@ class RefreshConfigTaskTest { when(cbsClient.get(any())).thenReturn(Mono.error(new IOException())); final ListAppender logAppender = LoggingUtils.getLogListAppender(RefreshConfigTask.class, WARN); - Flux task = refreshTaskUnderTest.createRefreshTask(); StepVerifier // - .create(task) // + .create(refreshTaskUnderTest.createRefreshTask()) // .expectSubscription() // .expectNoEvent(Duration.ofMillis(1000)) // .thenCancel() // @@ -259,16 +264,14 @@ class RefreshConfigTaskTest { doReturn(Mono.just(props)).when(refreshTaskUnderTest).getEnvironment(any()); doReturn(Mono.just(cbsClient)).when(refreshTaskUnderTest).createCbsClient(props); - JsonObject configAsJson = getJsonRootObject(); + JsonObject configAsJson = getJsonRootObject(true); String newBaseUrl = "newBaseUrl"; modifyTheRicConfiguration(configAsJson, newBaseUrl); when(cbsClient.get(any())).thenReturn(Mono.just(configAsJson)); doNothing().when(refreshTaskUnderTest).runRicSynchronization(any(Ric.class)); - Flux task = refreshTaskUnderTest.createRefreshTask(); - StepVerifier // - .create(task) // + .create(refreshTaskUnderTest.createRefreshTask()) // .expectSubscription() // .expectNext(Type.CHANGED) // .expectNext(Type.ADDED) // @@ -288,6 +291,35 @@ class RefreshConfigTaskTest { assertThat(policies.size()).isEqualTo(0); } + @Test + void whenPeriodicConfigRefreshInvalidJson_thenErrorIsLogged() throws Exception { + Rics rics = new Rics(); + Policies policies = new Policies(); + refreshTaskUnderTest = this.createTestObject(CONFIG_FILE_DOES_NOT_EXIST, rics, policies, false); + refreshTaskUnderTest.systemEnvironment = new Properties(); + + appConfig.setConfiguration(configParserResult()); + + EnvProperties props = properties(); + doReturn(Mono.just(props)).when(refreshTaskUnderTest).getEnvironment(any()); + doReturn(Mono.just(cbsClient)).when(refreshTaskUnderTest).createCbsClient(props); + + JsonObject configAsJson = getJsonRootObject(false); + when(cbsClient.get(any())).thenReturn(Mono.just(configAsJson)); + + final ListAppender logAppender = LoggingUtils.getLogListAppender(RefreshConfigTask.class, ERROR); + + StepVerifier // + .create(refreshTaskUnderTest.createRefreshTask()) // + .expectSubscription() // + .expectNoEvent(Duration.ofMillis(1000)) // + .thenCancel() // + .verify(); + + assertThat(logAppender.list.toString() + .contains("Could not parse configuration org.oransc.policyagent.exceptions.ServiceException: ")).isTrue(); + } + private RicConfig getRicConfig(String name) { RicConfig ricConfig = ImmutableRicConfig.builder() // .name(name) // @@ -330,8 +362,9 @@ class RefreshConfigTaskTest { .addProperty("baseUrl", newBaseUrl); } - private JsonObject getJsonRootObject() throws JsonIOException, JsonSyntaxException, IOException { - JsonObject rootObject = JsonParser.parseReader(new InputStreamReader(getCorrectJson())).getAsJsonObject(); + private JsonObject getJsonRootObject(boolean valid) throws JsonIOException, JsonSyntaxException, IOException { + JsonObject rootObject = JsonParser + .parseReader(new InputStreamReader(valid ? getCorrectJson() : getIncorrectJson())).getAsJsonObject(); return rootObject; } @@ -342,9 +375,7 @@ class RefreshConfigTaskTest { } private static InputStream getIncorrectJson() { - String string = "{" + // - " \"config\": {" + // - " \"ric\": {"; // + String string = "{}"; // return new ByteArrayInputStream((string.getBytes(StandardCharsets.UTF_8))); } } diff --git a/policy-agent/src/test/java/org/oransc/policyagent/tasks/RicSynchronizationTaskTest.java b/policy-agent/src/test/java/org/oransc/policyagent/tasks/RicSynchronizationTaskTest.java index f74c9086..224803de 100644 --- a/policy-agent/src/test/java/org/oransc/policyagent/tasks/RicSynchronizationTaskTest.java +++ b/policy-agent/src/test/java/org/oransc/policyagent/tasks/RicSynchronizationTaskTest.java @@ -80,9 +80,9 @@ class RicSynchronizationTaskTest { .controllerName("controllerName") // .build()); - private static Policy createPolicy(boolean isTransient) { + private static Policy createPolicy(String policyId, boolean isTransient) { return ImmutablePolicy.builder() // - .id("policyId1") // + .id(policyId) // .json("") // .ownerServiceName("service") // .ric(RIC_1) // @@ -92,7 +92,7 @@ class RicSynchronizationTaskTest { .build(); } - private static final Policy POLICY_1 = createPolicy(false); + private static final Policy POLICY_1 = createPolicy("policyId1", false); private static final String SERVICE_1_NAME = "service1"; private static final String SERVICE_1_CALLBACK_URL = "callbackUrl"; @@ -201,7 +201,7 @@ class RicSynchronizationTaskTest { void ricIdleAndHavePolicies_thenSynchronizationWithRecreationOfPolicies() { RIC_1.setState(RicState.AVAILABLE); - Policy transientPolicy = createPolicy(true); + Policy transientPolicy = createPolicy("transientPolicyId", true); policies.put(transientPolicy); policies.put(POLICY_1); -- 2.16.6