diff --git a/appc-oam/appc-oam-bundle/pom.xml b/appc-oam/appc-oam-bundle/pom.xml
index fdc0c8f..a4cde77 100644
--- a/appc-oam/appc-oam-bundle/pom.xml
+++ b/appc-oam/appc-oam-bundle/pom.xml
@@ -166,6 +166,12 @@
             <version>1.6.2</version>
             <scope>test</scope>
         </dependency>
+        <dependency>
+            <groupId>org.javassist</groupId>
+            <artifactId>javassist</artifactId>
+            <version>3.22.0-GA</version>
+            <scope>test</scope>
+        </dependency>
         <!-- TEMP CODE -->
         <dependency>
             <groupId>org.json</groupId>
diff --git a/appc-oam/appc-oam-bundle/src/test/java/org/onap/appc/oam/AppcOamTest.java b/appc-oam/appc-oam-bundle/src/test/java/org/onap/appc/oam/AppcOamTest.java
new file mode 100644
index 0000000..c3aac56
--- /dev/null
+++ b/appc-oam/appc-oam-bundle/src/test/java/org/onap/appc/oam/AppcOamTest.java
@@ -0,0 +1,235 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP : APPC
+ * ================================================================================
+ * Copyright (C) 2017-2019 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Copyright (C) 2017 Amdocs
+ * ================================================================================
+ * Modifications (C) 2018 Ericsson
+ * =============================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * 
+ * ============LICENSE_END=========================================================
+ */
+
+package org.onap.appc.oam;
+
+import static org.junit.Assert.assertEquals;
+import static org.mockito.Mockito.mock;
+import static org.powermock.api.mockito.PowerMockito.spy;
+import java.util.Collection;
+import java.util.concurrent.ExecutionException;
+import java.util.concurrent.Future;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+import org.mockito.Mockito;
+import org.onap.appc.exceptions.APPCException;
+import org.onap.appc.i18n.Msg;
+import org.onap.appc.metricservice.MetricRegistry;
+import org.onap.appc.metricservice.MetricService;
+import org.onap.appc.metricservice.metric.Metric;
+import org.onap.appc.metricservice.metric.MetricType;
+import org.onap.appc.metricservice.metric.impl.DefaultPrimitiveCounter;
+import org.onap.appc.metricservice.metric.impl.DispatchingFuntionMetricImpl;
+import org.onap.appc.oam.processor.OamMmodeProcessor;
+import org.onap.appc.oam.processor.OamRestartProcessor;
+import org.onap.appc.oam.processor.OamStartProcessor;
+import org.onap.appc.oam.processor.OamStopProcessor;
+import org.onap.appc.oam.util.AsyncTaskHelper;
+import org.onap.appc.oam.util.ConfigurationHelper;
+import org.onap.appc.oam.util.OperationHelper;
+import org.onap.appc.oam.util.StateHelper;
+import org.opendaylight.yang.gen.v1.org.onap.appc.oam.rev170303.AppcState;
+import org.opendaylight.yang.gen.v1.org.onap.appc.oam.rev170303.GetAppcStateInput;
+import org.opendaylight.yang.gen.v1.org.onap.appc.oam.rev170303.GetAppcStateOutput;
+import org.opendaylight.yang.gen.v1.org.onap.appc.oam.rev170303.GetMetricsInput;
+import org.opendaylight.yang.gen.v1.org.onap.appc.oam.rev170303.GetMetricsOutput;
+import org.opendaylight.yang.gen.v1.org.onap.appc.oam.rev170303.MaintenanceModeInput;
+import org.opendaylight.yang.gen.v1.org.onap.appc.oam.rev170303.MaintenanceModeOutput;
+import org.opendaylight.yang.gen.v1.org.onap.appc.oam.rev170303.RestartInput;
+import org.opendaylight.yang.gen.v1.org.onap.appc.oam.rev170303.RestartOutput;
+import org.opendaylight.yang.gen.v1.org.onap.appc.oam.rev170303.StartInput;
+import org.opendaylight.yang.gen.v1.org.onap.appc.oam.rev170303.StartOutput;
+import org.opendaylight.yang.gen.v1.org.onap.appc.oam.rev170303.StopInput;
+import org.opendaylight.yang.gen.v1.org.onap.appc.oam.rev170303.StopOutput;
+import org.opendaylight.yang.gen.v1.org.onap.appc.oam.rev170303.common.header.CommonHeader;
+import org.opendaylight.yang.gen.v1.org.onap.appc.oam.rev170303.status.Status;
+import org.opendaylight.yangtools.yang.common.RpcError;
+import org.opendaylight.yangtools.yang.common.RpcResult;
+import org.powermock.reflect.Whitebox;
+import com.att.aft.dme2.internal.google.common.collect.Iterables;
+import com.att.eelf.configuration.EELFLogger;
+import com.google.common.collect.ImmutableMap;
+
+
+public class AppcOamTest {
+
+    private AppcOam appcOam;
+    private CommonHeader mockCommonHeader = mock(CommonHeader.class);
+    private Status mockStatus = mock(Status.class);
+    private OperationHelper mockOperationHelper = mock(OperationHelper.class);
+    private StateHelper mockStateHelper = mock(StateHelper.class);
+
+    @Before
+    public void setUp() throws Exception {
+        appcOam = spy(new AppcOam(null, null, null));
+
+        Whitebox.setInternalState(appcOam, "stateHelper", mockStateHelper);
+        Whitebox.setInternalState(appcOam, "operationHelper", mockOperationHelper);
+    }
+
+    @Test
+    public void testMaintenanceMode() throws Exception {
+        // mock processor creation
+        OamMmodeProcessor mockProcessor = mock(OamMmodeProcessor.class);
+        Mockito.doReturn(mockProcessor).when(appcOam).getOamMmodeProcessor(Mockito.any(EELFLogger.class),
+                Mockito.any(ConfigurationHelper.class), Mockito.any(StateHelper.class),
+                Mockito.any(AsyncTaskHelper.class), Mockito.any(OperationHelper.class));
+        // mock input
+        MaintenanceModeInput mockInput = mock(MaintenanceModeInput.class);
+        Mockito.doReturn(mockCommonHeader).when(mockInput).getCommonHeader();
+        // mock processor result
+        Mockito.doReturn(mockStatus).when(mockProcessor).processRequest(mockInput);
+
+        Future<RpcResult<MaintenanceModeOutput>> response = appcOam.maintenanceMode(mockInput);
+
+        Assert.assertEquals("Should have common header", mockCommonHeader,
+                response.get().getResult().getCommonHeader());
+        Assert.assertEquals("Should have status", mockStatus, response.get().getResult().getStatus());
+    }
+
+    @Test
+    public void testStart()  throws Exception {
+        // mock processor creation
+        OamStartProcessor mockProcessor = mock(OamStartProcessor.class);
+        Mockito.doReturn(mockProcessor).when(appcOam).getOamStartProcessor(Mockito.any(EELFLogger.class),
+                Mockito.any(ConfigurationHelper.class), Mockito.any(StateHelper.class),
+                Mockito.any(AsyncTaskHelper.class), Mockito.any(OperationHelper.class));
+        // mock input
+        StartInput mockInput = mock(StartInput.class);
+        Mockito.doReturn(mockCommonHeader).when(mockInput).getCommonHeader();
+        // mock processor result
+        Mockito.doReturn(mockStatus).when(mockProcessor).processRequest(mockInput);
+
+        Future<RpcResult<StartOutput>> response = appcOam.start(mockInput);
+
+        Assert.assertEquals("Should have common header", mockCommonHeader,
+                response.get().getResult().getCommonHeader());
+        Assert.assertEquals("Should have status", mockStatus, response.get().getResult().getStatus());
+    }
+
+    @Test
+    public void testStop()  throws Exception {
+        // mock processor creation
+        OamStopProcessor mockProcessor = mock(OamStopProcessor.class);
+        //Mockito.doNothing().when(mockProcessor).setInitialLogProperties();
+        Mockito.doReturn(mockProcessor).when(appcOam).getOamStopProcessor(Mockito.any(EELFLogger.class),
+                Mockito.any(ConfigurationHelper.class), Mockito.any(StateHelper.class),
+                Mockito.any(AsyncTaskHelper.class), Mockito.any(OperationHelper.class));
+        // mock input
+        StopInput mockInput = mock(StopInput.class);
+        Mockito.doReturn(mockCommonHeader).when(mockInput).getCommonHeader();
+        // mock processor result
+        Mockito.doReturn(mockStatus).when(mockProcessor).processRequest(mockInput);
+
+        Future<RpcResult<StopOutput>> response = appcOam.stop(mockInput);
+
+        Assert.assertEquals("Should have common header", mockCommonHeader,
+                response.get().getResult().getCommonHeader());
+        Assert.assertEquals("Should have status", mockStatus, response.get().getResult().getStatus());
+    }
+
+    @Test
+    public void testRestart()  throws Exception {
+        // mock processor creation
+        OamRestartProcessor mockProcessor = mock(OamRestartProcessor.class);
+        Mockito.doReturn(mockProcessor).when(appcOam).getOamRestartProcessor(Mockito.any(EELFLogger.class),
+                Mockito.any(ConfigurationHelper.class), Mockito.any(StateHelper.class),
+                Mockito.any(AsyncTaskHelper.class), Mockito.any(OperationHelper.class));
+        // mock input
+        RestartInput mockInput = mock(RestartInput.class);
+        Mockito.doReturn(mockCommonHeader).when(mockInput).getCommonHeader();
+        // mock processor result
+        Mockito.doReturn(mockStatus).when(mockProcessor).processRequest(mockInput);
+
+        Future<RpcResult<RestartOutput>> response = appcOam.restart(mockInput);
+
+        Assert.assertEquals("Should have common header", mockCommonHeader,
+                response.get().getResult().getCommonHeader());
+        Assert.assertEquals("Should have status", mockStatus, response.get().getResult().getStatus());
+    }
+
+    @Test
+    public void testGetAppcState() throws Exception {
+        AppcState appcState = AppcState.Started;
+        Mockito.doReturn(appcState).when(mockStateHelper).getCurrentOamYangState();
+        GetAppcStateInput getAppcStateInput = mock(GetAppcStateInput.class);
+        Future<RpcResult<GetAppcStateOutput>> state = appcOam.getAppcState(getAppcStateInput);
+        Assert.assertEquals("Should return the same state",
+                appcState, state.get().getResult().getState());
+    }
+
+    @Test
+    public void testGetMetricsMetricDisabled() throws InterruptedException, ExecutionException {
+        Whitebox.setInternalState(appcOam, "isMetricEnabled", false);
+        GetMetricsInput getMetricsInput = mock(GetMetricsInput.class);
+        Future<RpcResult<GetMetricsOutput>> result = appcOam.getMetrics(getMetricsInput);
+        assertEquals("Metric Service not enabled", Iterables.get(result.get().getErrors(), 0).getMessage());
+    }
+
+    @Test
+    public void testGetMetricsNoMetricsService() throws InterruptedException, ExecutionException, APPCException {
+        Whitebox.setInternalState(appcOam, "isMetricEnabled", true);
+        Mockito.doThrow(new APPCException()).when(mockOperationHelper).getService(MetricService.class);
+        GetMetricsInput getMetricsInput = mock(GetMetricsInput.class);
+        Future<RpcResult<GetMetricsOutput>> result = appcOam.getMetrics(getMetricsInput);
+        assertEquals("Metric Service not found", Iterables.get(result.get().getErrors(), 0).getMessage());
+    }
+
+    @Test
+    public void testGetMetricsNoMetrics() throws InterruptedException, ExecutionException, APPCException {
+        Whitebox.setInternalState(appcOam, "isMetricEnabled", true);
+        MetricService mockMetricService = mock(MetricService.class);
+        Mockito.doReturn(mockMetricService).when(mockOperationHelper).getService(MetricService.class);
+        GetMetricsInput getMetricsInput = mock(GetMetricsInput.class);
+        Future<RpcResult<GetMetricsOutput>> result = appcOam.getMetrics(getMetricsInput);
+        assertEquals("No metrics Registered", Iterables.get(result.get().getErrors(), 0).getMessage());
+    }
+
+    @Test
+    public void testGetMetricsWithMetricRegistry() throws InterruptedException, ExecutionException, APPCException {
+        Whitebox.setInternalState(appcOam, "isMetricEnabled", true);
+        MetricService mockMetricService = mock(MetricService.class);
+        MetricRegistry mockMetricRegistry = mock(MetricRegistry.class);
+        Mockito.doReturn(mockMetricService).when(mockOperationHelper).getService(MetricService.class);
+        Mockito.doReturn(ImmutableMap.of("TEST REGISTRY NAME", mockMetricRegistry)).when(mockMetricService).getAllRegistry();
+        Metric metric = new DispatchingFuntionMetricImpl("TEST METRIC NAME", MetricType.COUNTER, 0, 0);
+        Mockito.doReturn(new Metric[] {metric}).when(mockMetricRegistry).metrics();
+        GetMetricsInput getMetricsInput = mock(GetMetricsInput.class);
+        Future<RpcResult<GetMetricsOutput>> result = appcOam.getMetrics(getMetricsInput);
+        assertEquals(1, result.get().getResult().getMetrics().size());
+    }
+
+    @Test
+    public void testClose() throws Exception {
+        ConfigurationHelper mockConfigurationHelper = mock(ConfigurationHelper.class);
+        Mockito.doReturn("TEST APP NAME").when(mockConfigurationHelper).getAppcName();
+        Whitebox.setInternalState(appcOam, "configurationHelper", mockConfigurationHelper);
+        EELFLogger mockLogger = Mockito.mock(EELFLogger.class);
+        Whitebox.setInternalState(appcOam, "logger", mockLogger);
+        appcOam.close();
+        Mockito.verify(mockLogger).info(Msg.COMPONENT_TERMINATED, "TEST APP NAME", "oam");
+    }
+}
diff --git a/appc-oam/appc-oam-bundle/src/test/java/org/onap/appc/oam/processor/BaseCommonTest.java b/appc-oam/appc-oam-bundle/src/test/java/org/onap/appc/oam/processor/BaseCommonTest.java
new file mode 100644
index 0000000..60d9e3c
--- /dev/null
+++ b/appc-oam/appc-oam-bundle/src/test/java/org/onap/appc/oam/processor/BaseCommonTest.java
@@ -0,0 +1,185 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP : APPC
+ * ================================================================================
+ * Copyright (C) 2017-2018 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Copyright (C) 2017 Amdocs
+ * ================================================================================
+ * Modifications (C) 2018 Ericsson
+ * =============================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * 
+ * ============LICENSE_END=========================================================
+ */
+
+package org.onap.appc.oam.processor;
+
+import com.att.eelf.configuration.EELFLogger;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mockito;
+import org.opendaylight.yang.gen.v1.org.onap.appc.oam.rev170303.common.header.CommonHeader;
+import org.opendaylight.yang.gen.v1.org.onap.appc.oam.rev170303.status.Status;
+import org.onap.appc.exceptions.InvalidInputException;
+import org.onap.appc.exceptions.InvalidStateException;
+import org.onap.appc.oam.AppcOam;
+import org.onap.appc.oam.OAMCommandStatus;
+import org.onap.appc.oam.util.ConfigurationHelper;
+import org.onap.appc.oam.util.OperationHelper;
+import org.onap.appc.oam.util.StateHelper;
+import org.onap.appc.statemachine.impl.readers.AppcOamStates;
+import org.powermock.api.mockito.PowerMockito;
+import org.powermock.core.classloader.annotations.PrepareForTest;
+import org.powermock.modules.junit4.PowerMockRunner;
+import org.powermock.reflect.Whitebox;
+import org.slf4j.MDC;
+import java.util.Map;
+
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.spy;
+import static org.mockito.Mockito.times;
+import static org.powermock.api.mockito.PowerMockito.mockStatic;
+
+@RunWith(PowerMockRunner.class)
+@PrepareForTest({BaseCommon.class, MDC.class})
+public class BaseCommonTest {
+    private class TestAbc extends BaseCommon {
+
+        /**
+         * Constructor
+         *
+         * @param eelfLogger            for logging
+         * @param configurationHelperIn for property reading
+         * @param stateHelperIn         for APP-C OAM state checking
+         * @param operationHelperIn     for operational helper
+         */
+        TestAbc(EELFLogger eelfLogger,
+                ConfigurationHelper configurationHelperIn,
+                StateHelper stateHelperIn,
+                OperationHelper operationHelperIn) {
+            super(eelfLogger, configurationHelperIn, stateHelperIn, operationHelperIn);
+        }
+    }
+
+    private TestAbc testBaseCommon;
+    private ConfigurationHelper mockConfigHelper = mock(ConfigurationHelper.class);
+    private StateHelper mockStateHelper = mock(StateHelper.class);
+    private CommonHeader mockCommonHeader = mock(CommonHeader.class);
+
+    @Before
+    public void setUp() throws Exception {
+        testBaseCommon = spy(new TestAbc(null, mockConfigHelper, mockStateHelper, null));
+
+        Whitebox.setInternalState(testBaseCommon, "commonHeader", mockCommonHeader);
+        Whitebox.setInternalState(testBaseCommon, "rpc", AppcOam.RPC.maintenance_mode);
+
+        // to avoid operation on logger fail, mock up the logger
+        EELFLogger mockLogger = mock(EELFLogger.class);
+        Whitebox.setInternalState(testBaseCommon, "logger", mockLogger);
+    }
+
+    @Test
+    public void testSetStatus() throws Exception {
+        OAMCommandStatus oamCommandStatus = OAMCommandStatus.ACCEPTED;
+        testBaseCommon.setStatus(oamCommandStatus);
+        Status status = testBaseCommon.status;
+        Assert.assertEquals("Should have code", oamCommandStatus.getResponseCode(), status.getCode().intValue());
+        Assert.assertEquals("Should have message", oamCommandStatus.getResponseMessage(), status.getMessage());
+    }
+
+    @Test
+    public void testSetStatusWithParams() throws Exception {
+        String message = "testing";
+        OAMCommandStatus oamCommandStatus = OAMCommandStatus.REJECTED;
+        testBaseCommon.setStatus(oamCommandStatus, message);
+        Status status = testBaseCommon.status;
+        Assert.assertEquals("Should have code", oamCommandStatus.getResponseCode(), status.getCode().intValue());
+        Assert.assertTrue("Should have message", status.getMessage().endsWith(message));
+    }
+
+    @Test
+    public void testSetErrorStatus() throws Exception {
+        Mockito.doReturn("testName").when(mockConfigHelper).getAppcName();
+        Mockito.doReturn(AppcOamStates.Started).when(mockStateHelper).getCurrentOamState();
+        Mockito.doReturn("testRequestId").when(mockCommonHeader).getRequestId();
+        Mockito.doReturn("testOrigId").when(mockCommonHeader).getOriginatorId();
+        Mockito.doReturn("SOME HOST NAME").when(testBaseCommon).getHostInfo(Mockito.anyString());
+
+        String exceptionMessage = "testing";
+
+        OAMCommandStatus oamCommandStatus = OAMCommandStatus.INVALID_PARAMETER;
+        Throwable t = new InvalidInputException(exceptionMessage);
+        testBaseCommon.setErrorStatus(t);
+        Status status = testBaseCommon.status;
+        Assert.assertEquals("Should have code", oamCommandStatus.getResponseCode(), status.getCode().intValue());
+        Mockito.verify(testBaseCommon, times(1)).resetLogProperties(false);
+        Mockito.verify(testBaseCommon, times(1)).resetLogProperties(true);
+
+        oamCommandStatus = OAMCommandStatus.REJECTED;
+        t = new InvalidStateException(exceptionMessage);
+        testBaseCommon.setErrorStatus(t);
+        status = testBaseCommon.status;
+        Assert.assertEquals("Should have code", oamCommandStatus.getResponseCode(), status.getCode().intValue());
+        Mockito.verify(testBaseCommon, times(2)).resetLogProperties(false);
+        Mockito.verify(testBaseCommon, times(2)).resetLogProperties(true);
+
+        oamCommandStatus = OAMCommandStatus.UNEXPECTED_ERROR;
+        t = new NullPointerException(exceptionMessage);
+        testBaseCommon.setErrorStatus(t);
+        status = testBaseCommon.status;
+        Assert.assertEquals("Should have code", oamCommandStatus.getResponseCode(), status.getCode().intValue());
+        Mockito.verify(testBaseCommon, times(3)).resetLogProperties(false);
+        Mockito.verify(testBaseCommon, times(3)).resetLogProperties(true);
+    }
+
+    @Test
+    public void testSetInitialLogProperties() throws Exception {
+        mockStatic(MDC.class);
+        Mockito.doReturn("SOME HOST NAME").when(testBaseCommon).getHostInfo(Mockito.anyString());
+        testBaseCommon.setInitialLogProperties();
+        PowerMockito.verifyStatic(times(5));
+    }
+
+    @Test
+    public void testClearRequestLogProperties() throws Exception {
+        mockStatic(MDC.class);
+        testBaseCommon.clearRequestLogProperties();
+        PowerMockito.verifyStatic(times(5));
+    }
+
+    @Test
+    public void testResetLogProperties() throws Exception {
+        Mockito.doReturn("SOME HOST NAME").when(testBaseCommon).getHostInfo(Mockito.anyString());
+        testBaseCommon.setInitialLogProperties();
+
+        testBaseCommon.resetLogProperties(false);
+        Mockito.verify(mockCommonHeader, times(2)).getRequestId();
+        Mockito.verify(mockCommonHeader, times(2)).getOriginatorId();
+        Map<String, String> oldMdcMap = Whitebox.getInternalState(testBaseCommon, "oldMdcContent");
+        Assert.assertTrue("Should have 5 entries in persisted map", oldMdcMap.size() == 5);
+
+        testBaseCommon.resetLogProperties(false);
+        Mockito.verify(mockCommonHeader, times(3)).getRequestId();
+        Mockito.verify(mockCommonHeader, times(3)).getOriginatorId();
+
+        // test oldMdcMap is cleared
+        testBaseCommon.resetLogProperties(false);
+        Mockito.verify(mockCommonHeader, times(4)).getRequestId();
+        Mockito.verify(mockCommonHeader, times(4)).getOriginatorId();
+        oldMdcMap = Whitebox.getInternalState(testBaseCommon, "oldMdcContent");
+        Assert.assertTrue("Should have 5 entries in persisted map", oldMdcMap.size() == 5);
+    }
+}
diff --git a/appc-oam/appc-oam-bundle/src/test/java/org/onap/appc/oam/processor/BaseProcessorTest.java b/appc-oam/appc-oam-bundle/src/test/java/org/onap/appc/oam/processor/BaseProcessorTest.java
new file mode 100644
index 0000000..55ae11b
--- /dev/null
+++ b/appc-oam/appc-oam-bundle/src/test/java/org/onap/appc/oam/processor/BaseProcessorTest.java
@@ -0,0 +1,175 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP : APPC
+ * ================================================================================
+ * Copyright (C) 2017-2018 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Copyright (C) 2017 Amdocs
+ * ================================================================================
+ * Modifications (C) 2018 Ericsson
+ * =============================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * 
+ * ============LICENSE_END=========================================================
+ */
+
+package org.onap.appc.oam.processor;
+
+import com.att.eelf.configuration.EELFLogger;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+import org.mockito.Mockito;
+import org.opendaylight.yang.gen.v1.org.onap.appc.oam.rev170303.StartInput;
+import org.opendaylight.yang.gen.v1.org.onap.appc.oam.rev170303.common.header.CommonHeader;
+import org.opendaylight.yang.gen.v1.org.onap.appc.oam.rev170303.status.Status;
+import org.onap.appc.exceptions.APPCException;
+import org.onap.appc.exceptions.InvalidInputException;
+import org.onap.appc.exceptions.InvalidStateException;
+import org.onap.appc.i18n.Msg;
+import org.onap.appc.oam.AppcOam;
+import org.onap.appc.oam.OAMCommandStatus;
+import org.onap.appc.oam.util.AsyncTaskHelper;
+import org.onap.appc.oam.util.ConfigurationHelper;
+import org.onap.appc.oam.util.OperationHelper;
+import org.onap.appc.oam.util.StateHelper;
+import org.onap.appc.statemachine.impl.readers.AppcOamStates;
+import org.powermock.reflect.Whitebox;
+
+import static org.mockito.Matchers.any;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.spy;
+import static org.mockito.Mockito.times;
+
+@SuppressWarnings("ResultOfMethodCallIgnored")
+public class BaseProcessorTest {
+    private AppcOam.RPC testRpc = AppcOam.RPC.start;
+    private AppcOamStates currentState = AppcOamStates.Stopped;
+
+    private class TestAbc extends BaseProcessor {
+
+        /**
+         * Constructor
+         *
+         * @param eelfLogger            for logging
+         * @param configurationHelperIn for property reading
+         * @param stateHelperIn         for APP-C OAM state checking
+         * @param asyncTaskHelperIn     for scheduling async task
+         * @param operationHelperIn     for operational helper
+         */
+        TestAbc(EELFLogger eelfLogger,
+                ConfigurationHelper configurationHelperIn,
+                StateHelper stateHelperIn,
+                AsyncTaskHelper asyncTaskHelperIn,
+                OperationHelper operationHelperIn) {
+            super(eelfLogger, configurationHelperIn, stateHelperIn, asyncTaskHelperIn, operationHelperIn);
+
+            // must set rpc and auditMsg
+            rpc = testRpc;
+            auditMsg = Msg.OAM_OPERATION_STARTING;
+        }
+    }
+
+    private TestAbc testBaseProcessor;
+    private ConfigurationHelper mockConfigHelper = mock(ConfigurationHelper.class);
+    private StateHelper mockStateHelper = mock(StateHelper.class);
+    private AsyncTaskHelper mockTaskHelper = mock(AsyncTaskHelper.class);
+    private OperationHelper mockOperHelper = mock(OperationHelper.class);
+
+    private StartInput mockInput = mock(StartInput.class);
+    private CommonHeader mockCommonHeader = mock(CommonHeader.class);
+
+    @Before
+    public void setUp() throws Exception {
+        Mockito.doReturn(mockCommonHeader).when(mockOperHelper).getCommonHeader(mockInput);
+        Mockito.doReturn(mockCommonHeader).when(mockInput).getCommonHeader();
+
+        testBaseProcessor = spy(
+            new TestAbc(null, mockConfigHelper, mockStateHelper, mockTaskHelper, mockOperHelper));
+        Mockito.doReturn("SOME HOST NAME").when(testBaseProcessor).getHostInfo(Mockito.anyString());
+        Whitebox.setInternalState(testBaseProcessor, "commonHeader", mockCommonHeader);
+
+        // to avoid operation on logger fail, mock up the logger
+        EELFLogger mockLogger = mock(EELFLogger.class);
+        Whitebox.setInternalState(testBaseProcessor, "logger", mockLogger);
+    }
+
+    @Test
+    public void testProcessRequestError() throws Exception {
+        Mockito.doReturn(currentState).when(mockStateHelper).getCurrentOamState();
+        Mockito.doThrow(new InvalidInputException("test")).when(mockOperHelper).isInputValid(mockInput);
+        Status status = testBaseProcessor.processRequest(mockInput);
+        Assert.assertEquals("Should return reject",
+            OAMCommandStatus.INVALID_PARAMETER.getResponseCode(), status.getCode().intValue());
+    }
+
+    @Test
+    public void testProcessRequest() throws Exception {
+        Mockito.doReturn(currentState).when(mockStateHelper).getCurrentOamState();
+        Mockito.doReturn(AppcOamStates.Starting).when(mockOperHelper).getNextState(any(), any());
+        Mockito.doReturn(mockCommonHeader).when(mockInput).getCommonHeader();
+        Status status = testBaseProcessor.processRequest(mockInput);
+        Assert.assertEquals("Should return success",
+            OAMCommandStatus.ACCEPTED.getResponseCode(), status.getCode().intValue());
+    }
+
+    @Test(expected = InvalidInputException.class)
+    public void testPreProcessWithInvalidInput() throws Exception {
+        Mockito.doThrow(new InvalidInputException("test")).when(mockOperHelper).isInputValid(mockInput);
+        testBaseProcessor.preProcess(mockInput);
+    }
+
+    @Test(expected = InvalidStateException.class)
+    public void testPreProcessWithInvalidState() throws Exception {
+        Mockito.doReturn(currentState).when(mockStateHelper).getCurrentOamState();
+        Mockito.doThrow(new InvalidStateException("test"))
+            .when(mockOperHelper).getNextState(testRpc.getAppcOperation(), currentState);
+        testBaseProcessor.preProcess(mockInput);
+    }
+
+    @Test(expected = APPCException.class)
+    public void testPreProcessWithAppcException() throws Exception {
+        Mockito.doReturn(currentState).when(mockStateHelper).getCurrentOamState();
+        Mockito.doThrow(new APPCException("test"))
+            .when(mockOperHelper).getNextState(testRpc.getAppcOperation(), currentState);
+        testBaseProcessor.preProcess(mockInput);
+    }
+
+    @Test
+    public void testPreProcess() throws Exception {
+        Mockito.doReturn(currentState).when(mockStateHelper).getCurrentOamState();
+        AppcOamStates nextState = AppcOamStates.Starting;
+        Mockito.doReturn(nextState)
+            .when(mockOperHelper).getNextState(testRpc.getAppcOperation(), currentState);
+        testBaseProcessor.preProcess(mockInput);
+        Mockito.verify(mockOperHelper, times(1)).isInputValid(mockInput);
+        Mockito.verify(mockOperHelper, times(1)).getNextState(testRpc.getAppcOperation(), currentState);
+        Mockito.verify(mockStateHelper, times(1)).setState(nextState);
+    }
+
+    @Test
+    public void testScheduleAsyncTask() throws Exception {
+        // test no runnable
+        testBaseProcessor.scheduleAsyncTask();
+        Assert.assertTrue(Whitebox.getInternalState(testBaseProcessor, "runnable") == null);
+        Assert.assertTrue(Whitebox.getInternalState(testBaseProcessor, "scheduledRunnable") == null);
+
+        BaseActionRunnable mockRunnable = mock(BaseActionRunnable.class);
+        Whitebox.setInternalState(testBaseProcessor, "runnable", mockRunnable);
+        testBaseProcessor.scheduleAsyncTask();
+        // scheduledRunnable should still be null, there's no mock done
+        // as I have trouble to make mockTaskHelper.scheduleBaseRunnable to return a proper Future
+        Assert.assertTrue(Whitebox.getInternalState(testBaseProcessor, "scheduledRunnable") == null);
+    }
+
+}
diff --git a/appc-oam/appc-oam-bundle/src/test/java/org/onap/appc/oam/util/AsyncTaskHelperTest.java b/appc-oam/appc-oam-bundle/src/test/java/org/onap/appc/oam/util/AsyncTaskHelperTest.java
new file mode 100644
index 0000000..319b0c7
--- /dev/null
+++ b/appc-oam/appc-oam-bundle/src/test/java/org/onap/appc/oam/util/AsyncTaskHelperTest.java
@@ -0,0 +1,663 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP : APPC
+ * ================================================================================
+ * Copyright (C) 2017-2018 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Copyright (C) 2017 Amdocs
+ * =============================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * 
+ * ============LICENSE_END=========================================================
+ */
+
+package org.onap.appc.oam.util;
+
+import com.att.eelf.configuration.EELFLogger;
+import org.junit.After;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mockito;
+import org.onap.appc.oam.AppcOam;
+import org.onap.appc.statemachine.impl.readers.AppcOamStates;
+import org.osgi.framework.Bundle;
+import org.osgi.framework.FrameworkUtil;
+import org.powermock.api.mockito.PowerMockito;
+import org.powermock.core.classloader.annotations.PrepareForTest;
+import org.powermock.modules.junit4.PowerMockRunner;
+
+import java.util.LinkedList;
+import java.util.concurrent.Future;
+import java.util.concurrent.Semaphore;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.TimeoutException;
+import java.util.concurrent.atomic.AtomicReference;
+import java.util.function.Supplier;
+
+import static org.mockito.Matchers.any;
+import static org.mockito.Mockito.mock;
+import static org.powermock.api.mockito.PowerMockito.mockStatic;
+
+
+@RunWith(PowerMockRunner.class)
+@PrepareForTest({FrameworkUtil.class})
+public class AsyncTaskHelperTest {
+    private AsyncTaskHelper asyncTaskHelper;
+
+    private long initialDelayMillis = 0;
+    private long delayMillis = 10;
+
+
+    @Before
+    public void setUp() throws Exception {
+
+        // to avoid operation on logger fail, mock up the logger
+        EELFLogger mockLogger = mock(EELFLogger.class);
+
+
+        mockStatic(FrameworkUtil.class);
+        Bundle myBundle = mock(Bundle.class);
+        Mockito.doReturn("TestBundle").when(myBundle).getSymbolicName();
+        PowerMockito.when(FrameworkUtil.getBundle(any())).thenReturn(myBundle);
+
+        asyncTaskHelper = new AsyncTaskHelper(mockLogger);
+
+
+    }
+
+
+    @After
+    public void shutdown(){
+        asyncTaskHelper.close();
+    }
+
+
+    /**
+     * Test that Base Runnable
+     *
+     * Runs at a fix rate;
+     * Only one Base Runnable  can be scheduled at time;
+     * Future.cancle stops the Base Runnable;
+     * That another Base Runnable  can be scheduled once the previous isDone.
+     */
+    @Test
+    public void test_scheduleBaseRunnable_Base_isDone() throws Exception{
+
+
+
+        //loop is to test we can run consecutive Base Runnable
+        for(int testIteration = 0; testIteration < 3;testIteration++){
+            final ExecuteTest et = new ExecuteTest();
+
+            Future<?> future = asyncTaskHelper.scheduleBaseRunnable(
+                    et::test
+                    , s -> { }
+                    ,initialDelayMillis
+                    ,delayMillis
+            );
+
+            //make sure it is running at a fix rate
+            Assert.assertTrue("It should be iterating", et.waitForTestExec(5000));
+            Assert.assertFalse("It Should not be Done", future.isDone());
+            Assert.assertTrue("It should be iterating", et.waitForTestExec(5000));
+            Assert.assertFalse("It Should not be Done", future.isDone());
+
+
+            //make sure a seconds Runnable cannot be scheduled when one is already running
+            try {
+                asyncTaskHelper.scheduleBaseRunnable(et::test
+                        , s -> {}
+                        ,initialDelayMillis
+                        ,delayMillis
+                );
+                Assert.fail("scheduling should have been prevented.  ");
+            } catch (IllegalStateException e) {
+                //IllegalStateException means the second scheduling was not allowed.
+            }
+
+
+            //let it cancel itself
+            et.cancelSelfOnNextExecution(future);
+
+            //it should be done after it executes itself one more time.
+            Assert.assertTrue("it should be done", waitFor(future::isDone, 5000));
+            Assert.assertTrue("The test failed to execute", et.isExecuted);
+        }
+
+
+    }
+
+
+    /**
+     * Makes sure the Future.isDone one only returns true if its runnable is not currently executing and will not
+     * execute in the future.  Default implementation of isDone() returns true immediately after the future is
+     * canceled -- Even if is there is still a thread actively executing the runnable
+     */
+    @Test
+    public void test_scheduleBaseRunnable_Base_isDone_Ignore_Interrupt() throws Exception{
+
+
+        final ExecuteTest et = new ExecuteTest();
+
+        //configure test to run long and ignore interrupt
+        et.isContinuous = true;
+        et.isIgnoreInterrupt = true;
+
+
+
+        Future<?> future = asyncTaskHelper.scheduleBaseRunnable(
+                et::test
+                , s->{}
+                ,initialDelayMillis
+                ,delayMillis
+        );
+
+        //make sure it is running
+        Assert.assertTrue("It should be running",waitFor(et::isExecuting,1000));
+        Assert.assertTrue("It should be running",et.waitForTestExec(1000));
+        Assert.assertFalse("It Should not be Done", future.isDone());
+
+        //cancel it and make sure it is still running
+        future.cancel(true);
+        Assert.assertTrue("It should be running",waitFor(et::isExecuting,1000));
+        Assert.assertTrue("It should be running",et.waitForTestExec(1000));
+        Assert.assertFalse("It Should not be Done", future.isDone());
+
+        //let the thread die and then make sure its done
+        et.isContinuous = false;
+        Assert.assertTrue("It should not be running",waitForNot(et::isExecuting,1000));
+        Assert.assertTrue("It Should be Done", future.isDone());
+
+    }
+
+
+
+
+    /**
+     * Make sure the base Future.isDone returns false until the sub callable has completed execution.
+     */
+    @Test
+    public void test_scheduleBaseRunnable_SubTask_isDone_Ignore_Interrupt() throws Exception{
+
+
+        final ExecuteTest baseET = new ExecuteTest();
+        final ExecuteTest subET = new ExecuteTest();
+
+        //configure sub test to run long and ignore interrupt
+        subET.isContinuous = true;
+        subET.isIgnoreInterrupt = true;
+
+
+        //schedule the Base test to run and make sure it is running.
+        Future<?> baseFuture = asyncTaskHelper.scheduleBaseRunnable(
+                baseET::test
+                ,s->{}
+                ,initialDelayMillis
+                ,delayMillis
+                );
+        Assert.assertTrue("baseET should be running",waitFor(baseET::isExecuted,1000));
+        Assert.assertFalse("baseET Should not be Done because it runs at a fix rate", baseFuture.isDone());
+
+
+        //schedule the sub task and make sure it is  running
+        Future<?> subFuture = asyncTaskHelper.submitBaseSubCallable(subET::test);
+        Assert.assertTrue("subET should be running",waitFor(subET::isExecuting,1000));
+        Assert.assertTrue("subET should be running",subET.waitForTestExec(1000));
+        Assert.assertFalse("subET Should not be Done", subFuture.isDone());
+        Assert.assertFalse("baseET Should not be Done", baseFuture.isDone());
+
+        //cancel the base task and make sure isDone is still false
+        baseFuture.cancel(true);
+        Assert.assertTrue("subET should be running",waitFor(subET::isExecuting,1000));
+        Assert.assertTrue("subET should be running",subET.waitForTestExec(1000));
+        Assert.assertFalse("subET Should not be Done",subFuture.isDone());
+        Assert.assertFalse("baseET Should not be Done", baseFuture.isDone());
+
+
+        //let the sub task die and and make sure the base is now finally done
+        subET.isContinuous = false;
+        Assert.assertTrue("subET should not be running",waitForNot(subET::isExecuting,1000));
+        Assert.assertTrue("subET Should be Done", subFuture.isDone());
+        Assert.assertTrue("baseET Should be Done", baseFuture.isDone());
+
+    }
+
+
+    /**
+     * Make sure the base Future.isDone returns false until the 3 sub callable has completed execution.
+     * Each sub callable will be shutdown one at a time.
+     */
+    public void test_scheduleBaseRunnable_SubTasks_isDone() throws Exception {
+
+
+        //loop is to test we can run consecutive Base Runnable
+        for (int testIteration = 0; testIteration < 3; testIteration++) {
+            final ExecuteTest baseET = new ExecuteTest();
+            final LinkedList<Sub> subList = new LinkedList<>();
+            for (int i = 0; i < 3; i++) {
+                Sub sub = new Sub();
+                sub.et.isContinuous = true;
+                subList.add(sub);
+            }
+
+
+            //schedule the base runnable and make sure it is running
+            Future<?> baseFuture = asyncTaskHelper.scheduleBaseRunnable(
+                    baseET::test
+                    , s -> {
+                    }
+                    , initialDelayMillis
+                    , delayMillis
+            );
+            Assert.assertTrue("baseET should be running", waitFor(baseET::isExecuted, 1000));
+            Assert.assertFalse("baseET Should not be Done because it runs at a fix rate", baseFuture.isDone());
+
+
+            //schedule the sub Callables and make sure these are running
+            subList.forEach(sub -> sub.future = asyncTaskHelper.submitBaseSubCallable(sub.et::test));
+            for (Sub sub : subList) {
+                Assert.assertTrue("subET should be running", waitFor(sub.et::isExecuting, 100));
+                Assert.assertTrue("subET should be running", sub.et.waitForTestExec(1000));
+                Assert.assertFalse("subET Should not be Done", sub.future.isDone());
+            }
+            Assert.assertFalse("baseET Should not be Done", baseFuture.isDone());
+
+
+            //On each iteration shut down a sub callable.  Make sure it stops, the others are still running and the
+            // //base is still running.
+            while (!subList.isEmpty()) {
+
+                //stop one sub and make sure it stopped
+                {
+                    Sub sub = subList.removeFirst();
+                    Assert.assertTrue("subET should be running", waitFor(sub.et::isExecuting, 1000));
+                    sub.et.isContinuous = false;
+                    Assert.assertTrue("subET should not be running", waitForNot(sub.et::isExecuting,1000));
+                    Assert.assertTrue("subET Should not be Done", sub.future.isDone());
+                }
+
+                //make sure the other are still running
+                for (Sub sub : subList) {
+                    Assert.assertTrue("subET should be running", waitFor(sub.et::isExecuting, 1000));
+                    Assert.assertTrue("subET should be running", sub.et.waitForTestExec(1000));
+                    Assert.assertFalse("subET Should not be Done", sub.future.isDone());
+                }
+
+                //Make sure the Base is still running
+                Assert.assertFalse("baseET Should not be Done", baseFuture.isDone());
+            }
+
+            //let the base cancel itself and make sure it stops
+            baseET.cancelSelfOnNextExecution(baseFuture);
+            Assert.assertTrue("baseET should be done", waitFor(baseFuture::isDone, 1000));
+        }
+    }
+
+
+    /**
+     * Make sure SubCallable cannot be scheduled when there is not BaseRunnable
+     */
+    @Test(expected=IllegalStateException.class)
+    public void test_SubTasksScheduleFailWhenNoBase() throws Exception {
+        asyncTaskHelper.submitBaseSubCallable(()->null);
+    }
+
+
+
+    /**
+     * Make sure SubCallable cannot be scheduled when BaseRunnable is cancelled but is still actively running.
+     */
+    @Test(expected=IllegalStateException.class)
+    public void test_SubTasksScheduleFailWhenBaseCanceledBeforeisDone() throws Exception {
+
+        final ExecuteTest et = new ExecuteTest();
+        et.isContinuous = true;
+
+        Future<?> future = asyncTaskHelper.scheduleBaseRunnable(
+                et::test
+                , s -> { }
+                ,initialDelayMillis
+                ,delayMillis
+        );
+
+        Assert.assertTrue("It should be running",waitFor(et::isExecuting,1000));
+        future.cancel(false);
+        Assert.assertTrue("It should be running",waitFor(et::isExecuting,1000));
+
+        try {
+            asyncTaskHelper.submitBaseSubCallable(() -> null);
+        } finally {
+            et.isContinuous = false;
+        }
+
+
+
+    }
+
+
+    /**
+     * Make sure SubCallable cannot be scheduled after a BaseRunnable has completed
+     */
+    @Test(expected=IllegalStateException.class)
+    public void test_SubTasksScheduleFailAfterBaseDone() throws Exception {
+
+        final ExecuteTest et = new ExecuteTest();
+
+        Future<?> future = asyncTaskHelper.scheduleBaseRunnable(
+                et::test
+                , s -> { }
+                ,initialDelayMillis
+                ,delayMillis
+        );
+
+
+        future.cancel(false);
+        Assert.assertTrue("It should not be running",waitFor(future::isDone,1000));
+
+        try {
+            asyncTaskHelper.submitBaseSubCallable(() -> null);
+        } finally {
+            et.isContinuous = false;
+        }
+
+    }
+
+
+    /**
+     * Test {@link AsyncTaskHelper#cancelBaseActionRunnable(AppcOam.RPC, AppcOamStates, long, TimeUnit)}}
+     * Test cancel does not block when BaseRunnable is not scheduled
+     */
+    @Test
+    public void test_cancel_noBlockingWhenBaseRunnableNotScheduled() throws Exception{
+        //nothing is running so this should return immediately without TimeoutException
+        asyncTaskHelper.cancelBaseActionRunnable(AppcOam.RPC.stop , AppcOamStates.Started , 1, TimeUnit.MILLISECONDS);
+    }
+
+
+
+    /**
+     * Test {@link AsyncTaskHelper#cancelBaseActionRunnable(AppcOam.RPC, AppcOamStates, long, TimeUnit)}}
+     * Test cancel does blocks until BaseRunnable is done scheduled
+     */
+    @Test()
+    public void test_cancel_BlockingWhenBaseRunnableNotDone() throws Exception {
+
+
+        final ExecuteTest et = new ExecuteTest();
+        et.isContinuous = true;
+        et.isIgnoreInterrupt = true;
+        asyncTaskHelper.scheduleBaseRunnable(
+                et::test
+                , s -> {
+                }
+                , initialDelayMillis
+                , delayMillis
+        );
+
+        Assert.assertTrue("It should be running", waitFor(et::isExecuting, 1000));
+
+
+        //we should get a timeout
+        try {
+            asyncTaskHelper.cancelBaseActionRunnable(
+                    AppcOam.RPC.stop,
+                    AppcOamStates.Started,
+                    1,
+                    TimeUnit.MILLISECONDS);
+            Assert.fail("Should have gotten TimeoutException");
+        } catch (TimeoutException e) {
+            //just ignore as it is expected
+        }
+
+
+        //release the test thread
+        et.isContinuous = false;
+
+
+        //we should not get a timeout
+        asyncTaskHelper.cancelBaseActionRunnable(
+                AppcOam.RPC.stop,
+                AppcOamStates.Started,
+                1000,
+                TimeUnit.MILLISECONDS);
+
+    }
+
+
+
+    /**
+     * Test {@link AsyncTaskHelper#cancelBaseActionRunnable(AppcOam.RPC, AppcOamStates, long, TimeUnit)}}
+     * Test cancel does not block when BaseRunnable is not scheduled
+     */
+    @Test
+    public void test_BaseRunnableCancelCallback() throws Exception{
+
+        AtomicReference<AppcOam.RPC> cancelCallback = new AtomicReference<>(null);
+
+        final ExecuteTest et = new ExecuteTest();
+        et.isContinuous = true;
+        Future<?> future = asyncTaskHelper.scheduleBaseRunnable(
+                et::test
+                , cancelCallback::set
+                , initialDelayMillis
+                , delayMillis
+        );
+
+        Assert.assertTrue("It should be running", waitFor(et::isExecuting, 1000));
+        Assert.assertTrue("It should be running", waitForNot(future::isDone, 1000));
+
+
+        try {
+            asyncTaskHelper.cancelBaseActionRunnable(
+                    AppcOam.RPC.stop,
+                    AppcOamStates.Started,
+                    1,
+                    TimeUnit.MILLISECONDS);
+            Assert.fail("Should have gotten TimeoutException");
+        } catch (TimeoutException e) {
+           //just ignore as it is expected
+        }
+
+
+        Assert.assertEquals("Unexpected rpc in call back",AppcOam.RPC.stop,cancelCallback.get());
+    }
+
+
+
+
+
+
+
+
+    /**
+     * @return true if the negation of the expected value is returned from the supplier within the specified
+     * amount of time
+     */
+    private static boolean waitForNot(Supplier<Boolean> s,long timeoutMillis)throws Exception{
+        return waitFor(()->!s.get(),timeoutMillis);
+    }
+
+
+    /**
+     * @return true if the expected value is returned from the supplier within the specified
+     * amount of time
+     */
+    private static boolean waitFor(Supplier<Boolean> s,long timeoutMillis) throws Exception {
+        long timeout = TimeUnit.MILLISECONDS.toMillis(timeoutMillis);
+        long expiryTime = System.currentTimeMillis() + timeout;
+        long elapsedTime;
+        while(!s.get()){
+            elapsedTime = expiryTime - System.currentTimeMillis();
+            if(elapsedTime < 1) {
+                break;
+            }
+            Thread.sleep(10);
+        }
+        return s.get();
+    }
+
+
+    /**
+     * This class is used control a thread  executed in th {@link #test()}
+     */
+    @SuppressWarnings("unused")
+    private static class ExecuteTest {
+
+
+        /** A fail safe to insure this TEst does not run indefinitely */
+        private final long EXPIRY_TIME = System.currentTimeMillis() + 10000;
+
+
+
+        /** A thread sets this value to true when it has completed the execution the of executes {@link #test()}   */
+        private  volatile boolean isExecuted = false;
+
+        /**
+         * A thread sets this value to true when it is actively executing {@link #test()} and back to false when
+         * it is not
+         */
+        private  volatile boolean isExecuting = false;
+
+        /**
+         * While this value is true, a thread will not be allowed to return from {@link #test()} It will simulate  a
+         * long execution.
+         */
+        private  volatile boolean isContinuous = false;
+
+        /**
+         * When this value is set to true, an ongoing simulation of a long execution of {@link #test()} cannot be force
+         * to abort via a  {@link Thread#interrupt()}
+         */
+        private  volatile boolean isIgnoreInterrupt = false;
+
+
+
+        /** Use to send a signal to the thread executing {@link #notifyTestExcuted(long)} */
+        private  Semaphore inner = new Semaphore(0);
+
+        /** Use to send a signal to the thread executing {@link #waitForTestExec(long)} */
+        private  Semaphore outer = new Semaphore(0);
+
+        /** The {@link Future} of the Thread executing {@link #test()}*/
+        private volatile Future<?> future;
+
+        /**
+         * When set the Thread executing {@link #test()} will cancel itself
+         * @param future - The {@link Future} of the Thread executing {@link #test()}
+         */
+        private void cancelSelfOnNextExecution(Future<?> future) {
+            this.future = future;
+        }
+
+
+        private boolean isExecuted() {
+            return isExecuted;
+        }
+
+        private boolean isExecuting() {
+            return isExecuting;
+        }
+
+
+        private boolean isContinuous() {
+            return isContinuous;
+        }
+
+
+        private boolean isIgnoreInterrupt() {
+            return isIgnoreInterrupt;
+        }
+
+
+
+        /**
+         * The thread executing this method if blocked from returning until the thread executing
+         * {@link #test()}  invokes  {@link #notifyTestExcuted(long)} or the specified time elapses
+         * @param timeoutMillis - the amount of time to wait for a execution iteration.
+         * @return true if the Thread is released because of an invocation of {@link #notifyTestExcuted(long)}
+         * @throws InterruptedException - If the Caller thread is interrupted.
+         */
+        private boolean waitForTestExec(long timeoutMillis) throws InterruptedException {
+            inner.release();
+            return outer.tryAcquire(timeoutMillis,TimeUnit.MILLISECONDS);
+        }
+
+
+        /**
+         * Test simulator
+         * @return  Always returns true.
+         */
+        private Boolean test() {
+            isTestExpired();
+            System.out.println("started");
+             isExecuting = true;
+             try {
+                 if (future != null) {
+                     future.cancel(false);
+                 }
+                 if(!isContinuous){
+                     notifyTestExcuted(1);
+                 }
+
+                 while(isContinuous){
+                     notifyTestExcuted(100);
+                     isTestExpired();
+                 }
+
+             } finally {
+                 isExecuting = false;
+                 isExecuted = true;
+             }
+             return true;
+        }
+
+
+        /** @throws RuntimeException if the test  has bee running too long */
+        private void isTestExpired(){
+            if(System.currentTimeMillis() > EXPIRY_TIME){
+                throw new RuntimeException("Something went wrong the test expired.");
+            }
+        }
+
+
+        /**
+         * The thread executing {@link #test()}  if blocked from returning until another thread invokes
+         * {@link #waitForTestExec(long)} or the specified time elapses
+         * @param timeoutMillis - the amount of time to wait for a execution iteration.
+         * @return true if the Thread is released because of an invocation of {@link #waitForTestExec(long)}
+         */
+        private boolean notifyTestExcuted(long timeoutMillis){
+            try {
+                boolean acquire = inner.tryAcquire(timeoutMillis,TimeUnit.MILLISECONDS);
+                if(acquire){
+                    outer.release();
+                    System.out.println("release");
+                }
+            } catch (InterruptedException e) {
+                if(!isIgnoreInterrupt){
+                    return false;
+                }
+            }
+            return true;
+        }
+    }
+
+
+    static class Sub {
+        ExecuteTest et = new ExecuteTest();
+        Future<?> future = null;
+    }
+
+}
