IntegrityMonitor: remove sleep from junit tests

Modified the code to use a CurrentTime object for its "time"
operations (e.g., sleep(), currentTimeInMillis()).  Modified
junit tests to replace the CurrentTime object with TestTime
objects so they don't actually do any sleeping.
Update license date.
Remove unneeded dependency from pom.
Don't start FpManager thread within its own constructor.
toMillis() should handle -1 as an input.
Fix comment in test base superclass.
Change time units in test base from DAYS to MILLISECONDS.

Change-Id: Id6a4edb1747ca1a683e5d37522872b781294532d
Issue-ID: POLICY-908
Signed-off-by: Jim Hahn <jrh3@att.com>
diff --git a/integrity-monitor/pom.xml b/integrity-monitor/pom.xml
index 5ec1f5e..9a25c00 100644
--- a/integrity-monitor/pom.xml
+++ b/integrity-monitor/pom.xml
@@ -34,9 +34,19 @@
 	</parent>
 
 	<name>Integrity Monitor</name>
-
+	
+	<properties>
+        <powermock.version>1.6.6</powermock.version>
+    </properties>
+	
 	<dependencies>
 		<dependency>
+            <groupId>org.powermock</groupId>
+            <artifactId>powermock-api-mockito</artifactId>
+            <version>${powermock.version}</version>
+            <scope>test</scope>
+        </dependency>
+		<dependency>
 			<groupId>junit</groupId>
 			<artifactId>junit</artifactId>
 			<scope>test</scope>
diff --git a/integrity-monitor/src/main/java/org/onap/policy/common/im/IntegrityMonitor.java b/integrity-monitor/src/main/java/org/onap/policy/common/im/IntegrityMonitor.java
index 38dc20d..eee7705 100644
--- a/integrity-monitor/src/main/java/org/onap/policy/common/im/IntegrityMonitor.java
+++ b/integrity-monitor/src/main/java/org/onap/policy/common/im/IntegrityMonitor.java
@@ -29,7 +29,6 @@
 import java.util.Map;
 import java.util.Map.Entry;
 import java.util.Properties;
-import java.util.concurrent.TimeUnit;
 import javax.management.JMX;
 import javax.management.MBeanServerConnection;
 import javax.persistence.EntityManager;
@@ -58,6 +57,9 @@
 
     // only allow one instance of IntegrityMonitor
     private static IntegrityMonitor instance = null;
+    
+    // may be changed by junit tests
+    private static Factory factory = new Factory();
 
     private static String resourceName = null;
     boolean alarmExists = false;
@@ -75,16 +77,7 @@
     // Persistence Unit for JPA
     public static final String PERSISTENCE_UNIT = "operationalPU";
 
-    private static String persistenceUnit = PERSISTENCE_UNIT;
-
-    private static final long CYCLE_INTERVAL_MILLIS = 1000L;
-
-    private static long cycleIntervalMillis = CYCLE_INTERVAL_MILLIS;
-
-    /**
-     * Units used for intervals extracted from the properties, which are typically given in seconds.
-     */
-    private static TimeUnit propertyUnits = TimeUnit.SECONDS;
+    public static final long CYCLE_INTERVAL_MILLIS = 1000L;
 
     private StateManagement stateManager = null;
 
@@ -107,11 +100,11 @@
     // last dependency health check time. Initialize so that the periodic check
     // starts after 60 seconds.
     // This allows time for dependents to come up.
-    private long lastDependencyCheckTime = System.currentTimeMillis();
+    private long lastDependencyCheckTime = MonitorTime.getInstance().getMillis();
 
     // Time of the last state audit. It is initialized at the time of the IM
     // construction
-    private Date lastStateAuditTime = new Date();
+    private Date lastStateAuditTime = MonitorTime.getInstance().getDate();
 
     // Interval between state audits in ms. We leave it turned off by default so
     // that it will only
@@ -124,17 +117,17 @@
     private int missedCycles = 0;
 
     // forward progress monitoring interval
-    private static long monitorIntervalMs = 1000L * IntegrityMonitorProperties.DEFAULT_MONITOR_INTERVAL;
+    private static long monitorIntervalMs = toMillis(IntegrityMonitorProperties.DEFAULT_MONITOR_INTERVAL);
     // The number of periods the counter fails to increment before an alarm is
     // raised.
     private static int failedCounterThreshold = IntegrityMonitorProperties.DEFAULT_FAILED_COUNTER_THRESHOLD;
     // test transaction interval
-    private static long testTransIntervalMs = 1000L * IntegrityMonitorProperties.DEFAULT_TEST_INTERVAL;
+    private static long testTransIntervalMs = toMillis(IntegrityMonitorProperties.DEFAULT_TEST_INTERVAL);
     // write Fpc to DB interval
-    private static long writeFpcIntervalMs = 1000L * IntegrityMonitorProperties.DEFAULT_WRITE_FPC_INTERVAL;
+    private static long writeFpcIntervalMs = toMillis(IntegrityMonitorProperties.DEFAULT_WRITE_FPC_INTERVAL);
     // check the health of dependencies
     private static long checkDependencyIntervalMs =
-            1000L * IntegrityMonitorProperties.DEFAULT_CHECK_DEPENDENCY_INTERVAL;
+                    toMillis(IntegrityMonitorProperties.DEFAULT_CHECK_DEPENDENCY_INTERVAL);
 
     // A lead subsystem will have dependency groups with resource names in the
     // properties file.
@@ -151,7 +144,7 @@
 
     // this is the max interval allowed without any forward progress
     // counter updates
