From 37b7d29aa5b61127a794d356eaa3db87c9348a69 Mon Sep 17 00:00:00 2001 From: Jim Hahn Date: Thu, 21 Jun 2018 15:43:32 -0400 Subject: 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 --- .../onap/policy/common/im/AllSeemsWellTest.java | 54 +++++++++---- .../policy/common/im/IntegrityMonitorTest.java | 72 ++++++++++-------- .../policy/common/im/IntegrityMonitorTestBase.java | 88 ++++++++++++++++------ .../org/onap/policy/common/im/MonitorTimeTest.java | 40 ++++++++++ 4 files changed, 184 insertions(+), 70 deletions(-) create mode 100644 integrity-monitor/src/test/java/org/onap/policy/common/im/MonitorTimeTest.java (limited to 'integrity-monitor/src/test/java') 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 806c404c..8aec2f0b 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 @@ package org.onap.policy.common.im; 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 @@ public class AllSeemsWellTest extends IntegrityMonitorTestBase { 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 @@ public class AllSeemsWellTest extends IntegrityMonitorTestBase { super.tearDownTest(); } - // Ignore @Test public void testAllSeemsWell() throws Exception { logger.debug("\nIntegrityMonitorTest: Entering testAllSeemsWell\n\n"); @@ -84,22 +105,15 @@ public class AllSeemsWellTest extends IntegrityMonitorTestBase { 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 @@ public class AllSeemsWellTest extends IntegrityMonitorTestBase { "'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 @@ public class AllSeemsWellTest extends IntegrityMonitorTestBase { "'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 @@ public class AllSeemsWellTest extends IntegrityMonitorTestBase { 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 091dcc91..f7ffa217 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.IntegrityMonitor.Factory; 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 @@ import org.slf4j.LoggerFactory; */ 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 @@ public class IntegrityMonitorTest extends IntegrityMonitorTestBase { 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 @@ public class IntegrityMonitorTest extends IntegrityMonitorTestBase { // 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 @@ public class IntegrityMonitorTest extends IntegrityMonitorTestBase { 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 @@ public class IntegrityMonitorTest extends IntegrityMonitorTestBase { 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 @@ public class IntegrityMonitorTest extends IntegrityMonitorTestBase { final IntegrityMonitor im = makeMonitor(resourceName, myProp); - waitStep(); + waitCycles(1); // the state here is unlocked, enabled, null, null StateManagementEntity sme = null; @@ -651,10 +667,11 @@ public class IntegrityMonitorTest extends IntegrityMonitorTestBase { 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 @@ public class IntegrityMonitorTest extends IntegrityMonitorTestBase { 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 @@ public class IntegrityMonitorTest extends IntegrityMonitorTestBase { 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 @@ public class IntegrityMonitorTest extends IntegrityMonitorTestBase { // 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 @@ public class IntegrityMonitorTest extends IntegrityMonitorTestBase { 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 class IntegrityMonitorTest extends IntegrityMonitorTestBase { 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 e5562306..adde768e 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 java.util.concurrent.TimeUnit; 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 @@ import org.slf4j.LoggerFactory; */ 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 @@ public class IntegrityMonitorTestBase { 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 @@ public class IntegrityMonitorTestBase { * 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 @@ public class IntegrityMonitorTestBase { 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 @@ public class IntegrityMonitorTestBase { 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 @@ public class IntegrityMonitorTestBase { 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 @@ public class IntegrityMonitorTestBase { 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(); @@ -216,6 +232,13 @@ public class IntegrityMonitorTestBase { stopMonitor(); } + /** + * @return the original integrity monitor factory + */ + static Factory getSavedFactory() { + return savedFactory; + } + /** * Stops the IntegrityMonitor instance. */ @@ -227,6 +250,13 @@ public class IntegrityMonitorTestBase { // 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 @@ public class IntegrityMonitorTestBase { } /** - * 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 @@ public class IntegrityMonitorTestBase { 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 { 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 00000000..5f20a831 --- /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()); + } + +} -- cgit 1.2.3-korg