diff options
16 files changed, 2623 insertions, 3 deletions
diff --git a/appc-dg/appc-dg-shared/appc-dg-dependency-model/pom.xml b/appc-dg/appc-dg-shared/appc-dg-dependency-model/pom.xml index b52e7b189..085f65bab 100644 --- a/appc-dg/appc-dg-shared/appc-dg-dependency-model/pom.xml +++ b/appc-dg/appc-dg-shared/appc-dg-dependency-model/pom.xml @@ -2,7 +2,7 @@ ============LICENSE_START======================================================= ONAP : APPC ================================================================================ - Copyright (C) 2017-2018 AT&T Intellectual Property. All rights reserved. + Copyright (C) 2017-2019 AT&T Intellectual Property. All rights reserved. Copyright (C) 2017 Amdocs ================================================================================ Licensed under the Apache License, Version 2.0 (the "License"); @@ -98,6 +98,12 @@ <scope>test</scope> </dependency> <dependency> + <groupId>org.javassist</groupId> + <artifactId>javassist</artifactId> + <version>3.22.0-GA</version> + <scope>test</scope> + </dependency> + <dependency> <groupId>org.onap.appc</groupId> <artifactId>appc-dg-domain-model-lib</artifactId> <version>${project.version}</version> diff --git a/appc-dg/appc-dg-shared/appc-dg-dependency-model/src/test/java/org/onap/appc/dg/dependencymanager/impl/DependencyManagerImplTest.java b/appc-dg/appc-dg-shared/appc-dg-dependency-model/src/test/java/org/onap/appc/dg/dependencymanager/impl/DependencyManagerImplTest.java new file mode 100644 index 000000000..e0214b1d5 --- /dev/null +++ b/appc-dg/appc-dg-shared/appc-dg-dependency-model/src/test/java/org/onap/appc/dg/dependencymanager/impl/DependencyManagerImplTest.java @@ -0,0 +1,63 @@ +/* + * ============LICENSE_START======================================================= + * ONAP : APPC + * ================================================================================ + * Copyright (C) 2019 Ericsson + * ============================================================================= + * 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. + * + * ============LICENSE_END========================================================= + */ + +package org.onap.appc.dg.dependencymanager.impl; + +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.Mockito; +import org.onap.appc.cache.MetadataCache; +import org.onap.appc.cache.impl.MetadataCacheFactory; +import org.onap.appc.cache.impl.MetadataCacheImpl; +import org.onap.appc.dg.dependencymanager.DependencyManager; +import org.onap.appc.dg.objects.DependencyTypes; +import org.onap.appc.dg.objects.VnfcDependencyModel; +import org.onap.appc.metadata.objects.DependencyModelIdentifier; +import org.powermock.api.mockito.PowerMockito; +import org.powermock.core.classloader.annotations.PrepareForTest; +import org.powermock.modules.junit4.PowerMockRunner; + +@RunWith(PowerMockRunner.class) +@PrepareForTest(MetadataCacheFactory.class) +public class DependencyManagerImplTest { + + private MetadataCacheFactory metadataCacheFactory = Mockito.mock(MetadataCacheFactory.class); + private MetadataCache<DependencyModelIdentifier,VnfcDependencyModel> cache; + + @Before + public void setup() { + PowerMockito.mockStatic(MetadataCacheFactory.class); + PowerMockito.when(MetadataCacheFactory.getInstance()).thenReturn(metadataCacheFactory); + cache = (MetadataCacheImpl<DependencyModelIdentifier,VnfcDependencyModel>) Mockito.mock(MetadataCacheImpl.class); + PowerMockito.when(metadataCacheFactory.getMetadataCache()).thenReturn(cache); + } + + @Test + public void testDependencyManager() throws Exception { + DependencyManager dmImpl = DependencyModelFactory.createDependencyManager(); + DependencyModelIdentifier modelIdentifier = new DependencyModelIdentifier("VNF_TYPE", "CATALOG_VERSION"); + DependencyTypes dependencyType = DependencyTypes.findByString("resource"); + Mockito.when(cache.getObject(Mockito.any(DependencyModelIdentifier.class))).thenReturn(new VnfcDependencyModel(null)); + dmImpl.getVnfcDependencyModel(modelIdentifier, dependencyType); + } + +} diff --git a/appc-dg/appc-dg-shared/appc-dg-mdsal-store/appc-dg-mdsal-bundle/pom.xml b/appc-dg/appc-dg-shared/appc-dg-mdsal-store/appc-dg-mdsal-bundle/pom.xml index 6939fe4ce..d543f2ee9 100644 --- a/appc-dg/appc-dg-shared/appc-dg-mdsal-store/appc-dg-mdsal-bundle/pom.xml +++ b/appc-dg/appc-dg-shared/appc-dg-mdsal-store/appc-dg-mdsal-bundle/pom.xml @@ -79,6 +79,12 @@ <artifactId>powermock-module-junit4</artifactId> </dependency> <dependency> + <groupId>org.javassist</groupId> + <artifactId>javassist</artifactId> + <version>3.22.0-GA</version> + <scope>test</scope> + </dependency> + <dependency> <groupId>org.opendaylight.controller</groupId> <artifactId>config-api</artifactId> </dependency> diff --git a/appc-dg/appc-dg-shared/appc-dg-mdsal-store/appc-dg-mdsal-bundle/src/test/java/org/onap/appc/mdsal/MDSALStoreTest.java b/appc-dg/appc-dg-shared/appc-dg-mdsal-store/appc-dg-mdsal-bundle/src/test/java/org/onap/appc/mdsal/MDSALStoreTest.java new file mode 100644 index 000000000..2229eff9d --- /dev/null +++ b/appc-dg/appc-dg-shared/appc-dg-mdsal-store/appc-dg-mdsal-bundle/src/test/java/org/onap/appc/mdsal/MDSALStoreTest.java @@ -0,0 +1,74 @@ +/*- + * ============LICENSE_START======================================================= + * ONAP : APPC + * ================================================================================ + * Copyright (C) 2017-2018 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * Copyright (C) 2017 Amdocs + * ================================================================================ + * Modifications (C) 2019 Ericsson + * ============================================================================= + * 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. + * + * ============LICENSE_END========================================================= + */ + +package org.onap.appc.mdsal; + +import com.fasterxml.jackson.databind.ObjectMapper; +import org.junit.Before; +import org.junit.Ignore; +import org.junit.runner.RunWith; +import org.mockito.Mockito; +import org.onap.appc.mdsal.exception.MDSALStoreException; +import org.onap.appc.mdsal.impl.MDSALStoreFactory; +import org.onap.appc.mdsal.impl.MDSALStoreImpl; +import com.att.eelf.configuration.EELFLogger; +import com.att.eelf.configuration.EELFManager; +import org.onap.appc.mdsal.operation.ConfigOperationRequestFormatter; +import org.onap.appc.rest.client.RestClientInvoker; +import org.osgi.framework.*; +import org.powermock.api.mockito.PowerMockito; +import org.powermock.core.classloader.annotations.PrepareForTest; +import org.powermock.modules.junit4.PowerMockRunner; + +import java.net.URL; + +/** + * MDSALStore Tests + */ +@RunWith(PowerMockRunner.class) +@PrepareForTest({FrameworkUtil.class,BundleContext.class,ServiceReference.class, + BundleReference.class,Bundle.class,Filter.class,BundleListener.class,InvalidSyntaxException.class, + BundleException.class,FrameworkListener.class,ServiceRegistration.class,ServiceListener.class, + Version.class}) +public class MDSALStoreTest { + + private final EELFLogger logger = EELFManager.getInstance().getLogger(MDSALStoreTest.class); + private RestClientInvoker client = Mockito.mock(RestClientInvoker.class); + private ConfigOperationRequestFormatter requestFormatter = new ConfigOperationRequestFormatter(); + private ObjectMapper mapper = new ObjectMapper(); + MDSALStoreImpl store; + + @Before + public void init() throws Exception{ + PowerMockito.whenNew(RestClientInvoker.class).withArguments(Mockito.any(URL.class)).thenReturn(client); + store = (MDSALStoreImpl) MDSALStoreFactory.createMDSALStore(); + } + + @Ignore + public void testYangInput() throws MDSALStoreException { + store.storeYangModuleOnLeader("module test { }", "Name"); + } + +} diff --git a/appc-dg/appc-dg-shared/appc-dg-netconf/pom.xml b/appc-dg/appc-dg-shared/appc-dg-netconf/pom.xml index 85a6deb95..b53e43d75 100644 --- a/appc-dg/appc-dg-shared/appc-dg-netconf/pom.xml +++ b/appc-dg/appc-dg-shared/appc-dg-netconf/pom.xml @@ -83,7 +83,12 @@ <scope>test</scope> </dependency> - + <dependency> + <groupId>org.javassist</groupId> + <artifactId>javassist</artifactId> + <version>3.22.0-GA</version> + <scope>test</scope> + </dependency> </dependencies> diff --git a/appc-dg/appc-dg-shared/appc-dg-netconf/src/test/java/org/onap/appc/dg/netconf/impl/NetconfClientPluginImplTest.java b/appc-dg/appc-dg-shared/appc-dg-netconf/src/test/java/org/onap/appc/dg/netconf/impl/NetconfClientPluginImplTest.java new file mode 100644 index 000000000..9e2384e91 --- /dev/null +++ b/appc-dg/appc-dg-shared/appc-dg-netconf/src/test/java/org/onap/appc/dg/netconf/impl/NetconfClientPluginImplTest.java @@ -0,0 +1,650 @@ +/*- + * ============LICENSE_START======================================================= + * ONAP : APPC + * ================================================================================ + * Copyright (C) 2017-2018 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * Copyright (C) 2017 Amdocs + * ================================================================================ + * Modifications (C) 2019 Ericsson + * ============================================================================= + * 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. + * + * ============LICENSE_END========================================================= + */ + +package org.onap.appc.dg.netconf.impl; + +import org.onap.appc.exceptions.APPCException; +import com.fasterxml.jackson.databind.ObjectMapper; +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.Matchers; +import org.mockito.Mockito; +import org.onap.appc.adapter.netconf.util.Constants; +import org.onap.ccsdk.sli.core.sli.SvcLogicContext; +import org.onap.appc.adapter.netconf.ConnectionDetails; +import org.onap.appc.adapter.netconf.NetconfClientFactory; +import org.onap.appc.adapter.netconf.NetconfClientType; +import org.onap.appc.adapter.netconf.NetconfConnectionDetails; +import org.onap.appc.adapter.netconf.NetconfDataAccessService; +import org.onap.appc.adapter.netconf.OperationalStateValidatorFactory; +import org.onap.appc.adapter.netconf.VnfType; +import org.osgi.framework.Bundle; +import org.osgi.framework.BundleContext; +import org.osgi.framework.FrameworkUtil; +import org.osgi.framework.ServiceReference; +import org.powermock.api.mockito.PowerMockito; +import org.powermock.core.classloader.annotations.PrepareForTest; +import org.powermock.modules.junit4.PowerMockRunner; + +import java.lang.reflect.Field; +import java.text.DateFormat; +import java.text.SimpleDateFormat; +import java.util.Date; +import java.util.HashMap; +import java.util.Map; + +import static org.powermock.api.mockito.PowerMockito.when; + + + +@RunWith(PowerMockRunner.class) +@PrepareForTest({OperationalStateValidatorFactory.class, FrameworkUtil.class, ObjectMapper.class}) + +public class NetconfClientPluginImplTest { + private NetconfClientPluginImpl netconfClientPlugin; + private NetconfDataAccessService dao; + private NetconfClientFactory clientFactory; + private Map<String, String> params; + + private final BundleContext bundleContext = Mockito.mock(BundleContext.class); + private final Bundle bundleService = Mockito.mock(Bundle.class); + private final ServiceReference sref1 = Mockito.mock(ServiceReference.class); + private final ServiceReference sref2 = Mockito.mock(ServiceReference.class); + private final ServiceReference sref3 = Mockito.mock(ServiceReference.class); + private static final String DG_OUTPUT_STATUS_MESSAGE = "output.status.message"; + + + String host = "http://www.test.com"; + String host1 = "http://www.test1.com"; + String vnfType = "VNF"; + int port = 8080; + String username = "test"; + String password = "test"; + String connectionDetails = "{\"host\":\"" + host + "\",\"port\":" + port + ",\"username\":\"" + username + "\",\"password\":\"" + password + "\",\"capabilities\":null,\"additionalProperties\":null}"; + String fileContent = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" + + "<rpc message-id=\"101\" xmlns=\"urn:ietf:params:xml:ns:netconf:base:1.0\">\n" + + "\t<get-config>\n" + + "\t\t<source>\n" + + "\t\t\t<running/>\n" + + "\t\t </source>\n" + + "\t</get-config>\n" + + "</rpc>'"; + String operationalState = "<rpc message-id=\"101\" xmlns=\"urn:ietf:params:xml:ns:netconf:base:1.0\">\n" + + " <get>\n" + + " <filter>\n" + + " <ManagedElement xmlns=\"urn:org:onap:appc:Test\">\n" + + " <VnfFunction xmlns=\"urn:org:openecomop:appc:Test\">\n" + + " <ProcessorManagement>\n" + + " <MatedPair>\n" + + " <operationalState/>\n" + + " <PayloadProcessor>\n" + + " <operationalState/>\n" + + " </PayloadProcessor>\n" + + " </MatedPair>\n" + + " <SystemController>\n" + + " <operationalState/>\n" + + " </SystemController>\n" + + " </ProcessorManagement>\n" + + " </VnfFunction>\n" + + " </ManagedElement>\n" + + " </filter>\n" + + " </get>\n" + + "</rpc>\n"; + + + @Before + public void setUp() throws NoSuchFieldException, IllegalAccessException { + clientFactory = new NetconfClientFactoryMock(); + } + + + @Test + public void testConfigure() throws Exception { + shortInit(); + SvcLogicContext ctx = new SvcLogicContext(); + + params = new HashMap<>(); + params.put(Constants.CONNECTION_DETAILS_FIELD_NAME, connectionDetails); + params.put(Constants.FILE_CONTENT_FIELD_NAME, fileContent); + + netconfClientPlugin.configure(params, ctx); + + NetconfClientJschMock client = (NetconfClientJschMock) clientFactory.getNetconfClient(NetconfClientType.SSH); + + try { + Assert.assertEquals("wrong configuration", fileContent, client.getConf()); + Assert.assertEquals("wrong host", host, client.getLastConnectionDetails().getHost()); + Assert.assertEquals("wrong port", port, client.getLastConnectionDetails().getPort()); + Assert.assertEquals("wrong username", username, client.getLastConnectionDetails().getUsername()); + Assert.assertEquals("wrong password", password, client.getLastConnectionDetails().getPassword()); + Assert.assertFalse(client.isConnection()); + } catch (Exception e) { + Assert.fail("failed with because of " + e.getCause()); + } + } + + + @Test + public void testConfigureNegativeIOException() throws Exception { + shortInit(); + SvcLogicContext ctx = new SvcLogicContext(); + + params = new HashMap<>(); + params.put(Constants.CONNECTION_DETAILS_FIELD_NAME, "{" + connectionDetails); + params.put(Constants.FILE_CONTENT_FIELD_NAME, fileContent); + NetconfClientJschMock client = (NetconfClientJschMock) clientFactory.getNetconfClient(NetconfClientType.SSH); + + try { + netconfClientPlugin.configure(params, ctx); + Assert.assertTrue(false); + } catch (APPCException e) { + Assert.assertNull(client.getLastConnectionDetails()); + Assert.assertNull(client.getConf()); + } + + } + + @Test + public void testOperationStateValidation() throws Exception { + shortInit(); + SvcLogicContext ctx = new SvcLogicContext(); + DAOServiceMock daoServiceMock = (DAOServiceMock) dao; + daoServiceMock.setConfigFile(fileContent); + + NetconfClientJschMock client = (NetconfClientJschMock) clientFactory.getNetconfClient(NetconfClientType.SSH); + client.setAnswer(operationalState); + + params = new HashMap<>(); + params.put(Constants.VNF_TYPE_FIELD_NAME, vnfType); + params.put(Constants.VNF_HOST_IP_ADDRESS_FIELD_NAME, host1); + params.put(Constants.CONNECTION_DETAILS_FIELD_NAME, connectionDetails); + MockOperationalStateValidatorImpl validatorMock = new MockOperationalStateValidatorImpl(); + validatorMock.setConfigurationFileName("VnfGetRunningConfig"); + + PowerMockito.mockStatic(OperationalStateValidatorFactory.class); + when(OperationalStateValidatorFactory.getOperationalStateValidator(Matchers.any(VnfType.class))).thenReturn(validatorMock); + + netconfClientPlugin.operationStateValidation(params, ctx); + + Assert.assertTrue("validation process failed", validatorMock.isValidated()); + Assert.assertEquals(fileContent, client.getLastMessage()); + } + + @Test + public void testOperationStateValidationNegativeJsonProcessingNullIllegalStateException() throws Exception { + shortInit(); + SvcLogicContext ctx = new SvcLogicContext(); + DAOServiceMock daoServiceMock = (DAOServiceMock) dao; + daoServiceMock.setConfigFile(fileContent); + + NetconfClientJschMock client = (NetconfClientJschMock) clientFactory.getNetconfClient(NetconfClientType.SSH); + client.setAnswer(operationalState); + + params = new HashMap<>(); + params.put(Constants.VNF_TYPE_FIELD_NAME, vnfType); + params.put(Constants.VNF_HOST_IP_ADDRESS_FIELD_NAME, host1); + params.put(Constants.CONNECTION_DETAILS_FIELD_NAME, connectionDetails); + MockOperationalStateValidatorImpl validatorMock = new MockOperationalStateValidatorImpl(); + validatorMock.setConfigurationFileName("VnfGetRunningConfig"); + + PowerMockito.mockStatic(OperationalStateValidatorFactory.class); + when(OperationalStateValidatorFactory.getOperationalStateValidator(Matchers.any(VnfType.class))).thenReturn(validatorMock); + substituteMapper(true); + + try { + netconfClientPlugin.operationStateValidation(params, ctx); + substituteMapper(false); + } catch (APPCException e) { + substituteMapper(false); + Assert.assertNotNull(ctx.getAttribute(DG_OUTPUT_STATUS_MESSAGE)); + Assert.assertFalse(validatorMock.isValidated()); + Assert.assertNull(client.getLastMessage()); + } + } + + @Test + public void testOperationStateValidationNegativeConnectionDetailsAreNullNullPointerException() throws Exception { + shortInit(); + SvcLogicContext ctx = new SvcLogicContext(); + DAOServiceMock daoServiceMock = (DAOServiceMock) dao; + daoServiceMock.setConfigFile(fileContent); + + NetconfClientJschMock client = (NetconfClientJschMock) clientFactory.getNetconfClient(NetconfClientType.SSH); + client.setAnswer(operationalState); + + params = new HashMap<>(); + params.put(Constants.VNF_TYPE_FIELD_NAME, vnfType); + params.put(Constants.VNF_HOST_IP_ADDRESS_FIELD_NAME, host1); + params.put(Constants.CONNECTION_DETAILS_FIELD_NAME, null); + MockOperationalStateValidatorImpl validatorMock = new MockOperationalStateValidatorImpl(); + validatorMock.setConfigurationFileName("VnfGetRunningConfig"); + + PowerMockito.mockStatic(OperationalStateValidatorFactory.class); + when(OperationalStateValidatorFactory.getOperationalStateValidator(Matchers.any(VnfType.class))).thenReturn(validatorMock); + ObjectMapper mapper = PowerMockito.mock(ObjectMapper.class); + final NetconfConnectionDetails netconfConnectionDetails = null; + when(mapper.readValue(Matchers.anyString(), Matchers.any(Class.class))).thenReturn(netconfConnectionDetails); + + try { + netconfClientPlugin.operationStateValidation(params, ctx); + Assert.assertTrue(false); + } catch (APPCException e) { + Assert.assertNotNull(ctx.getAttribute(DG_OUTPUT_STATUS_MESSAGE)); + Assert.assertFalse("validation process failed", validatorMock.isValidated()); + } + } + + + @Test + public void testOperationStateValidationNegativeAppcException() throws Exception { + shortInit(); + SvcLogicContext ctx = new SvcLogicContext(); + DAOServiceMock daoServiceMock = (DAOServiceMock) dao; + daoServiceMock.setConfigFile(fileContent); + + NetconfClientJschMock client = (NetconfClientJschMock) clientFactory.getNetconfClient(NetconfClientType.SSH); + client.setAnswer("wrong"); + + params = new HashMap<>(); + params.put(Constants.VNF_TYPE_FIELD_NAME, vnfType); + params.put(Constants.VNF_HOST_IP_ADDRESS_FIELD_NAME, host1); + params.put(Constants.CONNECTION_DETAILS_FIELD_NAME, connectionDetails); + MockOperationalStateValidatorImpl validatorMock = new MockOperationalStateValidatorImpl(); + validatorMock.setConfigurationFileName("VnfGetRunningConfig"); + + PowerMockito.mockStatic(OperationalStateValidatorFactory.class); + when(OperationalStateValidatorFactory.getOperationalStateValidator(Matchers.any(VnfType.class))).thenReturn(validatorMock); + + try { + netconfClientPlugin.operationStateValidation(params, ctx); + Assert.assertTrue(false); + } catch (APPCException e) { + Assert.assertNotNull(ctx.getAttribute(DG_OUTPUT_STATUS_MESSAGE)); + Assert.assertFalse("validation process failed", validatorMock.isValidated()); + } + } + + + @Test + public void testOperationStateValidatioConnectionDetailsInParamsAreEmpty() throws Exception { + shortInit(); + SvcLogicContext ctx = new SvcLogicContext(); + DAOServiceMock daoServiceMock = (DAOServiceMock) dao; + daoServiceMock.setConfigFile(fileContent); + + NetconfClientJschMock client = (NetconfClientJschMock) clientFactory.getNetconfClient(NetconfClientType.SSH); + client.setAnswer(operationalState); + ((DAOServiceMock) dao).setConnection(getConnectionDetails()); + + params = new HashMap<>(); + params.put(Constants.VNF_TYPE_FIELD_NAME, vnfType); + params.put(Constants.VNF_HOST_IP_ADDRESS_FIELD_NAME, host1); + params.put(Constants.CONNECTION_DETAILS_FIELD_NAME, ""); + MockOperationalStateValidatorImpl validatorMock = new MockOperationalStateValidatorImpl(); + validatorMock.setConfigurationFileName("VnfGetRunningConfig"); + + PowerMockito.mockStatic(OperationalStateValidatorFactory.class); + when(OperationalStateValidatorFactory.getOperationalStateValidator(Matchers.any(VnfType.class))).thenReturn(validatorMock); + + netconfClientPlugin.operationStateValidation(params, ctx); + + Assert.assertTrue("validation process failed", validatorMock.isValidated()); + Assert.assertEquals(fileContent, client.getLastMessage()); + } + + @Test + public void testOperationStateValidatioConnectionDetailsInParamsAreNull() throws Exception { + shortInit(); + SvcLogicContext ctx = new SvcLogicContext(); + DAOServiceMock daoServiceMock = (DAOServiceMock) dao; + daoServiceMock.setConfigFile(fileContent); + + NetconfClientJschMock client = (NetconfClientJschMock) clientFactory.getNetconfClient(NetconfClientType.SSH); + client.setAnswer(operationalState); + ((DAOServiceMock) dao).setConnection(getConnectionDetails()); + + params = new HashMap<>(); + params.put(Constants.VNF_TYPE_FIELD_NAME, vnfType); + params.put(Constants.VNF_HOST_IP_ADDRESS_FIELD_NAME, host1); + params.put(Constants.CONNECTION_DETAILS_FIELD_NAME, null); + MockOperationalStateValidatorImpl validatorMock = new MockOperationalStateValidatorImpl(); + validatorMock.setConfigurationFileName("VnfGetRunningConfig"); + + PowerMockito.mockStatic(OperationalStateValidatorFactory.class); + when(OperationalStateValidatorFactory.getOperationalStateValidator(Matchers.any(VnfType.class))).thenReturn(validatorMock); + + netconfClientPlugin.operationStateValidation(params, ctx); + + Assert.assertTrue("validation process failed", validatorMock.isValidated()); + Assert.assertEquals(fileContent, client.getLastMessage()); + } + + + @Test + public void testBackupConfiguration() throws Exception { + shortInit(); + SvcLogicContext ctx = new SvcLogicContext(); + params = new HashMap<>(); + params.put(Constants.CONNECTION_DETAILS_FIELD_NAME, connectionDetails); + NetconfClientJschMock client = (NetconfClientJschMock) clientFactory.getNetconfClient(NetconfClientType.SSH); + client.setConf(fileContent); + netconfClientPlugin.backupConfiguration(params, ctx); + + DAOServiceMock mockdao = (DAOServiceMock) dao; + DateFormat dateFormat = new SimpleDateFormat("yyyy/MM/dd"); + Date date = new Date(); + String creationDateExpected = dateFormat.format(date); + String creationDateActual = mockdao.getBackupConf().get("creationDate").substring(0, 10); + + Assert.assertEquals("wrong configuration in db", fileContent, mockdao.getBackupConf().get("logText")); + Assert.assertEquals(creationDateExpected, creationDateActual); + } + + @Test + public void testBackupConfigurationNegativeDgErrorFieldName() throws Exception { + shortInit(); + SvcLogicContext ctx = new SvcLogicContext(); + params = new HashMap<>(); + params.put(Constants.CONNECTION_DETAILS_FIELD_NAME, "{" + connectionDetails); + NetconfClientJschMock client = (NetconfClientJschMock) clientFactory.getNetconfClient(NetconfClientType.SSH); + client.setConf(fileContent); + try { + netconfClientPlugin.backupConfiguration(params, ctx); + Assert.assertTrue(false); + } catch (APPCException e) { + Assert.assertNotNull(ctx.getAttribute(DG_OUTPUT_STATUS_MESSAGE)); + DAOServiceMock mockdao = (DAOServiceMock) dao; + Assert.assertNull(mockdao.getBackupConf()); + } + } + + @Test + public void testGetConfig() throws Exception { + fullInit(); + String entity = "123"; + + SvcLogicContext ctx = new SvcLogicContext(); + ctx.setAttribute("entity", entity); + + params = new HashMap<>(); + params.put("conf-id", "current"); + params.put(Constants.CONNECTION_DETAILS_FIELD_NAME, connectionDetails); + NetconfClientJschMock client = (NetconfClientJschMock) clientFactory.getNetconfClient(NetconfClientType.SSH); + client.setConf(fileContent); + + netconfClientPlugin.getConfig(params, ctx); + + Assert.assertEquals("Success", ctx.getAttribute("getConfig_Result")); + Assert.assertEquals(fileContent, ctx.getAttribute("fullConfig")); + Assert.assertNotNull(ctx.getAttribute(entity + ".Configuration")); + Assert.assertEquals(fileContent, ctx.getAttribute(entity + ".Configuration")); + } + + + @Test + public void testGetConfigNegativeConfigurationNull() throws Exception { + fullInit(); + String entity = "123"; + + SvcLogicContext ctx = new SvcLogicContext(); + ctx.setAttribute("entity", entity); + + params = new HashMap<>(); + params.put("conf-id", "current"); + params.put(Constants.CONNECTION_DETAILS_FIELD_NAME, connectionDetails); + + netconfClientPlugin.getConfig(params, ctx); + + Assert.assertEquals("failure", ctx.getAttribute("getConfig_Result")); + Assert.assertNull(ctx.getAttribute("fullConfig")); + Assert.assertNull(ctx.getAttribute(entity + ".Configuration")); + Assert.assertNull(ctx.getAttribute(entity + ".Configuration")); + } + + + @Test + public void testGetConfigNegativeNotSupportedConfId() throws Exception { + fullInit(); + String entity = "123"; + SvcLogicContext ctx = new SvcLogicContext(); + ctx.setAttribute("entity", entity); + + params = new HashMap<>(); + params.put("conf-id", "current1"); + params.put(Constants.CONNECTION_DETAILS_FIELD_NAME, connectionDetails); + + netconfClientPlugin.getConfig(params, ctx); + + Assert.assertNull(ctx.getAttribute("getConfig_Result")); + Assert.assertNull(ctx.getAttribute("fullConfig")); + Assert.assertNull(ctx.getAttribute(entity + ".Configuration")); + Assert.assertNull(ctx.getAttribute(entity + ".Configuration")); + } + + @Test + public void testGetConfigNegativeWronjJsonConnectionDetailsException() throws Exception { + fullInit(); + String entity = "123"; + + SvcLogicContext ctx = new SvcLogicContext(); + ctx.setAttribute("entity", entity); + + params = new HashMap<>(); + params.put("conf-id", "current"); + params.put(Constants.CONNECTION_DETAILS_FIELD_NAME, "{" + connectionDetails); + + try { + netconfClientPlugin.getConfig(params, ctx); + Assert.assertTrue(false); + } catch (APPCException e) { + Assert.assertEquals("failure", ctx.getAttribute("getConfig_Result")); + Assert.assertNull(ctx.getAttribute("fullConfig")); + Assert.assertNull(ctx.getAttribute(entity + ".Configuration")); + Assert.assertNull(ctx.getAttribute(entity + ".Configuration")); + Assert.assertNotNull(ctx.getAttribute(DG_OUTPUT_STATUS_MESSAGE)); + } + } + + @Test + public void testGetRunningConfig() throws Exception { + fullInit(); + SvcLogicContext ctx = new SvcLogicContext(); + params = new HashMap<>(); + params.put("host-ip-address", host); + params.put("user-name", username); + params.put("password", password); + params.put("port-number", String.valueOf(port)); + + NetconfClientJschMock client = (NetconfClientJschMock) clientFactory.getNetconfClient(NetconfClientType.SSH); + client.setConf(fileContent); + + netconfClientPlugin.getRunningConfig(params, ctx); + + Assert.assertEquals("Success", ctx.getAttribute("getRunningConfig_Result")); + Assert.assertEquals(fileContent, ctx.getAttribute("running-config")); + Assert.assertEquals("success", ctx.getStatus()); + } + + @Test + public void testGetRunningConfigWithoutPortNumberDgErrorFieldNameException() throws Exception { + fullInit(); + SvcLogicContext ctx = new SvcLogicContext(); + params = new HashMap<>(); + params.put("host-ip-address", host); + params.put("user-name", username); + params.put("password", password); + + NetconfClientJschMock client = (NetconfClientJschMock) clientFactory.getNetconfClient(NetconfClientType.SSH); + client.setConf(fileContent); + + try { + netconfClientPlugin.getRunningConfig(params, ctx); + Assert.assertTrue(false); + } catch (APPCException e) { + Assert.assertEquals("failure", ctx.getAttribute("getRunningConfig_Result")); + Assert.assertNull(ctx.getAttribute("running-config")); + Assert.assertNotNull(ctx.getAttribute(DG_OUTPUT_STATUS_MESSAGE)); + } + } + + @Test + public void testGetRunningConfigNegativeConfigurationNull() throws Exception { + fullInit(); + SvcLogicContext ctx = new SvcLogicContext(); + params = new HashMap<>(); + params.put("host-ip-address", host); + params.put("user-name", username); + params.put("password", password); + params.put("port-number", String.valueOf(port)); + + netconfClientPlugin.getRunningConfig(params, ctx); + + Assert.assertEquals("failure", ctx.getAttribute("getRunningConfig_Result")); + Assert.assertNull(ctx.getAttribute("running-config")); + } + + @Test + public void testValidateMandatoryParamNegativeEmptyParamValue() throws Exception { + shortInit(); + String paramName = "test"; + String paramValue = ""; + + try { + netconfClientPlugin.validateMandatoryParam(paramName, paramValue); + Assert.assertTrue(false); + } catch (Exception e) { + Assert.assertTrue(true); + } + } + + @Test + public void testRetrieveConnectionDetails() throws Exception { + shortInit(); + DAOServiceMock daoServiceMock = (DAOServiceMock) dao; + daoServiceMock.setConfigFile(fileContent); + ConnectionDetails connectionDetails1 = getConnectionDetails(); + daoServiceMock.setConnection(connectionDetails1); + + NetconfConnectionDetails connectionDetailsActual = netconfClientPlugin.retrieveConnectionDetails(VnfType.VNF); + + Assert.assertEquals("wrong host", connectionDetails1.getHost(), connectionDetailsActual.getHost()); + Assert.assertEquals("wrong password", connectionDetails1.getPassword(), connectionDetailsActual.getPassword()); + Assert.assertEquals("wrong port", connectionDetails1.getPort(), connectionDetailsActual.getPort()); + Assert.assertEquals("wrong usename", connectionDetails1.getUsername(), connectionDetailsActual.getUsername()); + } + + + @Test + public void testRetrieveConnectionDetailsNegativeMissingConfiguration() throws Exception { + shortInit(); + DAOServiceMock daoServiceMock = (DAOServiceMock) dao; + daoServiceMock.setConfigFile(fileContent); + ConnectionDetails connectionDetails1 = getConnectionDetails(); + daoServiceMock.setConnection(connectionDetails1); + + NetconfConnectionDetails connectionDetailsActual = null; + try { + connectionDetailsActual = netconfClientPlugin.retrieveConnectionDetails(VnfType.MOCK); + Assert.assertTrue(false); + } catch (APPCException e) { + Assert.assertNull(connectionDetailsActual); + } + } + + @Test + public void testRetrieveConfigurationFileContent() throws Exception { + shortInit(); + + DAOServiceMock daoServiceMock = (DAOServiceMock) dao; + daoServiceMock.setConfigFile(fileContent); + + Assert.assertEquals("wrong config in a database", fileContent, netconfClientPlugin.retrieveConfigurationFileContent("VnfGetRunningConfig")); + } + + private ConnectionDetails getConnectionDetails() { + ConnectionDetails connectionDetails = new ConnectionDetails(); + connectionDetails.setPassword(password); + connectionDetails.setPort(port); + connectionDetails.setUsername(username); + connectionDetails.setHost(host); + return connectionDetails; + } + + + private void initDao() throws NoSuchFieldException, IllegalAccessException { + dao = new DAOServiceMock(); + PowerMockito.mockStatic(FrameworkUtil.class); + when(FrameworkUtil.getBundle(Matchers.any(Class.class))).thenReturn(bundleService); + when(bundleService.getBundleContext()).thenReturn(bundleContext); + when(bundleContext.getServiceReference(NetconfDataAccessService.class)).thenReturn(sref1); + when(bundleContext.getService(sref1)).thenReturn(dao); + } + + private void fullInit() throws NoSuchFieldException, IllegalAccessException { + initClientFactory(); + initClientFactory2(); + initDao(); + netconfClientPlugin = new NetconfClientPluginImpl(); + netconfClientPlugin.setDao(this.dao); + } + + private void shortInit() throws NoSuchFieldException, IllegalAccessException { + initClientFactory(); + initDao(); + netconfClientPlugin = new NetconfClientPluginImpl(); + netconfClientPlugin.setDao(this.dao); + } + + private void initClientFactory() throws NoSuchFieldException, IllegalAccessException { + PowerMockito.mockStatic(FrameworkUtil.class); + when(FrameworkUtil.getBundle(Matchers.any(Class.class))).thenReturn(bundleService); + when(bundleService.getBundleContext()).thenReturn(bundleContext); + when(bundleContext.getServiceReference(NetconfClientFactory.class)).thenReturn(sref2); + when(bundleContext.getService(sref2)).thenReturn(clientFactory); + } + + private void initClientFactory2() { + PowerMockito.mockStatic(FrameworkUtil.class); + when(FrameworkUtil.getBundle(Matchers.any(Class.class))).thenReturn(bundleService); + when(bundleService.getBundleContext()).thenReturn(bundleContext); + when(bundleContext.getServiceReference(Matchers.anyString())).thenReturn(sref3); + when(bundleContext.getService(sref3)).thenReturn(clientFactory); + } + + private void substituteMapper(boolean command) throws NoSuchFieldException, IllegalAccessException { + ObjectMapper mapper = new ObjectMapperMock(); + ObjectMapper mapper2 = new ObjectMapper(); + Field field = NetconfClientPluginImpl.class.getDeclaredField("mapper"); + field.setAccessible(true); + if (command) { + field.set(netconfClientPlugin, mapper); + } else { + field.set(netconfClientPlugin, mapper2); + } + } + +} diff --git a/appc-oam/appc-oam-bundle/pom.xml b/appc-oam/appc-oam-bundle/pom.xml index fdc0c8ffd..a4cde77e1 100644 --- a/appc-oam/appc-oam-bundle/pom.xml +++ b/appc-oam/appc-oam-bundle/pom.xml @@ -166,6 +166,12 @@ <version>1.6.2</version> <scope>test</scope> </dependency> + <dependency> + <groupId>org.javassist</groupId> + <artifactId>javassist</artifactId> + <version>3.22.0-GA</version> + <scope>test</scope> + </dependency> <!-- TEMP CODE --> <dependency> <groupId>org.json</groupId> diff --git a/appc-oam/appc-oam-bundle/src/test/java/org/onap/appc/oam/AppcOamTest.java b/appc-oam/appc-oam-bundle/src/test/java/org/onap/appc/oam/AppcOamTest.java new file mode 100644 index 000000000..c3aac5635 --- /dev/null +++ b/appc-oam/appc-oam-bundle/src/test/java/org/onap/appc/oam/AppcOamTest.java @@ -0,0 +1,235 @@ +/*- + * ============LICENSE_START======================================================= + * ONAP : APPC + * ================================================================================ + * Copyright (C) 2017-2019 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * Copyright (C) 2017 Amdocs + * ================================================================================ + * Modifications (C) 2018 Ericsson + * ============================================================================= + * 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. + * + * ============LICENSE_END========================================================= + */ + +package org.onap.appc.oam; + +import static org.junit.Assert.assertEquals; +import static org.mockito.Mockito.mock; +import static org.powermock.api.mockito.PowerMockito.spy; +import java.util.Collection; +import java.util.concurrent.ExecutionException; +import java.util.concurrent.Future; +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; +import org.mockito.Mockito; +import org.onap.appc.exceptions.APPCException; +import org.onap.appc.i18n.Msg; +import org.onap.appc.metricservice.MetricRegistry; +import org.onap.appc.metricservice.MetricService; +import org.onap.appc.metricservice.metric.Metric; +import org.onap.appc.metricservice.metric.MetricType; +import org.onap.appc.metricservice.metric.impl.DefaultPrimitiveCounter; +import org.onap.appc.metricservice.metric.impl.DispatchingFuntionMetricImpl; +import org.onap.appc.oam.processor.OamMmodeProcessor; +import org.onap.appc.oam.processor.OamRestartProcessor; +import org.onap.appc.oam.processor.OamStartProcessor; +import org.onap.appc.oam.processor.OamStopProcessor; +import org.onap.appc.oam.util.AsyncTaskHelper; +import org.onap.appc.oam.util.ConfigurationHelper; +import org.onap.appc.oam.util.OperationHelper; +import org.onap.appc.oam.util.StateHelper; +import org.opendaylight.yang.gen.v1.org.onap.appc.oam.rev170303.AppcState; +import org.opendaylight.yang.gen.v1.org.onap.appc.oam.rev170303.GetAppcStateInput; +import org.opendaylight.yang.gen.v1.org.onap.appc.oam.rev170303.GetAppcStateOutput; +import org.opendaylight.yang.gen.v1.org.onap.appc.oam.rev170303.GetMetricsInput; +import org.opendaylight.yang.gen.v1.org.onap.appc.oam.rev170303.GetMetricsOutput; +import org.opendaylight.yang.gen.v1.org.onap.appc.oam.rev170303.MaintenanceModeInput; +import org.opendaylight.yang.gen.v1.org.onap.appc.oam.rev170303.MaintenanceModeOutput; +import org.opendaylight.yang.gen.v1.org.onap.appc.oam.rev170303.RestartInput; +import org.opendaylight.yang.gen.v1.org.onap.appc.oam.rev170303.RestartOutput; +import org.opendaylight.yang.gen.v1.org.onap.appc.oam.rev170303.StartInput; +import org.opendaylight.yang.gen.v1.org.onap.appc.oam.rev170303.StartOutput; +import org.opendaylight.yang.gen.v1.org.onap.appc.oam.rev170303.StopInput; +import org.opendaylight.yang.gen.v1.org.onap.appc.oam.rev170303.StopOutput; +import org.opendaylight.yang.gen.v1.org.onap.appc.oam.rev170303.common.header.CommonHeader; +import org.opendaylight.yang.gen.v1.org.onap.appc.oam.rev170303.status.Status; +import org.opendaylight.yangtools.yang.common.RpcError; +import org.opendaylight.yangtools.yang.common.RpcResult; +import org.powermock.reflect.Whitebox; +import com.att.aft.dme2.internal.google.common.collect.Iterables; +import com.att.eelf.configuration.EELFLogger; +import com.google.common.collect.ImmutableMap; + + +public class AppcOamTest { + + private AppcOam appcOam; + private CommonHeader mockCommonHeader = mock(CommonHeader.class); + private Status mockStatus = mock(Status.class); + private OperationHelper mockOperationHelper = mock(OperationHelper.class); + private StateHelper mockStateHelper = mock(StateHelper.class); + + @Before + public void setUp() throws Exception { + appcOam = spy(new AppcOam(null, null, null)); + + Whitebox.setInternalState(appcOam, "stateHelper", mockStateHelper); + Whitebox.setInternalState(appcOam, "operationHelper", mockOperationHelper); + } + + @Test + public void testMaintenanceMode() throws Exception { + // mock processor creation + OamMmodeProcessor mockProcessor = mock(OamMmodeProcessor.class); + Mockito.doReturn(mockProcessor).when(appcOam).getOamMmodeProcessor(Mockito.any(EELFLogger.class), + Mockito.any(ConfigurationHelper.class), Mockito.any(StateHelper.class), + Mockito.any(AsyncTaskHelper.class), Mockito.any(OperationHelper.class)); + // mock input + MaintenanceModeInput mockInput = mock(MaintenanceModeInput.class); + Mockito.doReturn(mockCommonHeader).when(mockInput).getCommonHeader(); + // mock processor result + Mockito.doReturn(mockStatus).when(mockProcessor).processRequest(mockInput); + + Future<RpcResult<MaintenanceModeOutput>> response = appcOam.maintenanceMode(mockInput); + + Assert.assertEquals("Should have common header", mockCommonHeader, + response.get().getResult().getCommonHeader()); + Assert.assertEquals("Should have status", mockStatus, response.get().getResult().getStatus()); + } + + @Test + public void testStart() throws Exception { + // mock processor creation + OamStartProcessor mockProcessor = mock(OamStartProcessor.class); + Mockito.doReturn(mockProcessor).when(appcOam).getOamStartProcessor(Mockito.any(EELFLogger.class), + Mockito.any(ConfigurationHelper.class), Mockito.any(StateHelper.class), + Mockito.any(AsyncTaskHelper.class), Mockito.any(OperationHelper.class)); + // mock input + StartInput mockInput = mock(StartInput.class); + Mockito.doReturn(mockCommonHeader).when(mockInput).getCommonHeader(); + // mock processor result + Mockito.doReturn(mockStatus).when(mockProcessor).processRequest(mockInput); + + Future<RpcResult<StartOutput>> response = appcOam.start(mockInput); + + Assert.assertEquals("Should have common header", mockCommonHeader, + response.get().getResult().getCommonHeader()); + Assert.assertEquals("Should have status", mockStatus, response.get().getResult().getStatus()); + } + + @Test + public void testStop() throws Exception { + // mock processor creation + OamStopProcessor mockProcessor = mock(OamStopProcessor.class); + //Mockito.doNothing().when(mockProcessor).setInitialLogProperties(); + Mockito.doReturn(mockProcessor).when(appcOam).getOamStopProcessor(Mockito.any(EELFLogger.class), + Mockito.any(ConfigurationHelper.class), Mockito.any(StateHelper.class), + Mockito.any(AsyncTaskHelper.class), Mockito.any(OperationHelper.class)); + // mock input + StopInput mockInput = mock(StopInput.class); + Mockito.doReturn(mockCommonHeader).when(mockInput).getCommonHeader(); + // mock processor result + Mockito.doReturn(mockStatus).when(mockProcessor).processRequest(mockInput); + + Future<RpcResult<StopOutput>> response = appcOam.stop(mockInput); + + Assert.assertEquals("Should have common header", mockCommonHeader, + response.get().getResult().getCommonHeader()); + Assert.assertEquals("Should have status", mockStatus, response.get().getResult().getStatus()); + } + + @Test + public void testRestart() throws Exception { + // mock processor creation + OamRestartProcessor mockProcessor = mock(OamRestartProcessor.class); + Mockito.doReturn(mockProcessor).when(appcOam).getOamRestartProcessor(Mockito.any(EELFLogger.class), + Mockito.any(ConfigurationHelper.class), Mockito.any(StateHelper.class), + Mockito.any(AsyncTaskHelper.class), Mockito.any(OperationHelper.class)); + // mock input + RestartInput mockInput = mock(RestartInput.class); + Mockito.doReturn(mockCommonHeader).when(mockInput).getCommonHeader(); + // mock processor result + Mockito.doReturn(mockStatus).when(mockProcessor).processRequest(mockInput); + + Future<RpcResult<RestartOutput>> response = appcOam.restart(mockInput); + + Assert.assertEquals("Should have common header", mockCommonHeader, + response.get().getResult().getCommonHeader()); + Assert.assertEquals("Should have status", mockStatus, response.get().getResult().getStatus()); + } + + @Test + public void testGetAppcState() throws Exception { + AppcState appcState = AppcState.Started; + Mockito.doReturn(appcState).when(mockStateHelper).getCurrentOamYangState(); + GetAppcStateInput getAppcStateInput = mock(GetAppcStateInput.class); + Future<RpcResult<GetAppcStateOutput>> state = appcOam.getAppcState(getAppcStateInput); + Assert.assertEquals("Should return the same state", + appcState, state.get().getResult().getState()); + } + + @Test + public void testGetMetricsMetricDisabled() throws InterruptedException, ExecutionException { + Whitebox.setInternalState(appcOam, "isMetricEnabled", false); + GetMetricsInput getMetricsInput = mock(GetMetricsInput.class); + Future<RpcResult<GetMetricsOutput>> result = appcOam.getMetrics(getMetricsInput); + assertEquals("Metric Service not enabled", Iterables.get(result.get().getErrors(), 0).getMessage()); + } + + @Test + public void testGetMetricsNoMetricsService() throws InterruptedException, ExecutionException, APPCException { + Whitebox.setInternalState(appcOam, "isMetricEnabled", true); + Mockito.doThrow(new APPCException()).when(mockOperationHelper).getService(MetricService.class); + GetMetricsInput getMetricsInput = mock(GetMetricsInput.class); + Future<RpcResult<GetMetricsOutput>> result = appcOam.getMetrics(getMetricsInput); + assertEquals("Metric Service not found", Iterables.get(result.get().getErrors(), 0).getMessage()); + } + + @Test + public void testGetMetricsNoMetrics() throws InterruptedException, ExecutionException, APPCException { + Whitebox.setInternalState(appcOam, "isMetricEnabled", true); + MetricService mockMetricService = mock(MetricService.class); + Mockito.doReturn(mockMetricService).when(mockOperationHelper).getService(MetricService.class); + GetMetricsInput getMetricsInput = mock(GetMetricsInput.class); + Future<RpcResult<GetMetricsOutput>> result = appcOam.getMetrics(getMetricsInput); + assertEquals("No metrics Registered", Iterables.get(result.get().getErrors(), 0).getMessage()); + } + + @Test + public void testGetMetricsWithMetricRegistry() throws InterruptedException, ExecutionException, APPCException { + Whitebox.setInternalState(appcOam, "isMetricEnabled", true); + MetricService mockMetricService = mock(MetricService.class); + MetricRegistry mockMetricRegistry = mock(MetricRegistry.class); + Mockito.doReturn(mockMetricService).when(mockOperationHelper).getService(MetricService.class); + Mockito.doReturn(ImmutableMap.of("TEST REGISTRY NAME", mockMetricRegistry)).when(mockMetricService).getAllRegistry(); + Metric metric = new DispatchingFuntionMetricImpl("TEST METRIC NAME", MetricType.COUNTER, 0, 0); + Mockito.doReturn(new Metric[] {metric}).when(mockMetricRegistry).metrics(); + GetMetricsInput getMetricsInput = mock(GetMetricsInput.class); + Future<RpcResult<GetMetricsOutput>> result = appcOam.getMetrics(getMetricsInput); + assertEquals(1, result.get().getResult().getMetrics().size()); + } + + @Test + public void testClose() throws Exception { + ConfigurationHelper mockConfigurationHelper = mock(ConfigurationHelper.class); + Mockito.doReturn("TEST APP NAME").when(mockConfigurationHelper).getAppcName(); + Whitebox.setInternalState(appcOam, "configurationHelper", mockConfigurationHelper); + EELFLogger mockLogger = Mockito.mock(EELFLogger.class); + Whitebox.setInternalState(appcOam, "logger", mockLogger); + appcOam.close(); + Mockito.verify(mockLogger).info(Msg.COMPONENT_TERMINATED, "TEST APP NAME", "oam"); + } +} diff --git a/appc-oam/appc-oam-bundle/src/test/java/org/onap/appc/oam/processor/BaseCommonTest.java b/appc-oam/appc-oam-bundle/src/test/java/org/onap/appc/oam/processor/BaseCommonTest.java new file mode 100644 index 000000000..60d9e3c92 --- /dev/null +++ b/appc-oam/appc-oam-bundle/src/test/java/org/onap/appc/oam/processor/BaseCommonTest.java @@ -0,0 +1,185 @@ +/*- + * ============LICENSE_START======================================================= + * ONAP : APPC + * ================================================================================ + * Copyright (C) 2017-2018 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * Copyright (C) 2017 Amdocs + * ================================================================================ + * Modifications (C) 2018 Ericsson + * ============================================================================= + * 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. + * + * ============LICENSE_END========================================================= + */ + +package org.onap.appc.oam.processor; + +import com.att.eelf.configuration.EELFLogger; +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.Mockito; +import org.opendaylight.yang.gen.v1.org.onap.appc.oam.rev170303.common.header.CommonHeader; +import org.opendaylight.yang.gen.v1.org.onap.appc.oam.rev170303.status.Status; +import org.onap.appc.exceptions.InvalidInputException; +import org.onap.appc.exceptions.InvalidStateException; +import org.onap.appc.oam.AppcOam; +import org.onap.appc.oam.OAMCommandStatus; +import org.onap.appc.oam.util.ConfigurationHelper; +import org.onap.appc.oam.util.OperationHelper; +import org.onap.appc.oam.util.StateHelper; +import org.onap.appc.statemachine.impl.readers.AppcOamStates; +import org.powermock.api.mockito.PowerMockito; +import org.powermock.core.classloader.annotations.PrepareForTest; +import org.powermock.modules.junit4.PowerMockRunner; +import org.powermock.reflect.Whitebox; +import org.slf4j.MDC; +import java.util.Map; + +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.spy; +import static org.mockito.Mockito.times; +import static org.powermock.api.mockito.PowerMockito.mockStatic; + +@RunWith(PowerMockRunner.class) +@PrepareForTest({BaseCommon.class, MDC.class}) +public class BaseCommonTest { + private class TestAbc extends BaseCommon { + + /** + * Constructor + * + * @param eelfLogger for logging + * @param configurationHelperIn for property reading + * @param stateHelperIn for APP-C OAM state checking + * @param operationHelperIn for operational helper + */ + TestAbc(EELFLogger eelfLogger, + ConfigurationHelper configurationHelperIn, + StateHelper stateHelperIn, + OperationHelper operationHelperIn) { + super(eelfLogger, configurationHelperIn, stateHelperIn, operationHelperIn); + } + } + + private TestAbc testBaseCommon; + private ConfigurationHelper mockConfigHelper = mock(ConfigurationHelper.class); + private StateHelper mockStateHelper = mock(StateHelper.class); + private CommonHeader mockCommonHeader = mock(CommonHeader.class); + + @Before + public void setUp() throws Exception { + testBaseCommon = spy(new TestAbc(null, mockConfigHelper, mockStateHelper, null)); + + Whitebox.setInternalState(testBaseCommon, "commonHeader", mockCommonHeader); + Whitebox.setInternalState(testBaseCommon, "rpc", AppcOam.RPC.maintenance_mode); + + // to avoid operation on logger fail, mock up the logger + EELFLogger mockLogger = mock(EELFLogger.class); + Whitebox.setInternalState(testBaseCommon, "logger", mockLogger); + } + + @Test + public void testSetStatus() throws Exception { + OAMCommandStatus oamCommandStatus = OAMCommandStatus.ACCEPTED; + testBaseCommon.setStatus(oamCommandStatus); + Status status = testBaseCommon.status; + Assert.assertEquals("Should have code", oamCommandStatus.getResponseCode(), status.getCode().intValue()); + Assert.assertEquals("Should have message", oamCommandStatus.getResponseMessage(), status.getMessage()); + } + + @Test + public void testSetStatusWithParams() throws Exception { + String message = "testing"; + OAMCommandStatus oamCommandStatus = OAMCommandStatus.REJECTED; + testBaseCommon.setStatus(oamCommandStatus, message); + Status status = testBaseCommon.status; + Assert.assertEquals("Should have code", oamCommandStatus.getResponseCode(), status.getCode().intValue()); + Assert.assertTrue("Should have message", status.getMessage().endsWith(message)); + } + + @Test + public void testSetErrorStatus() throws Exception { + Mockito.doReturn("testName").when(mockConfigHelper).getAppcName(); + Mockito.doReturn(AppcOamStates.Started).when(mockStateHelper).getCurrentOamState(); + Mockito.doReturn("testRequestId").when(mockCommonHeader).getRequestId(); + Mockito.doReturn("testOrigId").when(mockCommonHeader).getOriginatorId(); + Mockito.doReturn("SOME HOST NAME").when(testBaseCommon).getHostInfo(Mockito.anyString()); + + String exceptionMessage = "testing"; + + OAMCommandStatus oamCommandStatus = OAMCommandStatus.INVALID_PARAMETER; + Throwable t = new InvalidInputException(exceptionMessage); + testBaseCommon.setErrorStatus(t); + Status status = testBaseCommon.status; + Assert.assertEquals("Should have code", oamCommandStatus.getResponseCode(), status.getCode().intValue()); + Mockito.verify(testBaseCommon, times(1)).resetLogProperties(false); + Mockito.verify(testBaseCommon, times(1)).resetLogProperties(true); + + oamCommandStatus = OAMCommandStatus.REJECTED; + t = new InvalidStateException(exceptionMessage); + testBaseCommon.setErrorStatus(t); + status = testBaseCommon.status; + Assert.assertEquals("Should have code", oamCommandStatus.getResponseCode(), status.getCode().intValue()); + Mockito.verify(testBaseCommon, times(2)).resetLogProperties(false); + Mockito.verify(testBaseCommon, times(2)).resetLogProperties(true); + + oamCommandStatus = OAMCommandStatus.UNEXPECTED_ERROR; + t = new NullPointerException(exceptionMessage); + testBaseCommon.setErrorStatus(t); + status = testBaseCommon.status; + Assert.assertEquals("Should have code", oamCommandStatus.getResponseCode(), status.getCode().intValue()); + Mockito.verify(testBaseCommon, times(3)).resetLogProperties(false); + Mockito.verify(testBaseCommon, times(3)).resetLogProperties(true); + } + + @Test + public void testSetInitialLogProperties() throws Exception { + mockStatic(MDC.class); + Mockito.doReturn("SOME HOST NAME").when(testBaseCommon).getHostInfo(Mockito.anyString()); + testBaseCommon.setInitialLogProperties(); + PowerMockito.verifyStatic(times(5)); + } + + @Test + public void testClearRequestLogProperties() throws Exception { + mockStatic(MDC.class); + testBaseCommon.clearRequestLogProperties(); + PowerMockito.verifyStatic(times(5)); + } + + @Test + public void testResetLogProperties() throws Exception { + Mockito.doReturn("SOME HOST NAME").when(testBaseCommon).getHostInfo(Mockito.anyString()); + testBaseCommon.setInitialLogProperties(); + + testBaseCommon.resetLogProperties(false); + Mockito.verify(mockCommonHeader, times(2)).getRequestId(); + Mockito.verify(mockCommonHeader, times(2)).getOriginatorId(); + Map<String, String> oldMdcMap = Whitebox.getInternalState(testBaseCommon, "oldMdcContent"); + Assert.assertTrue("Should have 5 entries in persisted map", oldMdcMap.size() == 5); + + testBaseCommon.resetLogProperties(false); + Mockito.verify(mockCommonHeader, times(3)).getRequestId(); + Mockito.verify(mockCommonHeader, times(3)).getOriginatorId(); + + // test oldMdcMap is cleared + testBaseCommon.resetLogProperties(false); + Mockito.verify(mockCommonHeader, times(4)).getRequestId(); + Mockito.verify(mockCommonHeader, times(4)).getOriginatorId(); + oldMdcMap = Whitebox.getInternalState(testBaseCommon, "oldMdcContent"); + Assert.assertTrue("Should have 5 entries in persisted map", oldMdcMap.size() == 5); + } +} diff --git a/appc-oam/appc-oam-bundle/src/test/java/org/onap/appc/oam/processor/BaseProcessorTest.java b/appc-oam/appc-oam-bundle/src/test/java/org/onap/appc/oam/processor/BaseProcessorTest.java new file mode 100644 index 000000000..55ae11b8d --- /dev/null +++ b/appc-oam/appc-oam-bundle/src/test/java/org/onap/appc/oam/processor/BaseProcessorTest.java @@ -0,0 +1,175 @@ +/*- + * ============LICENSE_START======================================================= + * ONAP : APPC + * ================================================================================ + * Copyright (C) 2017-2018 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * Copyright (C) 2017 Amdocs + * ================================================================================ + * Modifications (C) 2018 Ericsson + * ============================================================================= + * 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. + * + * ============LICENSE_END========================================================= + */ + +package org.onap.appc.oam.processor; + +import com.att.eelf.configuration.EELFLogger; +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; +import org.mockito.Mockito; +import org.opendaylight.yang.gen.v1.org.onap.appc.oam.rev170303.StartInput; +import org.opendaylight.yang.gen.v1.org.onap.appc.oam.rev170303.common.header.CommonHeader; +import org.opendaylight.yang.gen.v1.org.onap.appc.oam.rev170303.status.Status; +import org.onap.appc.exceptions.APPCException; +import org.onap.appc.exceptions.InvalidInputException; +import org.onap.appc.exceptions.InvalidStateException; +import org.onap.appc.i18n.Msg; +import org.onap.appc.oam.AppcOam; +import org.onap.appc.oam.OAMCommandStatus; +import org.onap.appc.oam.util.AsyncTaskHelper; +import org.onap.appc.oam.util.ConfigurationHelper; +import org.onap.appc.oam.util.OperationHelper; +import org.onap.appc.oam.util.StateHelper; +import org.onap.appc.statemachine.impl.readers.AppcOamStates; +import org.powermock.reflect.Whitebox; + +import static org.mockito.Matchers.any; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.spy; +import static org.mockito.Mockito.times; + +@SuppressWarnings("ResultOfMethodCallIgnored") +public class BaseProcessorTest { + private AppcOam.RPC testRpc = AppcOam.RPC.start; + private AppcOamStates currentState = AppcOamStates.Stopped; + + private class TestAbc extends BaseProcessor { + + /** + * Constructor + * + * @param eelfLogger for logging + * @param configurationHelperIn for property reading + * @param stateHelperIn for APP-C OAM state checking + * @param asyncTaskHelperIn for scheduling async task + * @param operationHelperIn for operational helper + */ + TestAbc(EELFLogger eelfLogger, + ConfigurationHelper configurationHelperIn, + StateHelper stateHelperIn, + AsyncTaskHelper asyncTaskHelperIn, + OperationHelper operationHelperIn) { + super(eelfLogger, configurationHelperIn, stateHelperIn, asyncTaskHelperIn, operationHelperIn); + + // must set rpc and auditMsg + rpc = testRpc; + auditMsg = Msg.OAM_OPERATION_STARTING; + } + } + + private TestAbc testBaseProcessor; + private ConfigurationHelper mockConfigHelper = mock(ConfigurationHelper.class); + private StateHelper mockStateHelper = mock(StateHelper.class); + private AsyncTaskHelper mockTaskHelper = mock(AsyncTaskHelper.class); + private OperationHelper mockOperHelper = mock(OperationHelper.class); + + private StartInput mockInput = mock(StartInput.class); + private CommonHeader mockCommonHeader = mock(CommonHeader.class); + + @Before + public void setUp() throws Exception { + Mockito.doReturn(mockCommonHeader).when(mockOperHelper).getCommonHeader(mockInput); + Mockito.doReturn(mockCommonHeader).when(mockInput).getCommonHeader(); + + testBaseProcessor = spy( + new TestAbc(null, mockConfigHelper, mockStateHelper, mockTaskHelper, mockOperHelper)); + Mockito.doReturn("SOME HOST NAME").when(testBaseProcessor).getHostInfo(Mockito.anyString()); + Whitebox.setInternalState(testBaseProcessor, "commonHeader", mockCommonHeader); + + // to avoid operation on logger fail, mock up the logger + EELFLogger mockLogger = mock(EELFLogger.class); + Whitebox.setInternalState(testBaseProcessor, "logger", mockLogger); + } + + @Test + public void testProcessRequestError() throws Exception { + Mockito.doReturn(currentState).when(mockStateHelper).getCurrentOamState(); + Mockito.doThrow(new InvalidInputException("test")).when(mockOperHelper).isInputValid(mockInput); + Status status = testBaseProcessor.processRequest(mockInput); + Assert.assertEquals("Should return reject", + OAMCommandStatus.INVALID_PARAMETER.getResponseCode(), status.getCode().intValue()); + } + + @Test + public void testProcessRequest() throws Exception { + Mockito.doReturn(currentState).when(mockStateHelper).getCurrentOamState(); + Mockito.doReturn(AppcOamStates.Starting).when(mockOperHelper).getNextState(any(), any()); + Mockito.doReturn(mockCommonHeader).when(mockInput).getCommonHeader(); + Status status = testBaseProcessor.processRequest(mockInput); + Assert.assertEquals("Should return success", + OAMCommandStatus.ACCEPTED.getResponseCode(), status.getCode().intValue()); + } + + @Test(expected = InvalidInputException.class) + public void testPreProcessWithInvalidInput() throws Exception { + Mockito.doThrow(new InvalidInputException("test")).when(mockOperHelper).isInputValid(mockInput); + testBaseProcessor.preProcess(mockInput); + } + + @Test(expected = InvalidStateException.class) + public void testPreProcessWithInvalidState() throws Exception { + Mockito.doReturn(currentState).when(mockStateHelper).getCurrentOamState(); + Mockito.doThrow(new InvalidStateException("test")) + .when(mockOperHelper).getNextState(testRpc.getAppcOperation(), currentState); + testBaseProcessor.preProcess(mockInput); + } + + @Test(expected = APPCException.class) + public void testPreProcessWithAppcException() throws Exception { + Mockito.doReturn(currentState).when(mockStateHelper).getCurrentOamState(); + Mockito.doThrow(new APPCException("test")) + .when(mockOperHelper).getNextState(testRpc.getAppcOperation(), currentState); + testBaseProcessor.preProcess(mockInput); + } + + @Test + public void testPreProcess() throws Exception { + Mockito.doReturn(currentState).when(mockStateHelper).getCurrentOamState(); + AppcOamStates nextState = AppcOamStates.Starting; + Mockito.doReturn(nextState) + .when(mockOperHelper).getNextState(testRpc.getAppcOperation(), currentState); + testBaseProcessor.preProcess(mockInput); + Mockito.verify(mockOperHelper, times(1)).isInputValid(mockInput); + Mockito.verify(mockOperHelper, times(1)).getNextState(testRpc.getAppcOperation(), currentState); + Mockito.verify(mockStateHelper, times(1)).setState(nextState); + } + + @Test + public void testScheduleAsyncTask() throws Exception { + // test no runnable + testBaseProcessor.scheduleAsyncTask(); + Assert.assertTrue(Whitebox.getInternalState(testBaseProcessor, "runnable") == null); + Assert.assertTrue(Whitebox.getInternalState(testBaseProcessor, "scheduledRunnable") == null); + + BaseActionRunnable mockRunnable = mock(BaseActionRunnable.class); + Whitebox.setInternalState(testBaseProcessor, "runnable", mockRunnable); + testBaseProcessor.scheduleAsyncTask(); + // scheduledRunnable should still be null, there's no mock done + // as I have trouble to make mockTaskHelper.scheduleBaseRunnable to return a proper Future + Assert.assertTrue(Whitebox.getInternalState(testBaseProcessor, "scheduledRunnable") == null); + } + +} diff --git a/appc-oam/appc-oam-bundle/src/test/java/org/onap/appc/oam/util/AsyncTaskHelperTest.java b/appc-oam/appc-oam-bundle/src/test/java/org/onap/appc/oam/util/AsyncTaskHelperTest.java new file mode 100644 index 000000000..319b0c796 --- /dev/null +++ b/appc-oam/appc-oam-bundle/src/test/java/org/onap/appc/oam/util/AsyncTaskHelperTest.java @@ -0,0 +1,663 @@ +/*- + * ============LICENSE_START======================================================= + * ONAP : APPC + * ================================================================================ + * Copyright (C) 2017-2018 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * Copyright (C) 2017 Amdocs + * ============================================================================= + * 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. + * + * ============LICENSE_END========================================================= + */ + +package org.onap.appc.oam.util; + +import com.att.eelf.configuration.EELFLogger; +import org.junit.After; +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.Mockito; +import org.onap.appc.oam.AppcOam; +import org.onap.appc.statemachine.impl.readers.AppcOamStates; +import org.osgi.framework.Bundle; +import org.osgi.framework.FrameworkUtil; +import org.powermock.api.mockito.PowerMockito; +import org.powermock.core.classloader.annotations.PrepareForTest; +import org.powermock.modules.junit4.PowerMockRunner; + +import java.util.LinkedList; +import java.util.concurrent.Future; +import java.util.concurrent.Semaphore; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.TimeoutException; +import java.util.concurrent.atomic.AtomicReference; +import java.util.function.Supplier; + +import static org.mockito.Matchers.any; +import static org.mockito.Mockito.mock; +import static org.powermock.api.mockito.PowerMockito.mockStatic; + + +@RunWith(PowerMockRunner.class) +@PrepareForTest({FrameworkUtil.class}) +public class AsyncTaskHelperTest { + private AsyncTaskHelper asyncTaskHelper; + + private long initialDelayMillis = 0; + private long delayMillis = 10; + + + @Before + public void setUp() throws Exception { + + // to avoid operation on logger fail, mock up the logger + EELFLogger mockLogger = mock(EELFLogger.class); + + + mockStatic(FrameworkUtil.class); + Bundle myBundle = mock(Bundle.class); + Mockito.doReturn("TestBundle").when(myBundle).getSymbolicName(); + PowerMockito.when(FrameworkUtil.getBundle(any())).thenReturn(myBundle); + + asyncTaskHelper = new AsyncTaskHelper(mockLogger); + + + } + + + @After + public void shutdown(){ + asyncTaskHelper.close(); + } + + + /** + * Test that Base Runnable + * + * Runs at a fix rate; + * Only one Base Runnable can be scheduled at time; + * Future.cancle stops the Base Runnable; + * That another Base Runnable can be scheduled once the previous isDone. + */ + @Test + public void test_scheduleBaseRunnable_Base_isDone() throws Exception{ + + + + //loop is to test we can run consecutive Base Runnable + for(int testIteration = 0; testIteration < 3;testIteration++){ + final ExecuteTest et = new ExecuteTest(); + + Future<?> future = asyncTaskHelper.scheduleBaseRunnable( + et::test + , s -> { } + ,initialDelayMillis + ,delayMillis + ); + + //make sure it is running at a fix rate + Assert.assertTrue("It should be iterating", et.waitForTestExec(5000)); + Assert.assertFalse("It Should not be Done", future.isDone()); + Assert.assertTrue("It should be iterating", et.waitForTestExec(5000)); + Assert.assertFalse("It Should not be Done", future.isDone()); + + + //make sure a seconds Runnable cannot be scheduled when one is already running + try { + asyncTaskHelper.scheduleBaseRunnable(et::test + , s -> {} + ,initialDelayMillis + ,delayMillis + ); + Assert.fail("scheduling should have been prevented. "); + } catch (IllegalStateException e) { + //IllegalStateException means the second scheduling was not allowed. + } + + + //let it cancel itself + et.cancelSelfOnNextExecution(future); + + //it should be done after it executes itself one more time. + Assert.assertTrue("it should be done", waitFor(future::isDone, 5000)); + Assert.assertTrue("The test failed to execute", et.isExecuted); + } + + + } + + + /** + * Makes sure the Future.isDone one only returns true if its runnable is not currently executing and will not + * execute in the future. Default implementation of isDone() returns true immediately after the future is + * canceled -- Even if is there is still a thread actively executing the runnable + */ + @Test + public void test_scheduleBaseRunnable_Base_isDone_Ignore_Interrupt() throws Exception{ + + + final ExecuteTest et = new ExecuteTest(); + + //configure test to run long and ignore interrupt + et.isContinuous = true; + et.isIgnoreInterrupt = true; + + + + Future<?> future = asyncTaskHelper.scheduleBaseRunnable( + et::test + , s->{} + ,initialDelayMillis + ,delayMillis + ); + + //make sure it is running + Assert.assertTrue("It should be running",waitFor(et::isExecuting,1000)); + Assert.assertTrue("It should be running",et.waitForTestExec(1000)); + Assert.assertFalse("It Should not be Done", future.isDone()); + + //cancel it and make sure it is still running + future.cancel(true); + Assert.assertTrue("It should be running",waitFor(et::isExecuting,1000)); + Assert.assertTrue("It should be running",et.waitForTestExec(1000)); + Assert.assertFalse("It Should not be Done", future.isDone()); + + //let the thread die and then make sure its done + et.isContinuous = false; + Assert.assertTrue("It should not be running",waitForNot(et::isExecuting,1000)); + Assert.assertTrue("It Should be Done", future.isDone()); + + } + + + + + /** + * Make sure the base Future.isDone returns false until the sub callable has completed execution. + */ + @Test + public void test_scheduleBaseRunnable_SubTask_isDone_Ignore_Interrupt() throws Exception{ + + + final ExecuteTest baseET = new ExecuteTest(); + final ExecuteTest subET = new ExecuteTest(); + + //configure sub test to run long and ignore interrupt + subET.isContinuous = true; + subET.isIgnoreInterrupt = true; + + + //schedule the Base test to run and make sure it is running. + Future<?> baseFuture = asyncTaskHelper.scheduleBaseRunnable( + baseET::test + ,s->{} + ,initialDelayMillis + ,delayMillis + ); + Assert.assertTrue("baseET should be running",waitFor(baseET::isExecuted,1000)); + Assert.assertFalse("baseET Should not be Done because it runs at a fix rate", baseFuture.isDone()); + + + //schedule the sub task and make sure it is running + Future<?> subFuture = asyncTaskHelper.submitBaseSubCallable(subET::test); + Assert.assertTrue("subET should be running",waitFor(subET::isExecuting,1000)); + Assert.assertTrue("subET should be running",subET.waitForTestExec(1000)); + Assert.assertFalse("subET Should not be Done", subFuture.isDone()); + Assert.assertFalse("baseET Should not be Done", baseFuture.isDone()); + + //cancel the base task and make sure isDone is still false + baseFuture.cancel(true); + Assert.assertTrue("subET should be running",waitFor(subET::isExecuting,1000)); + Assert.assertTrue("subET should be running",subET.waitForTestExec(1000)); + Assert.assertFalse("subET Should not be Done",subFuture.isDone()); + Assert.assertFalse("baseET Should not be Done", baseFuture.isDone()); + + + //let the sub task die and and make sure the base is now finally done + subET.isContinuous = false; + Assert.assertTrue("subET should not be running",waitForNot(subET::isExecuting,1000)); + Assert.assertTrue("subET Should be Done", subFuture.isDone()); + Assert.assertTrue("baseET Should be Done", baseFuture.isDone()); + + } + + + /** + * Make sure the base Future.isDone returns false until the 3 sub callable has completed execution. + * Each sub callable will be shutdown one at a time. + */ + public void test_scheduleBaseRunnable_SubTasks_isDone() throws Exception { + + + //loop is to test we can run consecutive Base Runnable + for (int testIteration = 0; testIteration < 3; testIteration++) { + final ExecuteTest baseET = new ExecuteTest(); + final LinkedList<Sub> subList = new LinkedList<>(); + for (int i = 0; i < 3; i++) { + Sub sub = new Sub(); + sub.et.isContinuous = true; + subList.add(sub); + } + + + //schedule the base runnable and make sure it is running + Future<?> baseFuture = asyncTaskHelper.scheduleBaseRunnable( + baseET::test + , s -> { + } + , initialDelayMillis + , delayMillis + ); + Assert.assertTrue("baseET should be running", waitFor(baseET::isExecuted, 1000)); + Assert.assertFalse("baseET Should not be Done because it runs at a fix rate", baseFuture.isDone()); + + + //schedule the sub Callables and make sure these are running + subList.forEach(sub -> sub.future = asyncTaskHelper.submitBaseSubCallable(sub.et::test)); + for (Sub sub : subList) { + Assert.assertTrue("subET should be running", waitFor(sub.et::isExecuting, 100)); + Assert.assertTrue("subET should be running", sub.et.waitForTestExec(1000)); + Assert.assertFalse("subET Should not be Done", sub.future.isDone()); + } + Assert.assertFalse("baseET Should not be Done", baseFuture.isDone()); + + + //On each iteration shut down a sub callable. Make sure it stops, the others are still running and the + // //base is still running. + while (!subList.isEmpty()) { + + //stop one sub and make sure it stopped + { + Sub sub = subList.removeFirst(); + Assert.assertTrue("subET should be running", waitFor(sub.et::isExecuting, 1000)); + sub.et.isContinuous = false; + Assert.assertTrue("subET should not be running", waitForNot(sub.et::isExecuting,1000)); + Assert.assertTrue("subET Should not be Done", sub.future.isDone()); + } + + //make sure the other are still running + for (Sub sub : subList) { + Assert.assertTrue("subET should be running", waitFor(sub.et::isExecuting, 1000)); + Assert.assertTrue("subET should be running", sub.et.waitForTestExec(1000)); + Assert.assertFalse("subET Should not be Done", sub.future.isDone()); + } + + //Make sure the Base is still running + Assert.assertFalse("baseET Should not be Done", baseFuture.isDone()); + } + + //let the base cancel itself and make sure it stops + baseET.cancelSelfOnNextExecution(baseFuture); + Assert.assertTrue("baseET should be done", waitFor(baseFuture::isDone, 1000)); + } + } + + + /** + * Make sure SubCallable cannot be scheduled when there is not BaseRunnable + */ + @Test(expected=IllegalStateException.class) + public void test_SubTasksScheduleFailWhenNoBase() throws Exception { + asyncTaskHelper.submitBaseSubCallable(()->null); + } + + + + /** + * Make sure SubCallable cannot be scheduled when BaseRunnable is cancelled but is still actively running. + */ + @Test(expected=IllegalStateException.class) + public void test_SubTasksScheduleFailWhenBaseCanceledBeforeisDone() throws Exception { + + final ExecuteTest et = new ExecuteTest(); + et.isContinuous = true; + + Future<?> future = asyncTaskHelper.scheduleBaseRunnable( + et::test + , s -> { } + ,initialDelayMillis + ,delayMillis + ); + + Assert.assertTrue("It should be running",waitFor(et::isExecuting,1000)); + future.cancel(false); + Assert.assertTrue("It should be running",waitFor(et::isExecuting,1000)); + + try { + asyncTaskHelper.submitBaseSubCallable(() -> null); + } finally { + et.isContinuous = false; + } + + + + } + + + /** + * Make sure SubCallable cannot be scheduled after a BaseRunnable has completed + */ + @Test(expected=IllegalStateException.class) + public void test_SubTasksScheduleFailAfterBaseDone() throws Exception { + + final ExecuteTest et = new ExecuteTest(); + + Future<?> future = asyncTaskHelper.scheduleBaseRunnable( + et::test + , s -> { } + ,initialDelayMillis + ,delayMillis + ); + + + future.cancel(false); + Assert.assertTrue("It should not be running",waitFor(future::isDone,1000)); + + try { + asyncTaskHelper.submitBaseSubCallable(() -> null); + } finally { + et.isContinuous = false; + } + + } + + + /** + * Test {@link AsyncTaskHelper#cancelBaseActionRunnable(AppcOam.RPC, AppcOamStates, long, TimeUnit)}} + * Test cancel does not block when BaseRunnable is not scheduled + */ + @Test + public void test_cancel_noBlockingWhenBaseRunnableNotScheduled() throws Exception{ + //nothing is running so this should return immediately without TimeoutException + asyncTaskHelper.cancelBaseActionRunnable(AppcOam.RPC.stop , AppcOamStates.Started , 1, TimeUnit.MILLISECONDS); + } + + + + /** + * Test {@link AsyncTaskHelper#cancelBaseActionRunnable(AppcOam.RPC, AppcOamStates, long, TimeUnit)}} + * Test cancel does blocks until BaseRunnable is done scheduled + */ + @Test() + public void test_cancel_BlockingWhenBaseRunnableNotDone() throws Exception { + + + final ExecuteTest et = new ExecuteTest(); + et.isContinuous = true; + et.isIgnoreInterrupt = true; + asyncTaskHelper.scheduleBaseRunnable( + et::test + , s -> { + } + , initialDelayMillis + , delayMillis + ); + + Assert.assertTrue("It should be running", waitFor(et::isExecuting, 1000)); + + + //we should get a timeout + try { + asyncTaskHelper.cancelBaseActionRunnable( + AppcOam.RPC.stop, + AppcOamStates.Started, + 1, + TimeUnit.MILLISECONDS); + Assert.fail("Should have gotten TimeoutException"); + } catch (TimeoutException e) { + //just ignore as it is expected + } + + + //release the test thread + et.isContinuous = false; + + + //we should not get a timeout + asyncTaskHelper.cancelBaseActionRunnable( + AppcOam.RPC.stop, + AppcOamStates.Started, + 1000, + TimeUnit.MILLISECONDS); + + } + + + + /** + * Test {@link AsyncTaskHelper#cancelBaseActionRunnable(AppcOam.RPC, AppcOamStates, long, TimeUnit)}} + * Test cancel does not block when BaseRunnable is not scheduled + */ + @Test + public void test_BaseRunnableCancelCallback() throws Exception{ + + AtomicReference<AppcOam.RPC> cancelCallback = new AtomicReference<>(null); + + final ExecuteTest et = new ExecuteTest(); + et.isContinuous = true; + Future<?> future = asyncTaskHelper.scheduleBaseRunnable( + et::test + , cancelCallback::set + , initialDelayMillis + , delayMillis + ); + + Assert.assertTrue("It should be running", waitFor(et::isExecuting, 1000)); + Assert.assertTrue("It should be running", waitForNot(future::isDone, 1000)); + + + try { + asyncTaskHelper.cancelBaseActionRunnable( + AppcOam.RPC.stop, + AppcOamStates.Started, + 1, + TimeUnit.MILLISECONDS); + Assert.fail("Should have gotten TimeoutException"); + } catch (TimeoutException e) { + //just ignore as it is expected + } + + + Assert.assertEquals("Unexpected rpc in call back",AppcOam.RPC.stop,cancelCallback.get()); + } + + + + + + + + + /** + * @return true if the negation of the expected value is returned from the supplier within the specified + * amount of time + */ + private static boolean waitForNot(Supplier<Boolean> s,long timeoutMillis)throws Exception{ + return waitFor(()->!s.get(),timeoutMillis); + } + + + /** + * @return true if the expected value is returned from the supplier within the specified + * amount of time + */ + private static boolean waitFor(Supplier<Boolean> s,long timeoutMillis) throws Exception { + long timeout = TimeUnit.MILLISECONDS.toMillis(timeoutMillis); + long expiryTime = System.currentTimeMillis() + timeout; + long elapsedTime; + while(!s.get()){ + elapsedTime = expiryTime - System.currentTimeMillis(); + if(elapsedTime < 1) { + break; + } + Thread.sleep(10); + } + return s.get(); + } + + + /** + * This class is used control a thread executed in th {@link #test()} + */ + @SuppressWarnings("unused") + private static class ExecuteTest { + + + /** A fail safe to insure this TEst does not run indefinitely */ + private final long EXPIRY_TIME = System.currentTimeMillis() + 10000; + + + + /** A thread sets this value to true when it has completed the execution the of executes {@link #test()} */ + private volatile boolean isExecuted = false; + + /** + * A thread sets this value to true when it is actively executing {@link #test()} and back to false when + * it is not + */ + private volatile boolean isExecuting = false; + + /** + * While this value is true, a thread will not be allowed to return from {@link #test()} It will simulate a + * long execution. + */ + private volatile boolean isContinuous = false; + + /** + * When this value is set to true, an ongoing simulation of a long execution of {@link #test()} cannot be force + * to abort via a {@link Thread#interrupt()} + */ + private volatile boolean isIgnoreInterrupt = false; + + + + /** Use to send a signal to the thread executing {@link #notifyTestExcuted(long)} */ + private Semaphore inner = new Semaphore(0); + + /** Use to send a signal to the thread executing {@link #waitForTestExec(long)} */ + private Semaphore outer = new Semaphore(0); + + /** The {@link Future} of the Thread executing {@link #test()}*/ + private volatile Future<?> future; + + /** + * When set the Thread executing {@link #test()} will cancel itself + * @param future - The {@link Future} of the Thread executing {@link #test()} + */ + private void cancelSelfOnNextExecution(Future<?> future) { + this.future = future; + } + + + private boolean isExecuted() { + return isExecuted; + } + + private boolean isExecuting() { + return isExecuting; + } + + + private boolean isContinuous() { + return isContinuous; + } + + + private boolean isIgnoreInterrupt() { + return isIgnoreInterrupt; + } + + + + /** + * The thread executing this method if blocked from returning until the thread executing + * {@link #test()} invokes {@link #notifyTestExcuted(long)} or the specified time elapses + * @param timeoutMillis - the amount of time to wait for a execution iteration. + * @return true if the Thread is released because of an invocation of {@link #notifyTestExcuted(long)} + * @throws InterruptedException - If the Caller thread is interrupted. + */ + private boolean waitForTestExec(long timeoutMillis) throws InterruptedException { + inner.release(); + return outer.tryAcquire(timeoutMillis,TimeUnit.MILLISECONDS); + } + + + /** + * Test simulator + * @return Always returns true. + */ + private Boolean test() { + isTestExpired(); + System.out.println("started"); + isExecuting = true; + try { + if (future != null) { + future.cancel(false); + } + if(!isContinuous){ + notifyTestExcuted(1); + } + + while(isContinuous){ + notifyTestExcuted(100); + isTestExpired(); + } + + } finally { + isExecuting = false; + isExecuted = true; + } + return true; + } + + + /** @throws RuntimeException if the test has bee running too long */ + private void isTestExpired(){ + if(System.currentTimeMillis() > EXPIRY_TIME){ + throw new RuntimeException("Something went wrong the test expired."); + } + } + + + /** + * The thread executing {@link #test()} if blocked from returning until another thread invokes + * {@link #waitForTestExec(long)} or the specified time elapses + * @param timeoutMillis - the amount of time to wait for a execution iteration. + * @return true if the Thread is released because of an invocation of {@link #waitForTestExec(long)} + */ + private boolean notifyTestExcuted(long timeoutMillis){ + try { + boolean acquire = inner.tryAcquire(timeoutMillis,TimeUnit.MILLISECONDS); + if(acquire){ + outer.release(); + System.out.println("release"); + } + } catch (InterruptedException e) { + if(!isIgnoreInterrupt){ + return false; + } + } + return true; + } + } + + + static class Sub { + ExecuteTest et = new ExecuteTest(); + Future<?> future = null; + } + +} diff --git a/appc-outbound/appc-network-inventory-client/provider/pom.xml b/appc-outbound/appc-network-inventory-client/provider/pom.xml index 1d9f21581..ab4e39f13 100755 --- a/appc-outbound/appc-network-inventory-client/provider/pom.xml +++ b/appc-outbound/appc-network-inventory-client/provider/pom.xml @@ -3,7 +3,7 @@ ============LICENSE_START=======================================================
ONAP : APPC
================================================================================
- Copyright (C) 2017-2018 AT&T Intellectual Property. All rights reserved.
+ Copyright (C) 2017-2019 AT&T Intellectual Property. All rights reserved.
================================================================================
Copyright (C) 2017 Amdocs
=============================================================================
@@ -86,6 +86,12 @@ <scope>test</scope>
</dependency>
<dependency>
+ <groupId>org.javassist</groupId>
+ <artifactId>javassist</artifactId>
+ <version>3.22.0-GA</version>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
<groupId>org.onap.appc</groupId>
<artifactId>appc-config-params-provider</artifactId>
<version>${project.version}</version>
diff --git a/appc-outbound/appc-network-inventory-client/provider/src/test/java/org/onap/appc/instar/node/TestDme2Client.java b/appc-outbound/appc-network-inventory-client/provider/src/test/java/org/onap/appc/instar/node/TestDme2Client.java new file mode 100644 index 000000000..7e2a41820 --- /dev/null +++ b/appc-outbound/appc-network-inventory-client/provider/src/test/java/org/onap/appc/instar/node/TestDme2Client.java @@ -0,0 +1,153 @@ +/*- + * ============LICENSE_START======================================================= + * ONAP : APPC + * ================================================================================ + * Copyright (C) 2017-2018 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * Copyright (C) 2017 Amdocs + * ============================================================================= + * Modifications Copyright (C) 2019 Ericsson + * ============================================================================= + * 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. + * + * ============LICENSE_END========================================================= + */ + +package org.onap.appc.instar.node; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNull; +import static org.mockito.Matchers.anyObject; +import static org.mockito.Mockito.when; +import java.io.InputStream; +import java.net.URI; +import java.security.NoSuchAlgorithmException; +import java.util.HashMap; +import java.util.Properties; +import javax.net.ssl.SSLContext; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.Mockito; +import org.onap.appc.instar.dme2client.Dme2Client; +import org.onap.appc.instar.utils.InstarClientConstant; +import org.powermock.api.mockito.PowerMockito; +import org.powermock.core.classloader.annotations.PrepareForTest; +import org.powermock.modules.junit4.PowerMockRunner; +import org.powermock.reflect.Whitebox; +import com.sun.jersey.api.client.Client; +import com.sun.jersey.api.client.ClientResponse; +import com.sun.jersey.api.client.WebResource; +import com.sun.jersey.api.client.WebResource.Builder; + +@RunWith(PowerMockRunner.class) +@PrepareForTest({InstarClientConstant.class, SSLContext.class, Client.class}) +public class TestDme2Client { + + private Dme2Client dme2; + private InputStream inputStream; + private SSLContext sslContext; + private Properties properties; + private Client client; + private WebResource webResource; + private Builder builder; + private ClientResponse clientResponse; + + @Before + public void setUp() throws Exception { + inputStream = Mockito.mock(InputStream.class); + sslContext = PowerMockito.mock(SSLContext.class); + client = Mockito.mock(Client.class); + builder = Mockito.mock(Builder.class); + clientResponse = Mockito.mock(ClientResponse.class); + webResource = Mockito.mock(WebResource.class); + HashMap<String, String> data = new HashMap<String, String>(); + data.put("subtext", "value"); + PowerMockito.mockStatic(InstarClientConstant.class); + PowerMockito.mockStatic(SSLContext.class); + PowerMockito.mockStatic(Client.class); + PowerMockito.when(InstarClientConstant.getEnvironmentVariable("SDNC_CONFIG_DIR")) + .thenReturn("test"); + PowerMockito.when(InstarClientConstant.getInputStream("test/outbound.properties")) + .thenReturn(inputStream); + PowerMockito.when(SSLContext.getInstance("SSL")).thenReturn(sslContext); + PowerMockito.when(Client.create(anyObject())).thenReturn(client); + PowerMockito.when(client.resource(new URI("nullnullnullvalue"))).thenReturn(webResource); + + PowerMockito.when(builder.get(ClientResponse.class)).thenReturn(clientResponse); + properties = Mockito.mock(Properties.class); + dme2 = new Dme2Client("opt", "subtext", data); + Whitebox.setInternalState(dme2, "properties", properties); + when(properties.getProperty("MechID")).thenReturn("123"); + when(properties.getProperty("MechPass")).thenReturn("password"); + } + + @Test + public void testSendtoInstarGet() throws Exception { + PowerMockito.when(webResource.accept("application/json")).thenReturn(builder); + PowerMockito.when(clientResponse.getEntity(String.class)).thenReturn("Get Success"); + when(properties.getProperty("getIpAddressByVnf_method")).thenReturn("GET"); + assertEquals("Get Success", dme2.send()); + } + + @Test + public void testSendtoInstarPut() throws Exception { + PowerMockito.when(webResource.type("application/json")).thenReturn(builder); + PowerMockito.when(builder.put(ClientResponse.class, "")).thenReturn(clientResponse); + PowerMockito.when(clientResponse.getEntity(String.class)).thenReturn("Put Success"); + when(properties.getProperty("getIpAddressByVnf_method")).thenReturn("PUT"); + assertEquals("Put Success", dme2.send()); + } + + @Test + public void testSendtoInstarPost() throws Exception { + PowerMockito.when(webResource.type("application/json")).thenReturn(builder); + PowerMockito.when(builder.post(ClientResponse.class, "")).thenReturn(clientResponse); + PowerMockito.when(clientResponse.getEntity(String.class)).thenReturn("Post Success"); + when(properties.getProperty("getIpAddressByVnf_method")).thenReturn("POST"); + assertEquals("Post Success", dme2.send()); + } + + @Test + public void testSendtoInstarDelete() throws Exception { + PowerMockito.when(webResource.delete(ClientResponse.class)).thenReturn(clientResponse); + PowerMockito.when(clientResponse.getEntity(String.class)).thenReturn("Delete Success"); + when(properties.getProperty("getIpAddressByVnf_method")).thenReturn("DELETE"); + assertEquals("Delete Success", dme2.send()); + } + + @Test + public void testSendtoInstarException() throws Exception { + PowerMockito.when(SSLContext.getInstance("SSL")).thenThrow(new NoSuchAlgorithmException()); + when(properties.getProperty("getIpAddressByVnf_method")).thenReturn("DELETE"); + assertNull(dme2.send()); + } + + @Test + public void testSendtoInstarMaskNotNull() throws Exception { + Whitebox.setInternalState(dme2, "mask", "0.0.0.0/1"); + PowerMockito.when(webResource.accept("application/json")).thenReturn(builder); + PowerMockito.when(clientResponse.getEntity(String.class)).thenReturn("Get Success"); + when(properties.getProperty("getIpAddressByVnf_method")).thenReturn("GET"); + assertNull(dme2.send()); + } + + @Test + public void testSendtoInstarIpNotNull() throws Exception { + Whitebox.setInternalState(dme2, "ipAddress", "0.0.0.0"); + PowerMockito.when(webResource.accept("application/json")).thenReturn(builder); + PowerMockito.when(clientResponse.getEntity(String.class)).thenReturn("Get Success"); + when(properties.getProperty("getIpAddressByVnf_method")).thenReturn("GET"); + assertNull(dme2.send()); + } +} diff --git a/appc-sdc-listener/appc-sdc-listener-bundle/pom.xml b/appc-sdc-listener/appc-sdc-listener-bundle/pom.xml index 2c9685a43..7d3f6ca93 100644 --- a/appc-sdc-listener/appc-sdc-listener-bundle/pom.xml +++ b/appc-sdc-listener/appc-sdc-listener-bundle/pom.xml @@ -69,6 +69,12 @@ limitations under the License. <artifactId>powermock-api-mockito</artifactId> <scope>test</scope> </dependency> + <dependency> + <groupId>org.javassist</groupId> + <artifactId>javassist</artifactId> + <version>3.22.0-GA</version> + <scope>test</scope> + </dependency> <dependency> <groupId>org.onap.sdc.sdc-distribution-client</groupId> diff --git a/appc-sdc-listener/appc-sdc-listener-bundle/src/test/java/org/onap/appc/sdc/listener/SdcCallbackTest.java b/appc-sdc-listener/appc-sdc-listener-bundle/src/test/java/org/onap/appc/sdc/listener/SdcCallbackTest.java new file mode 100644 index 000000000..2dcdb4d1c --- /dev/null +++ b/appc-sdc-listener/appc-sdc-listener-bundle/src/test/java/org/onap/appc/sdc/listener/SdcCallbackTest.java @@ -0,0 +1,231 @@ +/*- + * ============LICENSE_START======================================================= + * ONAP : APPC + * ================================================================================ + * Copyright (C) 2017-2018 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * Copyright (C) 2017 Amdocs + * ============================================================================= + * 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. + * ============LICENSE_END========================================================= + */ + +package org.onap.appc.sdc.listener; + + +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.Matchers; +import org.mockito.Mockito; +import org.onap.appc.adapter.message.EventSender; +import org.onap.appc.sdc.artifacts.helper.ArtifactStorageService; +import org.onap.appc.sdc.artifacts.helper.DependencyModelGenerator; +import org.onap.appc.sdc.artifacts.impl.ArtifactProcessorFactory; +import org.onap.appc.sdc.artifacts.impl.ToscaCsarArtifactProcessor; +import org.onap.appc.sdc.artifacts.object.SDCArtifact; +import org.onap.appc.sdc.artifacts.object.SDCReference; +import org.onap.sdc.api.IDistributionClient; +import org.onap.sdc.api.consumer.INotificationCallback; +import org.onap.sdc.api.notification.IArtifactInfo; +import org.onap.sdc.api.notification.INotificationData; +import org.onap.sdc.api.notification.IResourceInstance; +import org.onap.sdc.api.results.IDistributionClientDownloadResult; +import org.onap.sdc.impl.DistributionClientDownloadResultImpl; +import org.onap.sdc.utils.DistributionActionResultEnum; +import org.powermock.api.mockito.PowerMockito; +import org.powermock.core.classloader.annotations.PrepareForTest; +import org.powermock.modules.junit4.PowerMockRunner; +import org.powermock.reflect.Whitebox; + +import java.io.File; +import java.io.FileInputStream; +import java.io.IOException; +import java.lang.reflect.Constructor; +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; +import java.net.URISyntaxException; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import java.util.stream.Collectors; + +import static org.mockito.Matchers.anyObject; + +@RunWith(PowerMockRunner.class) +@PrepareForTest({IDistributionClient.class, + EventSender.class, + ArtifactStorageService.class, + ToscaCsarArtifactProcessor.class, + ArtifactProcessorFactory.class, + DependencyModelGenerator.class}) +public class SdcCallbackTest { + + private INotificationCallback sdcCallback; + private ArtifactStorageService storageService; + private ToscaCsarArtifactProcessor artifactProcessor; + private String resourceContent; + + + @Before + public void setup() throws Exception { + IDistributionClient client = PowerMockito.mock(IDistributionClient.class); + EventSender eventSender = PowerMockito.mock(EventSender.class); + sdcCallback = new SdcCallback(null, client); + resourceContent=readInput("/output/resource-ResourceAppc-template.yml").replaceAll(System.lineSeparator(),""); + artifactProcessor = Mockito.spy(new ToscaCsarArtifactProcessor(client, eventSender, getNotificationData(), getResources().get(0) + , getServiceArtifacts().get(0), null)); + storageService = PowerMockito.mock(ArtifactStorageService.class); + Whitebox.setInternalState(artifactProcessor,"artifactStorageService", storageService); + DependencyModelGenerator dependencyModelGeneratorMock=PowerMockito.mock(DependencyModelGenerator.class); + PowerMockito.when(dependencyModelGeneratorMock.getDependencyModel(Matchers.anyString(),Matchers.anyString())) + .thenReturn("Dependency_model"); + Whitebox.setInternalState(artifactProcessor,"dependencyModelGenerator",dependencyModelGeneratorMock); + + PowerMockito.doCallRealMethod().when(artifactProcessor).processArtifact(anyObject()); + PowerMockito.doCallRealMethod().when(artifactProcessor).run(); + + //PowerMockito.mockStatic(ArtifactProcessorFactory.class); + ArtifactProcessorFactory artifactProcessorFactory=PowerMockito.mock(ArtifactProcessorFactory.class); + PowerMockito.when(artifactProcessorFactory.getArtifactProcessor(anyObject(), anyObject(), + anyObject(), anyObject(), + anyObject(), anyObject())).thenReturn(artifactProcessor); + + Whitebox.setInternalState(sdcCallback,"eventSender", eventSender); + PowerMockito.doReturn(readDownloadResult()).when(client).download(anyObject()); + PowerMockito.doReturn(null).when(client).sendDownloadStatus(anyObject()); + + PowerMockito.doReturn(null).when(storageService).retrieveSDCArtifact(Matchers.anyString(), + Matchers.anyString(),Matchers.anyString()); + + PowerMockito.doAnswer(invocationOnMock -> { + System.out.print(invocationOnMock.getArguments()[0].toString()); + return null; + }).when(storageService).storeSDCArtifact(anyObject()); + } + + private IDistributionClientDownloadResult readDownloadResult() throws IOException, URISyntaxException { + DistributionClientDownloadResultImpl downloadResult = new DistributionClientDownloadResultImpl + (DistributionActionResultEnum.SUCCESS,"Download success"); + File file = new File(this.getClass().getResource("/csar/service-ServiceAppc-csar.csar").toURI()); + + byte[] bFile = new byte[(int) file.length()]; + FileInputStream fileInputStream = new FileInputStream(file); + fileInputStream.read(bFile); + fileInputStream.close(); + + downloadResult.setArtifactPayload(bFile); + return downloadResult; + } + + + @Test + public void testSDCListener() throws ClassNotFoundException, InstantiationException, IllegalAccessException, InvocationTargetException { + INotificationData notificationData = getNotificationData(); + sdcCallback.activateCallback(notificationData); + pause(); + } + + @Test + public void testArtifacts() throws Exception { + PowerMockito.doAnswer(invocationOnMock -> { + SDCArtifact artifact =(SDCArtifact)invocationOnMock.getArguments()[0]; + SDCReference reference=(SDCReference)invocationOnMock.getArguments()[1]; + Assert.assertEquals("abcd-efgh-ijkl",artifact.getArtifactUUID()); + Assert.assertEquals("Resource-APPC",reference.getVnfType()); + Assert.assertEquals(resourceContent.trim(),artifact.getArtifactContent().replaceAll(System.lineSeparator(),"")); + return null; + }).doAnswer(invocation -> { + SDCArtifact artifact =(SDCArtifact)invocation.getArguments()[0]; + SDCReference reference=(SDCReference)invocation.getArguments()[1]; + Assert.assertEquals("Resource-APPC",reference.getVnfType()); + Assert.assertEquals("tosca_dependency_model",reference.getFileCategory()); + Assert.assertEquals("Dependency_model",artifact.getArtifactContent()); + Assert.assertEquals("Resource-APPC",artifact.getResourceName()); + return null; + }).when(storageService).storeSDCArtifactWithReference(anyObject(),anyObject()); + + artifactProcessor.processArtifact(readDownloadResult()); + } + + private void pause(){ + try { + Thread.sleep(5000); + } catch (InterruptedException e) { + } + } + + private String readInput(String inputFile) throws URISyntaxException { + File file = new File(this.getClass().getResource(inputFile).toURI()); + byte[] bFile = new byte[(int) file.length()]; + try(FileInputStream fileInputStream = new FileInputStream(file)){ + fileInputStream.read(bFile); + } catch (Exception e){ + e.printStackTrace(); + } + return new String(bFile); + } + + private INotificationData getNotificationData() throws ClassNotFoundException, IllegalAccessException, InstantiationException, InvocationTargetException { + + INotificationData notificationData = (INotificationData)getObject("org.onap.sdc.impl.NotificationDataImpl"); + + List<IArtifactInfo> serviceArtifacts = getServiceArtifacts(); + + invokeMethod(notificationData, "setServiceArtifacts", serviceArtifacts); + return notificationData; + } + + private List<IResourceInstance> getResources() throws ClassNotFoundException, InvocationTargetException, InstantiationException, IllegalAccessException { + List<IResourceInstance> resources = new ArrayList<>(); + IResourceInstance resource = (IResourceInstance)getObject("org.onap.sdc.impl.JsonContainerResourceInstance"); + + List<IArtifactInfo> serviceArtifacts = getServiceArtifacts(); + invokeMethod(resource,"setArtifacts",serviceArtifacts); + invokeMethod(resource,"setResourceName","Vnf"); + invokeMethod(resource,"setResourceVersion","1.0"); + + resources.add(resource); + return resources; + } + + private void invokeMethod(Object object, String methodName,Object... arguments) throws IllegalAccessException, InvocationTargetException { + Method[] methods = object.getClass().getDeclaredMethods(); + for(Method method:methods){ + if(methodName.equalsIgnoreCase(method.getName())){ + method.setAccessible(true); + method.invoke(object,arguments); + } + } + } + + private Object getObject(String fqcn) throws ClassNotFoundException, InstantiationException, IllegalAccessException, InvocationTargetException { + Constructor constructor = Arrays.asList(Class.forName(fqcn).getDeclaredConstructors()) + .stream() + .filter(constructor1 -> constructor1.getParameterCount()==0) + .collect(Collectors.toList()) + .get(0); + constructor.setAccessible(true); + return constructor.newInstance(); + } + + private List<IArtifactInfo> getServiceArtifacts() throws ClassNotFoundException, InvocationTargetException, InstantiationException, IllegalAccessException { + List<IArtifactInfo> serviceArtifacts = new ArrayList<>(); + IArtifactInfo artifactInfo = (IArtifactInfo)getObject("org.onap.sdc.impl.ArtifactInfoImpl"); + invokeMethod(artifactInfo,"setArtifactType","TOSCA_CSAR"); + invokeMethod(artifactInfo,"setArtifactUUID","abcd-efgh-ijkl"); + serviceArtifacts.add(artifactInfo); + return serviceArtifacts; + } +} diff --git a/appc-sdc-listener/appc-sdc-listener-bundle/src/test/java/org/onap/appc/sdc/listener/SdcListenerTest.java b/appc-sdc-listener/appc-sdc-listener-bundle/src/test/java/org/onap/appc/sdc/listener/SdcListenerTest.java new file mode 100644 index 000000000..2e10065e5 --- /dev/null +++ b/appc-sdc-listener/appc-sdc-listener-bundle/src/test/java/org/onap/appc/sdc/listener/SdcListenerTest.java @@ -0,0 +1,156 @@ +/*- + * ============LICENSE_START======================================================= + * ONAP : APPC + * ================================================================================ + * Copyright (C) 2017-2018 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * Copyright (C) 2017 Amdocs + * ============================================================================= + * 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. + * ============LICENSE_END========================================================= + */ +package org.onap.appc.sdc.listener; + +import com.att.eelf.configuration.EELFLogger; +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.Mockito; +import org.onap.sdc.api.IDistributionClient; +import org.powermock.core.classloader.annotations.PrepareForTest; +import org.powermock.modules.junit4.PowerMockRunner; +import org.powermock.reflect.Whitebox; + +import java.util.concurrent.CountDownLatch; +import java.util.concurrent.TimeUnit; + +import static org.mockito.Matchers.any; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.spy; +import static org.mockito.Mockito.times; + +@RunWith(PowerMockRunner.class) +@PrepareForTest(Thread.class) +public class SdcListenerTest { + private SdcListener sdcListener; + private EELFLogger mockLogger = mock(EELFLogger.class); + + @Before + public void setUp() throws Exception { + sdcListener = new SdcListener(); + + // to avoid operation on logger fail, mock up the logger + Whitebox.setInternalState(sdcListener, "logger", mockLogger); + } + + @Test + public void testStart() throws Exception { + sdcListener.start(); + Assert.assertTrue("Should created startThread", + Whitebox.getInternalState(sdcListener, "startThread") != null); + } + + @Test + public void testStop() throws Exception { + // test interrupt thread and other null case + MockThread mockThread = spy(new MockThread()); + mockThread.setNewState(Thread.State.TIMED_WAITING); + Whitebox.setInternalState(sdcListener, "startThread", mockThread); + + sdcListener.stop(); + Mockito.verify(mockThread, times(1)).interrupt(); + Assert.assertTrue("Should reset startThread", + Whitebox.getInternalState(sdcListener, "startThread") == null); + + // test other non-null case and thread null case + IDistributionClient mockClient = mock(IDistributionClient.class); + Whitebox.setInternalState(sdcListener, "client", mockClient); + SdcCallback mockCallback = mock(SdcCallback.class); + Whitebox.setInternalState(sdcListener, "callback", mockCallback); + CountDownLatch mockLatch = mock(CountDownLatch.class); + Whitebox.setInternalState(sdcListener, "latch", mockLatch); + + sdcListener.stop(); + + Mockito.verify(mockLatch, times(1)).await(10, TimeUnit.SECONDS); + Mockito.verify(mockCallback, times(1)).stop(); + Mockito.verify(mockClient, times(1)).stop(); + Assert.assertTrue("Should reset latch", + Whitebox.getInternalState(sdcListener, "latch") == null); + Assert.assertTrue("Should reset callback", + Whitebox.getInternalState(sdcListener, "callback") == null); + Assert.assertTrue("Should reset client", + Whitebox.getInternalState(sdcListener, "client") == null); + } + + @Test + public void testStopStartThread() throws Exception { + // null case + sdcListener.stopStartThread(123); + //Mockito.verify(mockLogger, times(0)).debug(String.valueOf(any())); + + MockThread mockThread = spy(new MockThread()); + + // thread terminated case + Whitebox.setInternalState(sdcListener, "startThread", mockThread); + mockThread.setNewState(Thread.State.TERMINATED); + sdcListener.stopStartThread(123); + Mockito.verify(mockThread, times(0)).interrupt(); + //Mockito.verify(mockLogger, times(1)).debug(String.valueOf(any())); + Assert.assertTrue("Should reset startThread", + Whitebox.getInternalState(sdcListener, "startThread") == null); + + // thread not termianted case + int timesCallThread = 0; + int timesCallLogger = 1; + for(Thread.State state : Thread.State.values()) { + if (state == Thread.State.TERMINATED) { + continue; + } + Whitebox.setInternalState(sdcListener, "startThread", mockThread); + mockThread.setNewState(state); + sdcListener.stopStartThread(123); + Mockito.verify(mockThread, times(++ timesCallThread)).interrupt(); + //Mockito.verify(mockLogger, times(timesCallLogger += 2)).debug(String.valueOf(any())); + Assert.assertTrue("Should reset startThread", + Whitebox.getInternalState(sdcListener, "startThread") == null); + } + } + + /* + * I have used the following PowerMockito (due to Thread.getName() is a final method) + * try to mock up the thread behavior. But the mock Thread.getName() always returns null + * which works in intelliJ Junit test, but not Jenkins build: + * Thread mockThread = PowerMockito.mock(Thread.class); + * PowerMockito.doReturn(Thread.State.TERMINATED).when(mockThread).getState(); + * PowerMockito.doReturn("testing").when(mockThread).getName(); + * Hence, here goes the MockThread class to override Thread to my expected behavior. + */ + class MockThread extends Thread { + private State state; + + private MockThread() { + super.setName("testing"); + } + + void setNewState(State newState) { + state = newState; + } + + @Override + public State getState() { + return state; + } + } +} |