-    private static long maxFpcUpdateIntervalMs = 1000L * IntegrityMonitorProperties.DEFAULT_MAX_FPC_UPDATE_INTERVAL;
+    private static long maxFpcUpdateIntervalMs = toMillis(IntegrityMonitorProperties.DEFAULT_MAX_FPC_UPDATE_INTERVAL);
 
     // Node types
     private enum NodeType {
@@ -192,23 +185,6 @@
      */
     protected IntegrityMonitor(String resourceName, Properties properties) throws IntegrityMonitorException {
 
-        this(resourceName, properties, new Factory());
-    }
-
-    /**
-     * IntegrityMonitor constructor. It is invoked from the getInstance() method in this class or
-     * from the constructor of a child or sub-class. A class can extend the IntegrityMonitor class
-     * if there is a need to override any of the base methods (ex. subsystemTest()). Only one
-     * instance is allowed to be created per resource name.
-     * 
-     * @param resourceName The resource name of the resource
-     * @param properties a set of properties passed in from the resource
-     * @param factory Factory to use to control the FPManager thread
-     * @throws IntegrityMonitorException if any errors are encountered in the constructor
-     */
-    protected IntegrityMonitor(String resourceName, Properties properties, Factory factory)
-            throws IntegrityMonitorException {
-
         // singleton check since this constructor can be called from a child or
         // sub-class
         if (instance != null) {
@@ -232,12 +208,12 @@
         //
         // Create the entity manager factory
         //
-        emf = Persistence.createEntityManagerFactory(persistenceUnit, properties);
+        emf = Persistence.createEntityManagerFactory(factory.getPersistenceUnit(), properties);
         //
         // Did it get created?
         //
         if (emf == null) {
-            logger.error("Error creating IM entity manager factory with persistence unit: {}", persistenceUnit);
+            logger.error("Error creating IM entity manager factory with persistence unit: {}", factory.getPersistenceUnit());
             throw new IntegrityMonitorException("Unable to create IM Entity Manager Factory");
         }
 
@@ -298,7 +274,7 @@
                     logger.debug("Resource {} exists and will be updated - old url= {}, createdDate={}", resourceName,
                             rrx.getResourceUrl(), rrx.getCreatedDate());
                 }
-                rrx.setLastUpdated(new Date());
+                rrx.setLastUpdated(MonitorTime.getInstance().getDate());
             } else {
                 // register resource by adding entry to table in DB
                 logger.debug("Adding resource {} to ResourceRegistration table", resourceName);
@@ -353,7 +329,7 @@
             logger.error("ComponentAdmin constructor exception: {}", e.toString(), e);
         }
 
-        fpManager = new FpManager(factory);
+        fpManager = new FpManager();
         fpManager.start();
 
     }
@@ -370,22 +346,6 @@
      */
     public static IntegrityMonitor getInstance(String resourceName, Properties properties)
             throws IntegrityMonitorException {
-        return getInstance(resourceName, properties, new Factory());
-    }
-
-    /**
-     * Get an instance of IntegrityMonitor for a given resource name. It creates one if it does not
-     * exist. Only one instance is allowed to be created per resource name.
-     * 
-     * @param resourceName The resource name of the resource
-     * @param properties a set of properties passed in from the resource
-     * @param factory Factory to use to control the FPManager thread
-     * @return The new instance of IntegrityMonitor
-     * @throws IntegrityMonitorException if unable to create jmx url or the constructor returns an
-     *         exception
-     */
-    protected static IntegrityMonitor getInstance(String resourceName, Properties properties,
-                    Factory factory) throws IntegrityMonitorException {
 
         synchronized (getInstanceLock) {
             logger.debug("getInstance() called - resourceName= {}", resourceName);
@@ -396,7 +356,7 @@
 
             if (instance == null) {
                 logger.debug("Creating new instance of IntegrityMonitor");
-                instance = new IntegrityMonitor(resourceName, properties, factory);
+                instance = new IntegrityMonitor(resourceName, properties);
             }
             return instance;
         }
@@ -628,7 +588,7 @@
         // verify that the ForwardProgress is current (check last_updated)
         if (errorMsg == null) {
             if (forwardProgressEntity != null && stateManagementEntity != null) {
-                Date date = new Date();
+                Date date = MonitorTime.getInstance().getDate();
                 long diffMs = date.getTime() - forwardProgressEntity.getLastUpdated().getTime();
                 logger.debug("IntegrityMonitor.stateCheck(): diffMs = {}", diffMs);
 
@@ -719,7 +679,7 @@
                     logger.debug("Dependent resource {} - fpc= {}, lastUpdated={}", dep, fpx.getFpcCount(),
                             fpx.getLastUpdated());
                 }
-                long currTime = System.currentTimeMillis();
+                long currTime = MonitorTime.getInstance().getMillis();
                 // if dependent resource FPC has not been updated, consider it
                 // an error
                 if ((currTime - fpx.getLastUpdated().getTime()) > maxFpcUpdateIntervalMs) {
@@ -1049,7 +1009,7 @@
             }
 
             dependencyCheckErrorMsg = errorMsg;
-            lastDependencyCheckTime = System.currentTimeMillis();
+            lastDependencyCheckTime = MonitorTime.getInstance().getMillis();
             logger.debug("dependencyCheck: exit");
             return errorMsg;
         }
@@ -1413,7 +1373,7 @@
                 return; // monitoring is disabled
             }
 
-            elapsedTime = elapsedTime + cycleIntervalMillis;
+            elapsedTime = elapsedTime + CYCLE_INTERVAL_MILLIS;
             if (elapsedTime < monitorIntervalMs) {
                 return; // monitoring interval not reached
             }
@@ -1487,7 +1447,7 @@
             }
         }
 
