From e5218ab9d42ce1c633f5a147c7b0502d41f4a1a2 Mon Sep 17 00:00:00 2001 From: Krishnan Mahadevan Date: Fri, 22 Mar 2024 00:19:08 +0530 Subject: [PATCH] Streamline random generation * Add edit checks to ensure that when using Random it always gives a non zero value --- .../issue3081/TestClassSample.java | 6 +-- .../TestClassWithPrioritiesSample.java | 6 +-- .../factory/issue326/SampleTestClass.java | 6 +-- .../test/java/test/support/SafeRandoms.java | 39 +++++++++++++++++++ .../test/thread/TrueParallelSampleTest.java | 3 +- .../thread/issue188/Issue188TestSample.java | 13 +------ 6 files changed, 49 insertions(+), 24 deletions(-) create mode 100644 testng-core/src/test/java/test/support/SafeRandoms.java diff --git a/testng-core/src/test/java/test/dataprovider/issue3081/TestClassSample.java b/testng-core/src/test/java/test/dataprovider/issue3081/TestClassSample.java index 0647a6abdf..7b5567d21c 100644 --- a/testng-core/src/test/java/test/dataprovider/issue3081/TestClassSample.java +++ b/testng-core/src/test/java/test/dataprovider/issue3081/TestClassSample.java @@ -1,18 +1,16 @@ package test.dataprovider.issue3081; -import java.security.SecureRandom; import java.util.Collections; -import java.util.Random; import java.util.Set; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.TimeUnit; import java.util.stream.IntStream; import org.testng.annotations.DataProvider; import org.testng.annotations.Test; +import test.support.SafeRandoms; public class TestClassSample { private static final Set logs = ConcurrentHashMap.newKeySet(); - private static final Random random = new SecureRandom(); public static Set getLogs() { return Collections.unmodifiableSet(logs); @@ -30,7 +28,7 @@ public static Object[] parallelDpStrings() { @Test(dataProvider = "parallelDpStrings") public void testStrings(String ignored) throws InterruptedException { print(); - TimeUnit.MILLISECONDS.sleep(random.nextInt(500)); + TimeUnit.MILLISECONDS.sleep(SafeRandoms.nextInt(200, 300)); } private static void print() { diff --git a/testng-core/src/test/java/test/dataprovider/issue3081/TestClassWithPrioritiesSample.java b/testng-core/src/test/java/test/dataprovider/issue3081/TestClassWithPrioritiesSample.java index ccf00c85f4..ae71bb3f9e 100644 --- a/testng-core/src/test/java/test/dataprovider/issue3081/TestClassWithPrioritiesSample.java +++ b/testng-core/src/test/java/test/dataprovider/issue3081/TestClassWithPrioritiesSample.java @@ -1,18 +1,16 @@ package test.dataprovider.issue3081; -import java.security.SecureRandom; import java.util.Collections; -import java.util.Random; import java.util.Set; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.TimeUnit; import java.util.stream.IntStream; import org.testng.annotations.DataProvider; import org.testng.annotations.Test; +import test.support.SafeRandoms; public class TestClassWithPrioritiesSample { private static final Set logs = ConcurrentHashMap.newKeySet(); - private static final Random random = new SecureRandom(); public static Set getLogs() { return Collections.unmodifiableSet(logs); @@ -30,7 +28,7 @@ public static Object[] parallelDpStrings() { @Test(dataProvider = "parallelDpStrings", priority = 1) public void testStrings(String ignored) throws InterruptedException { print(); - TimeUnit.MILLISECONDS.sleep(random.nextInt(500)); + TimeUnit.MILLISECONDS.sleep(SafeRandoms.nextInt(200, 300)); } @Test(priority = 2) diff --git a/testng-core/src/test/java/test/factory/issue326/SampleTestClass.java b/testng-core/src/test/java/test/factory/issue326/SampleTestClass.java index 6a7787de17..1a882e7e66 100644 --- a/testng-core/src/test/java/test/factory/issue326/SampleTestClass.java +++ b/testng-core/src/test/java/test/factory/issue326/SampleTestClass.java @@ -3,13 +3,13 @@ import java.util.Arrays; import java.util.Iterator; import java.util.List; -import java.util.Random; import java.util.concurrent.TimeUnit; import org.testng.ITestResult; import org.testng.Reporter; import org.testng.annotations.DataProvider; import org.testng.annotations.Factory; import org.testng.annotations.Test; +import test.support.SafeRandoms; public class SampleTestClass { @@ -18,12 +18,10 @@ public class SampleTestClass { static final String BARNEY = "Barney"; private final String instance; - private final Random random; @Factory(dataProvider = "dp") public SampleTestClass(String instance) { this.instance = instance; - random = new Random(); } @DataProvider @@ -50,6 +48,6 @@ public String toString() { private void printer() throws InterruptedException { ITestResult result = Reporter.getCurrentTestResult(); result.setAttribute(THREAD_ID, Thread.currentThread().getId()); - TimeUnit.MILLISECONDS.sleep(10 * random.nextInt(100)); + TimeUnit.MILLISECONDS.sleep(10L * SafeRandoms.nextInt(30, 70)); } } diff --git a/testng-core/src/test/java/test/support/SafeRandoms.java b/testng-core/src/test/java/test/support/SafeRandoms.java new file mode 100644 index 0000000000..8a14b25316 --- /dev/null +++ b/testng-core/src/test/java/test/support/SafeRandoms.java @@ -0,0 +1,39 @@ +package test.support; + +import static org.assertj.core.util.Preconditions.checkArgument; + +import java.util.Objects; +import java.util.Random; + +public final class SafeRandoms { + + private static final Random random = new Random(); + + private SafeRandoms() {} + + /** + * @param delta - Represents a constant that should be added to the generated random value. This + * will ensure that there are no zero values generated. + * @param upperBound - The upper bound (exclusive). Must be positive. + * @return - A random number which is a summation of the delta and the actual random value that is + * lesser than the upperBound value. + */ + public static int nextInt(int delta, int upperBound) { + return nextInt(delta, upperBound, random); + } + + /** + * @param delta - Represents a constant that should be added to the generated random value. This + * will ensure that there are no zero values generated. + * @param upperBound - The upper bound (exclusive). Must be positive. + * @param random - An existing instance of {@link Random} to be used. + * @return - A random number which is a summation of the delta and the actual random value that is + * lesser than the upperBound value. + */ + public static int nextInt(int delta, int upperBound, Random random) { + checkArgument(delta >= 0, "Delta should be non-zero"); + checkArgument(upperBound >= 0, "Upper bound should be non-zero"); + checkArgument(delta < upperBound, "Delta should be less than Upper bound"); + return delta + Objects.requireNonNull(random).nextInt(upperBound); + } +} diff --git a/testng-core/src/test/java/test/thread/TrueParallelSampleTest.java b/testng-core/src/test/java/test/thread/TrueParallelSampleTest.java index d1db4cfcef..55715402f2 100644 --- a/testng-core/src/test/java/test/thread/TrueParallelSampleTest.java +++ b/testng-core/src/test/java/test/thread/TrueParallelSampleTest.java @@ -2,6 +2,7 @@ import java.util.Random; import org.testng.annotations.Test; +import test.support.SafeRandoms; @Test public class TrueParallelSampleTest extends BaseThreadTest { @@ -10,7 +11,7 @@ public class TrueParallelSampleTest extends BaseThreadTest { private void log(String s) { logString(s); try { - Thread.sleep(random.nextInt(10)); + Thread.sleep(SafeRandoms.nextInt(3, 7, random)); } catch (InterruptedException ex) { Thread.yield(); } diff --git a/testng-core/src/test/java/test/thread/issue188/Issue188TestSample.java b/testng-core/src/test/java/test/thread/issue188/Issue188TestSample.java index d9a354a381..d7a73b2acf 100644 --- a/testng-core/src/test/java/test/thread/issue188/Issue188TestSample.java +++ b/testng-core/src/test/java/test/thread/issue188/Issue188TestSample.java @@ -1,7 +1,6 @@ package test.thread.issue188; import java.util.Map; -import java.util.Random; import java.util.Set; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.TimeUnit; @@ -9,10 +8,10 @@ import org.testng.Reporter; import org.testng.annotations.BeforeMethod; import org.testng.annotations.Test; +import test.support.SafeRandoms; public class Issue188TestSample { public static final Map> timestamps = new ConcurrentHashMap<>(); - private static final Random random = new Random(); @BeforeMethod public void logTime(ITestResult itr) { @@ -37,17 +36,9 @@ public void anotherSampleTest() { private void sleepSilently() { try { - TimeUnit.MILLISECONDS.sleep(500 * random()); + TimeUnit.MILLISECONDS.sleep(500L * SafeRandoms.nextInt(1, 10)); } catch (InterruptedException e) { Thread.currentThread().interrupt(); } } - - private static long random() { - int value = random.nextInt(10); - if (value == 0) { - return 1; - } - return value; - } }