Merge "Add memory usage to integration tests [UPDATED]"
[cps.git] / cps-ncmp-rest / src / test / groovy / org / onap / cps / ncmp / rest / controller / NetworkCmProxyInventoryControllerSpec.groovy
index 079554a..1d03be1 100644 (file)
@@ -1,7 +1,7 @@
 /*
  *  ============LICENSE_START=======================================================
- *  Copyright (C) 2021 Bell Canada
- *  Modifications Copyright (C) 2021-2022 Nordix Foundation
+ *  Copyright (C) 2021-2022 Bell Canada
+ *  Modifications Copyright (C) 2021-2023 Nordix Foundation
  *  ================================================================================
  *  Licensed under the Apache License, Version 2.0 (the "License");
  *  you may not use this file except in compliance with the License.
@@ -24,8 +24,14 @@ package org.onap.cps.ncmp.rest.controller
 import com.fasterxml.jackson.databind.ObjectMapper
 import org.onap.cps.TestUtils
 import org.onap.cps.ncmp.api.NetworkCmProxyDataService
+import org.onap.cps.ncmp.api.models.CmHandleRegistrationResponse
 import org.onap.cps.ncmp.api.models.DmiPluginRegistration
+import org.onap.cps.ncmp.api.models.DmiPluginRegistrationResponse
+import org.onap.cps.ncmp.rest.model.CmHandleQueryParameters
+import org.onap.cps.ncmp.rest.model.CmHandlerRegistrationErrorResponse
+import org.onap.cps.ncmp.rest.model.DmiPluginRegistrationErrorResponse
 import org.onap.cps.ncmp.rest.model.RestDmiPluginRegistration
+import org.onap.cps.ncmp.api.models.CmHandleQueryServiceParameters
 import org.onap.cps.utils.JsonObjectMapper
 import org.spockframework.spring.SpringBean
 import org.springframework.beans.factory.annotation.Autowired
@@ -36,6 +42,8 @@ import org.springframework.http.HttpStatus
 import org.springframework.http.MediaType
 import org.springframework.test.web.servlet.MockMvc
 import spock.lang.Specification
+
+import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get
 import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post
 
 @WebMvcTest(NetworkCmProxyInventoryController)
@@ -49,22 +57,25 @@ class NetworkCmProxyInventoryControllerSpec extends Specification {
     NetworkCmProxyDataService mockNetworkCmProxyDataService = Mock()
 
     @SpringBean
-    RestInputMapper restInputMapper = Mock()
+    NcmpRestInputMapper ncmpRestInputMapper = Mock()
 
     DmiPluginRegistration mockDmiPluginRegistration = Mock()
 
+    CmHandleQueryServiceParameters cmHandleQueryServiceParameters = Mock()
+
+    @SpringBean
     JsonObjectMapper jsonObjectMapper = new JsonObjectMapper(new ObjectMapper())
 
     @Value('${rest.api.ncmp-inventory-base-path}/v1')
     def ncmpBasePathV1
 
-    def 'Dmi plugin registration #scenario' () {
+    def 'Dmi plugin registration #scenario'() {
         given: 'a dmi plugin registration with #scenario'
             def jsonData = TestUtils.getResourceFileContent(dmiRegistrationJson)
         and: 'the expected rest input as an object'
             def expectedRestDmiPluginRegistration = jsonObjectMapper.convertJsonString(jsonData, RestDmiPluginRegistration)
         and: 'the converter returns a dmi registration (only for the expected input object)'
-            restInputMapper.toDmiPluginRegistration(expectedRestDmiPluginRegistration) >> mockDmiPluginRegistration
+            ncmpRestInputMapper.toDmiPluginRegistration(expectedRestDmiPluginRegistration) >> mockDmiPluginRegistration
         when: 'post request is performed & registration is called with correct DMI plugin information'
             def response = mvc.perform(
                 post("$ncmpBasePathV1/ch")
@@ -72,9 +83,9 @@ class NetworkCmProxyInventoryControllerSpec extends Specification {
                     .content(jsonData)
             ).andReturn().response
         then: 'the converted object is forwarded to the registration service'
-            1 * mockNetworkCmProxyDataService.updateDmiRegistrationAndSyncModule(mockDmiPluginRegistration)
+            1 * mockNetworkCmProxyDataService.updateDmiRegistrationAndSyncModule(mockDmiPluginRegistration) >> new DmiPluginRegistrationResponse()
         and: 'response status is no content'
-            response.status ==  HttpStatus.NO_CONTENT.value()
+            response.status == HttpStatus.OK.value()
         where: 'the following registration json is used'
             scenario                                                                       | dmiRegistrationJson
             'multiple services, added, updated and removed cm handles and many properties' | 'dmi_registration_all_singing_and_dancing.json'
@@ -82,7 +93,7 @@ class NetworkCmProxyInventoryControllerSpec extends Specification {
             'without any properties'                                                       | 'dmi_registration_without_properties.json'
     }
 
-    def 'Dmi plugin registration with invalid json' () {
+    def 'Dmi plugin registration with invalid json'() {
         given: 'a dmi plugin registration with #scenario'
             def jsonDataWithUndefinedDataLabel = '{"notAdmiPlugin":""}'
         when: 'post request is performed & registration is called with correct DMI plugin information'
@@ -95,4 +106,156 @@ class NetworkCmProxyInventoryControllerSpec extends Specification {
             response.status == HttpStatus.BAD_REQUEST.value()
     }
 
+    def 'CmHandle search endpoint test #scenario.'() {
+        given: 'a query object'
+            def cmHandleQueryParameters = jsonObjectMapper.asJsonString(new CmHandleQueryParameters())
+        and: 'the mapper service returns a converted object'
+            ncmpRestInputMapper.toCmHandleQueryServiceParameters(_) >> cmHandleQueryServiceParameters
+        and: 'the service returns the desired results'
+            mockNetworkCmProxyDataService.executeCmHandleIdSearchForInventory(cmHandleQueryServiceParameters) >> serviceMockResponse
+        when: 'post request is performed & search is called with the given request parameters'
+            def response = mvc.perform(
+                    post("$ncmpBasePathV1/ch/searches")
+                            .contentType(MediaType.APPLICATION_JSON)
+                            .content(cmHandleQueryParameters)
+            ).andReturn().response
+        then: 'response status is OK'
+            assert response.status == HttpStatus.OK.value()
+        and: 'the response data matches the service response.'
+            jsonObjectMapper.convertJsonString(response.getContentAsString(), List) == serviceMockResponse
+        where: 'the service respond with'
+            scenario             | serviceMockResponse
+            'empty response'     | []
+            'populates response' | ['cmHandle1', 'cmHandle2']
+    }
+
+    def 'CmHandle search endpoint test #scenario with blank cmHandleQueryParameters.'() {
+        given: 'a query object'
+            def cmHandleQueryParameters = "{}"
+        and: 'the mapper service returns a converted object'
+            ncmpRestInputMapper.toCmHandleQueryServiceParameters(_) >> cmHandleQueryServiceParameters
+        and: 'the service returns the desired results'
+            mockNetworkCmProxyDataService.executeCmHandleIdSearchForInventory(cmHandleQueryServiceParameters) >> serviceMockResponse
+        when: 'post request is performed & search is called with the given request parameters'
+            def response = mvc.perform(
+                    post("$ncmpBasePathV1/ch/searches")
+                            .contentType(MediaType.APPLICATION_JSON)
+                            .content(cmHandleQueryParameters)
+            ).andReturn().response
+        then: 'response status is OK'
+            assert response.status == HttpStatus.OK.value()
+        and: 'the response data matches the service response.'
+            jsonObjectMapper.convertJsonString(response.getContentAsString(), List) == serviceMockResponse
+        where: 'the service respond with'
+            scenario             | serviceMockResponse
+            'empty response'     | []
+            'populates response' | ['cmHandle1', 'cmHandle2']
+    }
+
+    def 'CmHandle search endpoint Error Handling.'() {
+        given: 'the mapper service returns a converted object'
+            ncmpRestInputMapper.toCmHandleQueryServiceParameters(_) >> cmHandleQueryServiceParameters
+        and: 'the service returns the desired results'
+            mockNetworkCmProxyDataService.executeCmHandleIdSearchForInventory(cmHandleQueryServiceParameters) >> []
+        when: 'post request is performed & search is called with the given request parameters'
+            def response = mvc.perform(
+                    post("$ncmpBasePathV1/ch/searches")
+                            .contentType(MediaType.APPLICATION_JSON)
+                            .content(cmHandleQueryParameters)
+            ).andReturn().response
+        then: 'response status is BAD_REQUEST'
+            assert response.status == HttpStatus.BAD_REQUEST.value()
+        where: 'the cmHandleQueryParameters are'
+            scenario          | cmHandleQueryParameters
+            'empty string'    | ""
+            'non-json string' | "this is a test"
+    }
+
+    def 'DMI Registration: All cm-handles operations processed successfully.'() {
+        given: 'a dmi plugin registration'
+            def dmiRegistrationRequest = '{}'
+        and: 'service can register cm-handles successfully'
+            def dmiRegistrationResponse = new DmiPluginRegistrationResponse(
+                createdCmHandles: [CmHandleRegistrationResponse.createSuccessResponse('cm-handle-1')],
+                updatedCmHandles: [CmHandleRegistrationResponse.createSuccessResponse('cm-handle-2')],
+                removedCmHandles: [CmHandleRegistrationResponse.createSuccessResponse('cm-handle-3')]
+            )
+            mockNetworkCmProxyDataService.updateDmiRegistrationAndSyncModule(*_) >> dmiRegistrationResponse
+        when: 'registration endpoint is invoked'
+            def response = mvc.perform(
+                post("$ncmpBasePathV1/ch")
+                    .contentType(MediaType.APPLICATION_JSON)
+                    .content(dmiRegistrationRequest)
+            ).andReturn().response
+        then: 'response status is ok'
+            response.status == HttpStatus.OK.value()
+        and: 'the response body is empty'
+            response.getContentAsString() == ''
+
+    }
+
+    def 'DMI Registration Error Handling: #scenario.'() {
+        given: 'a dmi plugin registration'
+            def dmiRegistrationRequest = '{}'
+        and: '#scenario: service failed to register few cm-handle'
+            def dmiRegistrationResponse = new DmiPluginRegistrationResponse(
+                createdCmHandles: [createCmHandleResponse],
+                updatedCmHandles: [updateCmHandleResponse],
+                removedCmHandles: [removeCmHandleResponse]
+            )
+            mockNetworkCmProxyDataService.updateDmiRegistrationAndSyncModule(*_) >> dmiRegistrationResponse
+        when: 'registration endpoint is invoked'
+            def response = mvc.perform(
+                post("$ncmpBasePathV1/ch")
+                    .contentType(MediaType.APPLICATION_JSON)
+                    .content(dmiRegistrationRequest)
+            ).andReturn().response
+        then: 'request status is internal server error'
+            response.status == HttpStatus.INTERNAL_SERVER_ERROR.value()
+        and: 'the response body is in the expected format'
+            def responseBody = jsonObjectMapper.convertJsonString(response.getContentAsString(), DmiPluginRegistrationErrorResponse)
+        and: 'contains only the failure responses'
+            responseBody.getFailedCreatedCmHandles() == expectedFailedCreatedCmHandle
+            responseBody.getFailedUpdatedCmHandles() == expectedFailedUpdateCmHandle
+            responseBody.getFailedRemovedCmHandles() == expectedFailedRemovedCmHandle
+        where:
+        scenario               | createCmHandleResponse                 | updateCmHandleResponse                 | removeCmHandleResponse                 || expectedFailedCreatedCmHandle                 | expectedFailedUpdateCmHandle                  | expectedFailedRemovedCmHandle
+        'only create failed'   | expectedFailedResponse('cm-handle-1')  | expectedSuccessResponse('cm-handle-2') | expectedSuccessResponse('cm-handle-3') || [expectedUnknownErrorResponse('cm-handle-1')] | []                                            | []
+        'only update failed'   | expectedSuccessResponse('cm-handle-1') | expectedFailedResponse('cm-handle-2')  | expectedSuccessResponse('cm-handle-3') || []                                            | [expectedUnknownErrorResponse('cm-handle-2')] | []
+        'only delete failed'   | expectedSuccessResponse('cm-handle-1') | expectedSuccessResponse('cm-handle-2') | expectedFailedResponse('cm-handle-3')  || []                                            | []                                            | [expectedUnknownErrorResponse('cm-handle-3')]
+        'all three failed'     | expectedFailedResponse('cm-handle-1')  | expectedFailedResponse('cm-handle-2')  | expectedFailedResponse('cm-handle-3')  || [expectedUnknownErrorResponse('cm-handle-1')] | [expectedUnknownErrorResponse('cm-handle-2')] | [expectedUnknownErrorResponse('cm-handle-3')]
+        'create update failed' | expectedFailedResponse('cm-handle-1')  | expectedFailedResponse('cm-handle-2')  | expectedSuccessResponse('cm-handle-3') || [expectedUnknownErrorResponse('cm-handle-1')] | [expectedUnknownErrorResponse('cm-handle-2')] | []
+        'create delete failed' | expectedFailedResponse('cm-handle-1')  | expectedSuccessResponse('cm-handle-2') | expectedFailedResponse('cm-handle-3')  || [expectedUnknownErrorResponse('cm-handle-1')] | []                                            | [expectedUnknownErrorResponse('cm-handle-3')]
+        'update delete failed' | expectedSuccessResponse('cm-handle-1') | expectedFailedResponse('cm-handle-2')  | expectedFailedResponse('cm-handle-3')  || []                                            | [expectedUnknownErrorResponse('cm-handle-2')] | [expectedUnknownErrorResponse('cm-handle-3')]
+    }
+
+    def 'Get all cm handle IDs by DMI plugin identifier.'() {
+        given: 'an endpoint for returning cm handle IDs for a registered dmi plugin'
+            def getUrl = "$ncmpBasePathV1/ch/cmHandles?dmi-plugin-identifier=some-dmi-plugin-identifier"
+        and: 'a collection of cm handle IDs are returned'
+            1 * mockNetworkCmProxyDataService.getAllCmHandleIdsByDmiPluginIdentifier('some-dmi-plugin-identifier')
+                    >> ['cm-handle-id-1','cm-handle-id-2']
+        when: 'the endpoint is invoked'
+            def response = mvc.perform(
+                    get(getUrl)
+                            .contentType(MediaType.APPLICATION_JSON)
+                            .accept(MediaType.APPLICATION_JSON_VALUE)
+            ).andReturn().response
+        then: 'the response matches the result returned by the service layer'
+            assert response.contentAsString.contains('cm-handle-id-1')
+            assert response.contentAsString.contains('cm-handle-id-2')
+    }
+
+    def expectedUnknownErrorResponse(cmHandle) {
+        return new CmHandlerRegistrationErrorResponse('cmHandle': cmHandle, 'errorCode': '108', 'errorText': 'Failed')
+    }
+
+    def expectedFailedResponse(cmHandle) {
+        return CmHandleRegistrationResponse.createFailureResponse(cmHandle, new RuntimeException('Failed'))
+    }
+
+    def expectedSuccessResponse(cmHandle) {
+        return CmHandleRegistrationResponse.createSuccessResponse(cmHandle)
+    }
+
 }