-        Date date = new Date();
+        Date date = MonitorTime.getInstance().getDate();
         long timeSinceLastStateAudit = date.getTime() - lastStateAuditTime.getTime();
         if (timeSinceLastStateAudit < stateAuditIntervalMs) {
             logger.debug("IntegrityMonitor.stateAudit(): Not time to run. returning");
@@ -1506,7 +1466,7 @@
      */
     public void executeStateAudit() {
         logger.debug("IntegrityMonitor.executeStateAudit(): entry");
-        Date date = new Date();
+        Date date = MonitorTime.getInstance().getDate();
 
         // Get all entries in the forwardprogressentity table
         List<ForwardProgressEntity> fpList = getAllForwardProgressEntity();
@@ -1610,7 +1570,7 @@
                 return; // test transaction is disabled
             }
 
-            elapsedTestTransTime = elapsedTestTransTime + cycleIntervalMillis;
+            elapsedTestTransTime = elapsedTestTransTime + CYCLE_INTERVAL_MILLIS;
             if (elapsedTestTransTime < testTransIntervalMs) {
                 return; // test transaction interval not reached
             }
@@ -1637,7 +1597,7 @@
                 return; // write Fpc is disabled
             }
 
-            elapsedWriteFpcTime = elapsedWriteFpcTime + cycleIntervalMillis;
+            elapsedWriteFpcTime = elapsedWriteFpcTime + CYCLE_INTERVAL_MILLIS;
             if (elapsedWriteFpcTime < writeFpcIntervalMs) {
                 return; // write Fpc interval not reached
             }
@@ -1664,7 +1624,7 @@
             return; // dependency monitoring is disabled
         }
 
-        long currTime = System.currentTimeMillis();
+        long currTime = MonitorTime.getInstance().getMillis();
         logger.debug("checkDependentHealth currTime - lastDependencyCheckTime = {}",
                 currTime - lastDependencyCheckTime);
         if ((currTime - lastDependencyCheckTime) > checkDependencyIntervalMs) {
@@ -1702,7 +1662,7 @@
         logger.debug("executeRefreshStateAudit(): entry");
         synchronized (refreshStateAuditLock) {
             logger.debug("refreshStateAudit: entry");
-            Date now = new Date();
+            Date now = MonitorTime.getInstance().getDate();
             long nowMs = now.getTime();
             long lastTimeMs = refreshStateAuditLastRunDate.getTime();
             logger.debug("refreshStateAudit: ms since last run = {}", nowMs - lastTimeMs);
@@ -1725,7 +1685,7 @@
                         logger.error("refreshStateAudit: caught unexpected exception from stateManager.unlock(): ", e);
                     }
                 }
-                refreshStateAuditLastRunDate = new Date();
+                refreshStateAuditLastRunDate = MonitorTime.getInstance().getDate();
                 logger.debug("refreshStateAudit: exit");
             }
         }
@@ -1737,15 +1697,13 @@
      * dependencies, does a refresh state audit and runs the stateAudit.
      */
     class FpManager extends Thread {
-        private boolean stopRequested = false;
-
-        private final Factory factory;
+        
+        private volatile boolean stopRequested = false;
 
         // Constructor - start FP manager thread
-        FpManager(Factory factory) {
-            this.factory = factory;
+        FpManager() {
             // set now as the last time the refreshStateAudit ran
-            IntegrityMonitor.this.refreshStateAuditLastRunDate = new Date();
+            IntegrityMonitor.this.refreshStateAuditLastRunDate = MonitorTime.getInstance().getDate();
         }
 
         @Override
@@ -1756,7 +1714,7 @@
                 factory.runStarted();
 
                 while(!stopRequested) {
-                    factory.doSleep(cycleIntervalMillis);
+                    MonitorTime.getInstance().sleep(CYCLE_INTERVAL_MILLIS);
                     
                     IntegrityMonitor.this.runOnce();
                     factory.monitorCompleted();
@@ -1887,7 +1845,7 @@
             logger.debug("allSeemsWell exit");
         }
     }
-
+    
     /**
      * Converts the given value to milliseconds using the current {@link #propertyUnits}.
      * 
@@ -1895,7 +1853,7 @@
      * @return the value, in milliseconds, or -1
      */
     private static long toMillis(long value) {
-        return (value < 0 ? -1 : propertyUnits.toMillis(value));
+        return (value < 0 ? -1 : value * 1000L);
     }
 
     public Map<String, String> getAllSeemsWellMap() {
@@ -1907,7 +1865,7 @@
     }
 
     /**
-     * Used to access various objects. Overridden by junit tests.
+     * Wrapper used to access various objects. Overridden by junit tests.
      */
     public static class Factory {
 
@@ -1922,15 +1880,6 @@
         }
 
         /**
-         * Sleeps for a period of time.
-         * @param sleepMs   amount of time to sleep, in milliseconds
-         * @throws InterruptedException 
-         */
-        public void doSleep(long sleepMs) throws InterruptedException {
-            Thread.sleep(sleepMs);
-        }
-
-        /**
          * Indicates that a monitor activity has completed. This method simply returns.
          * 
          * @throws InterruptedException
@@ -1938,6 +1887,13 @@
         public void monitorCompleted() throws InterruptedException {
             // does nothing
         }
+
+        /**
+         * @return the persistence unit to be used
+         */
+        public String getPersistenceUnit() {
+            return PERSISTENCE_UNIT;
+        }
     }
 
     /*
@@ -1951,28 +1907,4 @@
     public static void setUnitTesting(boolean isUnitTesting) {
         IntegrityMonitor.isUnitTesting = isUnitTesting;
     }
-
-    protected static TimeUnit getPropertyUnits() {
-        return propertyUnits;
-    }
-
-    protected static void setPropertyUnits(TimeUnit propertyUnits) {
-        IntegrityMonitor.propertyUnits = propertyUnits;
-    }
-
-    protected static long getCycleIntervalMillis() {
-        return cycleIntervalMillis;
-    }
-
-    protected static void setCycleIntervalMillis(long cycleIntervalMillis) {
-        IntegrityMonitor.cycleIntervalMillis = cycleIntervalMillis;
-    }
-
-    protected static String getPersistenceUnit() {
-        return persistenceUnit;
-    }
-
-    protected static void setPersistenceUnit(String persistenceUnit) {
-        IntegrityMonitor.persistenceUnit = persistenceUnit;
-    }
 }
diff --git a/integrity-monitor/src/main/java/org/onap/policy/common/im/MonitorTime.java b/integrity-monitor/src/main/java/org/onap/policy/common/im/MonitorTime.java
new file mode 100644
index 0000000..271fa65
--- /dev/null
+++ b/integrity-monitor/src/main/java/org/onap/policy/common/im/MonitorTime.java
@@ -0,0 +1,48 @@
+/*
+ * ============LICENSE_START=======================================================
+ * Integrity Monitor
+ * ================================================================================
+ * Copyright (C) 2018 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * 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.policy.common.im;
+
+import org.onap.policy.common.utils.time.CurrentTime;
+
+/**
+ * "Current" time used by IntegrityMonitor classes.
+ */
+public class MonitorTime {
+
+    /**
+     * Instance to be used. This is overridden by junit tests.
+     */
+    private static CurrentTime instance = new CurrentTime();
+
+    /**
+     * 
+     */
+    private MonitorTime() {
+        super();
+    }
+
+    /**
+     * @return the CurrentTime singleton
+     */
+    public static CurrentTime getInstance() {
+        return instance;
+    }
+}
diff --git a/integrity-monitor/src/main/java/org/onap/policy/common/im/StateManagement.java b/integrity-monitor/src/main/java/org/onap/policy/common/im/StateManagement.java
index dbb278e..20bf9b0 100644
--- a/integrity-monitor/src/main/java/org/onap/policy/common/im/StateManagement.java
+++ b/integrity-monitor/src/main/java/org/onap/policy/common/im/StateManagement.java
@@ -20,16 +20,13 @@
 
 package org.onap.policy.common.im;
 
