Fix failing powermock tests 06/79306/4
authorPatrick Brady <patrick.brady@att.com>
Wed, 27 Feb 2019 21:41:53 +0000 (13:41 -0800)
committerPatrick Brady <patrick.brady@att.com>
Wed, 27 Feb 2019 21:55:11 +0000 (21:55 +0000)
The version of javassist coming from opendaylight is not working correctly
with powermock. Adding a test scoped dependency for a working version of
javassist.

Test classes added in this commit are not new, they were temporarily
removed as part of https://gerrit.onap.org/r/#/c/79046/

Change-Id: I193873c0d4abd7b11592a95bff9a6b07cf2d7191
Signed-off-by: Patrick Brady <patrick.brady@att.com>
Issue-ID: APPC-1277

16 files changed:
appc-dg/appc-dg-shared/appc-dg-dependency-model/pom.xml
appc-dg/appc-dg-shared/appc-dg-dependency-model/src/test/java/org/onap/appc/dg/dependencymanager/impl/DependencyManagerImplTest.java [new file with mode: 0644]
appc-dg/appc-dg-shared/appc-dg-mdsal-store/appc-dg-mdsal-bundle/pom.xml
appc-dg/appc-dg-shared/appc-dg-mdsal-store/appc-dg-mdsal-bundle/src/test/java/org/onap/appc/mdsal/MDSALStoreTest.java [new file with mode: 0644]
appc-dg/appc-dg-shared/appc-dg-netconf/pom.xml
appc-dg/appc-dg-shared/appc-dg-netconf/src/test/java/org/onap/appc/dg/netconf/impl/NetconfClientPluginImplTest.java [new file with mode: 0644]
appc-oam/appc-oam-bundle/pom.xml
appc-oam/appc-oam-bundle/src/test/java/org/onap/appc/oam/AppcOamTest.java [new file with mode: 0644]
appc-oam/appc-oam-bundle/src/test/java/org/onap/appc/oam/processor/BaseCommonTest.java [new file with mode: 0644]
appc-oam/appc-oam-bundle/src/test/java/org/onap/appc/oam/processor/BaseProcessorTest.java [new file with mode: 0644]
appc-oam/appc-oam-bundle/src/test/java/org/onap/appc/oam/util/AsyncTaskHelperTest.java [new file with mode: 0644]
appc-outbound/appc-network-inventory-client/provider/pom.xml
appc-outbound/appc-network-inventory-client/provider/src/test/java/org/onap/appc/instar/node/TestDme2Client.java [new file with mode: 0644]
appc-sdc-listener/appc-sdc-listener-bundle/pom.xml
appc-sdc-listener/appc-sdc-listener-bundle/src/test/java/org/onap/appc/sdc/listener/SdcCallbackTest.java [new file with mode: 0644]
appc-sdc-listener/appc-sdc-listener-bundle/src/test/java/org/onap/appc/sdc/listener/SdcListenerTest.java [new file with mode: 0644]

index b52e7b1..085f65b 100644 (file)
@@ -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");
       <version>1.6.4</version>
       <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>
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 (file)
index 0000000..e0214b1
--- /dev/null
@@ -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);
+    }
+
+}
index 6939fe4..d543f2e 100644 (file)
             <groupId>org.powermock</groupId>
             <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>
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 (file)
index 0000000..2229eff
--- /dev/null
@@ -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");
+    }
+
+}
index 85a6deb..b53e43d 100644 (file)
                        <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 (file)
index 0000000..9e2384e
--- /dev/null
@@ -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);
+        }
+    }
+
+}
index fdc0c8f..a4cde77 100644 (file)
             <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 (file)
index 0000000..c3aac56
--- /dev/null
@@ -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 (file)
index 0000000..60d9e3c
--- /dev/null
@@ -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 (file)
index 0000000..55ae11b
--- /dev/null
@@ -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 (file)
index 0000000..319b0c7
--- /dev/null
@@ -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;
+    }
+
+}
index 1d9f215..ab4e39f 100755 (executable)
@@ -3,7 +3,7 @@
   ============LICENSE_START=======================================================\r
   ONAP : APPC\r
   ================================================================================\r
-  Copyright (C) 2017-2018 AT&T Intellectual Property. All rights reserved.\r
+  Copyright (C) 2017-2019 AT&T Intellectual Property. All rights reserved.\r
   ================================================================================\r
   Copyright (C) 2017 Amdocs\r
   =============================================================================\r
             <version>1.6.4</version>\r
             <scope>test</scope>\r
         </dependency>\r
+        <dependency>\r
+            <groupId>org.javassist</groupId>\r
+            <artifactId>javassist</artifactId>\r
+            <version>3.22.0-GA</version>\r
+            <scope>test</scope>\r
+        </dependency>\r
         <dependency>\r
             <groupId>org.onap.appc</groupId>\r
             <artifactId>appc-config-params-provider</artifactId>\r
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 (file)
index 0000000..7e2a418
--- /dev/null
@@ -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());
+  }
+}
index 2c9685a..7d3f6ca 100644 (file)
@@ -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 (file)
index 0000000..2dcdb4d
--- /dev/null
@@ -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 (file)
index 0000000..2e10065
--- /dev/null
@@ -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;
+        }
+    }
+}