This commit is contained in:
Brian Neumann-Fopiano
2026-07-10 04:05:24 -04:00
parent 6111b5670a
commit 402bcb04fe
112 changed files with 5610 additions and 733 deletions
@@ -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));
}
}
@@ -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();
}
}
}
@@ -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));
}
}