-import java.util.Date;
 import java.util.List;
 import java.util.Observable;
-
 import javax.persistence.EntityManager;
 import javax.persistence.EntityManagerFactory;
 import javax.persistence.FlushModeType;
 import javax.persistence.LockModeType;
 import javax.persistence.TypedQuery;
-
 import org.onap.policy.common.im.exceptions.EntityRetrievalException;
 import org.onap.policy.common.im.jpa.StateManagementEntity;
 import org.onap.policy.common.utils.jpa.EntityMgrCloser;
@@ -879,7 +876,7 @@
                 final StateManagementEntity stateManagementEntity = resourceList.get(0);
                 // refresh the object from DB in case cached data was returned
                 em.refresh(stateManagementEntity);
-                stateManagementEntity.setModifiedDate(new Date());
+                stateManagementEntity.setModifiedDate(MonitorTime.getInstance().getDate());
                 return stateManagementEntity;
             } else {
                 // not exist - create one
diff --git a/integrity-monitor/src/main/java/org/onap/policy/common/im/jpa/ForwardProgressEntity.java b/integrity-monitor/src/main/java/org/onap/policy/common/im/jpa/ForwardProgressEntity.java
index 24f36c5..f0ea2c0 100644
--- a/integrity-monitor/src/main/java/org/onap/policy/common/im/jpa/ForwardProgressEntity.java
+++ b/integrity-monitor/src/main/java/org/onap/policy/common/im/jpa/ForwardProgressEntity.java
@@ -2,7 +2,7 @@
  * ============LICENSE_START=======================================================
  * Integrity Monitor
  * ================================================================================
- * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
+ * Copyright (C) 2017-2018 AT&T Intellectual Property. All rights reserved.
  * ================================================================================
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -38,6 +38,7 @@
 /*
  * The Entity class to persist a policy object ForwardProgress
  */
+import org.onap.policy.common.im.MonitorTime;
 
 @Entity
 @Table(name = "ForwardProgressEntity")
@@ -77,7 +78,7 @@
      */
     @PrePersist
     public void prePersist() {
-        Date date = new Date();
+        Date date = MonitorTime.getInstance().getDate();
         this.createdDate = date;
         this.lastUpdated = date;
         this.fpcCount = 0;
@@ -85,7 +86,7 @@
 
     @PreUpdate
     public void preUpdate() {
-        this.lastUpdated = new Date();
+        this.lastUpdated = MonitorTime.getInstance().getDate();
     }
 
     /**
diff --git a/integrity-monitor/src/main/java/org/onap/policy/common/im/jpa/ImTestEntity.java b/integrity-monitor/src/main/java/org/onap/policy/common/im/jpa/ImTestEntity.java
index 6fb1446..1822578 100644
--- a/integrity-monitor/src/main/java/org/onap/policy/common/im/jpa/ImTestEntity.java
+++ b/integrity-monitor/src/main/java/org/onap/policy/common/im/jpa/ImTestEntity.java
@@ -35,6 +35,7 @@
 import javax.persistence.Table;
 import javax.persistence.Temporal;
 import javax.persistence.TemporalType;
+import org.onap.policy.common.im.MonitorTime;
 
 @Entity
 @Table(name = "ImTestEntity")
@@ -74,14 +75,14 @@
      */
     @PrePersist
     public void prePersist() {
-        Date date = new Date();
+        Date date = MonitorTime.getInstance().getDate();
         this.createdDate = date;
         this.modifiedDate = date;
     }
 
     @PreUpdate
     public void preUpdate() {
-        this.modifiedDate = new Date();
+        this.modifiedDate = MonitorTime.getInstance().getDate();
     }
 
     /**
diff --git a/integrity-monitor/src/main/java/org/onap/policy/common/im/jpa/ResourceRegistrationEntity.java b/integrity-monitor/src/main/java/org/onap/policy/common/im/jpa/ResourceRegistrationEntity.java
index cfbf020..42e141a 100644
--- a/integrity-monitor/src/main/java/org/onap/policy/common/im/jpa/ResourceRegistrationEntity.java
+++ b/integrity-monitor/src/main/java/org/onap/policy/common/im/jpa/ResourceRegistrationEntity.java
@@ -35,6 +35,7 @@
 import javax.persistence.Table;
 import javax.persistence.Temporal;
 import javax.persistence.TemporalType;
+import org.onap.policy.common.im.MonitorTime;
 /*
  * The Entity class to persist a policy object ResourceRegistration
  */
@@ -86,14 +87,14 @@
      */
     @PrePersist
     public void prePersist() {
-        Date date = new Date();
+        Date date = MonitorTime.getInstance().getDate();
         this.createdDate = date;
         this.lastUpdated = date;
     }
 
     @PreUpdate
     public void preUpdate() {
-        this.lastUpdated = new Date();
+        this.lastUpdated = MonitorTime.getInstance().getDate();
     }
 
     /**
diff --git a/integrity-monitor/src/main/java/org/onap/policy/common/im/jpa/StateManagementEntity.java b/integrity-monitor/src/main/java/org/onap/policy/common/im/jpa/StateManagementEntity.java
index 0e96e55..78b90ab 100644
--- a/integrity-monitor/src/main/java/org/onap/policy/common/im/jpa/StateManagementEntity.java
+++ b/integrity-monitor/src/main/java/org/onap/policy/common/im/jpa/StateManagementEntity.java
@@ -34,6 +34,7 @@
 import javax.persistence.Table;
 import javax.persistence.Temporal;
 import javax.persistence.TemporalType;
+import org.onap.policy.common.im.MonitorTime;
 
 @Entity
 @Table(name = "StateManagementEntity")
@@ -74,13 +75,13 @@
 
     @PrePersist
     public void prePersist() {
-        this.createdDate = new Date();
-        this.modifiedDate = new Date();
+        this.createdDate = MonitorTime.getInstance().getDate();
+        this.modifiedDate = MonitorTime.getInstance().getDate();
     }
 
     @PreUpdate
     public void preUpdate() {
-        this.modifiedDate = new Date();
+        this.modifiedDate = MonitorTime.getInstance().getDate();
     }
 
     public StateManagementEntity() {
diff --git a/integrity-monitor/src/test/java/org/onap/policy/common/im/AllSeemsWellTest.java b/integrity-monitor/src/test/java/org/onap/policy/common/im/AllSeemsWellTest.java
index 806c404..8aec2f0 100644
--- a/integrity-monitor/src/test/java/org/onap/policy/common/im/AllSeemsWellTest.java
+++ b/integrity-monitor/src/test/java/org/onap/policy/common/im/AllSeemsWellTest.java
@@ -22,26 +22,28 @@
 
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertTrue;
-
 import java.util.Map;
 import java.util.Properties;
-
+import java.util.concurrent.Semaphore;
 import org.junit.After;
 import org.junit.AfterClass;
 import org.junit.Before;
 import org.junit.BeforeClass;
 import org.junit.Test;
+import org.onap.policy.common.im.IntegrityMonitor.Factory;
+import org.powermock.reflect.Whitebox;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
 public class AllSeemsWellTest extends IntegrityMonitorTestBase {
     private static Logger logger = LoggerFactory.getLogger(AllSeemsWellTest.class);
 
-    private static final long STATE_CYCLE_MS = 3 * CYCLE_INTERVAL_MS;
-
     private static Properties myProp;
     private static String resourceName;
 
+    private Semaphore monitorSem;
+    private Semaphore junitSem;
+
     /**
      * Set up for test class.
      */
@@ -66,6 +68,26 @@
 
         myProp = makeProperties();
 
+        monitorSem = new Semaphore(0);
+        junitSem = new Semaphore(0);
+        
+        Factory factory = new TestFactory() {
+            @Override
+            public void runStarted() throws InterruptedException {
+                monitorSem.acquire();
+                
+                junitSem.release();
+                monitorSem.acquire();
+            }
+
+            @Override
+            public void monitorCompleted() throws InterruptedException {
+                junitSem.release();
+                monitorSem.acquire();
+            }
+        };
+
+        Whitebox.setInternalState(IntegrityMonitor.class, FACTORY_FIELD, factory);
     }
 
     @After
@@ -73,7 +95,6 @@
         super.tearDownTest();
     }
 
