From a57f8b749ce4e4e5cfe99f8879a2011e70dd63e8 Mon Sep 17 00:00:00 2001 From: emaclee Date: Mon, 10 Nov 2025 15:06:25 +0000 Subject: [PATCH] Improve coverage with unit tests - removed unused records in data job subscriptions - add unit test to cover deleting a non existing subscription - add unit test in YangDataCoverter for xpath ending with 'state' Issue-ID: CPS-3036 Change-Id: Ia3439f12806971573501ebe17debb2c10b5bf6db Signed-off-by: emaclee --- .../subscription/models/DmiCmSubscriptionKey.java | 31 -------------------- .../models/DmiCmSubscriptionTuple.java | 34 ---------------------- .../CmSubscriptionPersistenceServiceSpec.groovy | 32 ++++++++++++++++++++ .../ncmp/impl/utils/YangDataConverterSpec.groovy | 12 ++++++-- 4 files changed, 41 insertions(+), 68 deletions(-) delete mode 100644 cps-ncmp-service/src/main/java/org/onap/cps/ncmp/impl/datajobs/subscription/models/DmiCmSubscriptionKey.java delete mode 100644 cps-ncmp-service/src/main/java/org/onap/cps/ncmp/impl/datajobs/subscription/models/DmiCmSubscriptionTuple.java diff --git a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/impl/datajobs/subscription/models/DmiCmSubscriptionKey.java b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/impl/datajobs/subscription/models/DmiCmSubscriptionKey.java deleted file mode 100644 index e67706a634..0000000000 --- a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/impl/datajobs/subscription/models/DmiCmSubscriptionKey.java +++ /dev/null @@ -1,31 +0,0 @@ -/* - * ============LICENSE_START======================================================= - * Copyright (C) 2024 Nordix Foundation - * ================================================================================ - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - * SPDX-License-Identifier: Apache-2.0 - * ============LICENSE_END========================================================= - */ - -package org.onap.cps.ncmp.impl.datajobs.subscription.models; - -/** - * Key used to find the records to be sent to the DMI plugin. - * - * @param datastoreName datastore name - * @param cmHandleId cmhandle id - * @param xpath xpath - */ -public record DmiCmSubscriptionKey(String datastoreName, String cmHandleId, String xpath) { -} diff --git a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/impl/datajobs/subscription/models/DmiCmSubscriptionTuple.java b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/impl/datajobs/subscription/models/DmiCmSubscriptionTuple.java deleted file mode 100644 index e76924c040..0000000000 --- a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/impl/datajobs/subscription/models/DmiCmSubscriptionTuple.java +++ /dev/null @@ -1,34 +0,0 @@ -/* - * ============LICENSE_START======================================================= - * Copyright (C) 2024 Nordix Foundation - * ================================================================================ - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - * SPDX-License-Identifier: Apache-2.0 - * ============LICENSE_END========================================================= - */ - -package org.onap.cps.ncmp.impl.datajobs.subscription.models; - -import java.util.Collection; -import java.util.Map; - -/** - * Tuple to be used during for to delete use case. - * - * @param lastRemainingSubscriptionsPerDmi subscriptions that are used by only one subscriber grouped per dmi - * @param overlappingSubscriptionsPerDmi subscriptions that are shared by multiple subscribers grouped per dmi - */ -public record DmiCmSubscriptionTuple(Map> lastRemainingSubscriptionsPerDmi, - Map> overlappingSubscriptionsPerDmi) { -} diff --git a/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/impl/datajobs/subscription/utils/CmSubscriptionPersistenceServiceSpec.groovy b/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/impl/datajobs/subscription/utils/CmSubscriptionPersistenceServiceSpec.groovy index a3e994d7e2..adc8803eb8 100644 --- a/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/impl/datajobs/subscription/utils/CmSubscriptionPersistenceServiceSpec.groovy +++ b/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/impl/datajobs/subscription/utils/CmSubscriptionPersistenceServiceSpec.groovy @@ -29,6 +29,11 @@ import static CmDataJobSubscriptionPersistenceService.PARENT_NODE_XPATH import static org.onap.cps.ncmp.impl.datajobs.subscription.models.CmSubscriptionStatus.ACCEPTED import static org.onap.cps.api.parameters.FetchDescendantsOption.OMIT_DESCENDANTS +import ch.qos.logback.classic.Level +import ch.qos.logback.classic.Logger +import ch.qos.logback.classic.spi.ILoggingEvent +import ch.qos.logback.core.read.ListAppender +import org.slf4j.LoggerFactory import com.fasterxml.jackson.databind.ObjectMapper import org.onap.cps.api.CpsDataService import org.onap.cps.api.CpsQueryService @@ -42,9 +47,20 @@ class CmSubscriptionPersistenceServiceSpec extends Specification { def jsonObjectMapper = new JsonObjectMapper(new ObjectMapper()) def mockCpsQueryService = Mock(CpsQueryService) def mockCpsDataService = Mock(CpsDataService) + def logAppender = Spy(ListAppender) def objectUnderTest = new CmDataJobSubscriptionPersistenceService(jsonObjectMapper, mockCpsQueryService, mockCpsDataService) + void setup() { + def logger = LoggerFactory.getLogger(CmDataJobSubscriptionPersistenceService) + logger.addAppender(logAppender) + logAppender.start() + } + + void cleanup() { + ((Logger) LoggerFactory.getLogger(CmDataJobSubscriptionPersistenceService.class)).detachAndStopAllAppenders() + } + def 'Check cm data job subscription details has at least one subscriber #scenario'() { given: 'a valid cm data job subscription query' def cpsPathQuery = CPS_PATH_TEMPLATE_FOR_SUBSCRIPTIONS_WITH_DATA_NODE_SELECTOR.formatted('/myDataNodeSelector') @@ -169,6 +185,22 @@ class CmSubscriptionPersistenceServiceSpec extends Specification { }, _, ContentType.JSON) } + def 'Delete subscription that does not exist'() { + given: 'the query service returns data node for given data node selector' + def query = CPS_PATH_TEMPLATE_FOR_SUBSCRIPTIONS_WITH_DATA_NODE_SELECTOR.formatted('/myDataNodeSelector') + def dataNode = new DataNode(leaves: ['dataJobId': ['some-id'], 'status': 'ACCEPTED']) + mockCpsQueryService.queryDataNodes('NCMP-Admin', 'cm-data-job-subscriptions', query, OMIT_DESCENDANTS) >> [dataNode] + when: 'deleting a subscription on a data node selector' + objectUnderTest.delete('non-existing-id', '/myDataNodeSelector') + then: 'no exception thrown' + noExceptionThrown() + and: 'an event is logged with level INFO' + def loggingEvent = logAppender.list[0] + assert loggingEvent.level == Level.WARN + and: 'the log indicates subscription id does not exist for data node selector' + assert loggingEvent.formattedMessage == 'SubscriptionId=non-existing-id not found under dataNodeSelector=/myDataNodeSelector' + } + def 'Update status of a subscription.'() { given: 'a data node selector and status' def myDataNodeSelector = "/myDataNodeSelector" diff --git a/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/impl/utils/YangDataConverterSpec.groovy b/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/impl/utils/YangDataConverterSpec.groovy index df669e6588..1729d75f32 100644 --- a/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/impl/utils/YangDataConverterSpec.groovy +++ b/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/impl/utils/YangDataConverterSpec.groovy @@ -20,18 +20,21 @@ package org.onap.cps.ncmp.impl.utils +import static org.onap.cps.ncmp.api.inventory.models.CmHandleState.ADVISED + import org.onap.cps.api.model.DataNode import spock.lang.Specification class YangDataConverterSpec extends Specification{ - def 'Convert a cm handle data node with additional and public properties.'() { - given: 'a datanode with some additional and public properties' + def 'Convert a cm handle data node with additional properties, public properties and state.'() { + given: 'a datanode with some additional properties, public properties and state' def dataNodeAdditionalProperties = new DataNode(xpath:'/additional-properties[@name="dmiProp1"]', leaves: ['name': 'dmiProp1', 'value': 'dmiValue1']) def dataNodePublicProperties = new DataNode(xpath:'/public-properties[@name="pubProp1"]', leaves: ['name': 'pubProp1', 'value': 'pubValue1']) - def dataNodeCmHandle = new DataNode(leaves:['id':'sample-id', 'alternate-id': 'alt-id', 'module-set-tag': 'my-tag', 'dmi-service-name': 'my-dmi', 'data-producer-identifier': 'my-dpi'], childDataNodes:[dataNodeAdditionalProperties, dataNodePublicProperties]) + def dataNodeState = new DataNode(xpath:'/parent/state', leaves: ['cm-handle-state': 'ADVISED', 'last-update-time': 'now']) + def dataNodeCmHandle = new DataNode(leaves:['id':'sample-id', 'alternate-id': 'alt-id', 'module-set-tag': 'my-tag', 'dmi-service-name': 'my-dmi', 'data-producer-identifier': 'my-dpi'], childDataNodes:[dataNodeAdditionalProperties, dataNodePublicProperties, dataNodeState]) when: 'the dataNode is converted' def yangModelCmHandle = YangDataConverter.toYangModelCmHandle(dataNodeCmHandle) then: 'the converted object has the fields' @@ -46,6 +49,9 @@ class YangDataConverterSpec extends Specification{ and: 'the public properties are included' assert yangModelCmHandle.publicProperties[0].name == 'pubProp1' assert yangModelCmHandle.publicProperties[0].value == 'pubValue1' + and: 'the composite state is set' + assert yangModelCmHandle.compositeState.lastUpdateTime == 'now' + assert yangModelCmHandle.compositeState.cmHandleState == ADVISED } def 'Convert multiple cm handle data nodes'(){ -- 2.16.6