aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--utils-test/pom.xml5
-rw-r--r--utils-test/src/main/java/org/onap/policy/common/utils/time/TestTime.java59
-rw-r--r--utils-test/src/main/java/org/onap/policy/common/utils/time/TestTimeMulti.java200
-rw-r--r--utils-test/src/test/java/org/onap/policy/common/utils/time/TestTimeMultiTest.java116
-rw-r--r--utils-test/src/test/java/org/onap/policy/common/utils/time/TestTimeTest.java66
-rw-r--r--utils/pom.xml5
-rw-r--r--utils/src/main/java/org/onap/policy/common/utils/properties/PropertyConfiguration.java61
-rw-r--r--utils/src/main/java/org/onap/policy/common/utils/properties/SpecProperties.java117
-rw-r--r--utils/src/main/java/org/onap/policy/common/utils/time/CurrentTime.java61
-rw-r--r--utils/src/test/java/org/onap/policy/common/utils/properties/PropertyConfigurationTest.java568
-rw-r--r--utils/src/test/java/org/onap/policy/common/utils/properties/SpecPropertiesTest.java224
-rw-r--r--utils/src/test/java/org/onap/policy/common/utils/properties/SpecPropertyConfigurationTest.java80
-rw-r--r--utils/src/test/java/org/onap/policy/common/utils/time/CurrentTimeTest.java59
13 files changed, 1441 insertions, 180 deletions
diff --git a/utils-test/pom.xml b/utils-test/pom.xml
index a7c2eaee..933104b0 100644
--- a/utils-test/pom.xml
+++ b/utils-test/pom.xml
@@ -42,6 +42,11 @@
<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId>
</dependency>
+ <dependency>
+ <groupId>org.onap.policy.common</groupId>
+ <artifactId>utils</artifactId>
+ <version>${project.version}</version>
+ </dependency>
</dependencies>
<build>
diff --git a/utils-test/src/main/java/org/onap/policy/common/utils/time/TestTime.java b/utils-test/src/main/java/org/onap/policy/common/utils/time/TestTime.java
new file mode 100644
index 00000000..3dfed4bd
--- /dev/null
+++ b/utils-test/src/main/java/org/onap/policy/common/utils/time/TestTime.java
@@ -0,0 +1,59 @@
+/*
+ * ============LICENSE_START=======================================================
+ * Common Utils-Test
+ * ================================================================================
+ * 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.utils.time;
+
+import java.util.Date;
+import java.util.concurrent.atomic.AtomicLong;
+
+/**
+ * "Current" time, when running junit tests. This is intended to be injected into classes
+ * under test, to replace their {@link CurrentTime} objects. When {@link #sleep(long)} is
+ * invoked, it simply advances the notion of "current" time and returns immediately.
+ */
+public class TestTime extends CurrentTime {
+
+ /**
+ * "Current" time, in milliseconds, used by tests.
+ */
+ private AtomicLong tcur = new AtomicLong(System.currentTimeMillis());
+
+ /**
+ *
+ */
+ public TestTime() {
+ super();
+ }
+
+ @Override
+ public long getMillis() {
+ return tcur.get();
+ }
+
+ @Override
+ public Date getDate() {
+ return new Date(tcur.get());
+ }
+
+ @Override
+ public void sleep(long sleepMs) throws InterruptedException {
+ tcur.addAndGet(sleepMs);
+ }
+}
diff --git a/utils-test/src/main/java/org/onap/policy/common/utils/time/TestTimeMulti.java b/utils-test/src/main/java/org/onap/policy/common/utils/time/TestTimeMulti.java
new file mode 100644
index 00000000..7a8277c7
--- /dev/null
+++ b/utils-test/src/main/java/org/onap/policy/common/utils/time/TestTimeMulti.java
@@ -0,0 +1,200 @@
+/*
+ * ============LICENSE_START=======================================================
+ * Common Utils-Test
+ * ================================================================================
+ * 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.utils.time;
+
+import java.util.Date;
+import java.util.PriorityQueue;
+import java.util.concurrent.CountDownLatch;
+
+/**
+ * "Current" time, when running junit tests in multiple threads. This is intended to be
+ * injected into classes under test, to replace their {@link CurrentTime} objects. The
+ * {@link #sleep(long)} method blocks until all threads enter and then it moves the notion
+ * of "current" time forward, allowing threads to resume, as the end of their sleep time
+ * is reached. Additional threads do not resume until all threads have once again entered
+ * {@link #sleep(long)} or when {@link #threadCompleted()} is invoked to indicate that a
+ * thread will not re-enter {@link #sleep(long)}.
+ */
+public class TestTimeMulti extends CurrentTime {
+
+ /**
+ * Number of threads that will be sleeping simultaneously.
+ */
+ private int nthreads;
+
+ /**
+ * "Current" time, in milliseconds, used by tests.
+ */
+ private long tcur = System.currentTimeMillis();
+
+ /**
+ * Queue of sleeping threads waiting to be awakened.
+ */
+ private final PriorityQueue<Info> queue = new PriorityQueue<>();
+
+ /**
+ * Used to synchronize updates.
+ */
+ private final Object locker = new Object();
+
+ /**
+ *
+ * @param nthreads number of threads that will be sleeping simultaneously
+ */
+ public TestTimeMulti(int nthreads) {
+ this.nthreads = nthreads;
+ }
+
+ @Override
+ public long getMillis() {
+ return tcur;
+ }
+
+ @Override
+ public Date getDate() {
+ return new Date(tcur);
+ }
+
+ @Override
+ public void sleep(long sleepMs) throws InterruptedException {
+ if (sleepMs <= 0) {
+ return;
+ }
+
+ Info info = new Info(tcur + sleepMs);
+
+ synchronized (locker) {
+ queue.add(info);
+
+ if (queue.size() == nthreads) {
+ // all threads are now sleeping - wake one up
+ wakeThreads();
+ }
+ }
+
+ // this MUST happen outside of the "synchronized" block
+ info.await();
+ }
+
+ /**
+ * Indicates that a thread has terminated or that it will no longer be invoking
+ * {@link #sleep(long)}. Awakens the next sleeping thread, if the queue is full after
+ * removing the terminated thread.
+ *
+ * @throws IllegalStateException if the queue is already full
+ */
+ public void threadCompleted() {
+ synchronized (locker) {
+ int sz = queue.size();
+ if (sz >= nthreads) {
+ throw new IllegalStateException("too many threads still sleeping");
+ }
+
+ --nthreads;
+
+ if (sz == nthreads) {
+ // after removing terminated thread - queue is now full; awaken something
+ wakeThreads();
+ }
+ }
+ }
+
+ /**
+ * Advances the "current" time and awakens any threads sleeping until that time.
+ */
+ private void wakeThreads() {
+ Info info = queue.poll();
+ if(info == null) {
+ return;
+ }
+
+ tcur = info.getAwakenAtMs();
+ info.wake();
+
+ while ((info = queue.poll()) != null) {
+ if (tcur == info.getAwakenAtMs()) {
+ info.wake();
+
+ } else {
+ // not ready to wake this thread - put it back in the queue
+ queue.add(info);
+ break;
+ }
+ }
+ }
+
+ /**
+ * Info about a sleeping thread.
+ */
+ private static class Info implements Comparable<Info> {
+
+ /**
+ * Time, in milliseconds, at which the associated thread should awaken.
+ */
+ private final long awakenAtMs;
+
+ /**
+ * This is triggered when the associated thread should awaken.
+ */
+ private final CountDownLatch latch = new CountDownLatch(1);
+
+ /**
+ * @param awakenAtMs time, in milliseconds, at which the associated thread should
+ * awaken
+ */
+ public Info(long awakenAtMs) {
+ this.awakenAtMs = awakenAtMs;
+ }
+
+ public long getAwakenAtMs() {
+ return awakenAtMs;
+ }
+
+ /**
+ * Awakens the associated thread by decrementing its latch.
+ */
+ public void wake() {
+ latch.countDown();
+ }
+
+ /**
+ * Blocks the current thread until awakened (i.e., until its latch is
+ * decremented).
+ *
+ * @throws InterruptedException
+ */
+ public void await() throws InterruptedException {
+ latch.await();
+ }
+
+ @Override
+ public int compareTo(Info o) {
+ int diff = Long.compare(awakenAtMs, o.awakenAtMs);
+
+ // this assumes that Object.toString() is unique for each Info object
+ if (diff == 0)
+ diff = this.toString().compareTo(o.toString());
+
+ return diff;
+ }
+
+ }
+}
diff --git a/utils-test/src/test/java/org/onap/policy/common/utils/time/TestTimeMultiTest.java b/utils-test/src/test/java/org/onap/policy/common/utils/time/TestTimeMultiTest.java
new file mode 100644
index 00000000..206ab5f1
--- /dev/null
+++ b/utils-test/src/test/java/org/onap/policy/common/utils/time/TestTimeMultiTest.java
@@ -0,0 +1,116 @@
+/*
+ * ============LICENSE_START=======================================================
+ * Common Utils-Test
+ * ================================================================================
+ * 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.utils.time;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.concurrent.Semaphore;
+import java.util.concurrent.TimeUnit;
+import org.junit.Test;
+
+/**
+ *
+ */
+public class TestTimeMultiTest {
+
+ private static final int NTHREADS = 10;
+ private static final int NTIMES = 100;
+ private static final long WAIT_SEC = 5L;
+ private static final long MIN_SLEEP_MS = 5L;
+
+ private TestTimeMulti ttm;
+ private Semaphore done;
+
+ @Test
+ public void test() throws Exception {
+ ttm = new TestTimeMulti(NTHREADS);
+ done = new Semaphore(0);
+
+ long tbeg = ttm.getMillis();
+
+ // create threads
+ List<MyThread> threads = new ArrayList<>(NTHREADS);
+ for (int x = 0; x < NTHREADS; ++x) {
+ threads.add(new MyThread(x + MIN_SLEEP_MS));
+ }
+
+ // launch threads
+ for (MyThread thr : threads) {
+ thr.start();
+ }
+
+ // wait for each one to complete
+ for (MyThread thr : threads) {
+ assertTrue("complete " + thr.getSleepMs(), done.tryAcquire(WAIT_SEC, TimeUnit.SECONDS));
+ ttm.threadCompleted();
+ }
+
+ // check results
+ for (MyThread thr : threads) {
+ assertEquals("time " + thr.getSleepMs(), thr.texpected, thr.tactual);
+ }
+
+ assertTrue(ttm.getMillis() >= tbeg + NTIMES * MIN_SLEEP_MS);
+ }
+
+ private class MyThread extends Thread {
+
+ private final long sleepMs;
+
+ private volatile long texpected;
+ private volatile long tactual;
+
+ public MyThread(long sleepMs) {
+ this.sleepMs = sleepMs;
+
+ this.setDaemon(true);
+ }
+
+ public long getSleepMs() {
+ return sleepMs;
+ }
+
+ @Override
+ public void run() {
+ try {
+ for (int x = 0; x < NTIMES; ++x) {
+ texpected = ttm.getMillis() + sleepMs;
+ ttm.sleep(sleepMs);
+
+ if ((tactual = ttm.getMillis()) != texpected) {
+ break;
+ }
+
+ if ((tactual = ttm.getDate().getTime()) != texpected) {
+ break;
+ }
+ }
+
+ } catch (InterruptedException expected) {
+ Thread.currentThread().interrupt();
+ }
+
+ done.release();
+ }
+ }
+}
diff --git a/utils-test/src/test/java/org/onap/policy/common/utils/time/TestTimeTest.java b/utils-test/src/test/java/org/onap/policy/common/utils/time/TestTimeTest.java
new file mode 100644
index 00000000..c1e15b38
--- /dev/null
+++ b/utils-test/src/test/java/org/onap/policy/common/utils/time/TestTimeTest.java
@@ -0,0 +1,66 @@
+/*
+ * ============LICENSE_START=======================================================
+ * Common Utils-Test
+ * ================================================================================
+ * 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.utils.time;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+import org.junit.Test;
+
+public class TestTimeTest {
+
+ @Test
+ public void test() throws Exception {
+ TestTime tm = new TestTime();
+ TestTime tm2 = new TestTime();
+
+ long treal = System.currentTimeMillis();
+
+ long tcur = tm.getMillis();
+ assertEquals(tcur, tm.getDate().getTime());
+
+ long tsleep = 10000L;
+ long tcur2 = tcur;
+
+ // sleep a bit and then check values
+ tcur2 += tsleep;
+ tm2.sleep(tsleep);
+ assertEquals(tcur2, tm2.getMillis());
+ assertEquals(tcur2, tm2.getDate().getTime());
+
+ // sleep some more and then check values
+ tcur2 += tsleep;
+ tm2.sleep(tsleep);
+ assertEquals(tcur2, tm2.getMillis());
+ assertEquals(tcur2, tm2.getDate().getTime());
+
+ // check again - to ensure unchanged
+ assertEquals(tcur2, tm2.getMillis());
+ assertEquals(tcur2, tm2.getDate().getTime());
+
+ // original should also be unchanged
+ assertEquals(tcur, tm.getMillis());
+ assertEquals(tcur, tm.getDate().getTime());
+
+ // ensure that no real time has elapsed
+ assertTrue(System.currentTimeMillis() < treal + tsleep / 2);
+ }
+
+}
diff --git a/utils/pom.xml b/utils/pom.xml
index cf34bd7c..8375408e 100644
--- a/utils/pom.xml
+++ b/utils/pom.xml
@@ -38,6 +38,11 @@
<dependencies>
<dependency>
+ <groupId>org.apache.commons</groupId>
+ <artifactId>commons-lang3</artifactId>
+ <version>3.4</version>
+ </dependency>
+ <dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<scope>test</scope>
diff --git a/utils/src/main/java/org/onap/policy/common/utils/properties/PropertyConfiguration.java b/utils/src/main/java/org/onap/policy/common/utils/properties/PropertyConfiguration.java
index 7253c746..e72ebaba 100644
--- a/utils/src/main/java/org/onap/policy/common/utils/properties/PropertyConfiguration.java
+++ b/utils/src/main/java/org/onap/policy/common/utils/properties/PropertyConfiguration.java
@@ -25,8 +25,11 @@ import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import java.lang.reflect.Field;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.util.Properties;
+import org.apache.commons.lang3.StringUtils;
import org.onap.policy.common.utils.properties.exception.PropertyAccessException;
import org.onap.policy.common.utils.properties.exception.PropertyException;
import org.onap.policy.common.utils.properties.exception.PropertyInvalidException;
@@ -35,7 +38,9 @@ import org.onap.policy.common.utils.properties.exception.PropertyMissingExceptio
/**
* Configuration whose fields are initialized by reading from a set of {@link Properties},
* as directed by the {@link Property} annotations that appear on fields within the
- * subclass.
+ * subclass. The values of the fields are set via <i>setXxx()</i> methods. As a result, if
+ * a field is annotated and there is no corresponding <i>setXxx()</i> method, then an
+ * exception will be thrown.
* <p>
* It is possible that an invalid <i>defaultValue</i> is specified via the
* {@link Property} annotation. This could remain undetected until an optional property is
@@ -104,7 +109,10 @@ public class PropertyConfiguration {
checkModifiable(field, prop);
- if (setValue(field, props, prop)) {
+ Method setter = getSetter(field, prop);
+ checkSetter(setter, prop);
+
+ if (setValue(setter, field, props, prop)) {
return true;
}
@@ -112,15 +120,33 @@ public class PropertyConfiguration {
}
/**
+ * @param field field whose value is to be set
+ * @param prop property of interest
+ * @return the method to be used to set the field's value
+ * @throws PropertyAccessException if a "set" method cannot be identified
+ */
+ private Method getSetter(Field field, Property prop) throws PropertyAccessException {
+ String nm = "set" + StringUtils.capitalize(field.getName());
+
+ try {
+ return this.getClass().getMethod(nm, field.getType());
+
+ } catch (NoSuchMethodException | SecurityException e) {
+ throw new PropertyAccessException(prop.name(), nm, e);
+ }
+ }
+
+ /**
* Sets a field's value from a particular property.
*
+ * @param setter method to be used to set the field's value
* @param field field whose value is to be set
* @param props properties from which to get the value
* @param prop property of interest
* @return {@code true} if the property's value was set, {@code false} otherwise
* @throws PropertyException if an error occurs
*/
- protected boolean setValue(Field field, Properties props, Property prop) throws PropertyException {
+ protected boolean setValue(Method setter, Field field, Properties props, Property prop) throws PropertyException {
try {
Object val = getValue(field, props, prop);
@@ -128,23 +154,15 @@ public class PropertyConfiguration {
return false;
} else {
-
- /*
- * According to java docs & blogs, "field" is our own copy, so we're free
- * to change the flags without impacting the real permissions of the field
- * within the real class.
- */
- field.setAccessible(true);
-
- field.set(this, val);
+ setter.invoke(this, val);
return true;
}
} catch (IllegalArgumentException e) {
throw new PropertyInvalidException(prop.name(), field.getName(), e);
- } catch (IllegalAccessException e) {
- throw new PropertyAccessException(prop.name(), field.getName(), e);
+ } catch (IllegalAccessException | InvocationTargetException e) {
+ throw new PropertyAccessException(prop.name(), setter.getName(), e);
}
}
@@ -203,6 +221,21 @@ public class PropertyConfiguration {
}
/**
+ * Verifies that the setter method is not <i>static</i>.
+ *
+ * @param setter method to be checked
+ * @param prop property of interest
+ * @throws PropertyAccessException if the method is static
+ */
+ private void checkSetter(Method setter, Property prop) throws PropertyAccessException {
+ int mod = setter.getModifiers();
+
+ if (Modifier.isStatic(mod)) {
+ throw new PropertyAccessException(prop.name(), setter.getName(), "method is 'static'");
+ }
+ }
+
+ /**
* Gets a property value, coercing it to a String.
*
* @param fieldName field whose value is to be set
diff --git a/utils/src/main/java/org/onap/policy/common/utils/properties/SpecProperties.java b/utils/src/main/java/org/onap/policy/common/utils/properties/SpecProperties.java
new file mode 100644
index 00000000..0f416c3a
--- /dev/null
+++ b/utils/src/main/java/org/onap/policy/common/utils/properties/SpecProperties.java
@@ -0,0 +1,117 @@
+/*
+ * ============LICENSE_START=======================================================
+ * ONAP
+ * ================================================================================
+ * 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.utils.properties;
+
+import java.util.Properties;
+
+/**
+ * Properties with an optional specialization (e.g., session name, controller name).
+ */
+public class SpecProperties extends Properties {
+ private static final long serialVersionUID = 1L;
+
+ /**
+ * The property prefix, ending with ".".
+ */
+ private final String prefix;
+
+ /**
+ * The specialized property prefix, ending with ".".
+ */
+ private final String specPrefix;
+
+ /**
+ *
+ * @param prefix the property name prefix that appears before any specialization, may
+ * be ""
+ * @param specialization the property name specialization (e.g., session name)
+ */
+ public SpecProperties(String prefix, String specialization) {
+ this.prefix = withTrailingDot(prefix);
+ this.specPrefix = withTrailingDot(this.prefix + specialization);
+ }
+
+ /**
+ *
+ * @param prefix the property name prefix that appears before any specialization, may
+ * be ""
+ * @param specialization the property name specialization (e.g., session name)
+ * @param props the default properties
+ */
+ public SpecProperties(String prefix, String specialization, Properties props) {
+ super(props);
+
+ this.prefix = withTrailingDot(prefix);
+ this.specPrefix = withTrailingDot(this.prefix + specialization);
+ }
+
+ /**
+ * Adds a trailing "." to a String, if it doesn't already have one.
+ *
+ * @param text text to which the "." should be added
+ * @return the text, with a trailing "."
+ */
+ private static String withTrailingDot(String text) {
+ return text.isEmpty() || text.endsWith(".") ? text : text + ".";
+ }
+
+ /**
+ * Gets the property whose value has the given key, looking first for the specialized
+ * property name, and then for the generalized property name.
+ *
+ * @param key property name, without the specialization
+ * @return the value from the property set, or {@code null} if the property set does
+ * not contain the value
+ */
+ @Override
+ public String getProperty(String key) {
+ if (!key.startsWith(prefix)) {
+ return super.getProperty(key);
+ }
+
+ String suffix = key.substring(prefix.length());
+
+ String val = super.getProperty(specPrefix + suffix);
+ if (val != null) {
+ return val;
+ }
+
+ return super.getProperty(key);
+ }
+
+ protected String getPrefix() {
+ return prefix;
+ }
+
+ protected String getSpecPrefix() {
+ return specPrefix;
+ }
+
+ @Override
+ public final int hashCode() {
+ throw new UnsupportedOperationException("SpecProperties cannot be hashed");
+ }
+
+ @Override
+ public final boolean equals(Object obj) {
+ throw new UnsupportedOperationException("cannot compare SpecProperties");
+ }
+}
diff --git a/utils/src/main/java/org/onap/policy/common/utils/time/CurrentTime.java b/utils/src/main/java/org/onap/policy/common/utils/time/CurrentTime.java
new file mode 100644
index 00000000..cab469e5
--- /dev/null
+++ b/utils/src/main/java/org/onap/policy/common/utils/time/CurrentTime.java
@@ -0,0 +1,61 @@
+/*
+ * ============LICENSE_START=======================================================
+ * Common Utils
+ * ================================================================================
+ * 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.utils.time;
+
+import java.util.Date;
+
+/**
+ * Methods to access the current time. Classes can use objects of this type to get current
+ * time information, while allowing the objects to be overridden by junit tests.
+ */
+public class CurrentTime {
+
+ /**
+ *
+ */
+ public CurrentTime() {
+ super();
+ }
+
+ /**
+ * @return the current time, in milliseconds
+ */
+ public long getMillis() {
+ return System.currentTimeMillis();
+ }
+
+ /**
+ * @return the current Date
+ */
+ public Date getDate() {
+ return new Date();
+ }
+
+ /**
+ * Sleeps for a period of time.
+ *
+ * @param sleepMs amount of time to sleep, in milliseconds
+ * @throws InterruptedException
+ */
+ public void sleep(long sleepMs) throws InterruptedException {
+ Thread.sleep(sleepMs);
+ }
+}
diff --git a/utils/src/test/java/org/onap/policy/common/utils/properties/PropertyConfigurationTest.java b/utils/src/test/java/org/onap/policy/common/utils/properties/PropertyConfigurationTest.java
index cf823b5d..121ae384 100644
--- a/utils/src/test/java/org/onap/policy/common/utils/properties/PropertyConfigurationTest.java
+++ b/utils/src/test/java/org/onap/policy/common/utils/properties/PropertyConfigurationTest.java
@@ -68,15 +68,9 @@ public class PropertyConfigurationTest {
@Test
public void testPropertyConfiguration() throws PropertyException {
- class Config extends PropertyConfiguration {
-
- @Property(name = THE_VALUE)
- private String value;
- };
-
props.setProperty(THE_VALUE, STRING_VALUE);
- Config cfg = new Config();
+ PlainStringConfig cfg = new PlainStringConfig();
assertEquals(null, cfg.value);
cfg.setAllFields(props);
@@ -85,18 +79,8 @@ public class PropertyConfigurationTest {
@Test
public void testPropertyConfigurationProperties() throws PropertyException {
- class Config extends PropertyConfiguration {
-
- @Property(name = THE_VALUE)
- private String value;
-
- public Config(Properties props) throws PropertyException {
- super(props);
- }
- };
-
props.setProperty(THE_VALUE, STRING_VALUE);
- Config cfg = new Config(props);
+ PlainStringConfig cfg = new PlainStringConfig(props);
assertEquals(STRING_VALUE, cfg.value);
}
@@ -111,6 +95,11 @@ public class PropertyConfigurationTest {
@Property(name = "grandparent.value")
protected boolean grandparentValue;
+
+ @SuppressWarnings("unused")
+ public void setGrandparentValue(boolean grandparentValue) {
+ this.grandparentValue = grandparentValue;
+ }
};
/*
@@ -120,12 +109,22 @@ public class PropertyConfigurationTest {
@Property(name = "parent.value")
protected long parentValue;
+
+ @SuppressWarnings("unused")
+ public void setParentValue(long parentValue) {
+ this.parentValue = parentValue;
+ }
};
class Config extends ParentConfig {
@Property(name = THE_VALUE)
private String value;
+
+ @SuppressWarnings("unused")
+ public void setValue(String value) {
+ this.value = value;
+ }
};
@@ -158,6 +157,11 @@ public class PropertyConfigurationTest {
class Config extends PropertyConfiguration {
private String value;
+
+ @SuppressWarnings("unused")
+ public void setValue(String value) {
+ this.value = value;
+ }
};
@@ -171,18 +175,8 @@ public class PropertyConfigurationTest {
@Test
public void testSetValueFieldProperties_FieldSet() throws PropertyException {
- class Config extends PropertyConfiguration {
-
- @Property(name = THE_VALUE)
- private String value;
-
- public Config(Properties props) throws PropertyException {
- super(props);
- }
- };
-
props.setProperty(THE_VALUE, STRING_VALUE);
- Config cfg = new Config(props);
+ PlainStringConfig cfg = new PlainStringConfig(props);
assertEquals(STRING_VALUE, cfg.value);
}
@@ -196,6 +190,11 @@ public class PropertyConfigurationTest {
public Config(Properties props) throws PropertyException {
super(props);
}
+
+ @SuppressWarnings("unused")
+ public void setValue(String value) {
+ this.value = value;
+ }
};
props.setProperty(THE_VALUE, STRING_VALUE);
@@ -215,14 +214,19 @@ public class PropertyConfigurationTest {
public Config(Properties props) throws PropertyException {
super(props);
}
+
+ @SuppressWarnings("unused")
+ public void setValue(Exception value) {
+ this.value = value;
+ }
};
props.setProperty(THE_VALUE, STRING_VALUE);
new Config(props);
}
- @Test(expected = PropertyMissingException.class)
- public void testSetValueFieldPropertyProperties_NoProperty_NoDefault() throws PropertyException {
+ @Test(expected = PropertyAccessException.class)
+ public void testGetSetter_NoSetter() throws PropertyException {
class Config extends PropertyConfiguration {
@Property(name = THE_VALUE)
@@ -233,15 +237,18 @@ public class PropertyConfigurationTest {
}
};
+ props.setProperty(THE_VALUE, STRING_VALUE);
new Config(props);
}
- @Test(expected = PropertyInvalidException.class)
- public void testSetValueFieldPropertyProperties_InvalidValue() throws PropertyException {
- class Config extends PropertyConfiguration {
+ @Test(expected = PropertyMissingException.class)
+ public void testSetValueMethodFieldPropertiesProperty_NoProperty_NoDefault() throws PropertyException {
+ new PlainStringConfig(props);
+ }
- @Property(name = THE_VALUE)
- private int value;
+ @Test(expected = PropertyInvalidException.class)
+ public void testSetValueMethodFieldPropertiesProperty_InvalidValue() throws PropertyException {
+ class Config extends PlainPrimIntConfig {
public Config(Properties props) throws PropertyException {
super(props);
@@ -260,6 +267,24 @@ public class PropertyConfigurationTest {
new Config(props);
}
+ @Test(expected = PropertyAccessException.class)
+ public void testSetValueMethodFieldPropertiesProperty_MethodEx() throws PropertyException {
+ class Config extends PlainStringConfig {
+
+ public Config(Properties props) throws PropertyException {
+ super(props);
+ }
+
+ @Override
+ public void setValue(String value) {
+ throw new IllegalArgumentException("expected exception");
+ }
+ };
+
+ props.setProperty(THE_VALUE, STRING_VALUE);
+ new Config(props);
+ }
+
@Test
public void testGetValue() throws PropertyException {
// this class contains all of the supported field types
@@ -295,6 +320,96 @@ public class PropertyConfigurationTest {
public Config(Properties props) throws PropertyException {
super(props);
}
+
+ @SuppressWarnings("unused")
+ public String getStringValue() {
+ return stringValue;
+ }
+
+ @SuppressWarnings("unused")
+ public void setStringValue(String stringValue) {
+ this.stringValue = stringValue;
+ }
+
+ @SuppressWarnings("unused")
+ public Boolean getBoolTrueValue() {
+ return boolTrueValue;
+ }
+
+ @SuppressWarnings("unused")
+ public void setBoolTrueValue(Boolean boolTrueValue) {
+ this.boolTrueValue = boolTrueValue;
+ }
+
+ @SuppressWarnings("unused")
+ public Boolean getBoolFalseValue() {
+ return boolFalseValue;
+ }
+
+ @SuppressWarnings("unused")
+ public void setBoolFalseValue(Boolean boolFalseValue) {
+ this.boolFalseValue = boolFalseValue;
+ }
+
+ @SuppressWarnings("unused")
+ public boolean isPrimBoolTrueValue() {
+ return primBoolTrueValue;
+ }
+
+ @SuppressWarnings("unused")
+ public void setPrimBoolTrueValue(boolean primBoolTrueValue) {
+ this.primBoolTrueValue = primBoolTrueValue;
+ }
+
+ @SuppressWarnings("unused")
+ public boolean isPrimBoolFalseValue() {
+ return primBoolFalseValue;
+ }
+
+ @SuppressWarnings("unused")
+ public void setPrimBoolFalseValue(boolean primBoolFalseValue) {
+ this.primBoolFalseValue = primBoolFalseValue;
+ }
+
+ @SuppressWarnings("unused")
+ public Integer getIntValue() {
+ return intValue;
+ }
+
+ @SuppressWarnings("unused")
+ public void setIntValue(Integer intValue) {
+ this.intValue = intValue;
+ }
+
+ @SuppressWarnings("unused")
+ public int getPrimIntValue() {
+ return primIntValue;
+ }
+
+ @SuppressWarnings("unused")
+ public void setPrimIntValue(int primIntValue) {
+ this.primIntValue = primIntValue;
+ }
+
+ @SuppressWarnings("unused")
+ public Long getLongValue() {
+ return longValue;
+ }
+
+ @SuppressWarnings("unused")
+ public void setLongValue(Long longValue) {
+ this.longValue = longValue;
+ }
+
+ @SuppressWarnings("unused")
+ public long getPrimLongValue() {
+ return primLongValue;
+ }
+
+ @SuppressWarnings("unused")
+ public void setPrimLongValue(long primLongValue) {
+ this.primLongValue = primLongValue;
+ }
};
props.setProperty("string", "a string");
@@ -331,6 +446,11 @@ public class PropertyConfigurationTest {
public Config(Properties props) throws PropertyException {
super(props);
}
+
+ @SuppressWarnings("unused")
+ public void setValue(Exception value) {
+ this.value = value;
+ }
};
props.setProperty(THE_VALUE, STRING_VALUE);
@@ -354,6 +474,21 @@ public class PropertyConfigurationTest {
public Config(Properties props) throws PropertyException {
super(props);
}
+
+ @SuppressWarnings("unused")
+ public void setPublicString(String publicString) {
+ this.publicString = publicString;
+ }
+
+ @SuppressWarnings("unused")
+ public void setPrivateString(String privateString) {
+ this.privateString = privateString;
+ }
+
+ @SuppressWarnings("unused")
+ public void setProtectedString(String protectedString) {
+ this.protectedString = protectedString;
+ }
};
props.setProperty("public", "a public string");
@@ -370,7 +505,7 @@ public class PropertyConfigurationTest {
@Test(expected = PropertyAccessException.class)
public void testCheckModifiable_Static() throws PropertyException {
props.setProperty(THE_VALUE, STRING_VALUE);
- new StaticConfig(props);
+ new StaticPropConfig(props);
}
@Test(expected = PropertyAccessException.class)
@@ -390,38 +525,24 @@ public class PropertyConfigurationTest {
new Config(props);
}
+ @Test(expected = PropertyAccessException.class)
+ public void testCheckSetter_Static() throws PropertyException {
+ props.setProperty(THE_VALUE, STRING_VALUE);
+ new StaticMethodConfig(props);
+ }
+
@Test
public void testGetStringValue() throws PropertyException {
- class Config extends PropertyConfiguration {
-
- @Property(name = THE_VALUE)
- private String value;
-
- public Config(Properties props) throws PropertyException {
- super(props);
- }
- };
-
props.setProperty(THE_VALUE, STRING_VALUE);
- Config cfg = new Config(props);
+ PlainStringConfig cfg = new PlainStringConfig(props);
assertEquals(STRING_VALUE, cfg.value);
}
@Test
public void testGetBooleanValue_NoDefault() throws PropertyException {
- class Config extends PropertyConfiguration {
-
- @Property(name = THE_VALUE)
- private Boolean value;
-
- public Config(Properties props) throws PropertyException {
- super(props);
- }
- };
-
props.setProperty(THE_VALUE, "true");
- Config cfg = new Config(props);
+ PlainBooleanConfig cfg = new PlainBooleanConfig(props);
assertEquals(true, cfg.value);
}
@@ -436,6 +557,11 @@ public class PropertyConfigurationTest {
public Config(Properties props) throws PropertyException {
super(props);
}
+
+ @SuppressWarnings("unused")
+ public void setValue(Boolean value) {
+ this.value = value;
+ }
};
props.setProperty(THE_VALUE, "true");
@@ -452,6 +578,11 @@ public class PropertyConfigurationTest {
public Config(Properties props) throws PropertyException {
super(props);
}
+
+ @SuppressWarnings("unused")
+ public void setValue(Boolean value) {
+ this.value = value;
+ }
};
// property not defined
@@ -479,6 +610,11 @@ public class PropertyConfigurationTest {
public Config(Properties props) throws PropertyException {
super(props);
}
+
+ @SuppressWarnings("unused")
+ public void setValue(Boolean value) {
+ this.value = value;
+ }
};
// property not defined
@@ -506,6 +642,11 @@ public class PropertyConfigurationTest {
public Config(Properties props) throws PropertyException {
super(props);
}
+
+ @SuppressWarnings("unused")
+ public void setValue(Integer value) {
+ this.value = value;
+ }
};
props.setProperty(THE_VALUE, "200");
@@ -524,6 +665,11 @@ public class PropertyConfigurationTest {
public Config(Properties props) throws PropertyException {
super(props);
}
+
+ @SuppressWarnings("unused")
+ public void setValue(Integer value) {
+ this.value = value;
+ }
};
props.setProperty(THE_VALUE, "200");
@@ -540,6 +686,11 @@ public class PropertyConfigurationTest {
public Config(Properties props) throws PropertyException {
super(props);
}
+
+ @SuppressWarnings("unused")
+ public void setValue(Integer value) {
+ this.value = value;
+ }
};
// property not defined
@@ -562,6 +713,11 @@ public class PropertyConfigurationTest {
public Config(Properties props) throws PropertyException {
super(props);
}
+
+ @SuppressWarnings("unused")
+ public void setValue(Long value) {
+ this.value = value;
+ }
};
props.setProperty(THE_VALUE, "20000");
@@ -580,6 +736,11 @@ public class PropertyConfigurationTest {
public Config(Properties props) throws PropertyException {
super(props);
}
+
+ @SuppressWarnings("unused")
+ public void setValue(Long value) {
+ this.value = value;
+ }
};
props.setProperty(THE_VALUE, "20000");
@@ -596,6 +757,11 @@ public class PropertyConfigurationTest {
public Config(Properties props) throws PropertyException {
super(props);
}
+
+ @SuppressWarnings("unused")
+ public void setValue(Long value) {
+ this.value = value;
+ }
};
// property not defined
@@ -610,18 +776,8 @@ public class PropertyConfigurationTest {
@Test
public void testGetPropValue_Prop_NoDefault() throws PropertyException {
- class Config extends PropertyConfiguration {
-
- @Property(name = THE_VALUE)
- private String value;
-
- public Config(Properties props) throws PropertyException {
- super(props);
- }
- };
-
props.setProperty(THE_VALUE, STRING_VALUE);
- Config cfg = new Config(props);
+ PlainStringConfig cfg = new PlainStringConfig(props);
assertEquals(STRING_VALUE, cfg.value);
}
@@ -636,6 +792,11 @@ public class PropertyConfigurationTest {
public Config(Properties props) throws PropertyException {
super(props);
}
+
+ @SuppressWarnings("unused")
+ public void setValue(String value) {
+ this.value = value;
+ }
};
props.setProperty(THE_VALUE, STRING_VALUE);
@@ -654,6 +815,11 @@ public class PropertyConfigurationTest {
public Config(Properties props) throws PropertyException {
super(props);
}
+
+ @SuppressWarnings("unused")
+ public void setValue(String value) {
+ this.value = value;
+ }
};
props.setProperty(THE_VALUE, "");
@@ -672,6 +838,11 @@ public class PropertyConfigurationTest {
public Config(Properties props) throws PropertyException {
super(props);
}
+
+ @SuppressWarnings("unused")
+ public void setValue(String value) {
+ this.value = value;
+ }
};
Config cfg = new Config(props);
@@ -689,6 +860,11 @@ public class PropertyConfigurationTest {
public Config(Properties props) throws PropertyException {
super(props);
}
+
+ @SuppressWarnings("unused")
+ public void setValue(String value) {
+ this.value = value;
+ }
};
Config cfg = new Config(props);
@@ -706,6 +882,11 @@ public class PropertyConfigurationTest {
public Config(Properties props) throws PropertyException {
super(props);
}
+
+ @SuppressWarnings("unused")
+ public void setValue(String value) {
+ this.value = value;
+ }
};
new Config(props);
@@ -721,6 +902,11 @@ public class PropertyConfigurationTest {
public Config(Properties props) throws PropertyException {
super(props);
}
+
+ @SuppressWarnings("unused")
+ public void setValue(String value) {
+ this.value = value;
+ }
};
Config cfg = new Config(props);
@@ -730,10 +916,7 @@ public class PropertyConfigurationTest {
@Test
public void testGetRawPropertyValue() throws PropertyException {
- class Config extends PropertyConfiguration {
-
- @Property(name = THE_VALUE)
- private String value;
+ class Config extends PlainStringConfig {
public Config(Properties props) throws PropertyException {
super(props);
@@ -747,144 +930,64 @@ public class PropertyConfigurationTest {
Config cfg = new Config(props);
- assertEquals(STRING_VALUE, cfg.value);
+ assertEquals(STRING_VALUE, cfg.getValue());
}
@Test
public void testMakeBoolean_True() throws PropertyException {
- class Config extends PropertyConfiguration {
-
- @Property(name = THE_VALUE)
- private Boolean value;
-
- public Config(Properties props) throws PropertyException {
- super(props);
- }
- };
-
props.setProperty(THE_VALUE, "true");
- Config cfg = new Config(props);
+ PlainBooleanConfig cfg = new PlainBooleanConfig(props);
assertEquals(true, cfg.value);
}
@Test
public void testMakeBoolean_False() throws PropertyException {
- class Config extends PropertyConfiguration {
-
- @Property(name = THE_VALUE)
- private Boolean value;
-
- public Config(Properties props) throws PropertyException {
- super(props);
- }
- };
-
props.setProperty(THE_VALUE, "false");
- Config cfg = new Config(props);
+ PlainBooleanConfig cfg = new PlainBooleanConfig(props);
assertEquals(false, cfg.value);
}
@Test(expected = PropertyInvalidException.class)
public void testMakeBoolean_Invalid() throws PropertyException {
- class Config extends PropertyConfiguration {
-
- @Property(name = THE_VALUE)
- private Boolean value;
-
- public Config(Properties props) throws PropertyException {
- super(props);
- }
- };
-
props.setProperty(THE_VALUE, INVALID_VALUE);
- new Config(props);
+ new PlainBooleanConfig(props);
}
@Test
public void testMakeInteger_Valid() throws PropertyException {
- class Config extends PropertyConfiguration {
-
- @Property(name = THE_VALUE)
- private int value;
-
- public Config(Properties props) throws PropertyException {
- super(props);
- }
- };
-
props.setProperty(THE_VALUE, "300");
- Config cfg = new Config(props);
+ PlainPrimIntConfig cfg = new PlainPrimIntConfig(props);
assertEquals(300, cfg.value);
}
@Test(expected = PropertyInvalidException.class)
public void testMakeInteger_Invalid() throws PropertyException {
- class Config extends PropertyConfiguration {
-
- @Property(name = THE_VALUE)
- private int value;
-
- public Config(Properties props) throws PropertyException {
- super(props);
- }
- };
-
props.setProperty(THE_VALUE, INVALID_VALUE);
- new Config(props);
+ new PlainPrimIntConfig(props);
}
@Test(expected = PropertyInvalidException.class)
public void testMakeInteger_TooBig() throws PropertyException {
- class Config extends PropertyConfiguration {
-
- @Property(name = THE_VALUE)
- private int value;
-
- public Config(Properties props) throws PropertyException {
- super(props);
- }
- };
-
props.setProperty(THE_VALUE, String.valueOf(Integer.MAX_VALUE + 10L));
- new Config(props);
+ new PlainPrimIntConfig(props);
}
@Test
public void testMakeLong_Valid() throws PropertyException {
- class Config extends PropertyConfiguration {
-
- @Property(name = THE_VALUE)
- private long value;
-
- public Config(Properties props) throws PropertyException {
- super(props);
- }
- };
-
props.setProperty(THE_VALUE, "30000");
- Config cfg = new Config(props);
+ PlainPrimLongConfig cfg = new PlainPrimLongConfig(props);
assertEquals(30000L, cfg.value);
}
@Test(expected = PropertyInvalidException.class)
public void testMakeLong_Invalid() throws PropertyException {
- class Config extends PropertyConfiguration {
-
- @Property(name = THE_VALUE)
- private long value;
-
- public Config(Properties props) throws PropertyException {
- super(props);
- }
- };
-
props.setProperty(THE_VALUE, INVALID_VALUE);
- new Config(props);
+ new PlainPrimLongConfig(props);
}
@Test
@@ -897,6 +1000,11 @@ public class PropertyConfigurationTest {
public Config(Properties props) throws PropertyException {
super(props);
}
+
+ @SuppressWarnings("unused")
+ public void setValue(long value) {
+ this.value = value;
+ }
};
Config cfg = new Config(props);
@@ -914,6 +1022,11 @@ public class PropertyConfigurationTest {
public Config(Properties props) throws PropertyException {
super(props);
}
+
+ @SuppressWarnings("unused")
+ public void setValue(long value) {
+ this.value = value;
+ }
};
new Config(props);
@@ -929,6 +1042,11 @@ public class PropertyConfigurationTest {
public Config(Properties props) throws PropertyException {
super(props);
}
+
+ @SuppressWarnings("unused")
+ public void setValue(long value) {
+ this.value = value;
+ }
};
new Config(props);
@@ -944,6 +1062,11 @@ public class PropertyConfigurationTest {
public Config(Properties props) throws PropertyException {
super(props);
}
+
+ @SuppressWarnings("unused")
+ public void setValue(String value) {
+ this.value = value;
+ }
};
// missing property - should default to ""
@@ -971,6 +1094,11 @@ public class PropertyConfigurationTest {
public Config(Properties props) throws PropertyException {
super(props);
}
+
+ @SuppressWarnings("unused")
+ public void setValue(long value) {
+ this.value = value;
+ }
};
new Config(props);
@@ -986,6 +1114,11 @@ public class PropertyConfigurationTest {
public Config(Properties props) throws PropertyException {
super(props);
}
+
+ @SuppressWarnings("unused")
+ public void setValue(String value) {
+ this.value = value;
+ }
};
Config cfg = new Config(props);
@@ -1003,23 +1136,126 @@ public class PropertyConfigurationTest {
public Config(Properties props) throws PropertyException {
super(props);
}
+
+ @SuppressWarnings("unused")
+ public void setValue(long value) {
+ this.value = value;
+ }
};
new Config(props);
}
/**
- * A config whose annotated property is "static".
+ * Config with a String value having no qualifiers.
*/
- public static class StaticConfig extends PropertyConfiguration {
+ public class PlainStringConfig extends PropertyConfiguration {
+
+ @Property(name = THE_VALUE)
+ private String value;
+
+ public PlainStringConfig() {
+
+ }
+
+ public PlainStringConfig(Properties props) throws PropertyException {
+ super(props);
+ }
+
+ public String getValue() {
+ return value;
+ }
+
+ public void setValue(String value) {
+ this.value = value;
+ }
+ };
+
+ /**
+ * Config with a Boolean value having no qualifiers.
+ */
+ public class PlainBooleanConfig extends PropertyConfiguration {
+
+ @Property(name = THE_VALUE)
+ private Boolean value;
+
+ public PlainBooleanConfig(Properties props) throws PropertyException {
+ super(props);
+ }
+
+ public void setValue(Boolean value) {
+ this.value = value;
+ }
+ };
+
+ /**
+ * Config with an int value having no qualifiers.
+ */
+ public class PlainPrimIntConfig extends PropertyConfiguration {
+
+ @Property(name = THE_VALUE)
+ private int value;
+
+ public PlainPrimIntConfig(Properties props) throws PropertyException {
+ super(props);
+ }
+
+ public void setValue(int value) {
+ this.value = value;
+ }
+ };
+
+ /**
+ * Config with a long value having no qualifiers.
+ */
+ public class PlainPrimLongConfig extends PropertyConfiguration {
+
+ @Property(name = THE_VALUE)
+ private long value;
+
+ public PlainPrimLongConfig(Properties props) throws PropertyException {
+ super(props);
+ }
+
+ public void setValue(long value) {
+ this.value = value;
+ }
+ };
+
+ /**
+ * A config whose field is "static".
+ */
+ public static class StaticPropConfig extends PropertyConfiguration {
// "static" field cannot be set
@Property(name = THE_VALUE)
private static String value;
- public StaticConfig(Properties props) throws PropertyException {
+ public StaticPropConfig(Properties props) throws PropertyException {
super(props);
}
+
+ public static void setValue(String value) {
+ StaticPropConfig.value = value;
+ }
+ };
+
+ /**
+ * A config whose method is "static".
+ */
+ public static class StaticMethodConfig extends PropertyConfiguration {
+
+ // "static" field cannot be set
+ @Property(name = THE_VALUE)
+ private String value;
+
+ public StaticMethodConfig(Properties props) throws PropertyException {
+ super(props);
+ }
+
+ public static void setValue(String value) {
+
+ }
};
/**
diff --git a/utils/src/test/java/org/onap/policy/common/utils/properties/SpecPropertiesTest.java b/utils/src/test/java/org/onap/policy/common/utils/properties/SpecPropertiesTest.java
new file mode 100644
index 00000000..01f096d1
--- /dev/null
+++ b/utils/src/test/java/org/onap/policy/common/utils/properties/SpecPropertiesTest.java
@@ -0,0 +1,224 @@
+/*
+ * ============LICENSE_START=======================================================
+ * ONAP
+ * ================================================================================
+ * 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.utils.properties;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNull;
+import java.util.Properties;
+import org.junit.Before;
+import org.junit.Test;
+
+public class SpecPropertiesTest {
+
+ /**
+ * Property prefix of interest.
+ */
+ private static final String MY_PREFIX = "my.prefix";
+
+ /**
+ * Specialization, which follows the prefix.
+ */
+ private static final String MY_SPEC = "my.spec";
+
+ /**
+ * Generalized prefix (i.e., without the spec).
+ */
+ private static final String PREFIX_GEN = MY_PREFIX + ".";
+
+ /**
+ * Specialized prefix (i.e., with the spec).
+ */
+ private static final String PREFIX_SPEC = PREFIX_GEN + MY_SPEC + ".";
+
+ /**
+ * Suffix to add to property names to generate names of properties that are not
+ * populated.
+ */
+ private static final String SUFFIX = ".suffix";
+
+ /**
+ * Property name without a prefix.
+ */
+ private static final String PROP_NO_PREFIX = "other";
+
+ /**
+ * Generalized property name (i.e., without the spec).
+ */
+ private static final String PROP_GEN = PREFIX_GEN + "generalized";
+
+ // property names that include the spec
+ private static final String PROP_SPEC = PREFIX_SPEC + "specialized";
+ private static final String PROP_UNKNOWN = PREFIX_SPEC + "unknown";
+
+ // property values
+ private static final String VAL_NO_PREFIX = "no-prefix";
+ private static final String VAL_GEN = "gen";
+ private static final String VAL_SPEC = "spec";
+
+ private static final String VAL_DEFAULT = "default value";
+
+ private Properties supportingProps;
+ private SpecProperties props;
+
+ @Before
+ public void setUp() {
+ supportingProps = new Properties();
+
+ supportingProps.setProperty(PROP_NO_PREFIX, VAL_NO_PREFIX);
+ supportingProps.setProperty(PROP_GEN, VAL_GEN);
+ supportingProps.setProperty(PROP_SPEC, VAL_SPEC);
+
+ props = new SpecProperties(MY_PREFIX, MY_SPEC);
+
+ props.putAll(supportingProps);
+ }
+
+ @Test
+ public void testSpecPropertiesStringString() {
+
+ // no supporting properties
+ props = new SpecProperties(MY_PREFIX, MY_SPEC);
+
+ assertEquals(PREFIX_GEN, props.getPrefix());
+ assertEquals(PREFIX_SPEC, props.getSpecPrefix());
+
+ // everything is null
+ assertNull(props.getProperty(gen(PROP_NO_PREFIX)));
+ assertNull(props.getProperty(gen(PROP_GEN)));
+ assertNull(props.getProperty(gen(PROP_SPEC)));
+ assertNull(props.getProperty(gen(PROP_UNKNOWN)));
+ }
+
+ @Test
+ public void testSpecPropertiesStringStringProperties() {
+
+ // use supportingProps as default properties
+ props = new SpecProperties(MY_PREFIX, MY_SPEC, supportingProps);
+
+ assertEquals(PREFIX_GEN, props.getPrefix());
+ assertEquals(PREFIX_SPEC, props.getSpecPrefix());
+
+ assertEquals(VAL_NO_PREFIX, props.getProperty(gen(PROP_NO_PREFIX)));
+ assertEquals(VAL_GEN, props.getProperty(gen(PROP_GEN)));
+ assertEquals(VAL_SPEC, props.getProperty(gen(PROP_SPEC)));
+ assertNull(props.getProperty(gen(PROP_UNKNOWN)));
+ }
+
+ @Test
+ public void testSpecPropertiesStringStringProperties_EmptyPrefix() {
+ supportingProps = new Properties();
+
+ supportingProps.setProperty(PROP_NO_PREFIX, VAL_NO_PREFIX);
+ supportingProps.setProperty("a.value", VAL_GEN);
+ supportingProps.setProperty("b.value", VAL_GEN);
+ supportingProps.setProperty(MY_SPEC + ".b.value", VAL_SPEC);
+
+ // no supporting properties
+ props = new SpecProperties("", MY_SPEC, supportingProps);
+
+ assertEquals(VAL_NO_PREFIX, props.getProperty(gen(PROP_NO_PREFIX)));
+ assertEquals(VAL_GEN, props.getProperty(gen("a.value")));
+ assertEquals(VAL_SPEC, props.getProperty(MY_SPEC + ".b.value"));
+ assertNull(props.getProperty(gen(PROP_UNKNOWN)));
+ }
+
+ @Test
+ public void testWithTrailingDot() {
+ // neither has trailing dot
+ assertEquals(PREFIX_GEN, props.getPrefix());
+ assertEquals(PREFIX_SPEC, props.getSpecPrefix());
+
+ // both have trailing dot
+ props = new SpecProperties(PREFIX_GEN, MY_SPEC + ".");
+ assertEquals(PREFIX_GEN, props.getPrefix());
+ assertEquals(PREFIX_SPEC, props.getSpecPrefix());
+
+ // first is empty
+ props = new SpecProperties("", MY_SPEC);
+ assertEquals("", props.getPrefix());
+ assertEquals(MY_SPEC + ".", props.getSpecPrefix());
+
+ // second is empty
+ props = new SpecProperties(PREFIX_GEN, "");
+ assertEquals(PREFIX_GEN, props.getPrefix());
+ assertEquals(PREFIX_GEN, props.getSpecPrefix());
+ }
+
+ @Test
+ public void testGetPropertyString() {
+ // the key does contain the prefix
+ assertEquals(VAL_NO_PREFIX, props.getProperty(gen(PROP_NO_PREFIX)));
+ assertNull(props.getProperty(gen(PROP_NO_PREFIX + SUFFIX)));
+
+ // specialized value exists
+ assertEquals(VAL_GEN, props.getProperty(gen(PROP_GEN)));
+ assertNull(props.getProperty(gen(PROP_GEN + SUFFIX)));
+
+ // generalized value exists
+ assertEquals(VAL_SPEC, props.getProperty(gen(PROP_SPEC)));
+ assertNull(props.getProperty(gen(PROP_SPEC + SUFFIX)));
+
+ // not found
+ assertNull(props.getProperty(gen(PROP_UNKNOWN)));
+ assertNull(props.getProperty(gen(PROP_UNKNOWN + SUFFIX)));
+ }
+
+ @Test
+ public void testGetPropertyStringString() {
+ // the key does contain the prefix
+ assertEquals(VAL_NO_PREFIX, props.getProperty(gen(PROP_NO_PREFIX), VAL_DEFAULT));
+ assertEquals(VAL_DEFAULT, props.getProperty(gen(PROP_NO_PREFIX + SUFFIX), VAL_DEFAULT));
+
+ // specialized value exists
+ assertEquals(VAL_GEN, props.getProperty(gen(PROP_GEN), VAL_DEFAULT));
+ assertEquals(VAL_DEFAULT, props.getProperty(gen(PROP_GEN + SUFFIX), VAL_DEFAULT));
+
+ // generalized value exists
+ assertEquals(VAL_SPEC, props.getProperty(gen(PROP_SPEC), VAL_DEFAULT));
+ assertEquals(VAL_DEFAULT, props.getProperty(gen(PROP_SPEC + SUFFIX), VAL_DEFAULT));
+
+ // not found
+ assertEquals(VAL_DEFAULT, props.getProperty(gen(PROP_UNKNOWN), VAL_DEFAULT));
+ assertEquals(VAL_DEFAULT, props.getProperty(gen(PROP_UNKNOWN + SUFFIX), VAL_DEFAULT));
+
+ // can return null
+ assertNull(props.getProperty(gen(PROP_UNKNOWN), null));
+ }
+
+ @Test(expected = UnsupportedOperationException.class)
+ public void testHashCode() {
+ props.hashCode();
+ }
+
+ @Test(expected = UnsupportedOperationException.class)
+ public void testEquals() {
+ props.equals(props);
+ }
+
+ private String gen(String propnm) {
+ if (propnm.startsWith(PREFIX_SPEC)) {
+ return PREFIX_GEN + propnm.substring(PREFIX_SPEC.length());
+ }
+
+ return propnm;
+ }
+
+}
diff --git a/utils/src/test/java/org/onap/policy/common/utils/properties/SpecPropertyConfigurationTest.java b/utils/src/test/java/org/onap/policy/common/utils/properties/SpecPropertyConfigurationTest.java
index 39c8f01a..b5431c25 100644
--- a/utils/src/test/java/org/onap/policy/common/utils/properties/SpecPropertyConfigurationTest.java
+++ b/utils/src/test/java/org/onap/policy/common/utils/properties/SpecPropertyConfigurationTest.java
@@ -110,6 +110,66 @@ public class SpecPropertyConfigurationTest {
public Config(String specialization, Properties props) throws PropertyException {
super(specialization, props);
}
+
+ @SuppressWarnings("unused")
+ public void setNoSpec(String noSpec) {
+ this.noSpec = noSpec;
+ }
+
+ @SuppressWarnings("unused")
+ public void setNoSpecBool(boolean noSpecBool) {
+ this.noSpecBool = noSpecBool;
+ }
+
+ @SuppressWarnings("unused")
+ public void setType1NoPrefix(String type1NoPrefix) {
+ this.type1NoPrefix = type1NoPrefix;
+ }
+
+ @SuppressWarnings("unused")
+ public void setType1NoSuffix(String type1NoSuffix) {
+ this.type1NoSuffix = type1NoSuffix;
+ }
+
+ @SuppressWarnings("unused")
+ public void setType1Both(String type1Both) {
+ this.type1Both = type1Both;
+ }
+
+ @SuppressWarnings("unused")
+ public void setType1Int(int type1Int) {
+ this.type1Int = type1Int;
+ }
+
+ @SuppressWarnings("unused")
+ public void setType2NoPrefix(String type2NoPrefix) {
+ this.type2NoPrefix = type2NoPrefix;
+ }
+
+ @SuppressWarnings("unused")
+ public void setType2NoSuffix(String type2NoSuffix) {
+ this.type2NoSuffix = type2NoSuffix;
+ }
+
+ @SuppressWarnings("unused")
+ public void setType2NoSpecPrefix(String type2NoSpecPrefix) {
+ this.type2NoSpecPrefix = type2NoSpecPrefix;
+ }
+
+ @SuppressWarnings("unused")
+ public void setType2NoSpecSuffix(String type2NoSpecSuffix) {
+ this.type2NoSpecSuffix = type2NoSpecSuffix;
+ }
+
+ @SuppressWarnings("unused")
+ public void setType2Both(String type2Both) {
+ this.type2Both = type2Both;
+ }
+
+ @SuppressWarnings("unused")
+ public void setType2Long(long type2Long) {
+ this.type2Long = type2Long;
+ }
};
props.setProperty("prefix.suffix", "no.spec");
@@ -151,6 +211,11 @@ public class SpecPropertyConfigurationTest {
public Config(String specialization, Properties props) throws PropertyException {
super(specialization, props);
}
+
+ @SuppressWarnings("unused")
+ public void setValue(String value) {
+ this.value = value;
+ }
};
props.setProperty("prefix.suffix", "no.spec");
@@ -174,6 +239,11 @@ public class SpecPropertyConfigurationTest {
public Config(String specialization, Properties props) throws PropertyException {
super(specialization, props);
}
+
+ @SuppressWarnings("unused")
+ public void setNotFound(String notFound) {
+ this.notFound = notFound;
+ }
};
new Config("not found", props);
@@ -196,6 +266,11 @@ public class SpecPropertyConfigurationTest {
public Config(String specialization) {
super(specialization);
}
+
+ @SuppressWarnings("unused")
+ public void setValue(String value) {
+ this.value = value;
+ }
};
props.setProperty(specialize(propnm, SPEC), propval);
@@ -224,6 +299,11 @@ public class SpecPropertyConfigurationTest {
public Config(String specialization, Properties props) throws PropertyException {
super(specialization, props);
}
+
+ @SuppressWarnings("unused")
+ public void setValue(int value) {
+ this.value = value;
+ }
};
props.setProperty(specialize(propnm, SPEC), String.valueOf(propval));
diff --git a/utils/src/test/java/org/onap/policy/common/utils/time/CurrentTimeTest.java b/utils/src/test/java/org/onap/policy/common/utils/time/CurrentTimeTest.java
new file mode 100644
index 00000000..694a3d21
--- /dev/null
+++ b/utils/src/test/java/org/onap/policy/common/utils/time/CurrentTimeTest.java
@@ -0,0 +1,59 @@
+/*
+ * ============LICENSE_START=======================================================
+ * Common Utils
+ * ================================================================================
+ * 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.utils.time;
+
+import static org.junit.Assert.assertTrue;
+import org.junit.Test;
+
+public class CurrentTimeTest {
+
+ @Test
+ public void testGetMillis() {
+ long tcur = System.currentTimeMillis();
+ long tval = new CurrentTime().getMillis();
+ long tval2 = new CurrentTime().getMillis();
+ long tend = System.currentTimeMillis();
+
+ assertTrue(tval >= tcur && tval <= tend);
+ assertTrue(tval2 >= tcur && tval2 <= tend);
+ }
+
+ @Test
+ public void testGetDate() {
+ long tcur = System.currentTimeMillis();
+ long tval = new CurrentTime().getDate().getTime();
+ long tval2 = new CurrentTime().getDate().getTime();
+ long tend = System.currentTimeMillis();
+
+ assertTrue(tval >= tcur && tval <= tend);
+ assertTrue(tval2 >= tcur && tval2 <= tend);
+ }
+
+ @Test
+ public void testSleep() throws Exception {
+ long tcur = System.currentTimeMillis();
+ new CurrentTime().sleep(10);
+ long tend = System.currentTimeMillis();
+
+ assertTrue(tend >= tcur + 10 - 1);
+ }
+
+}