-    // Ignore
     @Test
     public void testAllSeemsWell() throws Exception {
         logger.debug("\nIntegrityMonitorTest: Entering testAllSeemsWell\n\n");
@@ -84,22 +105,15 @@
         myProp.put(IntegrityMonitorProperties.REFRESH_STATE_AUDIT_INTERVAL_MS, "-1");
         myProp.put(IntegrityMonitorProperties.STATE_AUDIT_INTERVAL_MS, "-1");
         myProp.put(IntegrityMonitorProperties.FAILED_COUNTER_THRESHOLD, "1");
-        myProp.put(IntegrityMonitorProperties.FP_MONITOR_INTERVAL, "5");
-        myProp.put(IntegrityMonitorProperties.TEST_TRANS_INTERVAL, "1");
-        myProp.put(IntegrityMonitorProperties.WRITE_FPC_INTERVAL, "1");
 
         IntegrityMonitor.updateProperties(myProp);
-        /*
-         * The monitorInterval is 5 and the failedCounterThreshold is 1 A forward progress will be
-         * stale after 5 seconds.
-         */
 
         IntegrityMonitor im = IntegrityMonitor.getInstance(resourceName, myProp);
 
         StateManagement sm = im.getStateManager();
 
         // Give it time to set the states in the DB
-        Thread.sleep(STATE_CYCLE_MS);
+        waitStateChange();
 
         // Check the state
         logger.debug(
@@ -114,7 +128,7 @@
                 "'AllSeemsWellTest - ALLNOTWELL'");
 
         // Wait for the state to change due to ALLNOTWELL
-        Thread.sleep(STATE_CYCLE_MS);
+        waitStateChange();
         // Check the state
         logger.debug(
                 "\n\ntestAllSeemsWell after ALLNOTWELL: im state \nAdminState = {}\nOpState() = {}\nAvailStatus = "
@@ -137,7 +151,7 @@
                 "'AllSeemsWellTest - ALLSEEMSWELL'");
 
         // Wait for the state to change due to ALLNOTWELL
-        Thread.sleep(STATE_CYCLE_MS);
+        waitStateChange();
         // Check the state
         logger.debug(
                 "\n\ntestAllSeemsWell after ALLSEEMSWELL: im state \nAdminState = {}\nOpState() = {}\nAvailStatus = "
@@ -179,4 +193,14 @@
         logger.debug("\n\ntestAllSeemsWell: Exit\n\n");
     }
 
+    /**
+     * Waits for the state to change.
+     * 
+     * @throws InterruptedException if the thread is interrupted
+     */
+    private void waitStateChange() throws InterruptedException {
+        monitorSem.release();
+        waitSem(junitSem);
+    }
+
 }
