From 58fc05aa61f690604bbcccaae2bab130d689c42f Mon Sep 17 00:00:00 2001 From: luca Date: Tue, 16 Jan 2024 14:21:29 +0100 Subject: [PATCH 1/3] fix: clean config --- ...HibernateSequentialNumberCounterStore.java | 5 +- .../reservedvalue/hibernate/DummyService.java | 53 ----------- ...rnateSequentialNumberCounterStoreTest.java | 87 +++++++++---------- 3 files changed, 42 insertions(+), 103 deletions(-) delete mode 100644 dhis-2/dhis-test-integration/src/test/java/org/hisp/dhis/reservedvalue/hibernate/DummyService.java diff --git a/dhis-2/dhis-services/dhis-service-core/src/main/java/org/hisp/dhis/reservedvalue/hibernate/HibernateSequentialNumberCounterStore.java b/dhis-2/dhis-services/dhis-service-core/src/main/java/org/hisp/dhis/reservedvalue/hibernate/HibernateSequentialNumberCounterStore.java index 2b93290f1f3d..bca79524f4b0 100644 --- a/dhis-2/dhis-services/dhis-service-core/src/main/java/org/hisp/dhis/reservedvalue/hibernate/HibernateSequentialNumberCounterStore.java +++ b/dhis-2/dhis-services/dhis-service-core/src/main/java/org/hisp/dhis/reservedvalue/hibernate/HibernateSequentialNumberCounterStore.java @@ -28,7 +28,6 @@ package org.hisp.dhis.reservedvalue.hibernate; import java.util.List; -import java.util.stream.Collectors; import java.util.stream.IntStream; import javax.persistence.EntityManager; import lombok.RequiredArgsConstructor; @@ -54,9 +53,7 @@ public List getNextValues(String uid, String key, int length) { .setParameter("length", length) .getSingleResult(); - return IntStream.range(count - length, length + (count - length)) - .boxed() - .collect(Collectors.toList()); + return IntStream.range(count - length, length + (count - length)).boxed().toList(); } @Override diff --git a/dhis-2/dhis-test-integration/src/test/java/org/hisp/dhis/reservedvalue/hibernate/DummyService.java b/dhis-2/dhis-test-integration/src/test/java/org/hisp/dhis/reservedvalue/hibernate/DummyService.java deleted file mode 100644 index baeb422e0aa9..000000000000 --- a/dhis-2/dhis-test-integration/src/test/java/org/hisp/dhis/reservedvalue/hibernate/DummyService.java +++ /dev/null @@ -1,53 +0,0 @@ -/* - * Copyright (c) 2004-2022, University of Oslo - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * Redistributions of source code must retain the above copyright notice, this - * list of conditions and the following disclaimer. - * - * Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * Neither the name of the HISP project nor the names of its contributors may - * be used to endorse or promote products derived from this software without - * specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR - * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON - * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ -package org.hisp.dhis.reservedvalue.hibernate; - -import java.util.List; -import org.hisp.dhis.reservedvalue.SequentialNumberCounterStore; -import org.springframework.transaction.annotation.Transactional; - -/** - * @author Luciano Fiandesio - */ -public class DummyService { - private SequentialNumberCounterStore sequentialNumberCounterStore; - - public DummyService(SequentialNumberCounterStore hibernateSequentialNumberCounterStore) { - this.sequentialNumberCounterStore = hibernateSequentialNumberCounterStore; - } - - @Transactional - public List getNextValues(String uid, String key, int length) { - return sequentialNumberCounterStore.getNextValues(uid, key, length); - } - - @Transactional - public void deleteCounter(String uid) { - sequentialNumberCounterStore.deleteCounter(uid); - } -} diff --git a/dhis-2/dhis-test-integration/src/test/java/org/hisp/dhis/reservedvalue/hibernate/HibernateSequentialNumberCounterStoreTest.java b/dhis-2/dhis-test-integration/src/test/java/org/hisp/dhis/reservedvalue/hibernate/HibernateSequentialNumberCounterStoreTest.java index f27414afaf1b..bafcda5e93ae 100644 --- a/dhis-2/dhis-test-integration/src/test/java/org/hisp/dhis/reservedvalue/hibernate/HibernateSequentialNumberCounterStoreTest.java +++ b/dhis-2/dhis-test-integration/src/test/java/org/hisp/dhis/reservedvalue/hibernate/HibernateSequentialNumberCounterStoreTest.java @@ -48,21 +48,19 @@ import org.hisp.dhis.test.integration.TransactionalIntegrationTest; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; class HibernateSequentialNumberCounterStoreTest extends TransactionalIntegrationTest { - @Autowired private DummyService dummyService; + @Autowired private SequentialNumberCounterStore sequentialNumberCounterStore; @Test void getNextValues() { - List result = dummyService.getNextValues("ABC", "ABC-#", 3); + List result = getNextValues("ABC", "ABC-#", 3); assertEquals(3, result.size()); assertTrue(result.contains(1)); assertTrue(result.contains(2)); assertTrue(result.contains(3)); - result = dummyService.getNextValues("ABC", "ABC-#", 50); + result = getNextValues("ABC", "ABC-#", 50); assertEquals(50, result.size()); assertTrue(result.contains(4)); assertTrue(result.contains(5)); @@ -70,31 +68,6 @@ void getNextValues() { assertTrue(result.contains(53)); } - private void test(final int threadCount) throws InterruptedException, ExecutionException { - final String uid = RandomStringUtils.randomAlphabetic(3).toUpperCase(); - Callable> task = () -> dummyService.getNextValues(uid, uid + "-#", 50); - List>> tasks = Collections.nCopies(threadCount, task); - ExecutorService executorService = Executors.newFixedThreadPool(threadCount); - List>> futures = executorService.invokeAll(tasks); - List> resultList = new ArrayList<>(futures.size()); - // Check for exceptions - for (Future> future : futures) { - // Throws an exception if an exception was thrown by the task. - resultList.add(future.get()); - } - assertEquals(threadCount, futures.size()); - Set allIds = new HashSet<>(); - List allIdList = new ArrayList<>(); - for (List integers : resultList) { - allIds.addAll(integers); - allIdList.addAll(integers); - } - assertThat(allIds, hasSize(threadCount * 50)); - Collections.sort(allIdList); - assertThat(allIdList.get(0), is(1)); - assertThat(allIdList.get(allIdList.size() - 1), is(50 * threadCount)); - } - @Test void test1() throws InterruptedException, ExecutionException { test(1); @@ -122,25 +95,47 @@ void test32() throws InterruptedException, ExecutionException { @Test void deleteCounter() { - assertTrue(dummyService.getNextValues("ABC", "ABC-#", 3).contains(1)); - dummyService.deleteCounter("ABC"); - assertTrue(dummyService.getNextValues("ABC", "ABC-#", 3).contains(1)); - assertTrue(dummyService.getNextValues("ABC", "ABC-##", 3).contains(1)); - assertTrue(dummyService.getNextValues("ABC", "ABC-###", 3).contains(1)); - dummyService.deleteCounter("ABC"); - assertTrue(dummyService.getNextValues("ABC", "ABC-#", 3).contains(1)); - assertTrue(dummyService.getNextValues("ABC", "ABC-##", 3).contains(1)); - assertTrue(dummyService.getNextValues("ABC", "ABC-###", 3).contains(1)); + assertTrue(getNextValues("ABC", "ABC-#", 3).contains(1)); + deleteCounter("ABC"); + assertTrue(getNextValues("ABC", "ABC-#", 3).contains(1)); + assertTrue(getNextValues("ABC", "ABC-##", 3).contains(1)); + assertTrue(getNextValues("ABC", "ABC-###", 3).contains(1)); + deleteCounter("ABC"); + assertTrue(getNextValues("ABC", "ABC-#", 3).contains(1)); + assertTrue(getNextValues("ABC", "ABC-##", 3).contains(1)); + assertTrue(getNextValues("ABC", "ABC-###", 3).contains(1)); } - @Configuration - static class TestConfig { + private void test(final int threadCount) throws InterruptedException, ExecutionException { + final String uid = RandomStringUtils.randomAlphabetic(3).toUpperCase(); + Callable> task = () -> getNextValues(uid, uid + "-#", 50); + List>> tasks = Collections.nCopies(threadCount, task); + ExecutorService executorService = Executors.newFixedThreadPool(threadCount); + List>> futures = executorService.invokeAll(tasks); + List> resultList = new ArrayList<>(futures.size()); + // Check for exceptions + for (Future> future : futures) { + // Throws an exception if an exception was thrown by the task. + resultList.add(future.get()); + } + assertEquals(threadCount, futures.size()); + Set allIds = new HashSet<>(); + List allIdList = new ArrayList<>(); + for (List integers : resultList) { + allIds.addAll(integers); + allIdList.addAll(integers); + } + assertThat(allIds, hasSize(threadCount * 50)); + Collections.sort(allIdList); + assertThat(allIdList.get(0), is(1)); + assertThat(allIdList.get(allIdList.size() - 1), is(50 * threadCount)); + } - @Autowired private SequentialNumberCounterStore sequentialNumberCounterStore; + public List getNextValues(String uid, String key, int length) { + return sequentialNumberCounterStore.getNextValues(uid, key, length); + } - @Bean - public DummyService dummyService() { - return new DummyService(sequentialNumberCounterStore); - } + public void deleteCounter(String uid) { + sequentialNumberCounterStore.deleteCounter(uid); } } From 42731a43938c96cbc733fc7202f4d658798035ef Mon Sep 17 00:00:00 2001 From: luca Date: Wed, 17 Jan 2024 16:00:13 +0100 Subject: [PATCH 2/3] fix: remove random string, parameterize tests --- ...rnateSequentialNumberCounterStoreTest.java | 75 ++++++++----------- 1 file changed, 32 insertions(+), 43 deletions(-) diff --git a/dhis-2/dhis-test-integration/src/test/java/org/hisp/dhis/reservedvalue/hibernate/HibernateSequentialNumberCounterStoreTest.java b/dhis-2/dhis-test-integration/src/test/java/org/hisp/dhis/reservedvalue/hibernate/HibernateSequentialNumberCounterStoreTest.java index bafcda5e93ae..29df11d6e37d 100644 --- a/dhis-2/dhis-test-integration/src/test/java/org/hisp/dhis/reservedvalue/hibernate/HibernateSequentialNumberCounterStoreTest.java +++ b/dhis-2/dhis-test-integration/src/test/java/org/hisp/dhis/reservedvalue/hibernate/HibernateSequentialNumberCounterStoreTest.java @@ -43,10 +43,13 @@ import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.concurrent.Future; -import org.apache.commons.lang3.RandomStringUtils; +import java.util.stream.Stream; import org.hisp.dhis.reservedvalue.SequentialNumberCounterStore; import org.hisp.dhis.test.integration.TransactionalIntegrationTest; import org.junit.jupiter.api.Test; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.Arguments; +import org.junit.jupiter.params.provider.MethodSource; import org.springframework.beans.factory.annotation.Autowired; class HibernateSequentialNumberCounterStoreTest extends TransactionalIntegrationTest { @@ -55,12 +58,12 @@ class HibernateSequentialNumberCounterStoreTest extends TransactionalIntegration @Test void getNextValues() { - List result = getNextValues("ABC", "ABC-#", 3); + List result = nextSequentialValues("ABC", "ABC-#", 3); assertEquals(3, result.size()); assertTrue(result.contains(1)); assertTrue(result.contains(2)); assertTrue(result.contains(3)); - result = getNextValues("ABC", "ABC-#", 50); + result = nextSequentialValues("ABC", "ABC-#", 50); assertEquals(50, result.size()); assertTrue(result.contains(4)); assertTrue(result.contains(5)); @@ -68,47 +71,20 @@ void getNextValues() { assertTrue(result.contains(53)); } - @Test - void test1() throws InterruptedException, ExecutionException { - test(1); - } - - @Test - void test4() throws InterruptedException, ExecutionException { - test(4); - } - - @Test - void test8() throws InterruptedException, ExecutionException { - test(8); - } - - @Test - void test16() throws InterruptedException, ExecutionException { - test(16); - } - - @Test - void test32() throws InterruptedException, ExecutionException { - test(32); + private static Stream threadCounter() { + return Stream.of( + Arguments.of(1, "AAA"), + Arguments.of(4, "BBB"), + Arguments.of(8, "CCC"), + Arguments.of(16, "DDD"), + Arguments.of(32, "EEE")); } - @Test - void deleteCounter() { - assertTrue(getNextValues("ABC", "ABC-#", 3).contains(1)); - deleteCounter("ABC"); - assertTrue(getNextValues("ABC", "ABC-#", 3).contains(1)); - assertTrue(getNextValues("ABC", "ABC-##", 3).contains(1)); - assertTrue(getNextValues("ABC", "ABC-###", 3).contains(1)); - deleteCounter("ABC"); - assertTrue(getNextValues("ABC", "ABC-#", 3).contains(1)); - assertTrue(getNextValues("ABC", "ABC-##", 3).contains(1)); - assertTrue(getNextValues("ABC", "ABC-###", 3).contains(1)); - } - - private void test(final int threadCount) throws InterruptedException, ExecutionException { - final String uid = RandomStringUtils.randomAlphabetic(3).toUpperCase(); - Callable> task = () -> getNextValues(uid, uid + "-#", 50); + @ParameterizedTest + @MethodSource("threadCounter") + void shouldGenerateSequentialValueGivenThreadCounter(int threadCount, String uid) + throws InterruptedException, ExecutionException { + Callable> task = () -> nextSequentialValues(uid, uid + "-#", 50); List>> tasks = Collections.nCopies(threadCount, task); ExecutorService executorService = Executors.newFixedThreadPool(threadCount); List>> futures = executorService.invokeAll(tasks); @@ -131,7 +107,20 @@ private void test(final int threadCount) throws InterruptedException, ExecutionE assertThat(allIdList.get(allIdList.size() - 1), is(50 * threadCount)); } - public List getNextValues(String uid, String key, int length) { + @Test + void deleteCounter() { + assertTrue(nextSequentialValues("ABC", "ABC-#", 3).contains(1)); + deleteCounter("ABC"); + assertTrue(nextSequentialValues("ABC", "ABC-#", 3).contains(1)); + assertTrue(nextSequentialValues("ABC", "ABC-##", 3).contains(1)); + assertTrue(nextSequentialValues("ABC", "ABC-###", 3).contains(1)); + deleteCounter("ABC"); + assertTrue(nextSequentialValues("ABC", "ABC-#", 3).contains(1)); + assertTrue(nextSequentialValues("ABC", "ABC-##", 3).contains(1)); + assertTrue(nextSequentialValues("ABC", "ABC-###", 3).contains(1)); + } + + public List nextSequentialValues(String uid, String key, int length) { return sequentialNumberCounterStore.getNextValues(uid, key, length); } From 08c851ccb82b140c8152493c330e4f720c24c305 Mon Sep 17 00:00:00 2001 From: luca Date: Wed, 17 Jan 2024 16:13:46 +0100 Subject: [PATCH 3/3] fix: missing test dependency --- dhis-2/dhis-test-integration/pom.xml | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/dhis-2/dhis-test-integration/pom.xml b/dhis-2/dhis-test-integration/pom.xml index 3d965115cbdb..16838399b7f0 100644 --- a/dhis-2/dhis-test-integration/pom.xml +++ b/dhis-2/dhis-test-integration/pom.xml @@ -189,6 +189,11 @@ junit-jupiter-api test + + org.junit.jupiter + junit-jupiter-params + test + org.skyscreamer jsonassert