mirror of
https://github.com/VolmitSoftware/Iris.git
synced 2026-08-27 20:48:54 +00:00
dd
This commit is contained in:
+143
@@ -0,0 +1,143 @@
|
||||
package art.arcane.iris.modded;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.ExecutorService;
|
||||
import java.util.concurrent.Executors;
|
||||
import java.util.concurrent.Future;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.concurrent.atomic.AtomicLong;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertFalse;
|
||||
import static org.junit.Assert.assertNull;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
|
||||
public class InitialSpawnQueueTest {
|
||||
@Test
|
||||
public void rejectsDuplicatesAndEnforcesCapacityWhileInFlight() {
|
||||
InitialSpawnQueue queue = new InitialSpawnQueue(2);
|
||||
|
||||
assertTrue(queue.offer(1L));
|
||||
assertFalse(queue.offer(1L));
|
||||
assertTrue(queue.offer(2L));
|
||||
assertEquals(Long.valueOf(1L), queue.poll());
|
||||
assertFalse(queue.offer(3L));
|
||||
queue.complete(1L);
|
||||
assertTrue(queue.offer(3L));
|
||||
assertEquals(2, queue.size());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void retryRotatesWithoutBlockingReadyEntries() {
|
||||
InitialSpawnQueue queue = new InitialSpawnQueue(4);
|
||||
queue.offer(1L);
|
||||
queue.offer(2L);
|
||||
queue.offer(3L);
|
||||
|
||||
int budget = queue.batchSize(8);
|
||||
Long unavailable = queue.poll();
|
||||
queue.retry(unavailable);
|
||||
Long firstReady = queue.poll();
|
||||
queue.complete(firstReady);
|
||||
Long secondReady = queue.poll();
|
||||
queue.complete(secondReady);
|
||||
|
||||
assertEquals(3, budget);
|
||||
assertEquals(Long.valueOf(1L), unavailable);
|
||||
assertEquals(Long.valueOf(2L), firstReady);
|
||||
assertEquals(Long.valueOf(3L), secondReady);
|
||||
assertEquals(1, queue.batchSize(8));
|
||||
assertEquals(Long.valueOf(1L), queue.poll());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void retryIsDeduplicated() {
|
||||
InitialSpawnQueue queue = new InitialSpawnQueue(2);
|
||||
queue.offer(7L);
|
||||
Long key = queue.poll();
|
||||
|
||||
queue.retry(key);
|
||||
queue.retry(key);
|
||||
|
||||
assertEquals(1, queue.batchSize(8));
|
||||
assertEquals(Long.valueOf(7L), queue.poll());
|
||||
assertNull(queue.poll());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void closeClearsAndRejectsFurtherWork() {
|
||||
InitialSpawnQueue queue = new InitialSpawnQueue(2);
|
||||
queue.offer(1L);
|
||||
|
||||
queue.close();
|
||||
|
||||
assertTrue(queue.isEmpty());
|
||||
assertEquals(0, queue.size());
|
||||
assertFalse(queue.offer(2L));
|
||||
assertEquals(0, queue.batchSize(8));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void clearAllowsLaterWork() {
|
||||
InitialSpawnQueue queue = new InitialSpawnQueue(2);
|
||||
queue.offer(1L);
|
||||
|
||||
queue.clear();
|
||||
|
||||
assertTrue(queue.offer(2L));
|
||||
assertEquals(Long.valueOf(2L), queue.poll());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void expiredEntriesReleaseCapacity() {
|
||||
AtomicLong now = new AtomicLong();
|
||||
InitialSpawnQueue queue = new InitialSpawnQueue(2, 100L, now::get);
|
||||
queue.offer(1L);
|
||||
queue.offer(2L);
|
||||
|
||||
now.set(100L);
|
||||
|
||||
assertTrue(queue.offer(3L));
|
||||
assertEquals(1, queue.size());
|
||||
assertEquals(Long.valueOf(3L), queue.poll());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void expiredInFlightEntryCannotRetry() {
|
||||
AtomicLong now = new AtomicLong();
|
||||
InitialSpawnQueue queue = new InitialSpawnQueue(2, 100L, now::get);
|
||||
queue.offer(1L);
|
||||
Long inFlight = queue.poll();
|
||||
|
||||
now.set(100L);
|
||||
queue.retry(inFlight);
|
||||
|
||||
assertEquals(0, queue.size());
|
||||
assertNull(queue.poll());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void concurrentOffersRemainDeduplicatedAndBounded() throws Exception {
|
||||
InitialSpawnQueue queue = new InitialSpawnQueue(256);
|
||||
ExecutorService executor = Executors.newFixedThreadPool(8);
|
||||
List<Future<?>> futures = new ArrayList<>();
|
||||
for (int thread = 0; thread < 8; thread++) {
|
||||
futures.add(executor.submit(() -> {
|
||||
for (long key = 0L; key < 512L; key++) {
|
||||
queue.offer(key);
|
||||
}
|
||||
}));
|
||||
}
|
||||
for (Future<?> future : futures) {
|
||||
future.get();
|
||||
}
|
||||
executor.shutdown();
|
||||
|
||||
assertTrue(executor.awaitTermination(10L, TimeUnit.SECONDS));
|
||||
assertEquals(256, queue.size());
|
||||
assertEquals(256, queue.batchSize(512));
|
||||
}
|
||||
}
|
||||
+47
@@ -0,0 +1,47 @@
|
||||
package art.arcane.iris.modded;
|
||||
|
||||
import net.minecraft.SharedConstants;
|
||||
import net.minecraft.server.Bootstrap;
|
||||
import net.minecraft.util.random.Weighted;
|
||||
import net.minecraft.util.random.WeightedList;
|
||||
import net.minecraft.world.entity.EntityTypes;
|
||||
import net.minecraft.world.level.biome.MobSpawnSettings;
|
||||
import org.junit.Test;
|
||||
import org.junit.BeforeClass;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
|
||||
public class IrisModdedChunkGeneratorSpawnTest {
|
||||
@BeforeClass
|
||||
public static void bootstrapMinecraftRegistries() {
|
||||
SharedConstants.tryDetectVersion();
|
||||
Bootstrap.bootStrap();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void explicitSpawnsReplaceMatchingVanillaTypesAndPreserveOthers() {
|
||||
MobSpawnSettings.SpawnerData zombie = new MobSpawnSettings.SpawnerData(EntityTypes.ZOMBIE, 1, 4);
|
||||
MobSpawnSettings.SpawnerData vanillaSlime = new MobSpawnSettings.SpawnerData(EntityTypes.SLIME, 1, 1);
|
||||
MobSpawnSettings.SpawnerData explicitSlime = new MobSpawnSettings.SpawnerData(EntityTypes.SLIME, 2, 5);
|
||||
MobSpawnSettings.SpawnerData explicitCow = new MobSpawnSettings.SpawnerData(EntityTypes.COW, 2, 4);
|
||||
WeightedList<MobSpawnSettings.SpawnerData> vanilla = WeightedList.of(List.of(
|
||||
new Weighted<>(zombie, 100),
|
||||
new Weighted<>(vanillaSlime, 1)));
|
||||
WeightedList<MobSpawnSettings.SpawnerData> explicit = WeightedList.of(List.of(
|
||||
new Weighted<>(explicitSlime, 7),
|
||||
new Weighted<>(explicitCow, 3)));
|
||||
|
||||
WeightedList<MobSpawnSettings.SpawnerData> merged = NativeSpawnTableMerger.merge(vanilla, explicit);
|
||||
List<Weighted<MobSpawnSettings.SpawnerData>> entries = merged.unwrap();
|
||||
|
||||
assertEquals(3, entries.size());
|
||||
assertEquals(EntityTypes.ZOMBIE, entries.get(0).value().type());
|
||||
assertEquals(100, entries.get(0).weight());
|
||||
assertEquals(explicitSlime, entries.get(1).value());
|
||||
assertEquals(7, entries.get(1).weight());
|
||||
assertEquals(explicitCow, entries.get(2).value());
|
||||
assertEquals(3, entries.get(2).weight());
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,87 @@
|
||||
package art.arcane.iris.modded;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.atomic.AtomicBoolean;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertFalse;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
|
||||
public class ModdedWorldCheckTest {
|
||||
@Test
|
||||
public void coordinatorThreadIsNonDaemon() {
|
||||
Thread thread = ModdedWorldCheck.coordinatorThread(() -> {
|
||||
});
|
||||
|
||||
assertFalse(thread.isDaemon());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void passStopsServerBeforeZeroExit() {
|
||||
List<String> events = new ArrayList<>();
|
||||
|
||||
ModdedWorldCheck.stopAndExit(
|
||||
() -> events.add("stop"),
|
||||
0,
|
||||
status -> events.add("exit:" + status)
|
||||
);
|
||||
|
||||
assertEquals(List.of("stop", "exit:0"), events);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void failureStopsServerBeforeNonzeroExit() {
|
||||
List<String> events = new ArrayList<>();
|
||||
|
||||
ModdedWorldCheck.stopAndExit(
|
||||
() -> events.add("stop"),
|
||||
1,
|
||||
status -> events.add("exit:" + status)
|
||||
);
|
||||
|
||||
assertEquals(List.of("stop", "exit:1"), events);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shutdownFailureForcesNonzeroExit() {
|
||||
AtomicInteger status = new AtomicInteger(-1);
|
||||
|
||||
ModdedWorldCheck.stopAndExit(
|
||||
() -> {
|
||||
throw new IllegalStateException("shutdown failed");
|
||||
},
|
||||
0,
|
||||
status::set
|
||||
);
|
||||
|
||||
assertEquals(1, status.get());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void interruptionIsClearedForShutdownAndRestoredBeforeExit() {
|
||||
AtomicBoolean interruptedDuringStop = new AtomicBoolean(true);
|
||||
AtomicBoolean interruptedDuringExit = new AtomicBoolean(false);
|
||||
AtomicInteger status = new AtomicInteger(-1);
|
||||
Thread.currentThread().interrupt();
|
||||
try {
|
||||
ModdedWorldCheck.stopAndExit(
|
||||
() -> interruptedDuringStop.set(Thread.currentThread().isInterrupted()),
|
||||
0,
|
||||
exitStatus -> {
|
||||
status.set(exitStatus);
|
||||
interruptedDuringExit.set(Thread.currentThread().isInterrupted());
|
||||
}
|
||||
);
|
||||
|
||||
assertFalse(interruptedDuringStop.get());
|
||||
assertTrue(interruptedDuringExit.get());
|
||||
assertEquals(1, status.get());
|
||||
} finally {
|
||||
Thread.interrupted();
|
||||
}
|
||||
}
|
||||
}
|
||||
+23
@@ -0,0 +1,23 @@
|
||||
package art.arcane.iris.modded.service;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
import static org.junit.Assert.assertFalse;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
|
||||
public class ModdedChunkUpdateServiceTest {
|
||||
@Test
|
||||
public void scansWhenPlayersArePresent() {
|
||||
assertTrue(ModdedChunkUpdateService.hasUpdateTargets(true, false));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void scansHeadlessForceLoadedChunks() {
|
||||
assertTrue(ModdedChunkUpdateService.hasUpdateTargets(false, true));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void skipsLevelsWithoutPlayersOrForcedChunks() {
|
||||
assertFalse(ModdedChunkUpdateService.hasUpdateTargets(false, false));
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user