diff --git a/integrity-monitor/src/test/java/org/onap/policy/common/im/IntegrityMonitorTest.java b/integrity-monitor/src/test/java/org/onap/policy/common/im/IntegrityMonitorTest.java
index 091dcc9..f7ffa21 100644
--- a/integrity-monitor/src/test/java/org/onap/policy/common/im/IntegrityMonitorTest.java
+++ b/integrity-monitor/src/test/java/org/onap/policy/common/im/IntegrityMonitorTest.java
@@ -21,11 +21,13 @@
 package org.onap.policy.common.im;
 
 import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
 import static org.junit.Assert.fail;
 import java.util.Date;
 import java.util.List;
 import java.util.Properties;
 import java.util.concurrent.Semaphore;
+import java.util.concurrent.TimeUnit;
 import javax.persistence.EntityTransaction;
 import javax.persistence.Query;
 import javax.persistence.TemporalType;
@@ -38,6 +40,7 @@
 import org.onap.policy.common.im.jpa.ForwardProgressEntity;
 import org.onap.policy.common.im.jpa.ResourceRegistrationEntity;
 import org.onap.policy.common.im.jpa.StateManagementEntity;
+import org.powermock.reflect.Whitebox;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -48,6 +51,11 @@
  */
 public class IntegrityMonitorTest extends IntegrityMonitorTestBase {
     private static Logger logger = LoggerFactory.getLogger(IntegrityMonitorTest.class);
+    
+    /**
+     * Number of monitor cycles it takes between dependency health checks.
+     */
+    private static final int DEPENDENCY_CHECK_CYCLES = 6;
 
     private static Properties myProp;
     private static EntityTransaction et;
@@ -101,6 +109,11 @@
 
         super.tearDownTest();
     }
