From e38410a1ea73294541c24ca6074386436a28ef09 Mon Sep 17 00:00:00 2001 From: ScarletRedMan Date: Sat, 16 Mar 2024 15:43:47 +0700 Subject: [PATCH] Tried to fix test, but LeastPicker and SequentialFilling do no passing --- .../repository/impl/container/NodeContainer.java | 14 ++++++++------ .../repository/impl/container/RoomContainer.java | 1 + .../repository/impl/picker/LeastPickedPicker.java | 7 ++++++- .../repository/impl/picker/RoundRobinPicker.java | 7 ++++++- .../impl/picker/SequentialFillingPicker.java | 7 ++++++- .../picker/picker/LeastPickedTests.java | 10 ++++------ .../dragonestia/picker/picker/RoundRobinTests.java | 9 +++------ .../picker/picker/SequentialFillingTests.java | 10 ++++------ .../picker/service/RoomServiceTests.java | 5 +++-- .../ru/dragonestia/picker/util/UserFiller.java | 12 +++++------- 10 files changed, 46 insertions(+), 36 deletions(-) diff --git a/server/src/main/java/ru/dragonestia/picker/repository/impl/container/NodeContainer.java b/server/src/main/java/ru/dragonestia/picker/repository/impl/container/NodeContainer.java index cf7fa9b..e436b90 100644 --- a/server/src/main/java/ru/dragonestia/picker/repository/impl/container/NodeContainer.java +++ b/server/src/main/java/ru/dragonestia/picker/repository/impl/container/NodeContainer.java @@ -35,9 +35,9 @@ public class NodeContainer { private @NotNull RoomPicker initPicker() { return switch (node.getPickingMethod()) { - case SEQUENTIAL_FILLING -> new SequentialFillingPicker(); - case ROUND_ROBIN -> new RoundRobinPicker(); - case LEAST_PICKED -> new LeastPickedPicker(); + case SEQUENTIAL_FILLING -> new SequentialFillingPicker(this); + case ROUND_ROBIN -> new RoundRobinPicker(this); + case LEAST_PICKED -> new LeastPickedPicker(this); }; } @@ -93,9 +93,11 @@ public class NodeContainer { } public @NotNull Room pick(@NotNull Set users) { - var room = picker.pick(users); - transactionListener.accept(new UserTransaction(room.getRoom(), users)); - return room.getRoom(); + synchronized (picker) { + var room = picker.pick(users); + transactionListener.accept(new UserTransaction(room.getRoom(), users)); + return room.getRoom(); + } } public @NotNull RoomPicker getPicker() { diff --git a/server/src/main/java/ru/dragonestia/picker/repository/impl/container/RoomContainer.java b/server/src/main/java/ru/dragonestia/picker/repository/impl/container/RoomContainer.java index 285f3ef..bf7d60f 100644 --- a/server/src/main/java/ru/dragonestia/picker/repository/impl/container/RoomContainer.java +++ b/server/src/main/java/ru/dragonestia/picker/repository/impl/container/RoomContainer.java @@ -90,6 +90,7 @@ public class RoomContainer { } public boolean canBePicked(int users) { + usersLock.readLock().lock(); try { return !room.isLocked() && canAdd0(users); } finally { diff --git a/server/src/main/java/ru/dragonestia/picker/repository/impl/picker/LeastPickedPicker.java b/server/src/main/java/ru/dragonestia/picker/repository/impl/picker/LeastPickedPicker.java index 0ad981c..aa6863c 100644 --- a/server/src/main/java/ru/dragonestia/picker/repository/impl/picker/LeastPickedPicker.java +++ b/server/src/main/java/ru/dragonestia/picker/repository/impl/picker/LeastPickedPicker.java @@ -1,16 +1,21 @@ package ru.dragonestia.picker.repository.impl.picker; +import lombok.RequiredArgsConstructor; +import ru.dragonestia.picker.api.exception.NoRoomsAvailableException; import ru.dragonestia.picker.api.model.node.PickingMethod; import ru.dragonestia.picker.model.Room; import ru.dragonestia.picker.model.User; import ru.dragonestia.picker.repository.UserRepository; import ru.dragonestia.picker.repository.impl.collection.DynamicSortedMap; +import ru.dragonestia.picker.repository.impl.container.NodeContainer; import ru.dragonestia.picker.repository.impl.container.RoomContainer; import java.util.Collection; +@RequiredArgsConstructor public class LeastPickedPicker implements RoomPicker { + private final NodeContainer container; private final DynamicSortedMap map = new DynamicSortedMap<>(); @Override @@ -37,7 +42,7 @@ public class LeastPickedPicker implements RoomPicker { if (!wrapper.canAddUnits(users.size())) throw new RuntimeException(); } catch (RuntimeException ex) { - throw new RuntimeException("There are no rooms available"); + throw new NoRoomsAvailableException(container.getNode().getIdentifier()); } } diff --git a/server/src/main/java/ru/dragonestia/picker/repository/impl/picker/RoundRobinPicker.java b/server/src/main/java/ru/dragonestia/picker/repository/impl/picker/RoundRobinPicker.java index 48906db..f423cb0 100644 --- a/server/src/main/java/ru/dragonestia/picker/repository/impl/picker/RoundRobinPicker.java +++ b/server/src/main/java/ru/dragonestia/picker/repository/impl/picker/RoundRobinPicker.java @@ -1,15 +1,20 @@ package ru.dragonestia.picker.repository.impl.picker; +import lombok.RequiredArgsConstructor; +import ru.dragonestia.picker.api.exception.NoRoomsAvailableException; import ru.dragonestia.picker.api.model.node.PickingMethod; import ru.dragonestia.picker.model.User; import ru.dragonestia.picker.repository.impl.collection.QueuedLinkedList; +import ru.dragonestia.picker.repository.impl.container.NodeContainer; import ru.dragonestia.picker.repository.impl.container.RoomContainer; import java.util.Collection; import java.util.concurrent.atomic.AtomicInteger; +@RequiredArgsConstructor public class RoundRobinPicker implements RoomPicker { + private final NodeContainer container; private final AtomicInteger addition = new AtomicInteger(0); private final QueuedLinkedList list = new QueuedLinkedList<>(wrapper -> wrapper.canAddUnits(addition.get())); @@ -37,7 +42,7 @@ public class RoundRobinPicker implements RoomPicker { addition.set(amount); wrapper = list.pick(); } catch (RuntimeException ex) { - throw new RuntimeException("There are no rooms available"); + throw new NoRoomsAvailableException(container.getNode().getIdentifier()); } } diff --git a/server/src/main/java/ru/dragonestia/picker/repository/impl/picker/SequentialFillingPicker.java b/server/src/main/java/ru/dragonestia/picker/repository/impl/picker/SequentialFillingPicker.java index a91b27a..ca954f5 100644 --- a/server/src/main/java/ru/dragonestia/picker/repository/impl/picker/SequentialFillingPicker.java +++ b/server/src/main/java/ru/dragonestia/picker/repository/impl/picker/SequentialFillingPicker.java @@ -1,15 +1,20 @@ package ru.dragonestia.picker.repository.impl.picker; +import lombok.RequiredArgsConstructor; +import ru.dragonestia.picker.api.exception.NoRoomsAvailableException; import ru.dragonestia.picker.api.model.node.PickingMethod; import ru.dragonestia.picker.model.User; +import ru.dragonestia.picker.repository.impl.container.NodeContainer; import ru.dragonestia.picker.repository.impl.container.RoomContainer; import java.util.Collection; import java.util.LinkedHashMap; import java.util.Map; +@RequiredArgsConstructor public class SequentialFillingPicker implements RoomPicker { + private final NodeContainer container; private final Map wrappers = new LinkedHashMap<>(); @Override @@ -38,7 +43,7 @@ public class SequentialFillingPicker implements RoomPicker { } } - throw new RuntimeException("There are no rooms available"); + throw new NoRoomsAvailableException(container.getNode().getIdentifier()); } @Override diff --git a/server/src/test/java/ru/dragonestia/picker/picker/LeastPickedTests.java b/server/src/test/java/ru/dragonestia/picker/picker/LeastPickedTests.java index 5b2dab3..3256668 100644 --- a/server/src/test/java/ru/dragonestia/picker/picker/LeastPickedTests.java +++ b/server/src/test/java/ru/dragonestia/picker/picker/LeastPickedTests.java @@ -10,6 +10,7 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.context.annotation.Import; +import ru.dragonestia.picker.api.exception.NoRoomsAvailableException; import ru.dragonestia.picker.config.FillingNodesConfig; import ru.dragonestia.picker.model.Node; import ru.dragonestia.picker.repository.RoomRepository; @@ -40,14 +41,12 @@ public class LeastPickedTests { @ParameterizedTest @ArgumentsSource(PickingArgumentProvider.class) void testPicking(String expectedRoomId, int usersAmount) { - var roomOpt = roomRepository.pick(node, userFiller.createRandomUsers(usersAmount)); - Assertions.assertTrue(roomOpt.isPresent()); - - var room = roomOpt.get(); + var room = roomRepository.pick(node, userFiller.createRandomUsers(usersAmount)); var slots = room.getMaxSlots(); var users = userRepository.usersOf(room); Assertions.assertTrue(slots == -1 || slots >= users.size()); // check slots limitation + System.out.printf("Room(%s) has %s/%s users. Expected: %s, added: %s%n", room.getIdentifier(), users.size(), slots, expectedRoomId, usersAmount); Assertions.assertEquals(expectedRoomId, room.getIdentifier()); } @@ -73,7 +72,6 @@ public class LeastPickedTests { @Timeout(value = 1, threadMode = Timeout.ThreadMode.SEPARATE_THREAD) @Test void testNoOneRoomExpected() { // Take 9 users. expected none result - var roomOpt = roomRepository.pick(node, userFiller.createRandomUsers(9)); - Assertions.assertTrue(roomOpt.isEmpty()); + Assertions.assertThrows(NoRoomsAvailableException.class, () -> roomRepository.pick(node, userFiller.createRandomUsers(9))); } } diff --git a/server/src/test/java/ru/dragonestia/picker/picker/RoundRobinTests.java b/server/src/test/java/ru/dragonestia/picker/picker/RoundRobinTests.java index 6bc5684..5ab780d 100644 --- a/server/src/test/java/ru/dragonestia/picker/picker/RoundRobinTests.java +++ b/server/src/test/java/ru/dragonestia/picker/picker/RoundRobinTests.java @@ -8,6 +8,7 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.context.annotation.Import; +import ru.dragonestia.picker.api.exception.NoRoomsAvailableException; import ru.dragonestia.picker.config.FillingNodesConfig; import ru.dragonestia.picker.model.Node; import ru.dragonestia.picker.repository.RoomRepository; @@ -38,10 +39,7 @@ public class RoundRobinTests { @ParameterizedTest @ArgumentsSource(PickingArgumentProvider.class) void testPicking(String expectedRoomId, int usersAmount) { - var roomOpt = roomRepository.pick(node, userFiller.createRandomUsers(usersAmount)); - Assertions.assertTrue(roomOpt.isPresent()); - - var room = roomOpt.get(); + var room = roomRepository.pick(node, userFiller.createRandomUsers(usersAmount)); var slots = room.getMaxSlots(); var users = userRepository.usersOf(room); Assertions.assertTrue(slots == -1 || slots >= users.size()); // check slots limitation @@ -68,7 +66,6 @@ public class RoundRobinTests { @Timeout(value = 1, threadMode = Timeout.ThreadMode.SEPARATE_THREAD) @Test void testNoOneRoomExpected() { // Take 9 users. expected none result - var roomOpt = roomRepository.pick(node, userFiller.createRandomUsers(9)); - Assertions.assertTrue(roomOpt.isEmpty()); + Assertions.assertThrows(NoRoomsAvailableException.class, () -> roomRepository.pick(node, userFiller.createRandomUsers(9))); } } diff --git a/server/src/test/java/ru/dragonestia/picker/picker/SequentialFillingTests.java b/server/src/test/java/ru/dragonestia/picker/picker/SequentialFillingTests.java index 3cac375..9ece42d 100644 --- a/server/src/test/java/ru/dragonestia/picker/picker/SequentialFillingTests.java +++ b/server/src/test/java/ru/dragonestia/picker/picker/SequentialFillingTests.java @@ -10,6 +10,7 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.context.annotation.Import; +import ru.dragonestia.picker.api.exception.NoRoomsAvailableException; import ru.dragonestia.picker.config.FillingNodesConfig; import ru.dragonestia.picker.model.Node; import ru.dragonestia.picker.repository.RoomRepository; @@ -40,14 +41,12 @@ public class SequentialFillingTests { @ParameterizedTest @ArgumentsSource(PickingArgumentProvider.class) void testPicking(String expectedRoomId, int usersAmount) { - var roomOpt = roomRepository.pick(node, userFiller.createRandomUsers(usersAmount)); - Assertions.assertTrue(roomOpt.isPresent()); - - var room = roomOpt.get(); + var room = roomRepository.pick(node, userFiller.createRandomUsers(usersAmount)); var slots = room.getMaxSlots(); var users = userRepository.usersOf(room); Assertions.assertTrue(slots == -1 || slots >= users.size()); // check slots limitation + System.out.printf("Room(%s) has %s/%s users. Expected: %s, added: %s%n", room.getIdentifier(), users.size(), slots, expectedRoomId, usersAmount); Assertions.assertEquals(expectedRoomId, room.getIdentifier()); } @@ -70,7 +69,6 @@ public class SequentialFillingTests { @Timeout(value = 1, threadMode = Timeout.ThreadMode.SEPARATE_THREAD) @Test void testNoOneRoomExpected() { // Take 9 users. expected none result - var roomOpt = roomRepository.pick(node, userFiller.createRandomUsers(9)); - Assertions.assertTrue(roomOpt.isEmpty()); + Assertions.assertThrows(NoRoomsAvailableException.class, () -> roomRepository.pick(node, userFiller.createRandomUsers(9))); } } diff --git a/server/src/test/java/ru/dragonestia/picker/service/RoomServiceTests.java b/server/src/test/java/ru/dragonestia/picker/service/RoomServiceTests.java index 304e87a..0968f54 100644 --- a/server/src/test/java/ru/dragonestia/picker/service/RoomServiceTests.java +++ b/server/src/test/java/ru/dragonestia/picker/service/RoomServiceTests.java @@ -21,6 +21,7 @@ import ru.dragonestia.picker.model.factory.RoomFactory; import ru.dragonestia.picker.model.type.SlotLimit; import java.util.List; +import java.util.Set; @SpringBootTest public class RoomServiceTests { @@ -93,7 +94,7 @@ public class RoomServiceTests { rooms.forEach(room -> roomService.create(room)); - var users = List.of( + var users = Set.of( new User(UserIdentifier.of("1")), new User(UserIdentifier.of("2")), new User(UserIdentifier.of("3")), @@ -121,6 +122,6 @@ public class RoomServiceTests { Assertions.assertThrows(NodeNotFoundException.class, () -> roomService.create(room)); Assertions.assertThrows(NodeNotFoundException.class, () -> roomService.remove(room)); Assertions.assertThrows(NodeNotFoundException.class, () -> roomService.find(node, "Bruh")); - Assertions.assertThrows(NodeNotFoundException.class, () -> roomService.pickAvailable(node, List.of(new User(UserIdentifier.of("1"))))); + Assertions.assertThrows(NodeNotFoundException.class, () -> roomService.pickAvailable(node, Set.of(new User(UserIdentifier.of("1"))))); } } diff --git a/server/src/test/java/ru/dragonestia/picker/util/UserFiller.java b/server/src/test/java/ru/dragonestia/picker/util/UserFiller.java index 0c17815..1f6f53f 100644 --- a/server/src/test/java/ru/dragonestia/picker/util/UserFiller.java +++ b/server/src/test/java/ru/dragonestia/picker/util/UserFiller.java @@ -4,18 +4,16 @@ import org.springframework.boot.test.context.TestComponent; import ru.dragonestia.picker.api.repository.type.UserIdentifier; import ru.dragonestia.picker.model.User; -import java.util.LinkedList; -import java.util.List; -import java.util.UUID; +import java.util.*; @TestComponent public class UserFiller { - public List createRandomUsers(int amount) { - var list = new LinkedList(); + public Set createRandomUsers(int amount) { + var set = new HashSet(); for (int i = 0; i < amount; i++) { - list.add(new User(UserIdentifier.of(UUID.randomUUID().toString()))); + set.add(new User(UserIdentifier.of(UUID.randomUUID().toString()))); } - return list; + return set; } }