+    
+    @Test
+    public void testFactory() {
+        assertNotNull(getSavedFactory());
+    }
 
     /*
      * The following test verifies the following test cases: New Install New Install - Bad
@@ -164,8 +177,11 @@
         // commit transaction
         et.commit();
 
-        // wait for the FPManager to check dependency health
-        waitStep();
+        /*
+         * wait for FPManager to perform dependency health check. Once that's done, it
+         * should now be stale and the sanity check should fail
+         */
+        waitCycles(DEPENDENCY_CHECK_CYCLES);
 
         assertException(im, imx -> {
             imx.evaluateSanity();
@@ -271,7 +287,7 @@
                 im.getStateManager().getAdminState(), im.getStateManager().getOpState(),
                 im.getStateManager().getAvailStatus(), im.getStateManager().getStandbyStatus());
 
-        waitStep();
+        waitCycles(1);
 
         // test evaluate sanity
         assertNoException(im, imx -> {
@@ -465,7 +481,7 @@
 
         final IntegrityMonitor im = makeMonitor(resourceName, myProp);
 
-        waitStep();
+        waitCycles(1);
 
         // Add a group1 dependent resources to put an entry in the forward
         // progress table
@@ -524,7 +540,7 @@
 
         final IntegrityMonitor im = makeMonitor(resourceName, myProp);
 
-        waitStep();
+        waitCycles(1);
 
         // the state here is unlocked, enabled, null, null
         StateManagementEntity sme = null;
@@ -651,10 +667,11 @@
             imx.evaluateSanity();
         });
 
-        // wait for FPManager to perform dependency health check. Once that's
-        // done,
-        // it should now be stale and the sanity check should fail
-        waitStep();
+        /*
+         * wait for FPManager to perform dependency health check. Once that's done, it
+         * should now be stale and the sanity check should fail
+         */
+        waitCycles(DEPENDENCY_CHECK_CYCLES);
 
         assertException(im, imx -> {
             imx.evaluateSanity();
@@ -683,7 +700,7 @@
         myProp.put(IntegrityMonitorProperties.WRITE_FPC_INTERVAL, "-1");
 
         final IntegrityMonitor im = makeMonitor(resourceName, myProp);
-        waitStep();
+        waitCycles(1);
 
         logger.debug("\nIntegrityMonitorTest: Creating ForwardProgressEntity entries\n\n");
         // Add resource entries in the forward progress table
@@ -739,7 +756,7 @@
         myProp.put(IntegrityMonitorProperties.MAX_FPC_UPDATE_INTERVAL, "120");
 
         final IntegrityMonitor im = makeMonitor(resourceName, myProp);
-        waitStep();
+        waitCycles(1);
 
         logger.debug("\nIntegrityMonitorTest: Creating ForwardProgressEntity entries\n\n");
         // Add resources to put an entry in the forward progress table
@@ -860,9 +877,9 @@
 
         // Give it a chance to write the DB and run the audit
         logger.debug("IntegrityMonitorTest:testStateAudit: (restart4) Running State Audit");
-        waitStep();
+        waitCycles(1);
         im.executeStateAudit();
-        waitStep();
+        waitCycles(1);
         logger.debug("IntegrityMonitorTest:testStateAudit: (restart4) State Audit complete");
 
         // Now check its state
@@ -900,16 +917,7 @@
         monitorSem = new Semaphore(0);
         junitSem = new Semaphore(0);
         
-        Factory factory = new IntegrityMonitor.Factory() {
-
-            @Override
-            public void doSleep(long sleepMs) throws InterruptedException {
-                /*
-                 * No need to sleep, as the thread won't progress until the
-                 * semaphore is released.
-                 */
-            }
-
+        Factory factory = new TestFactory() {
             @Override
             public void runStarted() throws InterruptedException {
                 monitorSem.acquire();
@@ -922,25 +930,27 @@
             public void monitorCompleted() throws InterruptedException {
                 junitSem.release();
                 monitorSem.acquire();
-            }
-            
+            }            
         };
+        
+        Whitebox.setInternalState(IntegrityMonitor.class, FACTORY_FIELD, factory);
 
-        IntegrityMonitor im = IntegrityMonitor.getInstance(resourceName, myProp, factory);
+        IntegrityMonitor im = IntegrityMonitor.getInstance(resourceName, myProp);
 
         // wait for the monitor thread to start
-        waitStep();
+        waitCycles(1);
 
         return im;
     }
 
     /**
-     * Waits for the FPManager to complete another cycle.
+     * Waits for several monitor cycles to complete.
+     * @param ncycles number of cycles to wait
      * 
      * @throws InterruptedException if the thread is interrupted
      */
-    private void waitStep() throws InterruptedException {
-        monitorSem.release();
-        waitSem(junitSem);
+    private void waitCycles(int ncycles) throws InterruptedException {
+        monitorSem.release(ncycles);
+        junitSem.tryAcquire(ncycles, WAIT_MS, TimeUnit.MILLISECONDS);
     }
 }
diff --git a/integrity-monitor/src/test/java/org/onap/policy/common/im/IntegrityMonitorTestBase.java b/integrity-monitor/src/test/java/org/onap/policy/common/im/IntegrityMonitorTestBase.java
index e556230..adde768 100644
--- a/integrity-monitor/src/test/java/org/onap/policy/common/im/IntegrityMonitorTestBase.java
+++ b/integrity-monitor/src/test/java/org/onap/policy/common/im/IntegrityMonitorTestBase.java
@@ -30,8 +30,12 @@
 import javax.persistence.EntityManager;
 import javax.persistence.EntityManagerFactory;
 import javax.persistence.Persistence;
+import org.onap.policy.common.im.IntegrityMonitor.Factory;
 import org.onap.policy.common.utils.jpa.EntityTransCloser;
 import org.onap.policy.common.utils.test.log.logback.ExtractAppender;
+import org.onap.policy.common.utils.time.CurrentTime;
+import org.onap.policy.common.utils.time.TestTime;
+import org.powermock.reflect.Whitebox;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -46,6 +50,16 @@
  */
 public class IntegrityMonitorTestBase {
     private static Logger logger = LoggerFactory.getLogger(IntegrityMonitorTestBase.class);
+    
+    /**
+     * Name of the factory field within the IntegrityMonitor class.
+     */
+    public static final String FACTORY_FIELD = "factory";
+    
+    /**
+     * Name of the instance field within the MonitorTime class.
+     */
+    public static final String TIME_INSTANCE_FIELD = "instance";
 
     /**
      * Directory containing the slf4j log files.
@@ -60,9 +74,9 @@
     protected static final long WAIT_MS = 5000L;
 
     /**
-     * Milliseconds that monitor should sleep between cycles.
+     * Milliseconds between state refreshes.
      */
-    protected static final long CYCLE_INTERVAL_MS = 2L;
+    protected static final long REFRESH_INTERVAL_MS = 3L * IntegrityMonitor.CYCLE_INTERVAL_MILLIS;
 
     public static final String DEFAULT_DB_URL_PREFIX = "jdbc:h2:mem:";
 
@@ -94,6 +108,11 @@
      * Entity manager factory pointing to the in-memory DB associated with emf.
      */
     protected static EntityManager em;
+    
+    /**
+     * Test time used by tests in lieu of CurrentTime.
+     */
+    private static TestTime testTime;
 
     /**
      * Saved JMX port from system properties, to be restored once all tests complete.
@@ -101,19 +120,15 @@
     private static Object savedJmxPort;
 
     /**
-     * Saved IM persistence unit, to be restored once all tests complete.
+     * Saved factory, to be restored once all tests complete.
      */
-    private static String savedPU;
+    private static Factory savedFactory;
 
     /**
-     * Saved monitor cycle interval, to be restored once all tests complete.
+     * Saved time accessor, to be restored once all tests complete.
      */
-    private static long savedCycleIntervalMillis;
+    private static CurrentTime savedTime;
 
-    /**
-     * Saved property time units, to be restored once all tests complete.
-     */
-    private static TimeUnit savedPropertyUnits;
 
     /**
      * Saves current configuration information and then sets new values.
@@ -136,19 +151,19 @@
         IntegrityMonitorTestBase.dbUrl = dbUrl;
 
         // save data that we have to restore at the end of the test
+        savedFactory = Whitebox.getInternalState(IntegrityMonitor.class, FACTORY_FIELD);
         savedJmxPort = systemProps.get(JMX_PORT_PROP);
-        savedPU = IntegrityMonitor.getPersistenceUnit();
-        savedCycleIntervalMillis = IntegrityMonitor.getCycleIntervalMillis();
-        savedPropertyUnits = IntegrityMonitor.getPropertyUnits();
+        savedTime = MonitorTime.getInstance();
 
         systemProps.put(JMX_PORT_PROP, "9797");
 
-        IntegrityMonitor.setPersistenceUnit(PERSISTENCE_UNIT);
-        IntegrityMonitor.setCycleIntervalMillis(CYCLE_INTERVAL_MS);
-        IntegrityMonitor.setPropertyUnits(TimeUnit.MILLISECONDS);
+        Whitebox.setInternalState(IntegrityMonitor.class, FACTORY_FIELD, new TestFactory());
 
         IntegrityMonitor.setUnitTesting(true);
-
+        
+        testTime = new TestTime();
+        Whitebox.setInternalState(MonitorTime.class, TIME_INSTANCE_FIELD, testTime);
+        
         properties = new Properties();
         properties.put(IntegrityMonitorProperties.DB_DRIVER, dbDriver);
         properties.put(IntegrityMonitorProperties.DB_URL, dbUrl);
@@ -157,7 +172,7 @@
         properties.put(IntegrityMonitorProperties.SITE_NAME, siteName);
         properties.put(IntegrityMonitorProperties.NODE_TYPE, nodeType);
         properties.put(IntegrityMonitorProperties.REFRESH_STATE_AUDIT_INTERVAL_MS,
-                String.valueOf(100L * CYCLE_INTERVAL_MS));
+                String.valueOf(REFRESH_INTERVAL_MS));
 
         emf = Persistence.createEntityManagerFactory(PERSISTENCE_UNIT, makeProperties());
 
@@ -180,12 +195,13 @@
             systemProps.put(JMX_PORT_PROP, savedJmxPort);
         }
 
-        IntegrityMonitor.setPersistenceUnit(savedPU);
-        IntegrityMonitor.setCycleIntervalMillis(savedCycleIntervalMillis);
-        IntegrityMonitor.setPropertyUnits(savedPropertyUnits);
+        Whitebox.setInternalState(MonitorTime.class, TIME_INSTANCE_FIELD, savedTime);
+        Whitebox.setInternalState(IntegrityMonitor.class, FACTORY_FIELD, savedFactory);
 
         IntegrityMonitor.setUnitTesting(false);
 
+        stopMonitor();
+
         // this should result in the in-memory DB being deleted
         em.close();
         emf.close();
@@ -217,6 +233,13 @@
     }
 
     /**
+     * @return the original integrity monitor factory
+     */
+    static Factory getSavedFactory() {
+        return savedFactory;
+    }
+
+    /**
      * Stops the IntegrityMonitor instance.
      */
     private static void stopMonitor() {
@@ -227,6 +250,13 @@
             // no need to log, as exception was already logged
         }
     }
+    
+    /**
+     * @return the "current" time, in milliseconds
+     */
+    protected static long getCurrentTestTime() {
+        return testTime.getMillis();
+    }
 
     /**
      * Makes a new Property set that's a clone of {@link #properties}.
@@ -240,11 +270,11 @@
     }
 
     /**
-     * Waits for a semaphore to be acquired
+     * Waits for a semaphore to be acquired.
      * 
-     * @param sem the latch
+     * @param sem
      * @throws InterruptedException if the thread is interrupted
-     * @throws AssertionError if the latch did not reach zero in the allotted time
+     * @throws AssertionError if the semaphore was not acquired within the allotted time
      */
     protected void waitSem(Semaphore sem) throws InterruptedException {
         assertTrue(sem.tryAcquire(WAIT_MS, TimeUnit.MILLISECONDS));
@@ -284,6 +314,16 @@
             System.out.println("action found expected exception: " + e);
         }
     }
+    
+    /**
+     * Factory with overrides for junit testing.
+     */
+    public static class TestFactory extends Factory {
+        @Override
+        public String getPersistenceUnit() {
+            return PERSISTENCE_UNIT;
+        }
+    }
 
     @FunctionalInterface
     protected static interface VoidFunction<T> {
diff --git a/integrity-monitor/src/test/java/org/onap/policy/common/im/MonitorTimeTest.java b/integrity-monitor/src/test/java/org/onap/policy/common/im/MonitorTimeTest.java
new file mode 100644
index 0000000..5f20a83
--- /dev/null
+++ b/integrity-monitor/src/test/java/org/onap/policy/common/im/MonitorTimeTest.java
@@ -0,0 +1,40 @@
+/*
+ * ============LICENSE_START=======================================================
+ * Integrity Monitor
+ * ================================================================================
+ * Copyright (C) 2018 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * 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.policy.common.im;
+
+import static org.junit.Assert.*;
+import org.junit.Test;
+import org.onap.policy.common.utils.time.CurrentTime;
+
+/**
+ * 
+ */
+public class MonitorTimeTest {
+
+    @Test
+    public void testGetInstance() {
+        CurrentTime inst = MonitorTime.getInstance();
+        assertNotNull(inst);
+        
+        assertEquals(inst, MonitorTime.getInstance());
+    }
+
+}