diff --git a/adapters/bukkit/plugin/build.gradle b/adapters/bukkit/plugin/build.gradle index f0ecff140..f0a3df139 100644 --- a/adapters/bukkit/plugin/build.gradle +++ b/adapters/bukkit/plugin/build.gradle @@ -59,12 +59,4 @@ tasks.named('jar', Jar).configure { } tasks.named('test').configure { - systemProperty('iris.pregeneratorJobSource', rootProject.file('core/src/main/java/art/arcane/iris/core/gui/PregeneratorJob.java').absolutePath) - systemProperty('iris.bukkitEnginePlatformHooksSource', file('src/main/java/art/arcane/iris/core/runtime/BukkitEnginePlatformHooks.java').absolutePath) - systemProperty('iris.engineSvcSource', file('src/main/java/art/arcane/iris/core/service/IrisEngineSVC.java').absolutePath) - systemProperty('iris.terrainSvcSource', file('src/main/java/art/arcane/iris/core/service/IrisTerrainSVC.java').absolutePath) - systemProperty('iris.apiEventSvcSource', file('src/main/java/art/arcane/iris/core/service/IrisApiEventSVC.java').absolutePath) - systemProperty('iris.worldInfoFactorySource', file('src/main/java/art/arcane/iris/core/service/terrain/IrisWorldInfoFactory.java').absolutePath) - systemProperty('iris.startupSource', file('src/main/java/art/arcane/iris/Iris.java').absolutePath) - systemProperty('iris.readmeSource', rootProject.file('README.md').absolutePath) } diff --git a/adapters/bukkit/plugin/src/test/java/art/arcane/iris/IrisDiagnosticLogLevelTest.java b/adapters/bukkit/plugin/src/test/java/art/arcane/iris/IrisDiagnosticLogLevelTest.java index e6842d9c1..2cd3c60c5 100644 --- a/adapters/bukkit/plugin/src/test/java/art/arcane/iris/IrisDiagnosticLogLevelTest.java +++ b/adapters/bukkit/plugin/src/test/java/art/arcane/iris/IrisDiagnosticLogLevelTest.java @@ -3,14 +3,10 @@ package art.arcane.iris; import art.arcane.iris.spi.LogLevel; import org.junit.Test; -import java.nio.file.Files; -import java.nio.file.Path; import java.util.logging.Level; import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertNull; -import static org.junit.Assert.assertTrue; /** * Core states a severity on every message it logs and the modded adapters honour it. Bukkit must preserve @@ -33,58 +29,4 @@ public class IrisDiagnosticLogLevelTest { public void lifecycleNoticesReachThePluginLoggerAtInfo() { assertEquals(Level.INFO, Iris.diagnosticLevel(LogLevel.NOTICE)); } - - @Test - public void adapterSideWarningsCarryTheSameSeverityAsCoreWarnings() throws Exception { - String source = Files.readString(Path.of("src/main/java/art/arcane/iris/Iris.java")).replace("\r\n", "\n"); - - String warn = method(source, "public static void warn(String format, Object... objs)"); - assertTrue(warn, warn.contains("diagnostic(Level.WARNING")); - assertFalse(warn, warn.contains("msg(")); - - String error = method(source, "public static void error(String format, Object... objs)"); - assertTrue(error, error.contains("diagnostic(Level.SEVERE")); - assertFalse(error, error.contains("msg(")); - } - - @Test - public void theCoreLogBridgeRoutesDiagnosticsToThePluginLogger() throws Exception { - String source = Files.readString(Path.of("src/main/java/art/arcane/iris/Iris.java")).replace("\r\n", "\n"); - String bridge = method(source, "private static void bridgeLog(LogLevel level, String message)"); - - assertTrue(bridge, bridge.contains("diagnosticLevel(target)")); - assertTrue(bridge, bridge.contains("diagnostic(diagnostic, message)")); - String diagnostic = method(source, "private static void diagnostic(Level level, String message)"); - assertTrue(diagnostic, diagnostic.contains("ComponentLog.log(")); - assertTrue(diagnostic, diagnostic.contains("ComponentText.literal(line)")); - } - - @Test - public void informationalMessagesUseTheSharedComponentLogger() throws Exception { - String source = Files.readString(Path.of("src/main/java/art/arcane/iris/Iris.java")).replace("\r\n", "\n"); - String message = method(source, "public static void msg(String string)"); - - assertTrue(message, message.contains("ComponentLog.logMarkup(")); - assertTrue(message, message.contains("logPrefix(plugin)")); - assertFalse(message, message.contains("getSender().sendMessage")); - } - - private static String method(String source, String signature) { - int start = source.indexOf(signature); - assertTrue("method not found: " + signature, start >= 0); - int open = source.indexOf('{', start); - int depth = 0; - for (int i = open; i < source.length(); i++) { - char c = source.charAt(i); - if (c == '{') { - depth++; - } else if (c == '}') { - depth--; - if (depth == 0) { - return source.substring(start, i + 1); - } - } - } - throw new AssertionError("unterminated method: " + signature); - } } diff --git a/adapters/bukkit/plugin/src/test/java/art/arcane/iris/core/IrisStartupOrderingTest.java b/adapters/bukkit/plugin/src/test/java/art/arcane/iris/core/IrisStartupOrderingTest.java deleted file mode 100644 index 00365eba2..000000000 --- a/adapters/bukkit/plugin/src/test/java/art/arcane/iris/core/IrisStartupOrderingTest.java +++ /dev/null @@ -1,72 +0,0 @@ -package art.arcane.iris.core; - -import org.junit.Test; - -import java.nio.file.Files; -import java.nio.file.Path; - -import static org.junit.Assert.assertTrue; - -public class IrisStartupOrderingTest { - @Test - public void admissionGateIsRegisteredBeforeStartupValidationBegins() throws Exception { - String source = Files.readString(Path.of(System.getProperty("iris.startupSource"))); - String onEnable = section(source, "public void onEnable()", "public void onDisable()"); - - assertOrdered(onEnable, - "IrisStartupValidation.begin();", - "registerEvents(new IrisStartupAdmissionListener(), this);", - "enable();"); - } - - @Test - public void externalDatapacksValidateBeforeDimensionPacks() throws Exception { - String source = Files.readString(Path.of(System.getProperty("iris.startupSource"))); - String enable = section(source, "private boolean enable()", "public void addShutdownHook()"); - - assertOrdered(enable, - "DatapackIngestService.validateOnStartup();", - "generatorResolver.validateAllPacks();"); - } - - @Test - public void externalProvidersEnableBeforePackValidation() throws Exception { - String source = Files.readString(Path.of(System.getProperty("iris.startupSource"))); - String enable = section(source, "private boolean enable()", "public void addShutdownHook()"); - - assertOrdered(enable, - "service.onEnable();", - "setContentChangeListener(generatorResolver::requestExternalContentRefresh)", - "generatorResolver.validateAllPacks();"); - } - - @Test - public void restartRequiredStartupTerminatesAfterPluginInitialization() throws Exception { - String source = Files.readString(Path.of(System.getProperty("iris.startupSource"))); - String onEnable = section(source, "public void onEnable()", "public void onDisable()"); - - assertOrdered(onEnable, - "BukkitGuiHost.install();", - "super.onEnable();", - "IrisStartupValidation.isRestartRequired()", - "ServerConfigurator.restartAtStartupBoundary(restartReason);"); - } - - private static String section(String source, String startMarker, String endMarker) { - int start = source.indexOf(startMarker); - int end = source.indexOf(endMarker, start); - assertTrue("Missing source section starting with " + startMarker, start >= 0); - assertTrue("Missing source section ending with " + endMarker, end > start); - return source.substring(start, end); - } - - private static void assertOrdered(String source, String... markers) { - int previous = -1; - for (String marker : markers) { - int current = source.indexOf(marker); - assertTrue("Missing source marker " + marker, current >= 0); - assertTrue("Source marker is out of order: " + marker, current > previous); - previous = current; - } - } -} diff --git a/adapters/bukkit/plugin/src/test/java/art/arcane/iris/core/IrisWorldGeneratorResolverTest.java b/adapters/bukkit/plugin/src/test/java/art/arcane/iris/core/IrisWorldGeneratorResolverTest.java index 4b57daca7..72c15df4a 100644 --- a/adapters/bukkit/plugin/src/test/java/art/arcane/iris/core/IrisWorldGeneratorResolverTest.java +++ b/adapters/bukkit/plugin/src/test/java/art/arcane/iris/core/IrisWorldGeneratorResolverTest.java @@ -140,23 +140,6 @@ public class IrisWorldGeneratorResolverTest { } } - @Test - public void startupValidationPublishesFingerprintBoundExactRootResults() throws Exception { - String source = Files.readString(Path.of( - "src/main/java/art/arcane/iris/core/IrisWorldGeneratorResolver.java")).replace("\r\n", "\n"); - int validateAll = source.indexOf("public void validateAllPacks()"); - int snapshot = source.indexOf("ServerConfigurator.computePackContentSnapshot(packsRoot)", validateAll); - int perPackFingerprint = source.indexOf("contentSnapshot.packContents()", snapshot); - int exactRootPublish = source.indexOf( - "PackValidationRegistry.publish(packDirectory.toPath(), result, packFingerprint)", - perPackFingerprint); - - assertTrue(validateAll >= 0); - assertTrue(snapshot > validateAll); - assertTrue(perPackFingerprint > snapshot); - assertTrue(exactRootPublish > perPackFingerprint); - } - @Test public void paperStartupAliasResolvesToCanonicalRuntimeKey() throws Exception { File levelRoot = ownedLevelRoot("startup-alias", "moon"); @@ -251,87 +234,6 @@ public class IrisWorldGeneratorResolverTest { return levelRoot; } - @Test - public void configuredWorldResolutionUsesOnlyActiveImmutableGenerationPack() throws Exception { - String source = Files.readString(Path.of( - "src/main/java/art/arcane/iris/core/IrisWorldGeneratorResolver.java")).replace("\r\n", "\n"); - int resolverStart = source.indexOf("private ChunkGenerator resolveFrozenWorldGenerator("); - int resolverEnd = source.indexOf("private record FreshValidation", resolverStart); - String resolver = source.substring(resolverStart, resolverEnd); - - int dimensionRoot = resolver.indexOf("IrisWorldStorage.requireFrozenDimensionRoot("); - int currentPlatformRoot = resolver.indexOf("WorldCreatorCompat.persistentDimensionRoot(worldKey)"); - int layoutRefusal = resolver.indexOf( - "Frozen Iris world storage does not match the current platform layout", - currentPlatformRoot - ); - int history = resolver.indexOf("requireGenerationHistory(dimensionRoot, id, worldSeed)"); - int snapshotRoot = resolver.indexOf("requireActivePack(history)", history); - int validation = resolver.indexOf("requireSnapshotLoadable(snapshotRoot)"); - int exactLoad = resolver.indexOf("requireHistoricalDimension(history, snapshotRoot, id)"); - int canonicalIdentity = resolver.indexOf(".platformIdentity(worldKey.toString())"); - int historicalSeed = resolver.indexOf(".seed(history.activeEpoch().worldSeed())"); - int resolvedStorage = resolver.indexOf(".worldFolder(dimensionRoot)"); - - assertTrue(dimensionRoot >= 0); - assertTrue(currentPlatformRoot > dimensionRoot); - assertTrue(layoutRefusal > currentPlatformRoot); - assertTrue(history > layoutRefusal); - assertTrue(snapshotRoot > history); - assertTrue(validation > snapshotRoot); - assertTrue(exactLoad > validation); - assertTrue(canonicalIdentity > exactLoad); - assertTrue(historicalSeed > canonicalIdentity); - assertTrue(resolvedStorage > historicalSeed); - assertFalse(resolver.contains("loadDimension(")); - assertFalse(resolver.contains("loadAnyDimension(")); - assertFalse(resolver.contains("replaceIntoWorld(")); - assertFalse(resolver.contains("installIntoWorld(")); - assertFalse(resolver.contains(".seed(1337)")); - assertTrue(resolver.contains("GenerationHistory.openIfPresent(root, worldSeed)")); - assertTrue(resolver.contains("GenerationHistory.adoptLegacyPack(")); - assertTrue(resolver.contains("GenerationRegistryContractFactory.captureRequiredDefinitions(")); - } - - @Test - public void ownedWorldSnapshotFailureStopsStartupAndRethrows() throws Exception { - String source = Files.readString(Path.of( - "src/main/java/art/arcane/iris/core/IrisWorldGeneratorResolver.java")).replace("\r\n", "\n"); - int resolverStart = source.indexOf("public ChunkGenerator resolveDefaultWorldGenerator("); - int resolverEnd = source.indexOf("private ChunkGenerator resolveFrozenWorldGenerator(", resolverStart); - String resolver = source.substring(resolverStart, resolverEnd); - - int plotSquaredProbe = resolver.indexOf("isPlotSquaredGeneratorDiscoveryProbe(worldName, id)"); - int probe = resolver.indexOf("isGeneratorDiscoveryProbe(worldName, id)", plotSquaredProbe); - int denial = resolver.indexOf("IrisStartupValidation.denialReason()", probe); - int failClosed = resolver.indexOf("IrisFailClosedChunkGenerator.startupLock(", denial); - int staged = resolver.indexOf("WorldLifecycleStaging.consumeGenerator(worldName)", failClosed); - int duplicateGuard = resolver.indexOf("requireWorldKeyAvailable(worldName, worldKey)"); - int ownership = resolver.indexOf("requireOwnedWorld(worldName, levelRoot, worldKey)"); - int frozen = resolver.indexOf("return resolveFrozenWorldGenerator(", ownership); - int failureCapture = resolver.indexOf("catch (RuntimeException failure)", frozen); - int report = resolver.indexOf("Iris.reportError(", failureCapture); - int shutdown = resolver.indexOf("Bukkit.shutdown()", report); - int rethrow = resolver.indexOf("throw failure", shutdown); - - assertTrue(plotSquaredProbe >= 0); - assertTrue(probe > plotSquaredProbe); - assertTrue(denial > probe); - assertTrue(failClosed > denial); - assertTrue(staged > failClosed); - assertTrue(duplicateGuard > staged); - assertTrue(ownership > duplicateGuard); - assertTrue(frozen > ownership); - assertTrue(failureCapture > frozen); - assertTrue(report > failureCapture); - assertTrue(shutdown > report); - assertTrue(rethrow > shutdown); - - String shutdownScope = "the fail-fast shutdown must stay scoped to the frozen snapshot of an owned world"; - assertEquals(shutdownScope, resolverStart + shutdown, source.indexOf("Bukkit.shutdown()")); - assertEquals(shutdownScope, resolverStart + shutdown, source.lastIndexOf("Bukkit.shutdown()")); - } - @Test public void plotSquaredDiscoveryProbeIsIgnoredQuietly() { try (MockedStatic bukkit = mockStatic(Bukkit.class); diff --git a/adapters/bukkit/plugin/src/test/java/art/arcane/iris/core/commands/CommandDeveloperGenerationHistoryTest.java b/adapters/bukkit/plugin/src/test/java/art/arcane/iris/core/commands/CommandDeveloperGenerationHistoryTest.java deleted file mode 100644 index c2308b371..000000000 --- a/adapters/bukkit/plugin/src/test/java/art/arcane/iris/core/commands/CommandDeveloperGenerationHistoryTest.java +++ /dev/null @@ -1,26 +0,0 @@ -package art.arcane.iris.core.commands; - -import org.junit.Test; - -import java.nio.file.Files; -import java.nio.file.Path; - -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertTrue; - -public final class CommandDeveloperGenerationHistoryTest { - @Test - public void updateWorldStagesThePackWithTheLiveWorldSeed() throws Exception { - String source = Files.readString(Path.of( - "src/main/java/art/arcane/iris/core/commands/CommandDeveloper.java" - )).replace("\r\n", "\n"); - int updateStart = source.indexOf("public void updateWorld("); - int updateEnd = source.indexOf("@Director(description = \"Test\"", updateStart); - String update = source.substring(updateStart, updateEnd); - - assertTrue(update.contains( - "replaceIntoWorld(sender(), pack, folder, world.getSeed())" - )); - assertFalse(update.contains("iris/pack")); - } -} diff --git a/adapters/bukkit/plugin/src/test/java/art/arcane/iris/core/commands/CommandIrisCreateOverwriteContractTest.java b/adapters/bukkit/plugin/src/test/java/art/arcane/iris/core/commands/CommandIrisCreateOverwriteContractTest.java index 70fcb612b..1ad9b1891 100644 --- a/adapters/bukkit/plugin/src/test/java/art/arcane/iris/core/commands/CommandIrisCreateOverwriteContractTest.java +++ b/adapters/bukkit/plugin/src/test/java/art/arcane/iris/core/commands/CommandIrisCreateOverwriteContractTest.java @@ -7,8 +7,6 @@ import org.junit.Test; import java.lang.reflect.Method; import java.lang.reflect.Parameter; -import java.nio.file.Files; -import java.nio.file.Path; import java.util.Arrays; import static org.junit.Assert.assertEquals; @@ -73,26 +71,4 @@ public class CommandIrisCreateOverwriteContractTest { assertEquals(Long.valueOf(Long.MAX_VALUE), handler.parse(Long.toString(Long.MAX_VALUE), false)); assertThrows(DirectorParsingException.class, () -> handler.parse("9223372036854775808", false)); } - - @Test - public void createAndReplaceUseLocalizedStyledMissingDimensionFeedback() throws Exception { - String source = Files.readString(Path.of( - "src/main/java/art/arcane/iris/core/commands/CommandIris.java" - )).replace("\r\n", "\n"); - - assertEquals(2, occurrences(source, "COMMAND_IRIS_DIMENSION_NOT_FOUND")); - assertEquals(2, occurrences(source, "COMMAND_IRIS_INSTALL_PACK_AND_RESTART")); - assertFalse(source.contains("sendMessage(\"Could not find dimension")); - assertFalse(source.contains("sendMessage(\"Install its pack with")); - } - - private static int occurrences(String value, String match) { - int count = 0; - int offset = 0; - while ((offset = value.indexOf(match, offset)) >= 0) { - count++; - offset += match.length(); - } - return count; - } } diff --git a/adapters/bukkit/plugin/src/test/java/art/arcane/iris/core/commands/CommandIrisDownloadContractTest.java b/adapters/bukkit/plugin/src/test/java/art/arcane/iris/core/commands/CommandIrisDownloadContractTest.java index 7de9dff59..6cf1bb112 100644 --- a/adapters/bukkit/plugin/src/test/java/art/arcane/iris/core/commands/CommandIrisDownloadContractTest.java +++ b/adapters/bukkit/plugin/src/test/java/art/arcane/iris/core/commands/CommandIrisDownloadContractTest.java @@ -5,13 +5,10 @@ import org.junit.Test; import java.lang.reflect.Method; import java.lang.reflect.Parameter; -import java.nio.file.Files; -import java.nio.file.Path; import java.util.Arrays; import java.util.List; import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertNull; import static org.junit.Assert.assertThrows; import static org.junit.Assert.assertTrue; @@ -47,20 +44,6 @@ public class CommandIrisDownloadContractTest { assertThrows(Exception.class, () -> handler.parse("custom", false)); } - @Test - public void commandDelegatesAcceptedDownloadsWithoutRawPreamble() throws Exception { - String source = Files.readString(Path.of( - "src/main/java/art/arcane/iris/core/commands/CommandIris.java" - )).replace("\r\n", "\n"); - String download = method(source, "public void download("); - - assertTrue(download.contains("downloadBuiltIn(sender(), builtInPack)")); - assertTrue(download.contains("downloadUrl(sender(), directLink)")); - assertFalse(download.contains("Downloading built-in Iris pack")); - assertFalse(download.contains("Downloading Iris pack from")); - assertFalse(download.contains("sendMessage(directLink")); - } - private static String method(String source, String signature) { int start = source.indexOf(signature); assertTrue(start >= 0); diff --git a/adapters/bukkit/plugin/src/test/java/art/arcane/iris/core/commands/CommandJigsawContractTest.java b/adapters/bukkit/plugin/src/test/java/art/arcane/iris/core/commands/CommandJigsawContractTest.java index 36965b6bc..58e5a00b3 100644 --- a/adapters/bukkit/plugin/src/test/java/art/arcane/iris/core/commands/CommandJigsawContractTest.java +++ b/adapters/bukkit/plugin/src/test/java/art/arcane/iris/core/commands/CommandJigsawContractTest.java @@ -115,21 +115,6 @@ public class CommandJigsawContractTest { new IllegalStateException("Unexpected Studio failure"))); } - @Test - public void committedActivationStartsInitialEvaluationBeforePlayerBinding() throws Exception { - String source = Files.readString(Path.of( - "src/main/java/art/arcane/iris/core/commands/CommandJigsaw.java")).replace("\r\n", "\n"); - int commit = source.indexOf("JigsawStudioActivation.commit(staged)"); - int evaluation = source.indexOf( - "studioService.activationCommitted(world, request.requestId())", - commit); - int binding = source.indexOf("PLAYER_PACKS.put", evaluation); - - assertTrue(commit >= 0); - assertTrue(evaluation > commit); - assertTrue(binding > evaluation); - } - @Test public void convertIsAddOnlyWorkflowWithAliasesAndDefaults() throws Exception { Method convert = CommandJigsaw.class.getDeclaredMethod( @@ -358,20 +343,6 @@ public class CommandJigsawContractTest { .getAnnotation(Director.class)); } - @Test - public void pieceCreateUsesResolvedWorkcellCapacityInsteadOfLayoutDefault() throws Exception { - String source = Files.readString(Path.of( - "src/main/java/art/arcane/iris/core/commands/CommandJigsaw.java")).replace("\r\n", "\n"); - int pieceCommands = source.indexOf("public static class CommandJigsawPiece"); - int create = source.indexOf("public void create(", pieceCommands); - int add = source.indexOf("public void add(", create); - String createSource = source.substring(create, add); - - assertTrue(createSource.contains("targetWorkcell = contextual;")); - assertTrue(createSource.contains("JigsawStudioCellDimensions dimensions = targetWorkcell.capacity();")); - assertFalse(createSource.contains("layout().cellDimensions()")); - } - @Test public void pieceAddUsesCanonicalAxesForRotatedRectangularPlanarWorkcells() { JigsawStudioLayout layout = nonuniformPlanarLayout(); @@ -510,25 +481,6 @@ public class CommandJigsawContractTest { assertEquals(1, releases.get()); } - @Test - public void exportSourceAcquiresStudioLeaseBeforeStaticLeaseAndReleasesBothPaths() throws Exception { - String source = Files.readString(Path.of( - "src/main/java/art/arcane/iris/core/commands/CommandJigsaw.java")).replace("\r\n", "\n"); - int serviceLease = source.indexOf("studioService.tryBeginExport(requestId, playerId)"); - int staticLease = source.indexOf("beginExport(playerId, destination)", serviceLease); - int dispatch = source.indexOf("J.a(() -> runExport(operation))", staticLease); - int schedulingRelease = source.indexOf("operation.lease().release()", dispatch); - int exporter = source.indexOf("new VanillaJigsawDatapackExporter().export(operation.request())", dispatch); - int completionRelease = source.indexOf("operation.lease().release()", exporter); - - assertTrue(serviceLease >= 0); - assertTrue(staticLease > serviceLease); - assertTrue(dispatch > staticLease); - assertTrue(schedulingRelease > dispatch); - assertTrue(exporter > schedulingRelease); - assertTrue(completionRelease > exporter); - } - private static void assertCommand(String name, Class... parameterTypes) throws Exception { Method method = CommandJigsaw.class.getDeclaredMethod(name, parameterTypes); assertNotNull(method.getAnnotation(Director.class)); diff --git a/adapters/bukkit/plugin/src/test/java/art/arcane/iris/core/link/IrisPapiExpansionTest.java b/adapters/bukkit/plugin/src/test/java/art/arcane/iris/core/link/IrisPapiExpansionTest.java index 5871fd757..633dad4b1 100644 --- a/adapters/bukkit/plugin/src/test/java/art/arcane/iris/core/link/IrisPapiExpansionTest.java +++ b/adapters/bukkit/plugin/src/test/java/art/arcane/iris/core/link/IrisPapiExpansionTest.java @@ -7,8 +7,6 @@ import org.bukkit.OfflinePlayer; import org.bukkit.World; import org.junit.Test; -import java.nio.file.Files; -import java.nio.file.Path; import java.util.List; import java.util.Locale; import java.util.UUID; @@ -212,20 +210,6 @@ public class IrisPapiExpansionTest { assertTrue(expansion.persist()); } - @Test - public void theReadmeDocumentsEveryPublishedKeyAndEveryRetiredOne() throws Exception { - String readme = Files.readString(Path.of(System.getProperty("iris.readmeSource"))); - - for (String key : PUBLISHED_KEYS) { - assertTrue("README must document %iris_" + key + "%", readme.contains("%iris_" + key + "%")); - } - - for (String retired : RETIRED_KEYS) { - assertTrue("README must carry the migration row for %iris_" + retired + "%", - readme.contains("%iris_" + retired + "%")); - } - } - @Test public void theTerrainServiceIsTheOnlyDoorIntoIris() { IrisTerrainService service = new FakeIrisTerrainService(); diff --git a/adapters/bukkit/plugin/src/test/java/art/arcane/iris/core/link/IrisPapiLifecycleTest.java b/adapters/bukkit/plugin/src/test/java/art/arcane/iris/core/link/IrisPapiLifecycleTest.java deleted file mode 100644 index 919fa76ea..000000000 --- a/adapters/bukkit/plugin/src/test/java/art/arcane/iris/core/link/IrisPapiLifecycleTest.java +++ /dev/null @@ -1,137 +0,0 @@ -package art.arcane.iris.core.link; - -import org.junit.Test; - -import java.nio.file.Files; -import java.nio.file.Path; - -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertTrue; - -public class IrisPapiLifecycleTest { - private static final Path PLUGIN_SOURCE = Path.of("src/main/java/art/arcane/iris/Iris.java"); - private static final String SETUP = "private void setupPapi() {"; - private static final String TEARDOWN = "private void teardownPapi() {"; - - private static String source() throws Exception { - // The assertions below match against literals written with \n, so a CRLF checkout has to - // be folded first or every multi-line expectation misses. - return Files.readString(PLUGIN_SOURCE).replace("\r\n", "\n"); - } - - private static String body(String declaration) throws Exception { - String source = source(); - int start = source.indexOf(declaration); - - assertTrue("Iris.java must declare " + declaration, start >= 0); - - int open = source.indexOf('{', start); - int depth = 0; - - for (int index = open; index < source.length(); index++) { - char character = source.charAt(index); - - if (character == '{') { - depth++; - continue; - } - - if (character != '}') { - continue; - } - - depth--; - - if (depth == 0) { - return source.substring(open + 1, index); - } - } - - throw new AssertionError(declaration + " is not brace balanced"); - } - - @Test - public void registrationIsGatedOnPlaceholderApiBeingEnabled() throws Exception { - assertTrue("setupPapi must bail out when PlaceholderAPI is absent", - body(SETUP).contains("if (!PlaceholderRegistration.isPlaceholderApiEnabled()) {")); - } - - @Test - public void theRegistrationTheListenerAndTheStateAreAllRetained() throws Exception { - String source = source(); - - assertTrue(source.contains("private volatile PlaceholderRegistration papiRegistration;")); - assertTrue(source.contains("private volatile IrisPapiListener papiListener;")); - assertTrue(source.contains("private volatile IrisPapiState papiState;")); - } - - @Test - public void teardownUnregistersTheExpansionTheListenerAndClearsTheState() throws Exception { - String teardown = body(TEARDOWN); - - assertTrue("the retained registration must be unregistered inside teardownPapi", - teardown.contains("registration.unregister();")); - assertTrue("the retained listener must be detached inside teardownPapi", - teardown.contains("HandlerList.unregisterAll(listener);")); - assertTrue("the retained state must drop every held world reference inside teardownPapi", - teardown.contains("state.clear();")); - assertTrue("teardownPapi must drop the retained listener", teardown.contains("papiListener = null;")); - assertTrue("teardownPapi must drop the retained registration", teardown.contains("papiRegistration = null;")); - assertTrue("teardownPapi must drop the retained state", teardown.contains("papiState = null;")); - } - - @Test - public void bothDisablePathsTearThePlaceholderSurfaceDown() throws Exception { - String disable = body("public void onDisable() {"); - String preUnload = body("public void onPreUnload(ReloadAware.PreUnloadReason reason) {"); - int disableTeardown = disable.indexOf("teardownPapi();"); - int preUnloadTeardown = preUnload.indexOf("teardownPapi();"); - - assertTrue("onDisable must tear the expansion down before branching into runtime shutdown", - disableTeardown >= 0 && disableTeardown < disable.indexOf("IrisToolbelt.isServerStopping()")); - assertTrue("the BileTools pre-unload hook must tear the expansion down before any shutdown branch", - preUnloadTeardown >= 0 && preUnloadTeardown < preUnload.indexOf("IrisToolbelt.isServerStopping()")); - } - - @Test - public void aFailedListenerAttachDoesNotLeaveTheExpansionRegistered() throws Exception { - String setup = body(SETUP); - int attach = setup.indexOf("registerEvents(listener, this)"); - - assertTrue("the listener must be attached inside setupPapi", attach >= 0); - - int rescue = setup.indexOf("} catch (Throwable failure) {", attach); - - assertTrue("the attach must be guarded inside setupPapi", rescue > attach); - - int rollback = setup.indexOf("registration.unregister();", rescue); - - assertTrue("a failed attach must roll the registration back inside setupPapi", rollback > rescue); - - int bail = setup.indexOf("return;", rollback); - - assertTrue("a failed attach must leave setupPapi", bail > rollback); - - int retained = setup.indexOf("papiRegistration = registration;"); - - assertTrue("setupPapi must retain the registration", retained > 0); - assertTrue("the registration may only be retained after a successful attach", retained > bail); - } - - @Test - public void theExpansionIsNeverConstructedFromAPluginStatic() throws Exception { - String setup = body(SETUP); - - assertFalse("the plugin class must not construct the expansion: that forces PlaceholderExpansion to load during enable and crashes a server without PlaceholderAPI", - setup.contains("new IrisPapiExpansion(")); - assertTrue("the expansion takes its state as a constructor argument, built inside the installer", - installerSource().contains("new IrisPapiExpansion(state, logger)")); - assertFalse("the hand rolled PlaceholderAPI presence check must be gone", - source().contains("isPluginEnabled(\"PlaceholderAPI\")")); - } - - private static String installerSource() throws Exception { - return java.nio.file.Files.readString(java.nio.file.Path.of( - "src/main/java/art/arcane/iris/core/link/IrisPapiInstaller.java")).replace("\r\n", "\n"); - } -} diff --git a/adapters/bukkit/plugin/src/test/java/art/arcane/iris/core/runtime/StudioPlayerModeContractTest.java b/adapters/bukkit/plugin/src/test/java/art/arcane/iris/core/runtime/StudioPlayerModeContractTest.java deleted file mode 100644 index 0e7eeba9d..000000000 --- a/adapters/bukkit/plugin/src/test/java/art/arcane/iris/core/runtime/StudioPlayerModeContractTest.java +++ /dev/null @@ -1,53 +0,0 @@ -package art.arcane.iris.core.runtime; - -import org.junit.Test; - -import java.io.IOException; -import java.nio.file.Files; -import java.nio.file.Path; - -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertTrue; - -public class StudioPlayerModeContractTest { - @Test - public void autoStartedStudioUsesSpectatorMode() throws IOException { - String plugin = Files.readString(Path.of("src/main/java/art/arcane/iris/Iris.java")).replace("\r\n", "\n"); - String commands = Files.readString(Path.of( - "src/main/java/art/arcane/iris/core/commands/CommandStudio.java")).replace("\r\n", "\n"); - - assertFalse(plugin.contains("GameMode.CREATIVE")); - assertFalse(commands.contains("GameMode.CREATIVE")); - assertTrue(plugin.contains("GameMode.SPECTATOR")); - } - - @Test - public void tpStudioUsesThePreparedCoordinatorEntry() throws IOException { - String commands = Files.readString(Path.of( - "src/main/java/art/arcane/iris/core/commands/CommandStudio.java")).replace("\r\n", "\n"); - int methodStart = commands.indexOf("public void tpstudio()"); - int methodEnd = commands.indexOf("\n @Director", methodStart); - String method = commands.substring(methodStart, methodEnd); - - assertTrue(method.contains("StudioSVC studioService = Iris.service(StudioSVC.class)")); - assertTrue(method.contains("studioService.teleportToActiveProject(player)")); - assertFalse(method.contains("setGameMode(")); - assertFalse(method.contains("getActiveProject()")); - assertFalse(method.contains("BukkitPlatform.teleportAsync")); - assertFalse(method.contains("BukkitWorldBinding.spawnLocation")); - } - - @Test - public void editingStudiosRemainCreative() throws IOException { - String objectCommands = Files.readString(Path.of( - "src/main/java/art/arcane/iris/core/commands/CommandObject.java")).replace("\r\n", "\n"); - String jigsawCommands = Files.readString(Path.of( - "src/main/java/art/arcane/iris/core/commands/CommandJigsaw.java")).replace("\r\n", "\n"); - - assertTrue(objectCommands.contains("GameMode.CREATIVE")); - assertTrue(objectCommands.contains("StudioOpenCoordinator.StudioOpenKind.OBJECT")); - assertTrue(jigsawCommands.contains("GameMode.CREATIVE")); - assertFalse(objectCommands.contains("GameMode.SPECTATOR")); - assertFalse(jigsawCommands.contains("GameMode.SPECTATOR")); - } -} diff --git a/adapters/bukkit/plugin/src/test/java/art/arcane/iris/core/service/IrisApiWiringContractTest.java b/adapters/bukkit/plugin/src/test/java/art/arcane/iris/core/service/IrisApiWiringContractTest.java deleted file mode 100644 index cfadd6843..000000000 --- a/adapters/bukkit/plugin/src/test/java/art/arcane/iris/core/service/IrisApiWiringContractTest.java +++ /dev/null @@ -1,195 +0,0 @@ -package art.arcane.iris.core.service; - -import org.junit.Test; - -import java.io.IOException; -import java.nio.file.Files; -import java.nio.file.Path; - -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertTrue; - -public class IrisApiWiringContractTest { - @Test - public void theTerrainServiceRegistersOnBothRegistriesAndReleasesBoth() throws IOException { - String source = source("iris.terrainSvcSource"); - String onEnable = method(source, "public void onEnable()"); - String onDisable = method(source, "public void onDisable()"); - - assertTrue(onEnable.contains("Bukkit.getServicesManager().register(")); - assertTrue(onEnable.contains("IrisTerrainService.class")); - assertTrue(onEnable.contains("IrisServices.register(IrisTerrainService.class, this)")); - assertTrue(onDisable.contains("Bukkit.getServicesManager().unregister(IrisTerrainService.class, this)")); - assertTrue(onDisable.contains("IrisServices.remove(IrisTerrainService.class)")); - assertBefore(onDisable, "serviceEnabled.set(false)", "Bukkit.getServicesManager().unregister("); - } - - @Test - public void theTerrainServiceNeverForcesEngineInitialisationOrLoadsTheMantle() throws IOException { - String source = source("iris.terrainSvcSource"); - - assertFalse("isIrisWorld must not touch the generator", source.contains("IrisToolbelt")); - assertFalse("isIrisWorld must not touch the generator", source.contains(".touch(")); - assertFalse("terrain queries must not load mantle chunks", source.contains("getMantle()")); - assertFalse("terrain queries must not load mantle chunks", source.contains("getObjectsAt(")); - assertFalse("terrain queries must not load mantle chunks", source.contains("getPOIsAt(")); - assertFalse("terrain queries must not load mantle chunks", source.contains("getCaveOrMantleBiome(")); - assertFalse("terrain queries must never block", source.contains(".join()")); - assertFalse("terrain queries must never block", source.contains("synchronized")); - assertFalse("terrain queries must never block", source.contains("J.sfut(")); - } - - @Test - public void sampleColumnsBoundsTheQueryBeforeItWalksAndTreatsAThrowingSinkAsARefusal() throws IOException { - String sampleColumns = method(source("iris.terrainSvcSource"), - "public boolean sampleColumns(World world, IrisColumnQuery query, IrisColumnSink sink)"); - - assertBefore(sampleColumns, "IrisSampleLimits.withinLimits(", "IrisColumnWalk.walk("); - assertBefore(sampleColumns, "IrisColumnWalk.walk(", "catch (Throwable error)"); - assertTrue(sampleColumns.contains("reportSinkFault(world, error)")); - assertTrue(sampleColumns.contains("return false;")); - assertTrue("the walk must abort when the engine closes underneath it", - sampleColumns.contains("engine.isClosed()")); - } - - @Test - public void thePregeneratorDispatchesPhasesFromItsExistingTickAndNeverBlocksOnTheSink() throws IOException { - String source = source("iris.pregeneratorJobSource"); - String dispatch = method(source, "private void dispatchApiPhases(List phases)"); - - assertTrue(dispatch.contains("IrisServices.getOrNull(PregenApiSink.class)")); - assertTrue(dispatch.contains("catch (Throwable error)")); - assertBefore(dispatch, "sink.pregen(phase, progress)", "catch (Throwable error)"); - assertFalse(dispatch.contains(".join()")); - - assertTrue(method(source, "public void onTick(").contains("dispatchApiPhases(apiPhases.onTick(paused()))")); - assertTrue(method(source, "public void onSaving()").contains("dispatchApiPhases(apiPhases.onSaving())")); - assertTrue(method(source, "public void onClose()").contains("dispatchApiPhases(apiPhases.onClose(reachedTotal()))")); - } - - @Test - public void worldPhasesAreFiredOutsideTheRegistrationLock() throws IOException { - String source = source("iris.engineSvcSource"); - - String add = method(source, "private void add(World world)"); - assertBefore(add, "catch (RejectedExecutionException exception)", "phases.ready(world)"); - assertBefore(add, "registered = true;", "phases.ready(world)"); - - String remove = method(source, - "private boolean remove(World world, CompletionStage unloadBoundary)"); - assertBefore(remove, "registered = worlds.remove(world)", "phases.closing(world)"); - assertBefore(remove, "phases.closing(world)", - "deferCloseUntilWorldUnload(world, registered, closing, unloadBoundary)"); - } - - @Test - public void everyRegisteredWorldIsAnnouncedClosingWhenTheServiceShutsDown() throws IOException { - String onDisable = method(source("iris.engineSvcSource"), "public void onDisable()"); - - assertTrue("service shutdown must announce ENGINE_CLOSING for every registered world", - onDisable.contains("phases.closing(teardown.world())")); - assertBefore(onDisable, "worlds.clear()", "phases.closing(teardown.world())"); - assertBefore(onDisable, "phases.closing(teardown.world())", "shutdownAndDrain(activeService)"); - assertBefore(onDisable, "phases.closing(teardown.world())", - "startClose(teardown.registered(), teardown.closing())"); - } - - @Test - public void aReplacedEngineIsAnnouncedClosingBeforeTheRetryReRegistersTheWorld() throws IOException { - String add = method(source("iris.engineSvcSource"), "private void add(World world)"); - - assertBefore(add, "catch (RejectedExecutionException exception)", "phases.closing(world)"); - assertBefore(add, "phases.closing(world)", "retryRegistrationAfterClose(world, retryAfter)"); - assertBefore(add, "phases.closing(world)", "startClose(replaced, replacementClose)"); - } - - @Test - public void aWorldPhaseIsNeverConditionalOnAnotherServicesRegistration() throws IOException { - String source = source("iris.apiEventSvcSource"); - String fire = method(source, "public static void fireWorldPhase(World world, IrisWorldPhase phase)"); - - assertFalse("world lifecycle must not resolve a swappable service to build its payload", - fire.contains("IrisServices")); - assertFalse("world lifecycle must not resolve a swappable service to build its payload", - fire.contains("IrisTerrainService")); - assertTrue(fire.contains("deliver(new IrisWorldEngineEvent(world, phase, describe(world, phase)))")); - - String describe = method(source, "private static IrisWorldInfo describe(World world, IrisWorldPhase phase)"); - assertTrue(describe.contains("IrisWorldInfoFactory.forWorld(world)")); - assertTrue("an undescribable world must be reported, not swallowed", - describe.contains("IrisLogging.reportError(")); - assertTrue("an undescribable world must still deliver the phase", describe.contains("return null;")); - } - - @Test - public void aWorldPhaseRaisedFromAServerThreadIsDeliveredBeforeThatThreadMovesOn() throws IOException { - String deliver = method(source("iris.apiEventSvcSource"), "private static void deliver(Event event)"); - - assertBefore(deliver, "Bukkit.isPrimaryThread()", "Bukkit.getPluginManager().callEvent(event)"); - assertBefore(deliver, "Bukkit.getPluginManager().callEvent(event)", "Iris.callEvent(event)"); - } - - @Test - public void theWorldInfoFactoryNeverForcesEngineInitialisationOrLoadsTheMantle() throws IOException { - String source = source("iris.worldInfoFactorySource"); - - assertFalse("the factory must not touch the generator", source.contains("IrisToolbelt")); - assertFalse("the factory must not touch the generator", source.contains(".touch(")); - assertFalse("the factory must not load mantle chunks", source.contains("getMantle()")); - assertFalse("the factory must never block", source.contains(".join()")); - assertFalse("the factory must never block", source.contains("synchronized")); - assertTrue("the factory must refuse a closed engine", source.contains("engine.isClosed()")); - } - - @Test - public void theHotloadHookStillFiresTheLegacyEventAlongsideTheApiEvent() throws IOException { - String hook = method(source("iris.bukkitEnginePlatformHooksSource"), "public void fireHotloadEvent(Engine engine)"); - - assertBefore(hook, "new IrisEngineHotloadEvent(engine)", - "IrisApiEventSVC.fireWorldPhase(BukkitWorldBinding.world(engine.getWorld()), IrisWorldPhase.ENGINE_HOTLOADED)"); - } - - @Test - public void theEventServiceNeverLetsAThirdPartyFailureEscapeALifecyclePath() throws IOException { - String fire = method(source("iris.apiEventSvcSource"), - "public static void fireWorldPhase(World world, IrisWorldPhase phase)"); - - assertTrue(fire.contains("catch (Throwable error)")); - assertTrue(fire.contains("IrisLogging.reportError(")); - assertFalse(fire.contains("printStackTrace")); - } - - private static String source(String property) throws IOException { - String path = System.getProperty(property); - assertTrue("missing source property " + property, path != null && !path.isBlank()); - return Files.readString(Path.of(path)); - } - - private static void assertBefore(String source, String first, String second) { - int firstIndex = source.indexOf(first); - int secondIndex = source.indexOf(second); - assertTrue("Missing source contract token: " + first, firstIndex >= 0); - assertTrue("Missing source contract token: " + second, secondIndex >= 0); - assertTrue(first + " must occur before " + second, firstIndex < secondIndex); - } - - private static String method(String source, String signature) { - int start = source.indexOf(signature); - assertTrue("Missing source contract signature: " + signature, start >= 0); - int openBrace = source.indexOf('{', start); - assertTrue("Missing source contract method body: " + signature, openBrace >= 0); - int depth = 0; - for (int index = openBrace; index < source.length(); index++) { - char current = source.charAt(index); - if (current == '{') { - depth++; - } else if (current == '}') { - depth--; - if (depth == 0) { - return source.substring(start, index + 1); - } - } - } - throw new IllegalArgumentException("Unclosed source contract method: " + signature); - } -} diff --git a/adapters/fabric/build.gradle b/adapters/fabric/build.gradle index 8a914a412..8725b0e34 100644 --- a/adapters/fabric/build.gradle +++ b/adapters/fabric/build.gradle @@ -207,7 +207,6 @@ tasks.named('compileJava', JavaCompile).configure { } tasks.named('test').configure { - systemProperty('iris.moddedCommonSources', file('../modded-common/src/main/java').absolutePath) } loom { diff --git a/adapters/forge/build.gradle b/adapters/forge/build.gradle index 925193d05..68d7280ae 100644 --- a/adapters/forge/build.gradle +++ b/adapters/forge/build.gradle @@ -240,7 +240,6 @@ tasks.named('compileJava', JavaCompile).configure { } tasks.named('test').configure { - systemProperty('iris.moddedCommonSources', file('../modded-common/src/main/java').absolutePath) } processResources { diff --git a/adapters/modded-common/src/test/java/art/arcane/iris/modded/IrisModLanguageAssetsTest.java b/adapters/modded-common/src/test/java/art/arcane/iris/modded/IrisModLanguageAssetsTest.java index c11c983cd..12d0eea95 100644 --- a/adapters/modded-common/src/test/java/art/arcane/iris/modded/IrisModLanguageAssetsTest.java +++ b/adapters/modded-common/src/test/java/art/arcane/iris/modded/IrisModLanguageAssetsTest.java @@ -73,15 +73,9 @@ public class IrisModLanguageAssetsTest { private Set resourceFiles() throws Exception { URL resource = IrisModLanguageAssetsTest.class.getClassLoader().getResource(ROOT); - Path directory; - if (resource != null && "file".equals(resource.getProtocol())) { - directory = Path.of(resource.toURI()); - } else { - String sources = System.getProperty("iris.moddedCommonSources"); - assertNotNull("Missing mod language resource directory and source root", sources); - directory = Path.of(sources).getParent() - .resolve("resources").resolve(ROOT); - } + assertNotNull("Missing mod language resource directory: " + ROOT, resource); + assertEquals("Mod language resources must resolve to a directory on disk", "file", resource.getProtocol()); + Path directory = Path.of(resource.toURI()); try (Stream paths = Files.list(directory)) { return paths .filter(Files::isRegularFile) diff --git a/adapters/modded-common/src/test/java/art/arcane/iris/modded/IrisModdedChunkGeneratorSpawnTest.java b/adapters/modded-common/src/test/java/art/arcane/iris/modded/IrisModdedChunkGeneratorSpawnTest.java index 23be3cd5f..9b2c34c5f 100644 --- a/adapters/modded-common/src/test/java/art/arcane/iris/modded/IrisModdedChunkGeneratorSpawnTest.java +++ b/adapters/modded-common/src/test/java/art/arcane/iris/modded/IrisModdedChunkGeneratorSpawnTest.java @@ -9,13 +9,9 @@ import net.minecraft.world.level.biome.MobSpawnSettings; import org.junit.Test; import org.junit.BeforeClass; -import java.io.IOException; -import java.nio.file.Files; -import java.nio.file.Path; import java.util.List; import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertTrue; public class IrisModdedChunkGeneratorSpawnTest { @BeforeClass @@ -48,21 +44,4 @@ public class IrisModdedChunkGeneratorSpawnTest { assertEquals(explicitCow, entries.get(2).value()); assertEquals(3, entries.get(2).weight()); } - - @Test - public void vanillaChunkGenerationMobsUseTheVisibleBiomesVanillaDerivative() throws IOException { - Path sourcePath = Path.of(System.getProperty("iris.moddedCommonSources"), - "art/arcane/iris/modded/IrisModdedChunkGenerator.java"); - String source = Files.readString(sourcePath); - int spawnStart = source.indexOf("public void spawnOriginalMobs"); - int spawnEnd = source.indexOf("@Override", spawnStart + 1); - String spawn = source.substring(spawnStart, spawnEnd); - - assertTrue(spawn.contains("spawnTables.initializeVanillaSpawnBiomes(registry)")); - assertTrue(spawn.contains("structureBiomeSource.getVisibleSurfaceBiome(")); - assertTrue(spawn.contains("spawnTables.vanillaSpawnBiome(visibleBiome.value())")); - assertTrue(spawn.contains("NaturalSpawner.spawnMobsForChunkGeneration(")); - assertTrue(spawn.contains("new LegacyRandomSource(RandomSupport.generateUniqueSeed())")); - assertTrue(spawn.contains("random.setDecorationSeed(region.getSeed()")); - } } diff --git a/adapters/modded-common/src/test/java/art/arcane/iris/modded/IrisModdedStructureParityTest.java b/adapters/modded-common/src/test/java/art/arcane/iris/modded/IrisModdedStructureParityTest.java index 8fc284d9c..f8ae89eae 100644 --- a/adapters/modded-common/src/test/java/art/arcane/iris/modded/IrisModdedStructureParityTest.java +++ b/adapters/modded-common/src/test/java/art/arcane/iris/modded/IrisModdedStructureParityTest.java @@ -14,9 +14,6 @@ import net.minecraft.server.Bootstrap; import org.junit.BeforeClass; import org.junit.Test; -import java.io.IOException; -import java.nio.file.Files; -import java.nio.file.Path; import java.util.List; import java.util.Locale; import java.util.Set; @@ -64,16 +61,10 @@ public class IrisModdedStructureParityTest { } @Test - public void strongholdRingSearchSamplesOneQuartColumnPerChunk() throws IOException { + public void strongholdRingSearchSamplesOneQuartColumnPerChunk() { assertEquals(4, IrisModdedBiomeSource.horizontalBiomeSearchQuartStep(0, 112)); assertEquals(1, IrisModdedBiomeSource.horizontalBiomeSearchQuartStep(1, 112)); assertEquals(1, IrisModdedBiomeSource.horizontalBiomeSearchQuartStep(0, 111)); - String source = Files.readString(Path.of( - System.getProperty("iris.moddedCommonSources"), - "art/arcane/iris/modded/IrisModdedBiomeSource.java")); - assertTrue(source.contains("x, y, z, searchRadius, quartStep, allowed, random, false, sampler")); - assertTrue(source.contains( - "return super.findBiomeHorizontal(x, y, z, searchRadius, allowed, random, sampler)")); } @Test @@ -130,126 +121,12 @@ public class IrisModdedStructureParityTest { } @Test - public void visibleBiomeResolutionSelectsStackOwnershipBeforeHostCaves() throws IOException { - String source = Files.readString(Path.of( - System.getProperty("iris.moddedCommonSources"), - "art/arcane/iris/modded/IrisModdedBiomeSource.java")); - int resolutionStart = source.indexOf("private BiomeResolution resolveBiomeResolution("); - int resolutionEnd = source.indexOf("private Holder resolveRequiredStructureBiome(", resolutionStart); - - assertTrue(resolutionStart >= 0); - assertTrue(resolutionEnd > resolutionStart); - String resolution = source.substring(resolutionStart, resolutionEnd); - - assertTrue(resolution.contains("resolveDimensionStackLayer(")); - assertTrue(resolution.contains("!stackLayer.terrainContext().isSelfReferencing()")); - assertTrue(resolution.indexOf("resolveDimensionStackLayer(") - < resolution.indexOf("boolean underground")); - assertTrue(resolution.contains("includeDimensionStack")); - assertTrue(resolution.contains( - "return resolveBiomeResolution(engine, quartX, quartY, quartZ, false)")); - assertTrue(source.contains("resolution.packName(), resolution.dimension(), customBiome.getId()")); - int helperStart = source.indexOf("private static IrisBiome resolveSurfaceStructureBiome("); - int helperEnd = source.indexOf("private static Set registeredBiomeKeys(", helperStart); - String helper = source.substring(helperStart, helperEnd); - assertTrue(helper.contains("engine.getComplex().getTrueBiomeStream().get(blockX, blockZ)")); - assertFalse(helper.contains("getDimensionStackContext()")); - assertFalse(helper.contains("getSurfaceBiome(")); - } - - @Test - public void stackBiomesAreVisibleButExcludedFromStructureReachability() throws IOException { - String source = Files.readString(Path.of( - System.getProperty("iris.moddedCommonSources"), - "art/arcane/iris/modded/IrisModdedBiomeSource.java")); - - assertTrue(source.contains("return biomeKeySets().structureRequired()")); - assertTrue(source.contains("generatedBiomeKeys.addAll(keys.visibleRequired())")); - assertTrue(source.contains("collectStructureBiomeKeys(")); - assertTrue(source.contains("dimension.getReachableBiomes(() -> data)")); - } - - @Test - public void biomeLocatorSearchesTheVisibleStack() throws IOException { - String source = Files.readString(Path.of( - System.getProperty("iris.moddedCommonSources"), - "art/arcane/iris/modded/IrisModdedBiomeSource.java")); - int start = source.indexOf("public Pair> findClosestBiome3d("); - int end = source.indexOf("private Holder getNoiseBiome(", start); - String method = source.substring(start, end); - - assertTrue(method.contains("modded_locate_visible_biome")); - assertTrue(method.contains("return super.findClosestBiome3d(")); - assertTrue(method.contains("collectVisibleBiomeHolders()")); - assertTrue(method.contains("QuartPos.toBlock(quartX), QuartPos.toBlock(quartZ)")); - assertTrue(method.contains("resolveVisibleBiome(")); - assertFalse(method.contains("Holder structureBiome = getNoiseBiome(")); - assertTrue(method.indexOf("tryAcquireGenerationLease(engine, \"modded_locate_visible_biome\")") - < method.indexOf("engine.getDimensionStackContext()")); - } - - @Test - public void surfaceSpawnBiomeUsesTheVisibleQuartCell() throws IOException { - String source = Files.readString(Path.of( - System.getProperty("iris.moddedCommonSources"), - "art/arcane/iris/modded/IrisModdedBiomeSource.java")); - int start = source.indexOf("Holder getVisibleSurfaceBiome("); - int end = source.indexOf("boolean isStructureReachable(", start); - String method = source.substring(start, end); - - assertTrue(method.contains("QuartPos.fromBlock(blockX)")); - assertTrue(method.contains("QuartPos.toBlock(quartX)")); - assertTrue(method.contains("QuartPos.fromBlock(internalY + engine.getMinHeight())")); - assertTrue(method.contains("stackContext.getLayout(sampleX, sampleZ).surfaceLayer()")); - assertTrue(method.contains("visibleBiomeCache")); - assertTrue(method.contains("isBiomeCacheable(engine, sampleX, sampleZ)")); - assertTrue(method.indexOf("boolean cacheable = isBiomeCacheable(engine, sampleX, sampleZ)") - < method.indexOf("Engine.hostHeight(engine, sampleX, sampleZ, true)")); - assertCacheGuarded(method, "visibleBiomeCache"); - } - - @Test - public void temporaryNaturalBiomeAnswersAreNotMemoized() throws IOException { + public void temporaryNaturalBiomeAnswersAreNotMemoized() { Engine engine = mock(Engine.class); when(engine.answersFromNaturalTerrain(12, -8)).thenReturn(true); assertFalse(IrisModdedBiomeSource.isBiomeCacheable(engine, 12, -8)); when(engine.answersFromNaturalTerrain(12, -8)).thenReturn(false); assertTrue(IrisModdedBiomeSource.isBiomeCacheable(engine, 12, -8)); - - String source = Files.readString(Path.of( - System.getProperty("iris.moddedCommonSources"), - "art/arcane/iris/modded/IrisModdedBiomeSource.java")); - int structureStart = source.indexOf("private Holder getNoiseBiome(Engine engine"); - int structureEnd = source.indexOf("Holder getVisibleNoiseBiome(", structureStart); - String structure = source.substring(structureStart, structureEnd); - assertTrue(structure.contains("QuartPos.toBlock(quartX)")); - assertTrue(structure.contains("QuartPos.toBlock(quartZ)")); - assertCacheGuarded(structure, "structureBiomeCache"); - - int visibleStart = source.indexOf( - "private Holder getVisibleNoiseBiomeWithActiveGenerationLease("); - int visibleEnd = source.indexOf("Holder getVisibleSurfaceBiome(", visibleStart); - String visible = source.substring(visibleStart, visibleEnd); - assertTrue(visible.contains("QuartPos.toBlock(quartX)")); - assertTrue(visible.contains("QuartPos.toBlock(quartZ)")); - assertCacheGuarded(visible, "visibleBiomeCache"); - - int predicateStart = source.indexOf("static boolean isBiomeCacheable("); - int predicateEnd = source.indexOf("static boolean isMonumentSurfaceBiomeQuery(", predicateStart); - String predicate = source.substring(predicateStart, predicateEnd); - assertTrue(predicate.contains("return !engine.answersFromNaturalTerrain(blockX, blockZ)")); - assertFalse(predicate.contains("getDimensionStackContext()")); - } - - @Test - public void importedFeaturesCollectOnlyHostOwnedStackCells() throws IOException { - String source = Files.readString(Path.of( - System.getProperty("iris.moddedCommonSources"), - "art/arcane/iris/modded/ModdedImportedFeatureStage.java")); - - assertTrue(source.contains("stackContext.getLayerAt(")); - assertTrue(source.contains("layer.terrainContext().isSelfReferencing()")); - assertTrue(source.contains("section.getBiomes().get(quartX, quartY, quartZ)")); } @Test @@ -281,17 +158,6 @@ public class IrisModdedStructureParityTest { assertTrue(recursiveKeys.contains("layers:sky/aurora")); } - @Test - public void biomeWriterDerivativeFallbackMatchesCanonicalRecursiveKeys() throws IOException { - String source = Files.readString(Path.of( - System.getProperty("iris.moddedCommonSources"), - "art/arcane/iris/modded/ModdedBiomeWriter.java")); - - assertTrue(source.contains( - "key.equalsIgnoreCase(dimension.getCustomBiomeKey(custom.getId()))")); - assertFalse(source.contains("String dimensionLoadKey = key.substring(0, colon)")); - } - @Test public void structureStateRejectsBiomesOutsideThePackContract() { Set generated = Set.of("minecraft:deep_ocean", "minecraft:dark_forest"); @@ -410,21 +276,4 @@ public class IrisModdedStructureParityTest { public void initialEntitySpawnsUseThePaperCompletionMarker() { assertSame(MantleFlag.INITIAL_SPAWNED_MARKER, ModdedWorldManager.INITIAL_SPAWN_COMPLETION_FLAG); } - - private static void assertCacheGuarded(String method, String cacheName) { - int predicate = method.indexOf("boolean cacheable = isBiomeCacheable("); - int cache = method.indexOf("BiomeHolderTable cache = " + cacheName, predicate); - int read = method.indexOf("cache.get(", predicate); - int readGuard = method.lastIndexOf("if (cacheable)", read); - int write = method.indexOf("cache.put(", read); - int writeGuard = method.lastIndexOf("if (cacheable)", write); - - assertTrue(predicate >= 0); - assertTrue(cache >= 0); - assertTrue(read > predicate); - assertTrue(readGuard >= predicate); - assertTrue(write > read); - assertTrue(writeGuard > read); - } - } diff --git a/adapters/modded-common/src/test/java/art/arcane/iris/modded/ModdedDynamicLevelLifecycleContractTest.java b/adapters/modded-common/src/test/java/art/arcane/iris/modded/ModdedDynamicLevelLifecycleContractTest.java deleted file mode 100644 index 2ba2ce090..000000000 --- a/adapters/modded-common/src/test/java/art/arcane/iris/modded/ModdedDynamicLevelLifecycleContractTest.java +++ /dev/null @@ -1,91 +0,0 @@ -package art.arcane.iris.modded; - -import org.junit.Test; - -import java.io.IOException; -import java.nio.file.Files; -import java.nio.file.Path; - -import static org.junit.Assert.assertTrue; - -public class ModdedDynamicLevelLifecycleContractTest { - private static final String SOURCE_ROOT_PROPERTY = "iris.moddedCommonSources"; - - @Test - public void sharedManagerPublishesDynamicLoadAndUnloadAroundRegistration() throws IOException { - String manager = commonSource("ModdedDimensionManager.java"); - String loader = commonSource("ModdedLoader.java"); - String injection = method(manager, "private static Handle inject("); - String removal = method(manager, "public static boolean remove("); - String injectionRollback = method(manager, "private static void rollbackInjection("); - String removalRollback = method(manager, "private static void rollbackRemoval("); - - assertTrue(loader.contains("void fireDynamicLevelLoad(MinecraftServer server, ServerLevel level);")); - assertTrue(loader.contains("void fireDynamicLevelUnload(MinecraftServer server, ServerLevel level);")); - assertBefore(injection, "serverAccess.putLevelIfAbsent(server, key, level);", - "fireDynamicLevelLoad(server, level);"); - assertBefore(removal, "fireDynamicLevelUnload(server, level);", - "serverAccess.removeLevel(server, key);"); - assertTrue(injectionRollback.contains("fireDynamicLevelUnload(server, level);")); - assertTrue(removalRollback.contains("fireDynamicLevelLoad(server, level);")); - } - - @Test - public void everyLoaderUsesItsNativeLifecycleBus() throws IOException { - String fabric = loaderSource("fabric", "art/arcane/iris/fabric/FabricModdedLoader.java"); - String forge = loaderSource("forge", "art/arcane/iris/forge/ForgeModdedLoader.java"); - String neoForge = loaderSource("neoforge", "art/arcane/iris/neoforge/NeoForgeModdedLoader.java"); - - assertTrue(fabric.contains("ServerLevelEvents.LOAD.invoker().onLevelLoad(server, level);")); - assertTrue(fabric.contains("ServerLevelEvents.UNLOAD.invoker().onLevelUnload(server, level);")); - assertTrue(forge.contains("LevelEvent.Load.BUS.post(new LevelEvent.Load(level));")); - assertTrue(forge.contains("LevelEvent.Unload.BUS.post(new LevelEvent.Unload(level));")); - assertTrue(neoForge.contains("NeoForge.EVENT_BUS.post(new LevelEvent.Load(level));")); - assertTrue(neoForge.contains("NeoForge.EVENT_BUS.post(new LevelEvent.Unload(level));")); - } - - private static String commonSource(String file) throws IOException { - return Files.readString(commonRoot().resolve("art/arcane/iris/modded").resolve(file)) - .replace("\r\n", "\n"); - } - - private static String loaderSource(String loader, String relative) throws IOException { - Path adaptersRoot = commonRoot().getParent().getParent().getParent().getParent(); - return Files.readString(adaptersRoot.resolve(loader).resolve("src/main/java").resolve(relative)) - .replace("\r\n", "\n"); - } - - private static Path commonRoot() { - String root = System.getProperty(SOURCE_ROOT_PROPERTY); - if (root == null || root.isBlank()) { - throw new IllegalStateException("Missing test property " + SOURCE_ROOT_PROPERTY); - } - return Path.of(root); - } - - private static String method(String source, String signature) { - int start = source.indexOf(signature); - if (start < 0) { - throw new IllegalArgumentException("Missing source method " + signature); - } - int open = source.indexOf('{', start); - int depth = 0; - for (int index = open; index < source.length(); index++) { - char current = source.charAt(index); - if (current == '{') { - depth++; - } else if (current == '}' && --depth == 0) { - return source.substring(start, index + 1); - } - } - throw new IllegalArgumentException("Unclosed source method " + signature); - } - - private static void assertBefore(String source, String first, String second) { - int firstIndex = source.indexOf(first); - int secondIndex = source.indexOf(second); - assertTrue("Missing source token " + first, firstIndex >= 0); - assertTrue("Missing source token " + second, secondIndex >= 0); - assertTrue(first + " must precede " + second, firstIndex < secondIndex); - } -} diff --git a/adapters/modded-common/src/test/java/art/arcane/iris/modded/ModdedGenerationBootstrapBindingTest.java b/adapters/modded-common/src/test/java/art/arcane/iris/modded/ModdedGenerationBootstrapBindingTest.java index e53978e84..c45012ffe 100644 --- a/adapters/modded-common/src/test/java/art/arcane/iris/modded/ModdedGenerationBootstrapBindingTest.java +++ b/adapters/modded-common/src/test/java/art/arcane/iris/modded/ModdedGenerationBootstrapBindingTest.java @@ -7,12 +7,8 @@ import net.minecraft.world.level.Level; import net.minecraft.world.level.chunk.ChunkGenerator; import org.junit.Test; -import java.io.IOException; -import java.nio.file.Files; -import java.nio.file.Path; import java.util.List; -import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertNull; import static org.junit.Assert.assertSame; import static org.junit.Assert.assertThrows; @@ -24,8 +20,6 @@ import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; public class ModdedGenerationBootstrapBindingTest { - private static final String SOURCE_ROOT_PROPERTY = "iris.moddedCommonSources"; - @Test public void publishedLevelRequiresCurrentGeneratorIdentity() { IrisModdedChunkGenerator generator = mock(IrisModdedChunkGenerator.class, CALLS_REAL_METHODS); @@ -89,62 +83,4 @@ public class ModdedGenerationBootstrapBindingTest { assertSame(dynamicLevel, generator.resolveBoundLevel(server, List.of(dynamicLevel))); verify(server, never()).getLevel(Level.OVERWORLD); } - - @Test - public void firstGenerationStagesProvideAuthoritativeLevelContext() throws IOException { - String source = source("IrisModdedChunkGenerator.java"); - String structures = method(source, "public void createStructures("); - String references = method(source, "public void createReferences("); - assertTrue(structures.contains("Engine current = engine(levelKey);")); - assertTrue(references.contains("Engine current = engine(level.getLevel());")); - - String publishedBinding = method(source, "private Engine engine(ResourceKey levelKey)"); - assertTrue(publishedBinding.contains("requirePublishedLevel(ModdedEngineBootstrap.currentServer(), levelKey)")); - assertTrue(publishedBinding.contains("return bindGenerationLevel(level);")); - assertFalse(publishedBinding.contains("ModdedServerLevels.level(")); - - String fullBinding = method(source, "private Engine bindGenerationLevel(ServerLevel level)"); - assertTrue(fullBinding.contains("bindLevel(level);")); - assertTrue(fullBinding.contains("Engine bound = readyEngine();")); - - String genericBinding = method(source, "Engine engine()"); - assertTrue(genericBinding.contains("return bindGenerationLevel(level);")); - } - - @Test - public void constructorMixinIsNotPartOfGenerationBootstrap() throws IOException { - String sourceRoot = System.getProperty(SOURCE_ROOT_PROPERTY); - assertTrue(sourceRoot != null && !sourceRoot.isBlank()); - Path root = Path.of(sourceRoot); - assertFalse(Files.exists(root.resolve(Path.of("art", "arcane", "iris", "modded", "mixin", - "ServerLevelBindingMixin.java")))); - String mixinConfig = Files.readString(root.getParent().resolve("resources/irisworldgen.entity.mixins.json")); - assertFalse(mixinConfig.contains("ServerLevelBindingMixin")); - } - - private String source(String fileName) throws IOException { - String sourceRoot = System.getProperty(SOURCE_ROOT_PROPERTY); - assertTrue(sourceRoot != null && !sourceRoot.isBlank()); - return Files.readString(Path.of(sourceRoot, "art", "arcane", "iris", "modded", fileName)); - } - - private String method(String source, String signature) { - int start = source.indexOf(signature); - assertTrue(start >= 0); - int body = source.indexOf('{', start); - assertTrue(body >= 0); - int depth = 0; - for (int index = body; index < source.length(); index++) { - char token = source.charAt(index); - if (token == '{') { - depth++; - } else if (token == '}') { - depth--; - if (depth == 0) { - return source.substring(start, index + 1); - } - } - } - throw new IllegalArgumentException("Unclosed source contract method: " + signature); - } } diff --git a/adapters/modded-common/src/test/java/art/arcane/iris/modded/ModdedGenerationHistoryRoutingContractTest.java b/adapters/modded-common/src/test/java/art/arcane/iris/modded/ModdedGenerationHistoryRoutingContractTest.java deleted file mode 100644 index 552b0bbae..000000000 --- a/adapters/modded-common/src/test/java/art/arcane/iris/modded/ModdedGenerationHistoryRoutingContractTest.java +++ /dev/null @@ -1,203 +0,0 @@ -package art.arcane.iris.modded; - -import org.junit.Test; - -import java.io.IOException; -import java.nio.file.Files; -import java.nio.file.Path; - -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertTrue; - -public class ModdedGenerationHistoryRoutingContractTest { - private static final String SOURCE_ROOT_PROPERTY = "iris.moddedCommonSources"; - - @Test - public void startupPublishesOnlyAnImmutableHistoryBoundRuntime() throws IOException { - String source = source("ModdedWorldEngines.java"); - String create = method(source, "private static Engine create("); - String createHistoryEngine = method(source, "private static Engine createHistoryEngine("); - String buildEngine = method(source, "private static IrisEngine buildEngine("); - - assertTrue(create.contains("ModdedGenerationHistoryStorage.openOrAdopt(")); - assertFalse(create.contains("resolvePack(")); - assertTrue(createHistoryEngine.contains("candidate.attachGenerationHistory(")); - assertTrue(createHistoryEngine.contains("IrisBoundarySignatureSampler.INSTANCE")); - assertTrue(createHistoryEngine.contains("getGenerationTransitionWidthBlocks()")); - assertTrue(createHistoryEngine.contains("router.preloadActiveRuntimes();")); - assertBefore(createHistoryEngine, "history.prepareCurrentGenerator(", - "opened = ModdedGenerationHistoryStorage.resolveActive(history)"); - assertBefore(createHistoryEngine, "opened = ModdedGenerationHistoryStorage.resolveActive(history)", - "IrisEngine candidate = buildEngine(level, seed, opened)"); - String promoted = method(createHistoryEngine, - "if (history.activeActivation().activationId() != openedActivationId)"); - assertBefore(promoted, "close(candidate);", "ModdedGenerationHistoryStorage.resolveActive(history)"); - assertBefore(promoted, "ModdedGenerationHistoryStorage.resolveActive(history)", - "candidate = buildEngine(level, seed, promoted)"); - assertTrue(createHistoryEngine.contains("GenerationHistoryRuntimeRouter.attach(")); - assertTrue(buildEngine.contains("active.packRoot().toFile()")); - assertTrue(buildEngine.contains("history.paths().activationMantleRoot(activation.activationId())")); - assertTrue(buildEngine.contains("epoch.kernelVersion()")); - assertTrue(buildEngine.contains("transitionPlan")); - } - - @Test - public void onlyExplicitTransientStudioEnginesBypassHistory() throws IOException { - String manager = source("ModdedDimensionManager.java"); - String transientCreate = method(manager, "public static Handle createTransientStudio("); - String persistentCreate = method(manager, "public static Handle createPersistent("); - String engines = source("ModdedWorldEngines.java"); - String studio = method(engines, "private static IrisEngine createTransientStudioEngine("); - String generator = source("IrisModdedChunkGenerator.java"); - String bypass = method(generator, "boolean allowsGenerationHistoryBypass("); - String route = method(generator, "private GenerationHistoryRuntimeRouter.RuntimeRoute openHistoryRoute("); - - assertTrue(transientCreate.contains("ModdedGenerationMode.TRANSIENT_STUDIO")); - assertTrue(persistentCreate.contains("ModdedGenerationMode.PERSISTENT_CREATE")); - assertTrue(studio.contains("IrisData.openRuntime(packDir)")); - assertTrue(studio.contains("IrisEngine.InitializationMode.STUDIO")); - assertFalse(studio.contains("ModdedGenerationHistoryStorage")); - assertFalse(studio.contains("attachGenerationHistory(")); - assertTrue(bypass.contains("generationMode != ModdedGenerationMode.TRANSIENT_STUDIO")); - assertTrue(bypass.contains("irisEngine.isStudio()")); - assertTrue(bypass.contains("Only an explicitly transient Iris Studio engine")); - assertBefore(route, "allowsGenerationHistoryBypass(current)", "requireHistoryRouter(current, operation)"); - } - - @Test - public void everyCoordinateBearingChunkStageOpensItsRoutedRuntime() throws IOException { - String source = source("IrisModdedChunkGenerator.java"); - - assertRuntimeRoute(source, "public Pair> findNearestMapStructure("); - assertCoordinateRoute(source, "public WeightedList getMobsAt("); - assertRuntimeRoute(source, "public CompletableFuture createBiomes("); - assertRuntimeRoute(source, "public void applyCarvers("); - assertRuntimeRoute(source, "public void buildSurface("); - assertRuntimeRoute(source, "public void applyBiomeDecoration("); - assertRuntimeRoute(source, "public void createStructures("); - assertRuntimeRoute(source, "public void createReferences("); - assertRuntimeRoute(source, "public void spawnOriginalMobs("); - assertCoordinateRoute(source, "public int getBaseHeight("); - assertCoordinateRoute(source, "public NoiseColumn getBaseColumn("); - } - - @Test - public void asyncTerrainKeepsTheRouteUntilDurableSemanticClaim() throws IOException { - String source = source("IrisModdedChunkGenerator.java"); - String fill = method(source, "public CompletableFuture fillFromNoise("); - String terrain = method(source, "private ChunkAccess generateTerrain("); - String completion = method(source, "private static CompletableFuture closeRouteOnCompletion("); - - assertBefore(fill, "openHistoryRoute(", "CompletableFuture.supplyAsync("); - assertTrue(fill.contains("generateTerrain(chunk, generationEngine, pos, air, route)")); - assertTrue(fill.contains("return closeRouteOnCompletion(pipeline, route);")); - assertTrue(terrain.contains("openHistoryRuntimeScope(route)")); - assertBefore(terrain, "generationEngine.generate(", "writeBlocks(chunk, blocks, dimMinY, height)"); - assertBefore(terrain, "writeBlocks(chunk, blocks, dimMinY, height)", "route.claimGeneratedSemantics("); - assertTrue(terrain.contains("chunk.getBlockState(position.set(x, dimMinY + y, z))")); - assertTrue(terrain.contains("state.isAir() || state.liquid()")); - assertBefore(terrain, "route.claimGeneratedSemantics(", "ModdedNativeTerrainReceipts.persist(chunk, route)"); - assertBefore(terrain, "ModdedNativeTerrainReceipts.persist(chunk, route)", "return chunk;"); - assertTrue(completion.contains("pipeline.whenComplete(")); - assertTrue(completion.contains("route.close();")); - assertBefore(completion, "pipeline.whenComplete(", "route.detachThread()"); - assertBefore(completion, "route.detachThread()", "return completion;"); - } - - @Test - public void biomeQueriesRouteEachCoordinateAndKeepRuntimeSpecificCaches() throws IOException { - String source = source("IrisModdedBiomeSource.java"); - String structure = method(source, "public Holder getNoiseBiome("); - String visible = method(source, "Holder getVisibleNoiseBiome("); - String batch = method(source, "public Set> getBiomesWithin("); - String resolution = method(source, "private Holder resolveVisibleBiome("); - - assertTrue(structure.contains("openHistoryCoordinateScope(")); - assertTrue(visible.contains("openHistoryCoordinateScope(")); - assertTrue(batch.contains("quartX << 2, quartZ << 2")); - assertTrue(source.contains("int runtimeIdentity = engine.getCacheID();")); - assertTrue(source.contains("cache.get(runtimeIdentity, key)")); - assertTrue(source.contains("cache.put(runtimeIdentity, key, resolved)")); - assertBefore(resolution, "historicalPhysicalBiomeKeyAt(", "ModdedWorldgenIds.biomeRef(engine"); - } - - @Test - public void pendingNativeStagesPreserveSavedStartsAndGuardNewFeatureFootprints() throws IOException { - String generator = source("IrisModdedChunkGenerator.java"); - String discrete = method(generator, "private boolean allowsRoutedDiscreteGeneration("); - String decoration = method(generator, "public void applyBiomeDecoration("); - String structures = method(generator, "public void createStructures("); - String mobs = method(generator, "public void spawnOriginalMobs("); - String nativeStage = source("ModdedNativeStructureStage.java"); - String adjust = method(nativeStage, "void adjustGeneratedStructures("); - String place = method(nativeStage, "void placeVanillaStructures("); - String savedStart = method(nativeStage, "private boolean isHistoricalStructureStart("); - - assertTrue(discrete.contains("chunk.getPersistedStatus().isOrAfter(stage)")); - assertFalse(discrete.contains("router.history().activeActivation().activationId()")); - assertFalse(discrete.contains("return true;")); - assertTrue(discrete.contains("allowsNewGenerationChunk(")); - assertTrue(discrete.contains("NativeGenerationWriteGuard.allowsPendingStage(current, chunk, stage)")); - assertTrue(decoration.contains("ChunkStatus.FEATURES")); - assertTrue(structures.contains("ChunkStatus.STRUCTURE_STARTS")); - assertTrue(mobs.contains("ChunkStatus.SPAWN")); - assertBefore(decoration, "chunk.getPersistedStatus().isOrAfter(ChunkStatus.FEATURES)", - "nativeStructures.placeVanillaStructures("); - assertBefore(decoration, "nativeStructures.placeVanillaStructures(", "allowsRoutedDiscreteGeneration("); - assertBefore(decoration, "allowsRoutedDiscreteGeneration(", "importedFeatures.run("); - assertBefore(decoration, "NativeGenerationWriteGuard.allowsDecoration(", "importedFeatures.run("); - assertBefore(structures, "allowsRoutedDiscreteGeneration(", "super.createStructures("); - assertBefore(mobs, "allowsRoutedDiscreteGeneration(", "NaturalSpawner.spawnMobsForChunkGeneration("); - assertBefore(adjust, "allowsNewGenerationFootprint(", "recordWorldCheckStructureShift("); - assertBefore(place, "!isHistoricalStructureStart(current, world, start)", "allowsNewGenerationFootprint("); - assertTrue(savedStart.contains("world.getChunk(origin.x(), origin.z(), ChunkStatus.EMPTY, false)")); - assertTrue(savedStart.contains("ModdedNativeTerrainReceipts.structureActivation(source)")); - assertBefore(structures, "super.createStructures(", "ModdedNativeTerrainReceipts.persistStructureActivation("); - } - - private static void assertRuntimeRoute(String source, String signature) { - String body = method(source, signature); - assertTrue(signature + " must open a generation-history route", body.contains("openHistoryRoute(")); - assertTrue(signature + " must open its routed runtime", body.contains("openHistoryRuntimeScope(route)")); - } - - private static void assertCoordinateRoute(String source, String signature) { - String body = method(source, signature); - assertTrue(signature + " must route its coordinate", body.contains("openHistoryCoordinateScope(")); - } - - private static void assertBefore(String source, String first, String second) { - int firstIndex = source.indexOf(first); - int secondIndex = source.indexOf(second); - assertTrue("Missing source contract token: " + first, firstIndex >= 0); - assertTrue("Missing source contract token: " + second, secondIndex >= 0); - assertTrue(first + " must occur before " + second, firstIndex < secondIndex); - } - - private static String source(String fileName) throws IOException { - String sourceRoot = System.getProperty(SOURCE_ROOT_PROPERTY); - assertTrue("Missing system property " + SOURCE_ROOT_PROPERTY, - sourceRoot != null && !sourceRoot.isBlank()); - return Files.readString(Path.of(sourceRoot, "art", "arcane", "iris", "modded", fileName)); - } - - private static String method(String source, String signature) { - int start = source.indexOf(signature); - assertTrue("Missing source contract signature: " + signature, start >= 0); - int openBrace = source.indexOf('{', start); - assertTrue("Missing source contract method body: " + signature, openBrace >= 0); - int depth = 0; - for (int index = openBrace; index < source.length(); index++) { - char current = source.charAt(index); - if (current == '{') { - depth++; - } else if (current == '}') { - depth--; - if (depth == 0) { - return source.substring(start, index + 1); - } - } - } - throw new IllegalArgumentException("Unclosed source contract method: " + signature); - } -} diff --git a/adapters/modded-common/src/test/java/art/arcane/iris/modded/ModdedGenerationLeaseContractTest.java b/adapters/modded-common/src/test/java/art/arcane/iris/modded/ModdedGenerationLeaseContractTest.java deleted file mode 100644 index 6bb7d329a..000000000 --- a/adapters/modded-common/src/test/java/art/arcane/iris/modded/ModdedGenerationLeaseContractTest.java +++ /dev/null @@ -1,244 +0,0 @@ -package art.arcane.iris.modded; - -import org.junit.Test; - -import java.io.IOException; -import java.nio.file.Files; -import java.nio.file.Path; - -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertTrue; - -public class ModdedGenerationLeaseContractTest { - private static final String SOURCE_ROOT_PROPERTY = "iris.moddedCommonSources"; - - @Test - public void biomeRuntimeReadsAreGenerationLeased() throws IOException { - String source = source("art/arcane/iris/modded/IrisModdedBiomeSource.java"); - - assertTrue(source.contains("tryAcquireGenerationLease(engine, \"modded_structure_biome\")")); - assertTrue(source.contains("tryAcquireGenerationLease(engine, \"modded_visible_biome\")")); - assertTrue(source.contains("tryAcquireGenerationLease(engine, \"modded_biomes_within\")")); - assertTrue(source.contains("tryAcquireGenerationLease(engine, \"modded_structure_reachability\")")); - assertTrue(source.contains("tryAcquireGenerationLease(engine, \"modded_structure_state_biome\")")); - assertTrue(source.contains("tryAcquireGenerationLease(engine, \"modded_structure_biome_keys\")")); - assertTrue(source.contains("engine == null || engine.isClosed()")); - assertTrue(source.contains("catch (GenerationSessionException e)")); - assertTrue(source.contains("e.isExpectedTeardown()")); - assertTrue(source.contains("Iris structure biome key lookup was rejected during an engine transition")); - assertTrue(source.contains("int runtimeIdentity = engine.getCacheID();")); - assertTrue(source.contains("cache.get(runtimeIdentity, key)")); - assertTrue(source.contains("cache.put(runtimeIdentity, key, resolved)")); - } - - @Test - public void terrainAndHeightQueriesShareGenerationSessions() throws IOException { - String source = source("art/arcane/iris/modded/IrisModdedChunkGenerator.java"); - - assertTrue(source.contains("generationEngine.acquireGenerationLease(\"modded_chunk_pipeline\")")); - assertTrue(source.contains("current.acquireGenerationLease(\"modded_base_height\")")); - assertTrue(source.contains("current.acquireGenerationLease(\"modded_base_column\")")); - assertTrue(source.contains("current.acquireGenerationLease(\"modded_configured_biome_keys\")")); - assertTrue(source.contains("generationEngine.isClosing() || e.isExpectedTeardown()")); - String terrain = method(source, "private ChunkAccess generateTerrain("); - int sessionFailure = terrain.indexOf("catch (GenerationSessionException e)"); - int generalFailure = terrain.indexOf("catch (Throwable e)", sessionFailure); - String sessionHandler = terrain.substring(sessionFailure, generalFailure); - assertTrue(sessionHandler.contains("throw new IllegalStateException")); - assertFalse(sessionHandler.contains("return chunk;")); - - String references = method(source, "public void createReferences("); - assertTrue(references.contains("requireGenerationLease(current, \"modded_create_references\")")); - assertTrue(references.contains("IrisContext.open(current, lease.sessionId(), null)")); - assertTrue(references.contains("NativeStructureReferenceRepair.createReferences(")); - assertFalse(references.contains("super.createReferences(level, structureManager, chunk);")); - } - - @Test - public void preservationDereferencesSharedPackData() throws IOException { - String source = source("art/arcane/iris/modded/service/ModdedPreservationService.java"); - int dereference = source.indexOf("public void dereference()"); - int irisData = source.indexOf("IrisData.dereference();", dereference); - int trackedResources = source.indexOf("threads.removeIf", dereference); - - assertTrue(dereference >= 0); - assertTrue(irisData > dereference); - assertTrue(trackedResources > irisData); - } - - @Test - public void hotloadShutdownOnlyTargetsItsOwnWorld() throws IOException { - String source = source("art/arcane/iris/modded/service/ModdedStudioHotloadService.java"); - int shutdown = source.indexOf("public void shutdownPregenerator(Engine engine)"); - int nextMethod = source.indexOf("private boolean throttled", shutdown); - String method = source.substring(shutdown, nextMethod); - - assertTrue(method.contains("ModdedPregenJob.shutdownForWorld(world.identity());")); - assertFalse(method.contains("PregeneratorJob.shutdownInstance();")); - } - - @Test - public void maintenanceOwnsOneGenerationSessionUntilWorkCompletes() throws IOException { - String source = source("art/arcane/iris/modded/service/ModdedEngineMaintenanceService.java"); - String maintain = method(source, "private void maintain(Engine engine, long scheduledAt)"); - - assertTrue(maintain.contains("engine.acquireGenerationLease(\"modded_engine_maintenance\")")); - assertTrue(maintain.contains("IrisContext.open(engine, lease.sessionId(), null)")); - assertTrue(maintain.contains("exception.isExpectedTeardown()")); - assertTrue(source.contains("active.awaitTermination(INTERRUPT_DRAIN_TIMEOUT_SECONDS, TimeUnit.SECONDS)")); - } - - @Test - public void packDownloadAdmissionPrecedesAsyncDispatch() throws IOException { - String source = source("art/arcane/iris/modded/command/IrisModdedCommands.java"); - String download = method(source, "static int download(CommandSourceStack source, String rawRequest)"); - int admission = download.indexOf("LifecycleOperationCoordinator.get().acquire("); - int executionTracking = download.indexOf("new PackDownloadExecution("); - int dispatch = download.indexOf("scheduler.asyncIfRunning(execution, execution::cancel)"); - - assertTrue(admission >= 0); - assertTrue(executionTracking > admission); - assertTrue(dispatch > admission); - assertTrue(download.contains("execution.cancel();")); - - String execution = method(source, "private static void executeDownload("); - assertTrue(execution.contains("PackDownloader.DownloadCancellation cancellation")); - assertTrue(execution.contains("catch (PackDownloader.PackDownloadCancelledException error)")); - assertTrue(execution.contains("dispatchDownloadFeedback(source,")); - assertFalse(execution.contains("scheduler.global(")); - assertFalse(execution.contains("lease.close();")); - - String feedback = method(source, "private static void dispatchDownloadFeedback("); - assertTrue(feedback.contains("source.getServer().execute(feedback);")); - } - - @Test - public void packDownloadsDrainBeforeModdedSchedulerShutdown() throws IOException { - String commands = source("art/arcane/iris/modded/command/IrisModdedCommands.java"); - String shutdownDownloads = method(commands, "public static void shutdownDownloads()"); - assertTrue(shutdownDownloads.contains("downloadAdmissionOpen = false;")); - assertTrue(shutdownDownloads.contains("execution.cancel();")); - assertTrue(shutdownDownloads.contains("execution.await(")); - - String bootstrap = source("art/arcane/iris/modded/ModdedEngineBootstrap.java"); - String stop = method(bootstrap, "public static void stop()"); - int downloads = stop.indexOf("IrisModdedCommands::shutdownDownloads"); - int scheduler = stop.indexOf("scheduler::shutdown"); - assertTrue(downloads >= 0); - assertTrue(scheduler > downloads); - } - - @Test - public void moddedSchedulerRejectsAndCancelsAbandonedDownloadSubmissions() throws IOException { - String scheduler = source("art/arcane/iris/modded/ModdedScheduler.java"); - String dispatch = method(scheduler, "public boolean asyncIfRunning(Runnable task, Runnable rejection)"); - assertTrue(dispatch.contains("RejectionAwareTask")); - assertTrue(dispatch.contains("Objects.requireNonNull(rejection")); - - String shutdown = method(scheduler, "public void shutdown()"); - assertTrue(shutdown.contains("asyncExecutor.shutdownNow()")); - assertTrue(shutdown.contains("rejectAbandonedTasks(abandonedTasks);")); - - String reset = method(scheduler, "public void reset()"); - assertTrue(reset.contains("asyncExecutor.getQueue().drainTo(abandonedTasks);")); - assertTrue(reset.contains("rejectAbandonedTasks(abandonedTasks);")); - - String rejection = method(scheduler, "private static void rejectAbandonedTasks("); - assertTrue(rejection.contains("rejectionAwareTask.reject();")); - } - - @Test - public void blockingPregenShutdownDefersItsFinalSaveToTheServerThread() throws IOException { - String jobSource = source("art/arcane/iris/modded/command/ModdedPregenJob.java"); - String shutdown = method(jobSource, "private static boolean shutdownAndSave("); - assertTrue(shutdown.contains("deferFinalSaveToServerThread()")); - assertTrue(shutdown.contains("completeDeferredFinalSave()")); - assertTrue(shutdown.contains("cancelDeferredFinalSave()")); - - String methodSource = source("art/arcane/iris/modded/command/ModdedPregenMethod.java"); - String close = method(methodSource, "public void close()"); - assertTrue(close.contains("deferFinalSaveIfRequested()")); - - String await = method(methodSource, "private void awaitFinalSave("); - assertTrue(await.contains("FINAL_SAVE_POLL_MILLIS")); - assertTrue(await.contains("deferFinalSaveIfRequested()")); - - String complete = method(methodSource, "void completeDeferredFinalSave()"); - int cancel = complete.indexOf("cancelQueuedFinalSave();"); - int directSave = complete.indexOf("saveLevelOnServerThread();"); - assertTrue(cancel >= 0); - assertTrue(directSave > cancel); - - String queuedSave = method(methodSource, "private void executeFinalSave("); - assertTrue(queuedSave.contains("if (!request.claim())")); - String cancelRequest = method(methodSource, "private void cancelQueuedFinalSave()"); - assertTrue(cancelRequest.contains("request.cancel();")); - String pending = method(methodSource, "boolean hasPendingFinalSave()"); - assertTrue(pending.contains("queuedFinalSave.get() != null")); - } - - @Test - public void firstPregenChunkFailureRetainsItsFullCause() throws IOException { - String methodSource = source("art/arcane/iris/modded/command/ModdedPregenMethod.java"); - String logFailure = method(methodSource, "private void logChunkFailure("); - - assertTrue(methodSource.contains("AtomicBoolean failureDetailLogged")); - assertTrue(logFailure.contains("unwrap(failure)")); - assertTrue(logFailure.contains("failureDetailLogged.compareAndSet(false, true)")); - assertTrue(logFailure.contains("x, z, cause);")); - assertTrue(logFailure.contains("cause.toString()")); - } - - @Test - public void pregenReportsOnlyCleanupCallbacksFromCoveredTargets() throws IOException { - String source = source("art/arcane/iris/modded/command/ModdedPregenMethod.java"); - String cleanup = method(source, "private void cleanupMantleChunksCoveredBy("); - - assertTrue(source.contains("cleanupMantleChunksCoveredBy(x, z, listener);")); - assertFalse(source.contains("cleanupMantleChunk(x, z);")); - assertTrue(cleanup.contains("cleanupChunksCoveredBy(x, z, true, listener::onChunkCleaned)")); - assertFalse(cleanup.contains("forceCleanupChunk")); - } - - @Test - public void invalidPregenBoundsFailBeforeRuntimeMutation() throws IOException { - String jobSource = source("art/arcane/iris/modded/command/ModdedPregenJob.java"); - String start = method(jobSource, "public static boolean start("); - int taskConstruction = start.indexOf("PregenTask task = PregenTask.builder()"); - int profileMutation = start.indexOf("PregenPerformanceProfile.apply(engine)"); - - assertTrue(taskConstruction >= 0); - assertTrue(profileMutation > taskConstruction); - - String commandSource = source("art/arcane/iris/modded/command/ModdedPregenCommands.java"); - String command = method(commandSource, "static int pregenStart("); - assertTrue(command.contains("catch (IllegalArgumentException failure)")); - assertTrue(command.contains("IrisModdedCommands.fail(source, failure.getMessage())")); - } - - private static String source(String relativePath) throws IOException { - String root = System.getProperty(SOURCE_ROOT_PROPERTY); - assertTrue("Missing system property " + SOURCE_ROOT_PROPERTY, root != null && !root.isBlank()); - return Files.readString(Path.of(root, relativePath)); - } - - private static String method(String source, String signature) { - int start = source.indexOf(signature); - assertTrue("Missing source contract signature: " + signature, start >= 0); - int openBrace = source.indexOf('{', start); - assertTrue("Missing source contract method body: " + signature, openBrace >= 0); - int depth = 0; - for (int index = openBrace; index < source.length(); index++) { - char current = source.charAt(index); - if (current == '{') { - depth++; - } else if (current == '}') { - depth--; - if (depth == 0) { - return source.substring(start, index + 1); - } - } - } - throw new IllegalArgumentException("Unclosed source contract method: " + signature); - } -} diff --git a/adapters/modded-common/src/test/java/art/arcane/iris/modded/ModdedIrisLogLevelCoverageTest.java b/adapters/modded-common/src/test/java/art/arcane/iris/modded/ModdedIrisLogLevelCoverageTest.java index d9c208f21..2982f7a39 100644 --- a/adapters/modded-common/src/test/java/art/arcane/iris/modded/ModdedIrisLogLevelCoverageTest.java +++ b/adapters/modded-common/src/test/java/art/arcane/iris/modded/ModdedIrisLogLevelCoverageTest.java @@ -2,32 +2,9 @@ package art.arcane.iris.modded; import org.junit.Test; -import java.io.IOException; -import java.nio.file.Files; -import java.nio.file.Path; -import java.util.List; -import java.util.stream.Stream; - import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertTrue; -/** - * The level router is a switch statement, which the compiler does not check for exhaustiveness. A level added - * to {@link art.arcane.iris.spi.LogLevel} with no arm here would compile and then drop every message at that - * level without a trace, so the fallback arm is what keeps a new level visible on the modded loaders. - */ public class ModdedIrisLogLevelCoverageTest { - @Test - public void everyLogLevelReachesTheLoggerIncludingOnesAddedLater() throws IOException { - String source = Files.readString(Path.of(System.getProperty("iris.moddedCommonSources"), - "art/arcane/iris/modded/ModdedIrisLog.java")); - int router = source.indexOf("public static void log(LogLevel level, String message)"); - assertTrue("log(LogLevel, String) not found", router >= 0); - - String body = source.substring(router, source.indexOf("public static void debug(", router)); - assertTrue(body, body.contains("default -> info(message);")); - } - @Test public void slf4jStyleArgumentsAndTrailingThrowableArePreserved() { RuntimeException failure = new RuntimeException("broken"); @@ -37,39 +14,4 @@ public class ModdedIrisLogLevelCoverageTest { assertEquals("chunk 4,9 failed", rendered.message()); assertEquals(failure, rendered.error()); } - - @Test - public void formattedDebugThrowableUsesTheVisibleDebugRouteWhenEnabled() throws IOException { - String source = Files.readString(Path.of(System.getProperty("iris.moddedCommonSources"), - "art/arcane/iris/modded/ModdedIrisLog.java")); - int start = source.indexOf("public static void debug(String format, Object... arguments)"); - int end = source.indexOf("public static void info(String message)", start); - assertTrue("formatted debug overload not found", start >= 0); - assertTrue("formatted debug overload boundary not found", end > start); - String body = source.substring(start, end); - - assertTrue(body, body.contains("if (!debugEnabled())")); - assertTrue(body, body.contains("LOGGER.info(\"[Iris/DEBUG] \" + clean(rendered.message()), rendered.error())")); - } - - @Test - public void moddedProductionUsesTheIrisLogFrontDoor() throws IOException { - Path root = Path.of(System.getProperty("iris.moddedCommonSources")); - try (Stream files = Files.walk(root)) { - List bypasses = files - .filter(path -> path.toString().endsWith(".java")) - .filter(path -> !path.getFileName().toString().equals("ModdedIrisLog.java")) - .filter(path -> { - try { - String source = Files.readString(path); - return source.contains("LoggerFactory.getLogger") - || source.contains("private static final Logger LOGGER"); - } catch (IOException unreadable) { - throw new IllegalStateException(unreadable); - } - }) - .toList(); - assertTrue(bypasses.toString(), bypasses.isEmpty()); - } - } } diff --git a/adapters/modded-common/src/test/java/art/arcane/iris/modded/ModdedLevelDataAttachmentTest.java b/adapters/modded-common/src/test/java/art/arcane/iris/modded/ModdedLevelDataAttachmentTest.java index 541337a32..dc6ed6bde 100644 --- a/adapters/modded-common/src/test/java/art/arcane/iris/modded/ModdedLevelDataAttachmentTest.java +++ b/adapters/modded-common/src/test/java/art/arcane/iris/modded/ModdedLevelDataAttachmentTest.java @@ -2,10 +2,6 @@ package art.arcane.iris.modded; import org.junit.Test; -import java.io.IOException; -import java.nio.file.Files; -import java.nio.file.Path; - import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertNull; import static org.junit.Assert.assertSame; @@ -48,25 +44,6 @@ public class ModdedLevelDataAttachmentTest { assertNull(failure.getCause()); } - @Test - public void initializesLevelDataBeforeBindingAndPublication() throws IOException { - String source = Files.readString(sourcePath("ModdedDimensionManager.java")); - int construction = source.indexOf("ServerLevel level = new ServerLevel("); - int initialization = source.indexOf("serverAccess.initializeLevelData(server, level);", construction); - int binding = source.indexOf("generator.bindLevel(level);", initialization); - int publication = source.indexOf("serverAccess.putLevelIfAbsent(server, key, level);", binding); - - assertTrue(construction >= 0); - assertTrue(initialization > construction); - assertTrue(binding > initialization); - assertTrue(publication > binding); - } - - private static Path sourcePath(String fileName) { - return Path.of(System.getProperty("iris.moddedCommonSources"), - "art/arcane/iris/modded", fileName); - } - public static final class AttachedLevelData { private RootData rootData; private DimensionKey dimensionKey; diff --git a/adapters/modded-common/src/test/java/art/arcane/iris/modded/ModdedLifecycleFailureContractTest.java b/adapters/modded-common/src/test/java/art/arcane/iris/modded/ModdedLifecycleFailureContractTest.java deleted file mode 100644 index 9aee5e796..000000000 --- a/adapters/modded-common/src/test/java/art/arcane/iris/modded/ModdedLifecycleFailureContractTest.java +++ /dev/null @@ -1,436 +0,0 @@ -package art.arcane.iris.modded; - -import org.junit.Test; - -import java.io.IOException; -import java.nio.file.Files; -import java.nio.file.Path; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertTrue; - -public class ModdedLifecycleFailureContractTest { - private static final String SOURCE_ROOT_PROPERTY = "iris.moddedCommonSources"; - - @Test - public void existingDimensionStagesWithoutReplacingTheLiveEngine() throws IOException { - String managerSource = source("ModdedDimensionManager.java"); - String create = method(managerSource, "private static Handle create("); - int existingStart = requiredIndex(create, "if (existing != null"); - int presentStart = requiredIndex(create, "if (serverAccess.hasLevel(server, key))", existingStart + 1); - int injectionStart = requiredIndex(create, "try {", presentStart); - - assertFalse(create.substring(existingStart, presentStart).contains("repointAndBind(")); - assertFalse(create.substring(presentStart, injectionStart).contains("repointAndBind(")); - assertBefore(create, "ModdedGenerationHistoryStorage.createOrStage(", "if (existing != null"); - - String generatorSource = source("IrisModdedChunkGenerator.java"); - String repointAndBind = method(generatorSource, "void repointAndBind("); - assertBefore(repointAndBind, "ModdedWorldEngines.prepareReplacement(", - "ModdedWorldEngines.installReplacement("); - assertBefore(repointAndBind, "ModdedWorldEngines.installReplacement(", "this.activePack = pack;"); - String failure = catchBlock(repointAndBind); - assertTrue(failure.contains("ModdedWorldEngines.closeUnregistered(replacement);")); - assertTrue(failure.contains("addSuppressed(")); - - String worldEnginesSource = source("ModdedWorldEngines.java"); - String installReplacement = method(worldEnginesSource, "static void installReplacement("); - assertTrue(installReplacement.contains("ENGINES.compute(")); - assertBefore(installReplacement, "close(current);", "return activeReplacement;"); - assertFalse(installReplacement.contains("catch (")); - } - - @Test - public void persistentPackUpdatesUseAnExplicitRestartBoundPath() throws IOException { - String managerSource = source("ModdedDimensionManager.java"); - String createPersistent = method(managerSource, "public static Handle createPersistent("); - String update = method(managerSource, "public static UpdateResult stagePersistentUpdate("); - - assertBefore(createPersistent, "if (previous != null)", "ModdedDimensionRegistryStore.put("); - assertTrue(createPersistent.contains("Use the Iris world update command")); - assertTrue(update.contains("ModdedGenerationHistoryStorage.createOrStage(")); - assertTrue(update.contains("active.history().pendingActivation()")); - assertTrue(update.contains("restartRequired()")); - assertFalse(update.contains("inject(")); - assertFalse(update.contains("repointAndBind(")); - assertBefore(update, "ModdedDimensionRegistryStore.put(server, updated);", - "ModdedGenerationHistoryStorage.createOrStage("); - assertTrue(update.contains("ModdedDimensionRegistryStore.put(server, previous);")); - - String commandsSource = source("command/ModdedWorldCommands.java"); - assertTrue(commandsSource.contains("root.then(updateTree());")); - String command = method(commandsSource, "private static int update("); - assertTrue(command.contains("ModdedDimensionManager.stagePersistentUpdate(")); - assertTrue(command.contains("Restart the server to activate it")); - assertTrue(command.contains("running world remains on its current pack")); - } - - @Test - public void injectionBindsBeforeRegistrationAndRollsBackEveryFailure() throws IOException { - String source = source("ModdedDimensionManager.java"); - String injection = method(source, "private static Handle inject("); - - assertBefore(injection, "generator.bindLevel(level);", "serverAccess.putLevelIfAbsent(server, key, level);"); - assertBefore(injection, "serverAccess.putLevelIfAbsent(server, key, level);", - "server.getPlayerList().addWorldborderListener(level);"); - assertFalse(injection.contains("serverAccess.putLevel(server, key, previous);")); - String failure = catchBlock(injection); - assertBefore(failure, "rollbackInjection(", "throw "); - - String rollback = method(source, "void rollbackInjection("); - assertBefore(rollback, "serverAccess.hasLevel(server, key)", "serverAccess.removeLevel(server, key);"); - assertTrue(rollback.contains("generator.unbindEngine(")); - assertTrue(rollback.contains("level.close();")); - assertTrue(rollback.contains("addSuppressed(")); - } - - @Test - public void persistentReinjectionQuarantinesBrokenEntriesAndContinues() throws IOException { - String source = source("ModdedStartup.java"); - String reinjection = method(source, "private static void reinjectPersistentDimensions("); - String failure = catchBlock(reinjection); - - assertTrue(failure.contains("ModdedIrisLog.error(")); - assertFalse(failure.contains("e.toString()")); - assertFalse(failure.contains("throw new IllegalStateException(")); - assertTrue(reinjection.contains("injected++;")); - } - - @Test - public void persistentReinjectionWaitsForPlayerServicesAndServerStarted() throws IOException { - String bootstrapSource = source("ModdedEngineBootstrap.java"); - String start = method(bootstrapSource, "public static void start("); - String serverAboutToStart = method(bootstrapSource, "public static void serverAboutToStart("); - String serverStarted = method(bootstrapSource, "public static void serverStarted("); - - assertFalse(start.contains("ModdedStartup.runOnce(server);")); - assertFalse(serverAboutToStart.contains("ModdedStartup.runOnce(server);")); - assertEquals(1, occurrences(serverStarted, "ModdedStartup.runOnce(server);")); - assertBefore(serverStarted, "bindWorldGenerators(server);", "ModdedStartup.runOnce(server);"); - assertBefore(serverStarted, "ModdedStartup.runOnce(server);", "reconcileSpawn(server);"); - - String startupSource = source("ModdedStartup.java"); - String runOnce = method(startupSource, "public static void runOnce("); - assertBefore(runOnce, "server.getPlayerList() == null", "STARTED.compareAndSet(false, true)"); - } - - @Test - public void dynamicLevelMutationsInvalidateLoaderTickCaches() throws IOException { - String levelsSource = source("ModdedServerLevels.java"); - String put = method(levelsSource, "public ServerLevel putLevel("); - String putIfAbsent = method(levelsSource, "public ServerLevel putLevelIfAbsent("); - String remove = method(levelsSource, "public ServerLevel removeLevel("); - - assertBefore(put, "server.levels.put(key, level);", "levelCacheInvalidator.accept(server);"); - assertTrue(put.contains("if (previous != level)")); - assertBefore(putIfAbsent, "server.levels.putIfAbsent(key, level);", "levelCacheInvalidator.accept(server);"); - assertTrue(putIfAbsent.contains("if (previous == null)")); - assertBefore(remove, "server.levels.remove(key);", "levelCacheInvalidator.accept(server);"); - assertTrue(remove.contains("if (removed != null)")); - - String loaderSource = source("ModdedLoader.java"); - assertTrue(loaderSource.contains("void invalidateLevelCache(MinecraftServer server);")); - String bootstrapSource = source("ModdedEngineBootstrap.java"); - assertTrue(bootstrapSource.contains("new ModdedServerLevels(boundLoader::invalidateLevelCache)")); - } - - @Test - public void persistentRestoreOpensHistoryBeforeConsultingTheGlobalPack() throws IOException { - String source = source("ModdedGenerationHistoryStorage.java"); - String restore = method(source, "static GenerationHistory restoreOrAdopt("); - - assertBefore(restore, "GenerationHistory.openIfPresent(", "sourceSupplier\").get();"); - assertTrue(restore.contains("if (existing.isPresent())")); - assertBefore(restore, "requireRegistryDefinitions(existing.get()", "return existing.get();"); - } - - @Test - public void productionPackResolutionNeverUsesTheParityProbeAsData() throws IOException { - String source = source("ModdedWorldEngines.java"); - String resolvePack = method(source, "static File resolvePack("); - - assertFalse(source.contains("System.getProperty(\"iris.parity\")")); - assertFalse(source.contains("parityPack")); - assertFalse(source.contains("falling back to parity pack")); - assertTrue(resolvePack.contains("throw new IllegalStateException(")); - } - - @Test - public void engineBootstrapResetsStartupExactlyOnceDuringStop() throws IOException { - String source = source("ModdedEngineBootstrap.java"); - String stop = method(source, "public static void stop("); - - assertEquals(1, occurrences(stop, "ModdedStartup::reset")); - } - - @Test - public void engineBootstrapAttemptsEveryShutdownStageAndAggregatesFailures() throws IOException { - String source = source("ModdedEngineBootstrap.java"); - String stop = method(source, "public static void stop("); - - assertBefore(stop, "\"services\"", "\"world engines\""); - assertBefore(stop, "\"world engines\"", "\"dimension manager\""); - assertBefore(stop, "\"server state\"", "if (failure != null)"); - assertFalse(stop.contains("throw")); - assertTrue(stop.contains("ModdedIrisLog.error(\"Iris modded shutdown completed with failures\", failure);")); - - String runStage = method(source, "private static Throwable runStopStage("); - assertTrue(runStage.contains("catch (Throwable stageFailure)")); - assertTrue(runStage.contains("failure.addSuppressed(stageFailure);")); - } - - @Test - public void worldShutdownRemovesOnlySuccessfullyClosedMappings() throws IOException { - String source = source("ModdedWorldEngines.java"); - String shutdown = method(source, "public static void shutdown()"); - - assertTrue(shutdown.contains("new ArrayList<>(ENGINES.entrySet())")); - assertFalse(shutdown.contains("ENGINES.clear()")); - // Bound generators must go through unbindEngine (latch unloading, then strict evict) so a - // late chunk-system drain cannot rebuild an engine nothing closes again. - assertTrue(shutdown.contains("generator.unbindEngine(level);")); - assertBefore(shutdown, "close(engine);", "ENGINES.remove(level, engine)"); - assertTrue(shutdown.contains("ENGINES.containsKey(level)")); - assertTrue(shutdown.contains("failure.addSuppressed(e);")); - assertTrue(shutdown.contains("failed mappings were retained")); - } - - @Test - public void engineEvictionRetainsTheMappingUntilCloseSucceeds() throws IOException { - String source = source("ModdedWorldEngines.java"); - String eviction = method(source, "static void evictOrThrow("); - - assertTrue(eviction.contains("ENGINES.computeIfPresent(")); - assertFalse(eviction.contains("ENGINES.remove(")); - assertBefore(eviction, "close(current);", "return null;"); - } - - @Test - public void generatorUnbindRetainsOwnershipWhenEvictionFails() throws IOException { - String source = source("IrisModdedChunkGenerator.java"); - String unbind = method(source, "synchronized void unbindEngine(ServerLevel level)"); - - assertFalse(unbind.contains("finally")); - assertBefore(unbind, "unloading = true;", "ModdedWorldEngines.evictOrThrow(level);"); - assertBefore(unbind, "ModdedWorldEngines.evictOrThrow(level);", "clearEngineBinding();"); - String binding = method(source, "private Engine bindEngine(ServerLevel level)"); - assertTrue(binding.contains("requireBindingAllowed();")); - assertTrue(binding.contains("requireCompletedShutdown(cached);")); - String bindLevel = method(source, "synchronized void bindLevel(ServerLevel level)"); - assertBefore(bindLevel, "requireCompletedShutdown(engine);", "unloading = false;"); - String boundEngine = method(source, "public Engine engineIfBound()"); - assertTrue(boundEngine.contains("unloading || current == null || current.isClosing() || current.isClosed()")); - } - - @Test - public void loaderUnloadSurfacesCloseFailureAndDynamicRemovalUsesStrictEviction() throws IOException { - String bootstrapSource = source("ModdedEngineBootstrap.java"); - String unload = method(bootstrapSource, "public static void levelUnloaded(ServerLevel level)"); - String failure = catchBlock(unload); - assertTrue(failure.contains("ModdedIrisLog.error(")); - assertTrue(failure.contains("throw ")); - - String managerSource = source("ModdedDimensionManager.java"); - String remove = method(managerSource, "public static boolean remove(MinecraftServer server, String dimensionId, boolean wipeStorage)"); - assertTrue(remove.contains("ModdedWorldEngines.evictOrThrow(level);")); - assertFalse(remove.contains("ModdedWorldEngines.evict(level);")); - assertTrue(remove.contains("unloadEventStarted = true;")); - assertTrue(remove.contains("rollbackRemoval(server, serverAccess, key, level, generator, unloadEventStarted, e);")); - - String rollback = method(managerSource, "private static void rollbackRemoval("); - assertTrue(rollback.contains("serverAccess.hasLevel(server, key)")); - assertTrue(rollback.contains("generator.bindLevel(level);")); - assertTrue(rollback.contains("failure.addSuppressed(rollbackFailure);")); - assertTrue(rollback.contains("ModdedIrisLog.error(")); - } - - @Test - public void engineBootstrapRollsBackEveryPublishedBindingBeforeRethrowing() throws IOException { - String source = source("ModdedEngineBootstrap.java"); - String bind = method(source, "public static ModdedPlatform bind("); - String failure = catchBlock(bind); - - assertBefore(bind, "createdServices.enableAll();", "runtime = new BoundRuntime("); - assertTrue(bind.contains("rollback.add(() -> GuiHost.suppressDesktop(")); - assertTrue(bind.contains("rollback.add(() -> restorePlatform(")); - assertTrue(bind.contains("rollback.add(() -> ModdedDimensionManager.restoreAccess(")); - assertTrue(bind.contains("rollback.add(() -> IrisObjectRotation.restorePlatformRotator(")); - assertTrue(bind.contains("rollback.add(() -> BlockDataMergeSupport.restorePlatformMerger(")); - assertTrue(bind.contains("rollback.add(() -> TileData.restorePlatformReader(")); - assertTrue(bind.contains("rollback.add(() -> TileData.restorePlatformFactory(")); - assertTrue(bind.contains("rollback.add(() -> GuiHost.set(")); - assertTrue(bind.contains("rollback.add(() -> DecoratorPlatformHooks.restore(")); - assertTrue(bind.contains("bindService(PreservationRegistry.class")); - assertTrue(bind.contains("bindService(EngineEffectsProvider.class")); - assertTrue(bind.contains("bindService(EnginePlatformHooks.class")); - assertTrue(bind.contains("bindService(EngineWorldManagerProvider.class")); - assertTrue(bind.contains("rollback.add(customContentDiscovery::rollback);")); - assertBefore(failure, "createdServices.rollback(failure);", "rollback.restore(failure);"); - assertBefore(failure, "rollback.restore(failure);", "throw "); - } - - private static void assertBefore(String source, String first, String second) { - int firstIndex = requiredIndex(source, first); - int secondIndex = requiredIndex(source, second); - assertTrue(first + " must occur before " + second, firstIndex < secondIndex); - } - - private static int requiredIndex(String source, String needle) { - return requiredIndex(source, needle, 0); - } - - private static int requiredIndex(String source, String needle, int start) { - int index = source.indexOf(needle, start); - assertTrue("Missing source contract token: " + needle, index >= 0); - return index; - } - - private static String source(String fileName) throws IOException { - String sourceRoot = System.getProperty(SOURCE_ROOT_PROPERTY); - assertTrue("Missing system property " + SOURCE_ROOT_PROPERTY, - sourceRoot != null && !sourceRoot.isBlank()); - Path sourcePath = Path.of(sourceRoot, "art", "arcane", "iris", "modded", fileName); - return Files.readString(sourcePath); - } - - private static String method(String source, String signature) { - int start = requiredIndex(source, signature); - int openBrace = openingBrace(source, start); - return source.substring(start, matchingBrace(source, openBrace) + 1); - } - - /** - * Returns the block of the shallowest catch in the method, i.e. the one attached to the - * method's outermost try. Textual first-match would return a nested catch instead, and a - * nested catch handles a different failure than the one these contracts pin. - */ - private static String catchBlock(String source) { - int bodyStart = openingBrace(source, 0); - int depth = 0; - int bestDepth = Integer.MAX_VALUE; - int catchIndex = -1; - int i = bodyStart; - while (i < source.length()) { - int skipped = skipNonCode(source, i); - if (skipped > i) { - i = skipped; - continue; - } - char current = source.charAt(i); - if (current == '{') { - depth++; - } else if (current == '}') { - depth--; - if (depth == 0) { - break; - } - } else if (current == 'c' && depth < bestDepth && source.startsWith("catch (", i)) { - bestDepth = depth; - catchIndex = i; - } - i++; - } - assertTrue("Missing source contract token: catch (", catchIndex >= 0); - return blockAt(source, openingBrace(source, catchIndex)); - } - - private static String blockAt(String source, int openBrace) { - return source.substring(openBrace, matchingBrace(source, openBrace) + 1); - } - - private static int openingBrace(String source, int start) { - int i = start; - while (i < source.length()) { - int skipped = skipNonCode(source, i); - if (skipped > i) { - i = skipped; - continue; - } - if (source.charAt(i) == '{') { - return i; - } - i++; - } - throw new IllegalArgumentException("No source block after offset " + start); - } - - private static int matchingBrace(String source, int openBrace) { - int depth = 0; - int i = openBrace; - while (i < source.length()) { - int skipped = skipNonCode(source, i); - if (skipped > i) { - i = skipped; - continue; - } - char current = source.charAt(i); - if (current == '{') { - depth++; - } else if (current == '}') { - depth--; - if (depth == 0) { - return i; - } - } - i++; - } - throw new IllegalArgumentException("Unclosed source block"); - } - - /** - * Advances past a comment, string, char or text block starting at the index, otherwise returns - * the index unchanged. Comments must be skipped: an apostrophe in prose ("generator's") would - * otherwise open a char literal and swallow the rest of the file. - */ - private static int skipNonCode(String source, int index) { - char current = source.charAt(index); - if (current == '/' && index + 1 < source.length()) { - char next = source.charAt(index + 1); - if (next == '/') { - int end = source.indexOf('\n', index); - return end < 0 ? source.length() : end + 1; - } - if (next == '*') { - int end = source.indexOf("*/", index + 2); - return end < 0 ? source.length() : end + 2; - } - return index; - } - if (current == '"' && source.startsWith("\"\"\"", index)) { - int end = source.indexOf("\"\"\"", index + 3); - return end < 0 ? source.length() : end + 3; - } - if (current == '"' || current == '\'') { - return endOfLiteral(source, index, current); - } - return index; - } - - private static int endOfLiteral(String source, int index, char terminator) { - for (int i = index + 1; i < source.length(); i++) { - char current = source.charAt(i); - if (current == '\\') { - i++; - continue; - } - if (current == terminator) { - return i + 1; - } - } - return source.length(); - } - - private static int occurrences(String source, String needle) { - int count = 0; - int offset = 0; - while (true) { - int index = source.indexOf(needle, offset); - if (index < 0) { - return count; - } - count++; - offset = index + needle.length(); - } - } -} diff --git a/adapters/modded-common/src/test/java/art/arcane/iris/modded/ModdedSpawnerRarityParityTest.java b/adapters/modded-common/src/test/java/art/arcane/iris/modded/ModdedSpawnerRarityParityTest.java index 95562cb3c..944315acd 100644 --- a/adapters/modded-common/src/test/java/art/arcane/iris/modded/ModdedSpawnerRarityParityTest.java +++ b/adapters/modded-common/src/test/java/art/arcane/iris/modded/ModdedSpawnerRarityParityTest.java @@ -5,13 +5,9 @@ import art.arcane.iris.engine.object.IrisEntitySpawn; import art.arcane.volmlib.util.collection.KList; import org.junit.Test; -import java.nio.file.Files; -import java.nio.file.Path; import java.util.List; import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertTrue; public class ModdedSpawnerRarityParityTest { private static IrisEntitySpawn spawn(int rarity) { @@ -39,37 +35,4 @@ public class ModdedSpawnerRarityParityTest { assertEquals(1, IRare.get(spawn(-5))); assertEquals(3, IRare.get(spawn(3))); } - - @Test - public void perPositionSpawnLoopsDoNotRerollEntryRarity() throws Exception { - String source = Files.readString(Path.of(System.getProperty("iris.moddedCommonSources"), - "art/arcane/iris/modded/ModdedWorldManager.java")); - - for (String method : List.of("private int spawnEntry(", "private int spawnEntryAt(")) { - String body = methodBody(source, method); - assertFalse(method + " must not re-roll rarity per position; rarityPick already weighted the pool", - body.contains("getRarity()")); - assertTrue(method + " must keep the min/max spawn-count roll", - body.contains("LootResolver.inclusive(")); - } - } - - private static String methodBody(String source, String declaration) { - int start = source.indexOf(declaration); - assertTrue("ModdedWorldManager must declare " + declaration, start >= 0); - int open = source.indexOf('{', start); - int depth = 0; - for (int index = open; index < source.length(); index++) { - char character = source.charAt(index); - if (character == '{') { - depth++; - } else if (character == '}') { - depth--; - if (depth == 0) { - return source.substring(open + 1, index); - } - } - } - throw new AssertionError(declaration + " is not brace balanced"); - } } diff --git a/adapters/modded-common/src/test/java/art/arcane/iris/modded/ModdedStructurePlacementFailureContractTest.java b/adapters/modded-common/src/test/java/art/arcane/iris/modded/ModdedStructurePlacementFailureContractTest.java deleted file mode 100644 index 0efa85911..000000000 --- a/adapters/modded-common/src/test/java/art/arcane/iris/modded/ModdedStructurePlacementFailureContractTest.java +++ /dev/null @@ -1,30 +0,0 @@ -package art.arcane.iris.modded; - -import org.junit.Test; - -import java.io.IOException; -import java.nio.file.Files; -import java.nio.file.Path; - -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertTrue; - -public class ModdedStructurePlacementFailureContractTest { - @Test - public void structurePlacementPropagatesRuntimeFailuresWithContext() throws IOException { - Path sourcePath = Path.of(System.getProperty("iris.moddedCommonSources"), - "art/arcane/iris/modded/ModdedStructureHooks.java"); - String source = Files.readString(sourcePath); - int methodStart = source.indexOf("public int[] placeStructure("); - int methodEnd = source.indexOf("\n @Override", methodStart + 1); - String method = source.substring(methodStart, methodEnd); - int catchStart = method.indexOf("catch (RuntimeException error)"); - - assertTrue(catchStart >= 0); - String failurePath = method.substring(catchStart); - assertTrue(failurePath.contains("throw NativeStructureGenerationException.failure(")); - assertTrue(failurePath.contains("\"capture placement\", structureKey, chunkX, chunkZ, error")); - assertFalse(failurePath.contains("return null;")); - assertFalse(failurePath.contains("catch (Throwable")); - } -} diff --git a/adapters/modded-common/src/test/java/art/arcane/iris/modded/ModdedStructureTemplateCacheTest.java b/adapters/modded-common/src/test/java/art/arcane/iris/modded/ModdedStructureTemplateCacheTest.java index edbedc22d..bf3f170da 100644 --- a/adapters/modded-common/src/test/java/art/arcane/iris/modded/ModdedStructureTemplateCacheTest.java +++ b/adapters/modded-common/src/test/java/art/arcane/iris/modded/ModdedStructureTemplateCacheTest.java @@ -4,8 +4,6 @@ import org.junit.Test; import java.io.InputStream; import java.nio.charset.StandardCharsets; -import java.nio.file.Files; -import java.nio.file.Path; import java.util.ArrayList; import java.util.List; import java.util.concurrent.ConcurrentHashMap; @@ -64,14 +62,9 @@ public class ModdedStructureTemplateCacheTest { config = new String(input.readAllBytes(), StandardCharsets.UTF_8); } assertTrue(config.contains("\"StructureTemplatePaletteConcurrencyMixin\"")); - - Path source = Path.of(System.getProperty("iris.moddedCommonSources")) - .resolve("art/arcane/iris/modded/mixin/StructureTemplatePaletteConcurrencyMixin.java"); - String mixin = Files.readString(source); - assertTrue(mixin.contains("@Mixin(StructureTemplate.Palette.class)")); - assertTrue(mixin.contains("@Shadow\n @Final\n @Mutable")); - assertTrue(mixin.contains("private Map> cache;")); - assertTrue(mixin.contains("@Inject(method = \"(Ljava/util/List;)V\", at = @At(\"RETURN\"))")); - assertTrue(mixin.contains("cache = new ConcurrentHashMap<>();")); + assertNotNull(Class.forName( + "art.arcane.iris.modded.mixin.StructureTemplatePaletteConcurrencyMixin", + false, + ModdedStructureTemplateCacheTest.class.getClassLoader())); } } diff --git a/adapters/modded-common/src/test/java/art/arcane/iris/modded/ModdedWorldCheckTest.java b/adapters/modded-common/src/test/java/art/arcane/iris/modded/ModdedWorldCheckTest.java index ddf92a2c2..3945b87bc 100644 --- a/adapters/modded-common/src/test/java/art/arcane/iris/modded/ModdedWorldCheckTest.java +++ b/adapters/modded-common/src/test/java/art/arcane/iris/modded/ModdedWorldCheckTest.java @@ -5,9 +5,6 @@ import net.minecraft.world.level.ChunkPos; import net.minecraft.world.level.levelgen.structure.BoundingBox; import org.junit.Test; -import java.io.IOException; -import java.nio.file.Files; -import java.nio.file.Path; import java.util.ArrayList; import java.util.List; import java.util.concurrent.atomic.AtomicBoolean; @@ -26,32 +23,6 @@ public class ModdedWorldCheckTest { assertTrue(thread.isDaemon()); } - @Test - public void poiAuditRunsInASecondServerTaskAfterVillageGeneration() throws IOException { - Path sourceRoot = Path.of(System.getProperty("iris.moddedCommonSources")); - String source = Files.readString(sourceRoot.resolve("art/arcane/iris/modded/ModdedWorldCheck.java")); - String auditSource = Files.readString( - sourceRoot.resolve("art/arcane/iris/modded/WorldCheckStructureAudit.java")); - int preparationSubmit = source.indexOf( - "WorldCheckPreparation preparation = serverRef.submit(() -> run(serverRef))"); - int completionSubmit = source.indexOf( - "exitCode = serverRef.submit(() -> runAndRequestStop(", preparationSubmit); - int completionMethod = source.indexOf("private static boolean completeWorldCheck"); - int deferredAudit = source.indexOf( - "PoiAudit poi = WorldCheckStructureAudit.auditStructurePois", completionMethod); - int structureMethod = auditSource.indexOf("private static StructureCheckResult checkNativeStructure"); - int structureMethodEnd = auditSource.indexOf("private static StructureStart resolveStructureStart", - structureMethod); - String structureSource = auditSource.substring(structureMethod, structureMethodEnd); - - assertTrue(preparationSubmit >= 0); - assertTrue(completionSubmit > preparationSubmit); - assertTrue(deferredAudit > completionMethod); - assertFalse(structureSource.contains("auditStructurePois")); - assertFalse(source.contains("prepareDeferredAudits")); - assertFalse(auditSource.contains("prepareDeferredAudits")); - } - @Test public void validStructureStartIsGenerationEvidence() { assertTrue(WorldCheckPredicates.hasNativeStructureEvidence(true, 0)); diff --git a/adapters/modded-common/src/test/java/art/arcane/iris/modded/NativeStructureFailureContractTest.java b/adapters/modded-common/src/test/java/art/arcane/iris/modded/NativeStructureFailureContractTest.java index f6e3c147b..be6e017b2 100644 --- a/adapters/modded-common/src/test/java/art/arcane/iris/modded/NativeStructureFailureContractTest.java +++ b/adapters/modded-common/src/test/java/art/arcane/iris/modded/NativeStructureFailureContractTest.java @@ -6,11 +6,6 @@ import net.minecraft.server.Bootstrap; import org.junit.BeforeClass; import org.junit.Test; -import java.io.IOException; -import java.nio.file.Files; -import java.nio.file.Path; - -import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertSame; import static org.junit.Assert.assertThrows; import static org.junit.Assert.assertTrue; @@ -22,25 +17,6 @@ public class NativeStructureFailureContractTest { Bootstrap.bootStrap(); } - @Test - public void structureLocateDoesNotCatchAndFallThroughToAnotherImplementation() throws IOException { - String source = moddedSource("IrisModdedChunkGenerator.java"); - int locateStart = source.indexOf("public Pair> findNearestMapStructure"); - int locateEnd = source.indexOf("public boolean isNativeStructureReachable", locateStart); - String locate = source.substring(locateStart, locateEnd); - String stage = moddedSource("ModdedNativeStructureStage.java"); - int filterStart = stage.indexOf("HolderSet filterReachableNativeStructures"); - int filterEnd = stage.indexOf("void adjustGeneratedStructures", filterStart); - String filter = stage.substring(filterStart, filterEnd); - - assertTrue(locate.contains("Engine current = engine();")); - assertFalse(locate.contains("catch (Throwable")); - assertFalse(locate.contains("return null;\n } catch")); - assertTrue(filter.contains("unregistered structure holder")); - assertFalse(filter.contains("catch (Throwable")); - assertFalse(filter.contains("failed closed")); - } - @Test public void globalStructureDisableRefusesGeneratorBinding() { IrisModdedChunkGenerator.requireGlobalStructureGeneration(true, "overworld:overworld"); @@ -56,66 +32,6 @@ public class NativeStructureFailureContractTest { assertTrue(error.getMessage().contains("importedStructures.disabledExact")); } - @Test - public void structureVegetationCleanupPrecedesTerrainPreparationAndPlacement() throws IOException { - String source = moddedSource("ModdedNativeStructureStage.java"); - int placementStart = source.indexOf("void placeVanillaStructures"); - int placementEnd = source.indexOf("private static String nativeStructureBatchContext", placementStart); - String placement = source.substring(placementStart, placementEnd); - - assertTrue(placement.contains("\"terrain integration\"")); - assertTrue(placement.contains("\"terrain preparation\"")); - assertTrue(placement.contains("\"foundation repair\"")); - assertFalse(placement.contains("\"terrain carving\"")); - assertTrue(placement.contains("visitExistingPois(chunk")); - assertTrue(placement.contains("level.updatePOIOnBlockStateChange(")); - assertTrue(placement.contains("Blocks.AIR.defaultBlockState(), state")); - assertTrue(placement.indexOf("visitExistingPois(chunk") - < placement.indexOf("WorldgenTerrainHeightmaps.primeStructurePlacement(")); - assertTrue(placement.contains("prepareSurfaceStructures")); - assertTrue(placement.contains("clearIntersectingVegetation")); - assertTrue(placement.indexOf("clearIntersectingVegetation") - < placement.indexOf("prepareSurfaceStructures")); - assertTrue(placement.indexOf("prepareSurfaceStructures") - < placement.indexOf("for (NativePlacementGroup group")); - assertTrue(placement.indexOf("repairVacuumFoundations") - > placement.indexOf("for (NativePlacementGroup group")); - } - - @Test - public void structurePlacementPrimesNeighbourWorldgenHeightmapsBeforeTerrainPreparation() throws IOException { - String source = moddedSource("ModdedNativeStructureStage.java"); - int placementStart = source.indexOf("void placeVanillaStructures"); - int placementEnd = source.indexOf("private static String nativeStructureBatchContext", placementStart); - String placement = source.substring(placementStart, placementEnd); - - assertTrue(source.contains("import art.arcane.iris.nativegen.WorldgenTerrainHeightmaps;")); - assertTrue(placement.contains("WorldgenTerrainHeightmaps.primeStructurePlacement(")); - assertTrue(placement.contains("\"heightmap priming\"")); - assertTrue(placement.contains("heightmapStarts.add(start);")); - assertTrue(placement.indexOf("WorldgenTerrainHeightmaps.primeStructurePlacement(") - < placement.indexOf("prepareSurfaceStructures")); - assertTrue(source.contains("Engine.hostHeight(generationEngine, x, z, false) + runtimeMinY + 1")); - assertTrue(source.contains("Engine.hostHeight(generationEngine, x, z, true) + runtimeMinY + 1")); - assertTrue(placement.contains("current.getDimensionStackContext() != null")); - assertTrue(source.contains("int minY = chunk.getMinY() + 1;")); - } - - @Test - public void nativeStructurePostProcessingUsesBoundedWorldgenAccess() throws IOException { - String source = moddedSource("ModdedNativeStructureStage.java"); - int placementStart = source.indexOf("void placeVanillaStructures"); - int placementEnd = source.indexOf("private List> structuresByStep", placementStart); - String placement = source.substring(placementStart, placementEnd); - - assertTrue(placement.contains("ModdedNativeStructureWorldgenAccess.create(")); - assertTrue(placement.contains("nativeStructureProtection(current, staticObjects)")); - assertTrue(placement.contains("Engine.hostHeight(current, x, z, true)")); - assertTrue(placement.contains("placeVanillaStructure(boundedWorld, structureManager")); - assertFalse(placement.contains("NativeStructurePostProcessor.place(world,")); - assertTrue(placement.contains("world.setCurrentlyGenerating(null);")); - } - @Test public void structureFailurePreservesPhaseIdentityChunkAndCause() { IllegalArgumentException cause = new IllegalArgumentException("broken placement"); @@ -128,10 +44,4 @@ public class NativeStructureFailureContractTest { assertTrue(error.getMessage().contains("12,-8")); assertTrue(error.getMessage().contains("aborted")); } - - private static String moddedSource(String fileName) throws IOException { - Path sourcePath = Path.of(System.getProperty("iris.moddedCommonSources"), - "art", "arcane", "iris", "modded", fileName); - return Files.readString(sourcePath); - } } diff --git a/adapters/modded-common/src/test/java/art/arcane/iris/modded/command/IrisModdedStructureCommandTest.java b/adapters/modded-common/src/test/java/art/arcane/iris/modded/command/IrisModdedStructureCommandTest.java index bd911e2a2..8549f7b06 100644 --- a/adapters/modded-common/src/test/java/art/arcane/iris/modded/command/IrisModdedStructureCommandTest.java +++ b/adapters/modded-common/src/test/java/art/arcane/iris/modded/command/IrisModdedStructureCommandTest.java @@ -7,9 +7,6 @@ import com.mojang.datafixers.util.Pair; import net.minecraft.core.BlockPos; import org.junit.Test; -import java.io.IOException; -import java.nio.file.Files; -import java.nio.file.Path; import java.util.List; import java.util.Set; import java.util.concurrent.atomic.AtomicInteger; @@ -48,30 +45,6 @@ public class IrisModdedStructureCommandTest { assertEquals(1, nativeReferences.get()); } - @Test - public void gotoStructureSupportsIrisAndNativeRegistryTargets() throws IOException { - String source = source("ModdedLocateCommands.java"); - String suggestions = source("ModdedCommandSuggestions.java"); - - assertTrue(source.contains("IrisStructureLocator.hasLocatableEditablePlacement(engine, key)")); - assertTrue(source.contains("registry.get(identifier)")); - assertTrue(source.contains("getPlacementsForStructure(holder)")); - assertTrue(source.contains("generator.findNearestMapStructure(")); - assertTrue(source.contains("NATIVE_STRUCTURE_LOCATE_RADIUS = 100")); - assertTrue(source.contains("HolderSet.direct(target.holder())")); - assertFalse(source.contains("NativeStructureLocateCapability")); - assertTrue(source.contains("boolean teleported = player.teleportTo(")); - assertTrue(suggestions.contains("combineStructureKeys(unregisteredIrisKeys, nativeKeys)")); - assertTrue(source.contains("irisGenerator.isNativeStructureReachable(holder)")); - assertTrue(source.contains("LocateStatus.SEARCH_LIMIT_REACHED")); - assertTrue(source.contains("IRIS_MODDED_COMMANDS_UNABLE_LOCATE_IRIS_PLACED_STRUCTURE_DENSITY_SEARCH_SAFETY_LIMIT_WAS")); - assertTrue(source.contains("int targetX = result.originX()")); - assertTrue(source.contains("int targetY = result.baseY() + 2")); - assertTrue(source.contains("int targetZ = result.originZ()")); - assertFalse(source.contains("at[0] + 8")); - assertFalse(source.contains("at[2] + 8")); - } - @Test public void registeredStructureEligibilityMatchesGotoAndSuggestions() { IrisNativeStructureDecision nativeDecision = decision(NativeStructureGenerationStatus.GENERATE_NATIVE); @@ -175,162 +148,6 @@ public class IrisModdedStructureCommandTest { .contains("non-positive density or a Y band outside")); } - @Test - public void unregisteredCommandUsesGotoEligibilityAndPrintsToConsole() throws IOException { - String command = source("ModdedUnregisteredStructures.java"); - String tree = source("ModdedCommandTree.java"); - - assertTrue(tree.contains("Commands.literal(\"unregistered\")")); - assertTrue(tree.contains("ModdedUnregisteredStructures.print(context.getSource())")); - assertTrue(command.contains("ModdedCommandSuggestions.isEligibleRegisteredStructure(")); - assertTrue(command.contains("ModdedLocateCommands.registeredStructureUnavailableMessage(")); - assertTrue(command.contains("engine.getData().getStructureLoader().getPossibleKeys()")); - assertTrue(command.contains("IrisStructureLocator.hasLocatableEditablePlacement(engine, key)")); - assertTrue(command.contains("ModdedIrisLog.info(\"[Iris goto unregistered] [{}] {} - {}\"")); - assertTrue(command.contains("UNREGISTERED(\"unregistered\")")); - assertFalse(command.contains("DatapackIngestService")); - } - - @Test - public void structureSuggestionsUseActiveLevelAvailability() throws IOException { - String suggestions = source("ModdedCommandSuggestions.java"); - int methodStart = suggestions.indexOf("static CompletableFuture suggestStructureKeys("); - int methodEnd = suggestions.indexOf("static boolean isEligibleRegisteredStructure(", methodStart); - String method = suggestions.substring(methodStart, methodEnd); - - assertTrue(method.contains("ServerLevel level = source.getLevel()")); - assertTrue(method.contains("Engine engine = IrisModdedCommands.engineFor(level)")); - assertFalse(method.contains("IrisStructureLocator.locatableKeys(engine)")); - assertTrue(method.contains("IrisStructureLocator.locatableEditableKeys(engine)")); - assertTrue(method.contains("StructureReachability.reachableKeys(engine)")); - assertTrue(method.contains("NativeStructureGenerationPolicy.resolve(engine, key, false)")); - assertTrue(method.contains("IrisStructureLocator.hasLocatableNativePlacement(engine, key)")); - assertTrue(method.contains("IrisStructureLocator.hasLocatableEditablePlacement(engine, key)")); - assertTrue(method.contains("reachableNativeKeys.contains(normalizeKey(key))")); - assertTrue(method.contains("nativeGenerationEnabled")); - assertTrue(method.contains("eligibleUnregisteredEditableKeys(")); - assertTrue(method.contains("IrisStructureLocator.hasNativePlacement(engine, candidate)")); - assertFalse(method.contains("NativeStructureGenerationKeys.active(level)")); - assertFalse(method.contains("getPlacementsForStructure")); - } - - @Test - public void generatorLocateUsesEveryIrisPlacedNativeStructure() throws IOException { - String source = moddedSource("ModdedNativeStructureStage.java"); - int methodStart = source.indexOf("Pair> findNearestIrisStructure("); - int methodEnd = source.indexOf("HolderSet filterReachableNativeStructures(", methodStart); - String method = source.substring(methodStart, methodEnd); - int registryLookup = method.indexOf("level.registryAccess().lookupOrThrow(Registries.STRUCTURE)"); - int placedCheck = method.indexOf( - "if (!IrisStructureLocator.hasNativePlacement(current, structureId))"); - int irisLocate = method.indexOf("NativeStructureLocatePersistence.search(", placedCheck); - int nearestSelection = method.indexOf( - "NativeStructureLocateResults.nearest(pos, predicted, nativeLocated)", irisLocate); - int selectedVerification = method.indexOf("bestSearch.search().verify(bestResult)", nearestSelection); - int selectedReference = method.indexOf( - "selectedSearch.search().reference(selectedStart)", selectedVerification); - - assertTrue(registryLookup >= 0); - assertTrue(placedCheck > registryLookup); - assertTrue(irisLocate > placedCheck); - assertTrue(nearestSelection > irisLocate); - assertTrue(selectedVerification > nearestSelection); - assertTrue(selectedReference > selectedVerification); - assertTrue(method.contains("NativeStructureLocatePersistence.probe(")); - assertTrue(method.contains("findUnexplored")); - assertTrue(method.contains("LocateStatus.SEARCH_LIMIT_REACHED")); - assertTrue(method.contains("verified.ownership().locatorY()")); - assertTrue(method.contains("selectedSearch.search().reference(selectedStart)")); - assertTrue(method.contains("NativeStructureLocateResults.selectAndReference(")); - assertFalse(method.contains("NativeStructureLocateCapability")); - assertTrue(source.contains("structureBiomeSource.isStructureReachable(holder)")); - assertFalse(source.contains("isPaperUnavailable")); - String generator = moddedSource("IrisModdedChunkGenerator.java"); - assertTrue(generator.contains("NativeStructureVanillaLocator.predict(")); - assertFalse(generator.contains("super.findNearestMapStructure(level, reachable")); - } - - @Test - public void commandResolvesNativePolicyBeforeAnyVanillaAliasLookup() throws IOException { - String source = source("ModdedLocateCommands.java"); - int methodStart = source.indexOf("static int gotoStructure("); - int methodEnd = source.indexOf("private static void locateIrisStructure(", methodStart); - String method = source.substring(methodStart, methodEnd); - int nativeResolution = method.indexOf("resolveNativeStructure(source, level, engine, key)"); - int editableIrisLookup = method.indexOf( - "IrisStructureLocator.hasLocatableEditablePlacement(engine, key)", nativeResolution); - int policyResolution = method.indexOf( - "NativeStructureGenerationPolicy.resolve(engine, target.key(), false)", editableIrisLookup); - int eligibilityCheck = method.indexOf( - "ModdedCommandSuggestions.isEligibleRegisteredStructure(", policyResolution); - int replacementLocate = method.indexOf( - "locateIrisStructure(source, level, engine, player, target.key())", eligibilityCheck); - int nativeLocate = method.indexOf("runNativeStructureLocate(source, level, player, target)", - replacementLocate); - - assertTrue(nativeResolution >= 0); - assertTrue(editableIrisLookup > nativeResolution); - assertTrue(policyResolution > editableIrisLookup); - assertTrue(eligibilityCheck > policyResolution); - assertTrue(replacementLocate > eligibilityCheck); - assertTrue(nativeLocate > replacementLocate); - assertTrue(method.contains("IrisStructureLocator.hasLocatableNativePlacement(engine, target.key())")); - assertTrue(method.contains("IrisStructureLocator.hasLocatableEditablePlacement(engine, target.key())")); - assertTrue(method.contains("!IrisStructureLocator.hasNativePlacement(engine, key)")); - assertTrue(method.contains("StructureReachability.isReachable(engine, target.key())")); - assertTrue(method.contains("getWorldGenSettings().options().generateStructures()")); - assertFalse(method.contains("IrisStructureLocator.isPlaced(engine, key)")); - } - - @Test - public void verifyResolvesRegisteredNativeBeforeGenericIrisAliases() throws IOException { - String source = source("ModdedLocateCommands.java"); - int methodStart = source.indexOf("private static int verifyStructure("); - int methodEnd = source.indexOf("private static Optional resolveNativeStructure(", - methodStart); - String method = source.substring(methodStart, methodEnd); - int nativeResolution = method.indexOf("resolveNativeStructure(source, level, engine, key)"); - int genericIrisLookup = method.indexOf("IrisStructureLocator.isPlaced(engine, key)", nativeResolution); - - assertTrue(nativeResolution >= 0); - assertTrue(genericIrisLookup > nativeResolution); - assertTrue(method.contains("NativeStructureAvailability.IRIS_SUPPRESSED")); - } - - @Test - public void structureVerificationNoLongerClaimsNativeGenerationIsMissing() throws IOException { - String source = source("ModdedStructureCommands.java"); - - assertTrue(source.contains("verifyTree(\"verify\")")); - assertTrue(source.contains("verifyTree(\"locateall\")")); - assertTrue(source.contains("IrisModdedCommands.verifyStructures(")); - assertFalse(source.contains("Vanilla structure locate is meaningless here")); - } - - private String source(String fileName) throws IOException { - Path source = commonSourceRoot().resolve("art/arcane/iris/modded/command/") - .resolve(fileName) - .normalize(); - return Files.readString(source); - } - - private String moddedSource(String fileName) throws IOException { - Path source = commonSourceRoot().resolve("art/arcane/iris/modded/") - .resolve(fileName) - .normalize(); - return Files.readString(source); - } - - private Path commonSourceRoot() { - String configuredRoot = System.getProperty("iris.moddedCommonSources"); - if (configuredRoot != null && !configuredRoot.isBlank()) { - return Path.of(configuredRoot); - } - return Path.of(System.getProperty("user.dir")) - .resolve("../modded-common/src/main/java") - .normalize(); - } - private IrisNativeStructureDecision decision(NativeStructureGenerationStatus status) { return new IrisNativeStructureDecision(status, 0, null, false, null, null); } diff --git a/adapters/modded-common/src/test/java/art/arcane/iris/modded/command/ModdedRiverLocateContractTest.java b/adapters/modded-common/src/test/java/art/arcane/iris/modded/command/ModdedRiverLocateContractTest.java deleted file mode 100644 index 120328f1f..000000000 --- a/adapters/modded-common/src/test/java/art/arcane/iris/modded/command/ModdedRiverLocateContractTest.java +++ /dev/null @@ -1,28 +0,0 @@ -package art.arcane.iris.modded.command; - -import org.junit.Test; - -import java.io.IOException; -import java.nio.file.Files; -import java.nio.file.Path; - -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertTrue; - -public final class ModdedRiverLocateContractTest { - @Test - public void riverLookupMergesRecordedAndEligibleActiveFeatures() throws IOException { - Path sourcePath = Path.of(System.getProperty("iris.moddedCommonSources")) - .resolve("art/arcane/iris/modded/command/ModdedLocateCommands.java"); - String source = Files.readString(sourcePath); - int methodStart = source.indexOf("static int gotoRiver("); - int methodEnd = source.indexOf("static int gotoStructure(", methodStart); - String method = source.substring(methodStart, methodEnd); - - assertTrue(method.contains("GenerationSemanticQueries.nearestRiver(")); - assertTrue(method.contains("runtime == null")); - assertTrue(method.contains("feature.y() + 2")); - assertFalse(method.contains("runtime.nearestFeature(")); - assertFalse(method.contains("feature.y() + engine.getDimension().getMinHeight()")); - } -} diff --git a/adapters/modded-common/src/test/java/art/arcane/iris/modded/command/ModdedStructureHistoryContractTest.java b/adapters/modded-common/src/test/java/art/arcane/iris/modded/command/ModdedStructureHistoryContractTest.java deleted file mode 100644 index 4acb0a399..000000000 --- a/adapters/modded-common/src/test/java/art/arcane/iris/modded/command/ModdedStructureHistoryContractTest.java +++ /dev/null @@ -1,34 +0,0 @@ -package art.arcane.iris.modded.command; - -import org.junit.Test; - -import java.io.IOException; -import java.nio.file.Files; -import java.nio.file.Path; - -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertTrue; - -public final class ModdedStructureHistoryContractTest { - @Test - public void retainedStructureNamesReachTheSemanticSearchOnBothAdmissionBranches() throws IOException { - Path root = Path.of(System.getProperty("iris.moddedCommonSources")); - String source = Files.readString(root.resolve("art/arcane/iris/modded/command/ModdedLocateCommands.java")); - int start = source.indexOf("static int gotoStructure("); - int end = source.indexOf("static String registeredStructureUnavailableMessage(", start); - String admission = source.substring(start, end); - String retainedCheck = "GenerationFindCatalog.hasRetainedStructurePlacement(engine, key)"; - int firstCheck = admission.indexOf(retainedCheck); - assertTrue(firstCheck >= 0); - assertTrue(admission.indexOf(retainedCheck, firstCheck + retainedCheck.length()) >= 0); - - int locateStart = source.indexOf("private static void locateIrisStructure("); - int locateEnd = source.indexOf("private static void runNativeStructureLocate(", locateStart); - String locate = source.substring(locateStart, locateEnd); - assertTrue(locate.contains("GenerationSemanticQueries.nearestStructure(")); - assertFalse(locate.contains("IrisStructureLocator.locate(")); - - String suggestions = Files.readString(root.resolve("art/arcane/iris/modded/command/ModdedCommandSuggestions.java")); - assertTrue(suggestions.contains("GenerationFindCatalog.retainedStructureKeys(engine)")); - } -} diff --git a/adapters/modded-common/src/test/java/art/arcane/iris/modded/command/ModdedStudioTeleportContractTest.java b/adapters/modded-common/src/test/java/art/arcane/iris/modded/command/ModdedStudioTeleportContractTest.java deleted file mode 100644 index e7047cadd..000000000 --- a/adapters/modded-common/src/test/java/art/arcane/iris/modded/command/ModdedStudioTeleportContractTest.java +++ /dev/null @@ -1,89 +0,0 @@ -package art.arcane.iris.modded.command; - -import org.junit.Test; - -import java.io.IOException; -import java.nio.file.Files; -import java.nio.file.Path; - -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertTrue; - -public class ModdedStudioTeleportContractTest { - private static final String SOURCE_ROOT_PROPERTY = "iris.moddedCommonSources"; - - @Test - public void studioOpenSerializesReplacementAndWaitsForTheNativePath() throws IOException { - String source = source("command/ModdedStudioCommands.java"); - String open = method(source, "private static int open("); - String execute = method(source, "private static void executeStudioOpen("); - - assertTrue(open.contains("TRANSITIONS.submit(")); - assertFalse(open.contains("orTimeout(")); - assertFalse(open.contains("deadlineNanos")); - assertBefore(execute, "replaceExistingStudio(", "ModdedDimensionManager.createTransientStudio("); - assertBefore(execute, "ModdedDimensionManager.createTransientStudio(", "ModdedDimensionManager.teleportAsync("); - assertFalse(execute.contains("deadlineNanos")); - assertFalse(source.contains("player.teleportTo(studio")); - } - - @Test - public void studioTeleportAndVisionShareWarmFutureSemantics() throws IOException { - String studio = source("command/ModdedStudioCommands.java"); - String vision = source("command/ModdedVisionOverlay.java"); - String dimensions = source("ModdedDimensionManager.java"); - - assertTrue(studio.contains("private static CompletableFuture teleportToStudio(")); - assertTrue(studio.contains("ModdedDimensionManager.teleportAsync(")); - assertTrue(dimensions.contains("TELEPORT_WARM_RADIUS = 0")); - assertTrue(dimensions.contains("addTicketAndLoadWithRadius(\n" - + " TELEPORT_WARM_TICKET,\n" - + " chunkPos,\n" - + " TELEPORT_WARM_RADIUS)")); - assertTrue(dimensions.contains("removeTicketWithRadius(\n" - + " TELEPORT_WARM_TICKET,\n" - + " chunkPos,\n" - + " TELEPORT_WARM_RADIUS)")); - assertTrue(vision.contains("Math.floor(worldX)")); - assertTrue(vision.contains("Math.floor(worldZ)")); - assertTrue(vision.contains("if (opener != null)")); - assertTrue(vision.contains("ModdedDimensionManager.teleportAsync(")); - assertFalse(vision.contains("level.getHeight(")); - assertFalse(vision.contains("player.teleportTo(")); - } - - private static String source(String relative) throws IOException { - String root = System.getProperty(SOURCE_ROOT_PROPERTY); - if (root == null || root.isBlank()) { - throw new IllegalStateException("Missing test property " + SOURCE_ROOT_PROPERTY); - } - return Files.readString(Path.of(root).resolve("art/arcane/iris/modded").resolve(relative)) - .replace("\r\n", "\n"); - } - - private static String method(String source, String signature) { - int start = source.indexOf(signature); - if (start < 0) { - throw new IllegalArgumentException("Missing source method " + signature); - } - int open = source.indexOf('{', start); - int depth = 0; - for (int index = open; index < source.length(); index++) { - char current = source.charAt(index); - if (current == '{') { - depth++; - } else if (current == '}' && --depth == 0) { - return source.substring(start, index + 1); - } - } - throw new IllegalArgumentException("Unclosed source method " + signature); - } - - private static void assertBefore(String source, String first, String second) { - int firstIndex = source.indexOf(first); - int secondIndex = source.indexOf(second); - assertTrue("Missing source token " + first, firstIndex >= 0); - assertTrue("Missing source token " + second, secondIndex >= 0); - assertTrue(first + " must precede " + second, firstIndex < secondIndex); - } -} diff --git a/adapters/neoforge/build.gradle b/adapters/neoforge/build.gradle index cde2ef066..ca7ea081c 100644 --- a/adapters/neoforge/build.gradle +++ b/adapters/neoforge/build.gradle @@ -222,7 +222,6 @@ tasks.named('compileJava', JavaCompile).configure { tasks.named('test').configure { useJUnitPlatform() - systemProperty('iris.moddedCommonSources', file('../modded-common/src/main/java').absolutePath) } processResources { diff --git a/core/src/test/java/art/arcane/iris/core/DiagnosticSeverityPolicyTest.java b/core/src/test/java/art/arcane/iris/core/DiagnosticSeverityPolicyTest.java deleted file mode 100644 index 143d5f018..000000000 --- a/core/src/test/java/art/arcane/iris/core/DiagnosticSeverityPolicyTest.java +++ /dev/null @@ -1,182 +0,0 @@ -package art.arcane.iris.core; - -import org.junit.Test; - -import java.io.IOException; -import java.nio.file.Files; -import java.nio.file.Path; -import java.util.List; -import java.util.stream.Stream; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertTrue; - -/** - * Every core diagnostic keeps its severity through to the server log, so the level a call site picks is the - * level an operator scanning for WARN and SEVERE sees. This pins the two ends of that decision: conditions an - * operator must act on stay at WARN or ERROR, and conditions that repeat per block, per sample or per chunk - - * or that report designed backpressure, a probe on an optional dependency, or a success - do not. - *

- * The pin is on the source rather than on a live engine because most of these call sites need a running world - * to reach, and what is being fixed is the choice of level, not the condition that triggers it. - */ -public class DiagnosticSeverityPolicyTest { - @Test - public void perBlockAndPerSampleConditionsDoNotReachTheServerLogAtWarnLevel() { - assertLoggedWith("util/project/hunk/Hunk.java", "OUT OF BOUNDS ", "debug"); - assertLoggedWith("engine/mantle/MantleWriter.java", "No set? ", "debug"); - assertLoggedWith("engine/mantle/MantleWriter.java", "Mantle Writer Accessed chunk out of bounds", "debug"); - assertLoggedWith("engine/object/IrisDecorator.java", "Empty Block Data for ", "warnOnce"); - assertLoggedWith("engine/object/IrisCompat.java", "Can't find block data for ", "warnOnce"); - assertLoggedWith("engine/data/cache/AtomicCache.java", "Atomic cache supplier failed: %s: %s", "warnOnce"); - assertLoggedWith("engine/IrisComplex.java", "Failed to sample interpolated biome bounds", "warnOnce"); - assertLoggedWith("engine/framework/placer/WorldObjectPlacer.java", "Tried to place custom block at", "warnOnce"); - } - - /** - * Backpressure pausing generation is the design working. It is reported every five seconds for the whole - * duration of a large pregen, so at WARN it would be the only thing a log scan finds. - */ - @Test - public void designedBackpressureIsReportedWithoutRaisingAWarning() { - assertLoggedWith("core/pregenerator/PregenMantleBackpressure.java", "Pregen mantle backpressure: ", "info"); - assertLoggedWith("core/pregenerator/PregenMantleBackpressure.java", "Pregen heap pressure: pausing generation", "info"); - assertLoggedWith("core/pregenerator/MantleHeapPressure.java", "Iris heap remained at", "info"); - assertLoggedWith("core/pregenerator/methods/AsyncPregenMethod.java", "is still pending after", "debug"); - } - - @Test - public void generationTracingStaysAtDebugLevel() { - assertLoggedWith("engine/mantle/components/MantleObjectComponent.java", "Regen object layer start:", "debug"); - assertLoggedWith("engine/mantle/components/MantleObjectComponent.java", "Goldendebug object attempt:", "debug"); - assertLoggedWith("engine/mantle/components/GoldenDebugObjectPlacer.java", "Goldendebug query:", "debug"); - assertLoggedWith("engine/mantle/components/IrisStructureComponent.java", "[StructTrace] ORIGIN", "debug"); - } - - @Test - public void coreProductionDoesNotWriteDirectlyToProcessStreams() throws IOException { - try (Stream files = Files.walk(Path.of("src/main/java"))) { - List bypasses = files - .filter(path -> path.toString().endsWith(".java")) - .filter(path -> { - try { - String source = Files.readString(path); - return source.contains("System.out") - || source.contains("System.err") - || source.contains(".printStackTrace();"); - } catch (IOException unreadable) { - throw new IllegalStateException(unreadable); - } - }) - .toList(); - assertTrue(bypasses.toString(), bypasses.isEmpty()); - } - } - - @Test - public void probesOnOptionalDependenciesAreNotWarnings() throws IOException { - assertLoggedWith("core/link/MultiverseCoreLink.java", "is not reachable; Iris world settings", "info"); - assertLoggedWith("core/link/MultiverseCoreLink.java", "Multiverse will record the live name", "info"); - assertLoggedWith("core/gui/GuiHost.java", "Unable to install the Iris desktop quit guard", "info"); - String slimJar = read("util/common/misc/SlimJar.java"); - assertTrue(slimJar.contains("debug(plugin, \"Failed to inject the library loader")); - assertTrue(slimJar.contains("if (DEBUG)")); - assertTrue(slimJar.contains("plugin.getLogger().info(\"[DEBUG] \" + message)")); - } - - /** - * A refused destructive command is the guard working, and the admin who typed it is told directly. The - * console record of it is not a warning about the server. - */ - @Test - public void aRefusedMultiverseCommandIsRecordedWithoutRaisingAWarning() throws IOException { - String guard = read("core/link/MultiverseGuardListener.java"); - - assertTrue("the console record of a refusal is kept", guard.contains("IrisLogging.info(\"%s %s\", reason, remedy)")); - assertFalse("the refusal is not a warning about the server", guard.contains("IrisLogging.warn(\"%s %s\"")); - } - - @Test - public void decorationAndBlankLinesAreNotEmittedAtAnySeverity() throws IOException { - String safeguard = read("core/safeguard/IrisSafeguard.java"); - assertFalse("a blank record renders as an empty [WARN] line", safeguard.contains("IrisLogging.warn(\"\")")); - assertFalse("a blank record renders as an empty [SEVERE] line", safeguard.contains("IrisLogging.error(\"\")")); - assertFalse("a blank record renders as an empty [INFO] line", safeguard.contains("IrisLogging.info(\"\")")); - assertFalse("a separator rule is not a diagnostic", safeguard.contains("--==<")); - - String configurator = read("core/ServerConfigurator.java"); - assertFalse("a separator rule is not a diagnostic", configurator.contains("IrisLogging.error(\"====")); - assertFalse("a separator rule is not a diagnostic", configurator.contains("IrisLogging.error(\"----")); - } - - /** - * A written debug image is a success, and the method that wrote it had no callers at all. - */ - @Test - public void theUnusedDebugImageWriterIsGone() throws IOException { - assertFalse(read("engine/object/IrisImage.java").contains("writeDebug")); - } - - /** - * The other end of the policy. These are the conditions the promotion exists for. - */ - @Test - public void operatorActionableConditionsKeepTheirSeverity() { - assertLoggedWith("core/lifecycle/VanishedWorldStorage.java", "Iris world storage is gone at", "error"); - assertLoggedWith("core/IrisWorlds.java", "has unusable world storage and is excluded", "error"); - assertLoggedWith("engine/EngineDataStore.java", "Failed to setup Engine Data", "error"); - assertLoggedWith("engine/IrisEngineMantle.java", "Failed to read chunk section, skipping it.", "error"); - assertLoggedWith("engine/IrisEngineMantle.java", "Failed to read chunk, creating a new chunk instead.", "error"); - assertLoggedWith("util/common/reflect/WrappedField.java", "Failed to created WrappedField", "error"); - assertLoggedWith("core/datapack/DatapackIngestService.java", "Repairing modified or corrupt Iris-managed datapack", "warn"); - assertLoggedWith("core/pregenerator/cache/PregenCacheImpl.java", "Pregen cache storage is gone at", "warn"); - assertLoggedWith("core/pregenerator/PregenMantleBackpressure.java", "Pregen mantle backpressure exceeded ", "warn"); - assertLoggedWith("core/pregenerator/PregenMantleBackpressure.java", "Pregen heap pressure wait exceeded ", "warn"); - assertLoggedWith("core/pregenerator/IrisPregenerator.java", "failed chunk(s); failures are not cached", "warn"); - assertLoggedWith("core/service/MultiverseSVC.java", "Multiverse world events are not bindable", "warn"); - } - - /** - * A handful of lifecycle lines an operator reads logs/latest.log to find. NOTICE is the level adapters - * route to the server's own logger rather than to the console sender. - */ - @Test - public void lifecycleLinesAreRaisedAtNoticeLevel() { - assertLoggedWith("engine/IrisEngine.java", "Engine init: ", "notice"); - assertLoggedWith("core/link/MultiverseCoreLink.java", "Adopted %d live Iris world", "notice"); - assertLoggedWith("core/pregenerator/IrisPregenerator.java", "Pregen finished: ", "notice"); - } - - private static void assertLoggedWith(String relativePath, String fragment, String expectedMethod) { - String source; - try { - source = read(relativePath); - } catch (IOException unreadable) { - throw new AssertionError("Cannot read " + relativePath, unreadable); - } - - int occurrences = 0; - for (int at = source.indexOf(fragment); at >= 0; at = source.indexOf(fragment, at + 1)) { - occurrences++; - assertEquals(relativePath + " @ \"" + fragment + "\" occurrence " + occurrences, - expectedMethod, loggingMethodBefore(source, at, relativePath, fragment)); - } - assertTrue(relativePath + " no longer contains \"" + fragment + "\"", occurrences > 0); - } - - private static String loggingMethodBefore(String source, int at, String relativePath, String fragment) { - int call = source.lastIndexOf("IrisLogging.", at); - assertTrue(relativePath + " @ \"" + fragment + "\" is not logged through IrisLogging", call >= 0); - int start = call + "IrisLogging.".length(); - int end = start; - while (end < source.length() && Character.isJavaIdentifierPart(source.charAt(end))) { - end++; - } - return source.substring(start, end); - } - - private static String read(String relativePath) throws IOException { - return Files.readString(Path.of("src/main/java/art/arcane/iris").resolve(relativePath)).replace("\r\n", "\n"); - } -} diff --git a/core/src/test/java/art/arcane/iris/core/IrisWorldsTest.java b/core/src/test/java/art/arcane/iris/core/IrisWorldsTest.java index a1ea35ebf..76942122a 100644 --- a/core/src/test/java/art/arcane/iris/core/IrisWorldsTest.java +++ b/core/src/test/java/art/arcane/iris/core/IrisWorldsTest.java @@ -95,28 +95,6 @@ public class IrisWorldsTest { * asserted against the source: one unusable world folder used to throw out of {@code clean()}, through * the constructor and into the cache, which returned null and NPE'd every caller. */ - @Test - public void oneUnusableWorldIsExcludedInsteadOfFailingTheWholeRegistry() throws Exception { - String source = Files.readString(Path.of("src/main/java/art/arcane/iris/core/IrisWorlds.java")).replace("\r\n", "\n"); - - int accessor = source.indexOf("public static IrisWorlds get()"); - int accessorEnd = source.indexOf("public synchronized void put(", accessor); - assertTrue("get() must not swallow a failure into a null return", - source.substring(accessor, accessorEnd).contains("cache.aquireOnceOrThrow(")); - - int clean = source.indexOf("public synchronized void clean()"); - int cleanEnd = source.indexOf("public synchronized void save()", clean); - String cleanBody = source.substring(clean, cleanEnd); - assertTrue("clean() must isolate an unusable entry", - cleanBody.contains("catch (IllegalStateException e)")); - assertTrue("an unusable entry stays in the registry so /iris remove can still find it", - cleanBody.contains("warnUnusableStorage(entry.getKey(), e);")); - - int loadDimension = source.indexOf("private IrisDimension loadDimension("); - assertTrue("loadDimension must exclude an unusable world rather than propagate", - source.substring(loadDimension).contains("catch (IllegalStateException unusableStorage)")); - } - @Test public void bukkitWorldFilteringRecognizesCurrentCraftBukkitConfiguredStorage() throws Exception { Path worldContainer = temporaryFolder.newFolder("configured-server").toPath(); diff --git a/core/src/test/java/art/arcane/iris/core/ProgressBossBarToggleTest.java b/core/src/test/java/art/arcane/iris/core/ProgressBossBarToggleTest.java index 15eed1c4f..b137b3d9d 100644 --- a/core/src/test/java/art/arcane/iris/core/ProgressBossBarToggleTest.java +++ b/core/src/test/java/art/arcane/iris/core/ProgressBossBarToggleTest.java @@ -3,9 +3,6 @@ package art.arcane.iris.core; import art.arcane.iris.platform.bukkit.BukkitPlatform; import org.junit.Test; -import java.nio.file.Files; -import java.nio.file.Path; - import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertThrows; import static org.junit.Assert.assertTrue; @@ -28,55 +25,6 @@ public class ProgressBossBarToggleTest { () -> BukkitPlatform.showProgressLane(null, "iris:job", "Working", 0.5D, 4000L))); } - @Test - public void studioOpenBossBarIsGatedBySettings() throws Exception { - assertGated("core/project/StudioOpenProgressReporter.java"); - } - - @Test - public void worldCreationAlwaysUsesTheActionBarInsteadOfABossBar() throws Exception { - String source = source("core/tools/WorldCreationProgressReporter.java"); - - assertFalse(source.contains("isProgressBossBar()")); - assertFalse(source.contains("Bukkit.createBossBar(")); - assertTrue(source.contains("WORLD_CREATE_LIFECYCLE_ACTION")); - } - - @Test - public void chunkJobBossBarIsGatedBySettings() throws Exception { - assertGated("core/runtime/ChunkJobReporter.java"); - } - - @Test - public void packDownloadLaneIsGatedWhileTheActionBarSurvives() throws Exception { - String source = source("core/service/PackDownloadProgressReporter.java"); - - assertTrue(source.contains("isProgressBossBar()")); - assertTrue("the action bar must keep reporting when boss bars are off", - source.contains("sender.sendAction(snapshot.line())")); - } - - @Test - public void pregenLaneIsGatedWhileTheActionBarSurvives() throws Exception { - String source = source("core/tools/IrisCreator.java"); - int lane = source.indexOf("\"iris:pregen\""); - int gate = source.lastIndexOf("isProgressBossBar()", lane); - - assertTrue("the pregen boss bar lane must sit behind general.progressBossBar", - gate > 0 && lane - gate < 200); - assertTrue("the action bar must keep reporting when boss bars are off", - source.contains("RuntimeProgressMessages.WORLD_PREGEN_ACTION")); - } - - private void assertGated(String relativePath) throws Exception { - assertTrue(relativePath + " must consult general.progressBossBar before creating a boss bar", - source(relativePath).contains("isProgressBossBar()")); - } - - private String source(String relativePath) throws Exception { - return Files.readString(Path.of("src/main/java/art/arcane/iris").resolve(relativePath)).replace("\r\n", "\n"); - } - private void withProgressBossBar(boolean enabled, Runnable body) { IrisSettings previous = IrisSettings.settings; try { diff --git a/core/src/test/java/art/arcane/iris/core/ServerConfiguratorDatapackFingerprintTest.java b/core/src/test/java/art/arcane/iris/core/ServerConfiguratorDatapackFingerprintTest.java index b9b8120fb..7a767d932 100644 --- a/core/src/test/java/art/arcane/iris/core/ServerConfiguratorDatapackFingerprintTest.java +++ b/core/src/test/java/art/arcane/iris/core/ServerConfiguratorDatapackFingerprintTest.java @@ -384,43 +384,6 @@ public class ServerConfiguratorDatapackFingerprintTest { } } - @Test - public void recoveryRunsBeforeRestoredFingerprintReuseHashFallbackAndCompilation() throws Exception { - String source = Files.readString(Path.of( - "src/main/java/art/arcane/iris/core/ServerConfigurator.java")).replace("\r\n", "\n"); - int installIfChanged = source.indexOf("installDataPacksIfChanged(boolean fullInstall)"); - int recovery = source.indexOf("DatapackIngestService.reapplyFromStaging", installIfChanged); - int restored = source.indexOf("restoredCompilerInputFingerprint()", recovery); - int fingerprint = source.indexOf("computeCurrentDatapackCompilerInputFingerprint", restored); - int earlyReturn = source.indexOf("resultForUnchangedFingerprint", fingerprint); - int compile = source.indexOf("compileDataPacksLocked(", earlyReturn); - int cache = source.indexOf("writeCompilerInputFingerprintCache(cacheFile.toPath(), current)", compile); - - assertTrue(recovery >= 0); - assertTrue(restored > recovery); - assertTrue(fingerprint > restored); - assertTrue(earlyReturn > fingerprint); - assertTrue(compile > earlyReturn); - assertTrue(cache > compile); - } - - @Test - public void studioTimingSeparatesRecoveryFingerprintCompilationAndTotal() throws Exception { - String source = Files.readString(Path.of( - "src/main/java/art/arcane/iris/core/ServerConfigurator.java")).replace("\r\n", "\n"); - int timedInstall = source.indexOf("BiConsumer timingConsumer"); - int recovery = source.indexOf("\"datapack_external_recovery\"", timedInstall); - int fingerprint = source.indexOf("\"datapack_compiler_input_fingerprint\"", recovery); - int compile = source.indexOf("\"datapack_compile_publish\"", fingerprint); - int total = source.indexOf("\"datapack_install_if_changed_total\"", compile); - - assertTrue(timedInstall >= 0); - assertTrue(recovery > timedInstall); - assertTrue(fingerprint > recovery); - assertTrue(compile > fingerprint); - assertTrue(total > compile); - } - @Test public void loadedRuntimeReuseRequiresAnExactPinnedCompilerInputFingerprint() { assertTrue(ServerConfigurator.reusableRuntimeFingerprint("abc", "abc")); diff --git a/core/src/test/java/art/arcane/iris/core/ServerConfiguratorStartupRestartTest.java b/core/src/test/java/art/arcane/iris/core/ServerConfiguratorStartupRestartTest.java index fc4773c40..2e4b0aefd 100644 --- a/core/src/test/java/art/arcane/iris/core/ServerConfiguratorStartupRestartTest.java +++ b/core/src/test/java/art/arcane/iris/core/ServerConfiguratorStartupRestartTest.java @@ -9,8 +9,6 @@ import org.objectweb.asm.ClassVisitor; import org.objectweb.asm.MethodVisitor; import org.objectweb.asm.Opcodes; -import java.nio.file.Files; -import java.nio.file.Path; import java.util.concurrent.atomic.AtomicBoolean; import static org.junit.Assert.assertFalse; @@ -92,30 +90,6 @@ public class ServerConfiguratorStartupRestartTest { assertFalse(directRestartInvocation.get()); } - @Test - public void startupRestartPathsPromoteTheValidationStateAndBypassTickQueues() throws Exception { - String source = Files.readString(Path.of( - "src/main/java/art/arcane/iris/core/ServerConfigurator.java")); - String configure = section( - source, - "public static void configure()", - "public static boolean isLoadedDatapackRuntimeReady"); - String startupRestart = section( - source, - "public static void restartAtStartupBoundary", - "public static boolean verifyDataPackInstalled"); - - int restartResult = configure.indexOf("if (result.restartRequired())"); - int validationRestart = configure.indexOf("requireDatapackRestart();", restartResult); - assertTrue(restartResult >= 0); - assertTrue(validationRestart > restartResult); - assertTrue(startupRestart.indexOf("invokeImmediateRestartIfSupported(Bukkit.class)") - < startupRestart.indexOf("Bukkit.shutdown();")); - assertFalse(startupRestart.contains("Bukkit.restart")); - assertFalse(startupRestart.contains("J.s(")); - assertFalse(startupRestart.contains("dispatchCommand")); - } - public static final class RestartCapableApi { private static boolean restarted; @@ -126,12 +100,4 @@ public class ServerConfiguratorStartupRestartTest { public static final class ShutdownOnlyApi { } - - private static String section(String source, String startMarker, String endMarker) { - int start = source.indexOf(startMarker); - int end = source.indexOf(endMarker, start); - assertTrue(start >= 0); - assertTrue(end > start); - return source.substring(start, end); - } } diff --git a/core/src/test/java/art/arcane/iris/core/SettingsHotloadWatchTest.java b/core/src/test/java/art/arcane/iris/core/SettingsHotloadWatchTest.java index 5dc9b9fce..af1f73860 100644 --- a/core/src/test/java/art/arcane/iris/core/SettingsHotloadWatchTest.java +++ b/core/src/test/java/art/arcane/iris/core/SettingsHotloadWatchTest.java @@ -15,7 +15,6 @@ import java.io.File; import java.io.PrintStream; import java.nio.charset.StandardCharsets; import java.nio.file.Files; -import java.nio.file.Path; import java.nio.file.attribute.FileTime; import java.util.concurrent.CountDownLatch; import java.util.concurrent.TimeUnit; @@ -255,23 +254,6 @@ public class SettingsHotloadWatchTest { assertEquals("Active " + PERMISSION, permissionMessage()); } - @Test - public void bukkitAndModdedUseTheSameCoreCoordinator() throws Exception { - String bukkit = Files.readString(Path.of( - "../adapters/bukkit/plugin/src/main/java/art/arcane/iris/Iris.java" - )); - String modded = Files.readString(Path.of( - "../adapters/modded-common/src/main/java/art/arcane/iris/modded/service/ModdedSettingsHotloadService.java" - )); - - assertTrue(bukkit.contains("new SettingsHotloadWatch(")); - assertTrue(modded.contains("new SettingsHotloadWatch(")); - assertFalse(bukkit.contains("new ConfigHotloadEngine(")); - assertFalse(modded.contains("new ConfigHotloadEngine(")); - assertFalse(bukkit.contains("IrisLanguage.update()")); - assertFalse(modded.contains("IrisLanguage.update()")); - } - private void awaitPermissionMessage(String expected) throws Exception { long deadline = System.nanoTime() + TimeUnit.SECONDS.toNanos(6L); while (System.nanoTime() < deadline) { diff --git a/core/src/test/java/art/arcane/iris/core/datapack/DatapackIngestRuntimeInvalidationTest.java b/core/src/test/java/art/arcane/iris/core/datapack/DatapackIngestRuntimeInvalidationTest.java deleted file mode 100644 index f5f78a13d..000000000 --- a/core/src/test/java/art/arcane/iris/core/datapack/DatapackIngestRuntimeInvalidationTest.java +++ /dev/null @@ -1,51 +0,0 @@ -package art.arcane.iris.core.datapack; - -import org.junit.Test; - -import java.nio.file.Files; -import java.nio.file.Path; - -import static org.junit.Assert.assertTrue; - -public class DatapackIngestRuntimeInvalidationTest { - @Test - public void everyPublicMutationInvalidatesLoadedRuntimeBeforeLocking() throws Exception { - String source = Files.readString(Path.of( - "src/main/java/art/arcane/iris/core/datapack/DatapackIngestService.java")).replace("\r\n", "\n"); - - assertInvalidatesBeforeLock(source, "public static Report ingest("); - assertInvalidatesBeforeLock(source, "public static ReapplyOutcome reapplyFromStaging("); - assertInvalidatesBeforeLock(source, "public static boolean remove("); - } - - @Test - public void noChangeChecksRestoreWhileChangedIngestRemainsRestartBound() throws Exception { - String source = Files.readString(Path.of( - "src/main/java/art/arcane/iris/core/datapack/DatapackIngestService.java")).replace("\r\n", "\n"); - int ingest = source.indexOf("public static Report ingest("); - int unlock = source.indexOf("TRANSACTION_LOCK.unlock();", ingest); - int restore = source.indexOf( - "ServerConfigurator.restoreLoadedDatapackRuntimeIfUnchanged(invalidation);", - unlock); - int changed = source.indexOf("else if (report.changed())", restore); - int restart = source.indexOf("ServerConfigurator.restart();", changed); - int restartRequired = source.indexOf("ServerConfigurator.requireDatapackRestart();", restart); - - assertTrue(ingest >= 0); - assertTrue(unlock > ingest); - assertTrue(restore > unlock); - assertTrue(changed > restore); - assertTrue(restart > changed); - assertTrue(restartRequired > restart); - } - - private void assertInvalidatesBeforeLock(String source, String signature) { - int method = source.indexOf(signature); - int invalidation = source.indexOf("ServerConfigurator.invalidateLoadedDatapackRuntime();", method); - int lock = source.indexOf("TRANSACTION_LOCK.lock();", method); - - assertTrue("Missing datapack mutation entry point " + signature, method >= 0); - assertTrue("Loaded runtime must be invalidated before " + signature, invalidation > method); - assertTrue("Loaded runtime invalidation must precede the transaction lock", invalidation < lock); - } -} diff --git a/core/src/test/java/art/arcane/iris/core/datapack/DatapackIngestServiceTest.java b/core/src/test/java/art/arcane/iris/core/datapack/DatapackIngestServiceTest.java index eebb01096..de8447788 100644 --- a/core/src/test/java/art/arcane/iris/core/datapack/DatapackIngestServiceTest.java +++ b/core/src/test/java/art/arcane/iris/core/datapack/DatapackIngestServiceTest.java @@ -246,39 +246,6 @@ public class DatapackIngestServiceTest { validated, "26.2", 4000, true, true, validated.urls)); } - @Test - public void startupChecksCheapCacheContextBeforeHashingManagedDatapacks() throws Exception { - String source = Files.readString(Path.of( - "src/main/java/art/arcane/iris/core/datapack/DatapackIngestService.java")).replace("\r\n", "\n"); - int validation = source.indexOf("public static StartupValidationOutcome validateOnStartup()"); - int cacheRead = source.indexOf("readStartupValidationCache", validation); - int contextCheck = source.indexOf("startupValidationContextMatches(", cacheRead); - int fingerprint = source.indexOf("startupValidationFingerprint(", contextCheck); - int fullValidation = source.indexOf("if (autoIngest && !configured.isEmpty())", fingerprint); - - assertTrue(validation >= 0); - assertTrue(cacheRead > validation); - assertTrue(contextCheck > cacheRead); - assertTrue(fingerprint > contextCheck); - assertTrue(fullValidation > fingerprint); - } - - @Test - public void unchangedPostStartupMaintenanceReturnsBeforeFingerprinting() throws Exception { - String source = Files.readString(Path.of( - "src/main/java/art/arcane/iris/core/datapack/DatapackIngestService.java")).replace("\r\n", "\n"); - int refresh = source.indexOf( - "refreshStartupValidationAfterMaintenance(boolean maintenanceChanged)"); - int unchangedGuard = source.indexOf("if (!maintenanceChanged)", refresh); - int validatedState = source.indexOf("StartupValidationCache validated", refresh); - int fingerprint = source.indexOf("startupValidationFingerprint(", refresh); - - assertTrue(refresh >= 0); - assertTrue(unchangedGuard > refresh); - assertTrue(validatedState > unchangedGuard); - assertTrue(fingerprint > unchangedGuard); - } - @Test public void packMetadataMustContainAValidPackContract() throws Exception { File valid = temporaryFolder.newFolder("valid"); @@ -894,27 +861,6 @@ public class DatapackIngestServiceTest { assertEquals(expected, ownershipHash(managed)); } - @Test - public void directoryHashRestatsAttributesAndVolumeBeforeOpeningEachFile() throws Exception { - String source = Files.readString(Path.of( - "src/main/java/art/arcane/iris/core/datapack/DatapackIngestService.java")).replace("\r\n", "\n"); - int method = source.indexOf("private static String directoryHash(File root)"); - int entries = source.indexOf("List entries = new ArrayList<>()", method); - int loop = source.indexOf("for (Path entry : entries)", entries); - int attributes = source.indexOf("BasicFileAttributes attributes = Files.readAttributes(", loop); - int fileStore = source.indexOf("Files.getFileStore(entry)", attributes); - int open = source.indexOf("Files.newInputStream(", fileStore); - int digest = source.indexOf("return hex(digest.digest())", open); - - assertTrue(method >= 0); - assertTrue(entries > method); - assertTrue(loop > entries); - assertTrue(attributes > loop); - assertTrue(fileStore > attributes); - assertTrue(open > fileStore); - assertTrue(digest > open); - } - @Test public void failedUpdateStagingCannotBeAdoptedByTheCommittedManifest() throws Exception { File staging = datapackDirectory("candidate-staging"); @@ -3880,8 +3826,6 @@ public class DatapackIngestServiceTest { } private static final class DeleteAttemptFile extends File { - private static final long serialVersionUID = 1L; - private final int successfulAttempt; private int deleteAttempts; diff --git a/core/src/test/java/art/arcane/iris/core/lifecycle/WorldLifecycleUnloadAsyncTest.java b/core/src/test/java/art/arcane/iris/core/lifecycle/WorldLifecycleUnloadAsyncTest.java index 45c433f33..83ff1a86c 100644 --- a/core/src/test/java/art/arcane/iris/core/lifecycle/WorldLifecycleUnloadAsyncTest.java +++ b/core/src/test/java/art/arcane/iris/core/lifecycle/WorldLifecycleUnloadAsyncTest.java @@ -10,8 +10,6 @@ import org.junit.Test; import org.mockito.MockedStatic; import java.lang.reflect.Method; -import java.nio.file.Files; -import java.nio.file.Path; import java.util.concurrent.CompletableFuture; import java.util.concurrent.CompletionException; import java.util.concurrent.CompletionStage; @@ -59,40 +57,6 @@ public class WorldLifecycleUnloadAsyncTest { } } - @Test - public void paperLikeManualUnloadDetachesBeforeOffThreadChunkDrain() throws Exception { - String source = Files.readString(Path.of( - "src/main/java/art/arcane/iris/core/lifecycle/WorldLifecycleSupport.java")) - .replace("\r\n", "\n"); - int unloadStart = source.indexOf("private static CompletableFuture unloadWorldWithoutAsyncApi("); - int unloadEnd = source.indexOf("static boolean announceManualWorldUnload", unloadStart); - String unloadMethod = source.substring(unloadStart, unloadEnd); - int capabilityFallback = unloadMethod.indexOf( - "capabilities.minecraftServer() == null || capabilities.removeLevelMethod() == null"); - int bukkitUnload = unloadMethod.indexOf("Bukkit.unloadWorld(world, save)", capabilityFallback); - int detach = unloadMethod.indexOf("detachServerLevelAsync(capabilities, serverLevel, world)"); - int drain = unloadMethod.indexOf("drainChunkTasksAsync(world, serverLevel)"); - int close = unloadMethod.indexOf("closeServerLevelAsync(world, serverLevel)"); - int closeStart = source.indexOf("private static CompletableFuture closeServerLevelAsync("); - int closeEnd = source.indexOf("private static CompletableFuture drainChunkTasksAsync(", closeStart); - String closeMethod = source.substring(closeStart, closeEnd); - int drainStart = closeEnd; - int drainEnd = source.indexOf("private static void removeWorldFromCraftServerMap", drainStart); - String drainMethod = source.substring(drainStart, drainEnd); - - assertTrue(capabilityFallback >= 0); - assertTrue(bukkitUnload > capabilityFallback); - assertTrue(detach > bukkitUnload); - assertTrue(drain > detach); - assertTrue(close > drain); - assertTrue(drainMethod.contains("return J.afut(() ->")); - assertTrue(drainMethod.contains("\"moonrise$getChunkTaskScheduler\"")); - assertTrue(drainMethod.contains("\"halt\"")); - assertTrue(closeMethod.contains("return runGlobalAsync(closeTask)")); - assertFalse(closeMethod.contains("J.afut(")); - assertFalse(closeMethod.contains("J.runRegion(")); - } - @Test public void reflectedAsyncUnloadWaitsForTrueCallback() throws Exception { CallbackServer server = new CallbackServer(); diff --git a/core/src/test/java/art/arcane/iris/core/link/MultiverseCoreLinkTest.java b/core/src/test/java/art/arcane/iris/core/link/MultiverseCoreLinkTest.java index 83e9aa9d6..4fd50e2d7 100644 --- a/core/src/test/java/art/arcane/iris/core/link/MultiverseCoreLinkTest.java +++ b/core/src/test/java/art/arcane/iris/core/link/MultiverseCoreLinkTest.java @@ -18,8 +18,6 @@ import org.mvplugins.multiverse.external.vavr.control.Option; import java.io.File; import java.lang.reflect.Method; -import java.nio.file.Files; -import java.nio.file.Path; import java.util.Arrays; import java.util.List; import java.util.Map; @@ -53,16 +51,6 @@ public class MultiverseCoreLinkTest { && method.getParameterCount() == 2)); } - @Test - public void registrationDoesNotRewriteTheRecordedMultiverseName() throws Exception { - String source = Files.readString(Path.of("src/main/java/art/arcane/iris/core/link/MultiverseCoreLink.java")).replace("\r\n", "\n"); - - assertFalse("worlds are created under the startup name, so the recorded name needs no correction", - source.contains("setLegacyWorldName")); - assertTrue("Multiverse still has to be told the live world name it will record", - source.contains("ImportWorldOptions.worldName(world.getName())")); - } - @Test public void lookupNamesAddTheIrisKeyAndRuntimeNameForConfiguredStartupNames() { assertEquals( diff --git a/core/src/test/java/art/arcane/iris/core/pack/PackExportClosureTest.java b/core/src/test/java/art/arcane/iris/core/pack/PackExportClosureTest.java index c3c3aed2c..263785347 100644 --- a/core/src/test/java/art/arcane/iris/core/pack/PackExportClosureTest.java +++ b/core/src/test/java/art/arcane/iris/core/pack/PackExportClosureTest.java @@ -8,8 +8,6 @@ import art.arcane.iris.engine.object.IrisStaticObject; import art.arcane.volmlib.util.collection.KList; import org.junit.Test; -import java.nio.file.Files; -import java.nio.file.Path; import java.util.List; import java.util.Map; @@ -102,47 +100,4 @@ public class PackExportClosureTest { * Source guard: both packagers must export the ambient-spawning graph. Spawner and marker * folders were silently omitted from exports, leaving dangling entitySpawners references. */ - @Test - public void bothPackagersExportSpawnersMarkersAndTheFullEntityGraph() throws Exception { - String bukkit = Files.readString(Path.of( - "src/main/java/art/arcane/iris/core/project/IrisPackageCompiler.java")).replace("\r\n", "\n"); - assertTrue("Bukkit packager must write spawners/", bukkit.contains("\"spawners/\"")); - assertTrue("Bukkit packager must write markers/", bukkit.contains("\"markers/\"")); - assertTrue("Bukkit packager must export region objects alongside biome objects", - bukkit.contains("regions.forEach((r) -> allPlacements.addAll(r.getObjects()))")); - assertTrue("Bukkit packager must export static objects", - bukkit.contains("exportedDimension.getStaticObjects()")); - assertTrue("Bukkit obfuscation must rewrite static object references", - bukkit.contains("placement.setObject(renameObjects.get(placement.getObject()))")); - assertTrue("Bukkit packager must export entity loot tables", bukkit.contains("getLoot().getTables()")); - assertTrue("Bukkit packager must include dimension-stack resources", - bukkit.contains("PackExportClosure.collectDimensionKeys(dimension)")); - assertTrue("Bukkit packager must export expression-backed stack blend styles", - bukkit.contains("dm.getExpressionLoader().getPossibleKeys()") - && bukkit.contains("\"expressions/\"")); - int bukkitValidation = bukkit.indexOf("PackValidator.validateForPackaging(project.getPath())"); - assertTrue("Bukkit packager must validate before opening or mutating package state", - bukkitValidation >= 0 - && bukkitValidation < bukkit.indexOf("IrisData.openRuntime(project.getPath())") - && bukkitValidation < bukkit.indexOf("IO.delete(folder)")); - - String modded = Files.readString(Path.of( - "../adapters/modded-common/src/main/java/art/arcane/iris/modded/command/ModdedStudioCommands.java")).replace("\r\n", "\n"); - assertTrue("modded packager must write spawners/", modded.contains("\"spawners\"")); - assertTrue("modded packager must write markers/", modded.contains("\"markers\"")); - assertTrue("modded packager must include initial spawns", modded.contains("getInitialSpawns")); - assertTrue("modded packager must export region objects", modded.contains("region.getObjects()")); - assertTrue("modded packager must export static objects", - modded.contains("PackExportClosure.collectStaticObjectKeys(exportedDimension.getStaticObjects())")); - assertTrue("modded packager must include dimension-stack resources", - modded.contains("PackExportClosure.collectDimensionKeys(dimension)")); - assertTrue("modded packager must export expression-backed stack blend styles", - modded.contains("dm.getExpressionLoader().getPossibleKeys()") - && modded.contains("\"expressions\"")); - assertTrue("modded packager must retain referenced style snippets", - modded.contains("copyStyleSnippets(packFolder, folder)")); - int moddedValidation = modded.indexOf("PackValidator.validateForPackaging(packFolder)"); - assertTrue("modded packager must validate before mutating package state", - moddedValidation >= 0 && moddedValidation < modded.indexOf("IO.delete(folder)")); - } } diff --git a/core/src/test/java/art/arcane/iris/core/pregenerator/methods/PregenMantleCleanupContractTest.java b/core/src/test/java/art/arcane/iris/core/pregenerator/methods/PregenMantleCleanupContractTest.java deleted file mode 100644 index fc4d18c93..000000000 --- a/core/src/test/java/art/arcane/iris/core/pregenerator/methods/PregenMantleCleanupContractTest.java +++ /dev/null @@ -1,144 +0,0 @@ -package art.arcane.iris.core.pregenerator.methods; - -import org.junit.Test; - -import java.io.IOException; -import java.net.URISyntaxException; -import java.nio.file.Files; -import java.nio.file.Path; - -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertTrue; - -public class PregenMantleCleanupContractTest { - @Test - public void normalEngineCleanupRetriesCandidatesCoveredByTheNewestRealChunk() throws IOException { - String source = read("art/arcane/iris/engine/framework/Engine.java"); - String cleanup = method(source, "default void cleanupMantleChunk(int x, int z)"); - - assertTrue(cleanup.contains("cleanupChunksCoveredBy(")); - assertTrue(cleanup.contains("EngineMantle.ChunkCleanupCallback.NONE")); - assertFalse(cleanup.contains(".cleanupChunk(x, z)")); - } - - @Test - public void asyncPregenReportsOnlyCleanupCallbacksFromCoveredTargets() throws IOException { - String source = read("art/arcane/iris/core/pregenerator/methods/AsyncPregenMethod.java"); - String completion = method(source, "private void completeChunk("); - String cleanup = method(source, "private void cleanupMantleChunksCoveredBy("); - - assertTrue(completion.contains("cleanupMantleChunksCoveredBy(x, z, listener)")); - assertFalse(completion.contains("listener.onChunkCleaned")); - assertTrue(cleanup.contains("cleanupChunksCoveredBy(x, z, true, listener::onChunkCleaned)")); - assertFalse(cleanup.contains("forceCleanupChunk")); - } - - @Test - public void finalChunkFlushUsesTargetedPersistenceWithoutFullWorldSave() throws IOException { - String source = read("art/arcane/iris/core/pregenerator/methods/AsyncPregenMethod.java"); - String flush = method(source, "private void flushAllRemainingChunks()"); - String medievalSource = read("art/arcane/iris/core/pregenerator/methods/MedievalPregenMethod.java"); - String medievalFlush = method(medievalSource, "private void unloadAndSaveAllChunks("); - - assertTrue(flush.contains("evictRegion(regionKey)")); - assertTrue(flush.contains("INMS.get().flushChunkIO(world)")); - assertFalse(flush.contains("world.save()")); - assertTrue(medievalFlush.contains("i.unload(true)")); - assertTrue(medievalFlush.contains("INMS.get().flushChunkIO(world)")); - assertFalse(medievalFlush.contains("world.save()")); - } - - @Test - public void foliaFinalEvictionUsesAwaitableRegionOwnedTasks() throws IOException { - String source = read("art/arcane/iris/core/pregenerator/methods/AsyncPregenMethod.java"); - String eviction = method(source, "private CompletableFuture evictFoliaRegion("); - - assertTrue(eviction.contains("J.runRegionFuture(")); - assertTrue(eviction.contains("CompletableFuture.allOf(")); - assertFalse(eviction.contains("J.runRegion(")); - } - - @Test - public void shutdownReclaimsMantleBeforeReleasingTheJob() throws IOException { - String source = read("art/arcane/iris/core/pregenerator/IrisPregenerator.java"); - String shutdown = method(source, "private void shutdown()"); - int generator = shutdown.indexOf("shutdownStep(\"generator\""); - int interruptBoundary = shutdown.indexOf("Thread.interrupted()", generator); - int mantle = shutdown.indexOf("shutdownStep(\"mantle\""); - int protocol = shutdown.indexOf("shutdownStep(\"protocol\""); - int listener = shutdown.indexOf("shutdownStep(\"listener\""); - - assertTrue(generator >= 0); - assertTrue(interruptBoundary > generator); - assertTrue(mantle > interruptBoundary); - assertTrue(protocol > mantle); - assertTrue(listener > protocol); - } - - @Test - public void directStopDoesNotReleaseTheActiveJobBeforeWorkerCleanup() throws IOException { - String source = read("art/arcane/iris/core/gui/PregeneratorJob.java"); - String stop = method(source, "public void stop()"); - String close = method(source, "public void onClose()"); - - assertTrue(stop.contains("requestStop()")); - assertFalse(stop.contains("instance.compareAndSet")); - assertTrue(close.contains("instance.compareAndSet(this, null)")); - } - - @Test - public void performanceProfilePreparationRunsOnThePregenWorker() throws IOException { - String source = read("art/arcane/iris/core/gui/PregeneratorJob.java"); - String constructor = method(source, "public PregeneratorJob(Configuration configuration)"); - String worker = method(source, "private void runWorker(Runnable preparation)"); - - assertTrue(constructor.contains("runWorker(configuration.preparation())")); - assertBefore(worker, "preparation.run()", "pregenerator.start()"); - } - - private static String read(String relativePath) throws IOException { - Path current; - try { - current = Path.of(PregenMantleCleanupContractTest.class.getProtectionDomain() - .getCodeSource() - .getLocation() - .toURI()); - } catch (URISyntaxException e) { - throw new IOException("Unable to resolve the core source root", e); - } - while (current != null && !Files.isDirectory(current.resolve("src/main/java"))) { - current = current.getParent(); - } - if (current == null) { - throw new IOException("Unable to locate the core source root"); - } - return Files.readString(current.resolve("src/main/java").resolve(relativePath)); - } - - private static String method(String source, String signature) { - int start = source.indexOf(signature); - assertTrue("Missing source contract signature: " + signature, start >= 0); - int openBrace = source.indexOf('{', start); - assertTrue("Missing source contract method body: " + signature, openBrace >= 0); - int depth = 0; - for (int index = openBrace; index < source.length(); index++) { - char current = source.charAt(index); - if (current == '{') { - depth++; - } else if (current == '}') { - depth--; - if (depth == 0) { - return source.substring(start, index + 1); - } - } - } - throw new IllegalArgumentException("Unclosed source contract method: " + signature); - } - - private static void assertBefore(String source, String first, String second) { - int firstIndex = source.indexOf(first); - int secondIndex = source.indexOf(second); - assertTrue(firstIndex >= 0); - assertTrue(secondIndex > firstIndex); - } -} diff --git a/core/src/test/java/art/arcane/iris/core/runtime/StudioEntitySpawningTest.java b/core/src/test/java/art/arcane/iris/core/runtime/StudioEntitySpawningTest.java index f1001852b..e00e2652e 100644 --- a/core/src/test/java/art/arcane/iris/core/runtime/StudioEntitySpawningTest.java +++ b/core/src/test/java/art/arcane/iris/core/runtime/StudioEntitySpawningTest.java @@ -4,9 +4,6 @@ import art.arcane.iris.core.IrisSettings; import art.arcane.iris.core.service.ObjectStudioSaveService; import org.junit.Test; -import java.io.IOException; -import java.nio.file.Files; -import java.nio.file.Path; import java.util.Arrays; import static org.junit.Assert.assertFalse; @@ -18,32 +15,6 @@ public class StudioEntitySpawningTest { assertTrue(new IrisSettings.IrisSettingsStudio().isEntitySpawning()); } - @Test - public void studioWorldRulesEnableVanillaMobSpawning() throws IOException { - String source = Files.readString(Path.of( - "src/main/java/art/arcane/iris/core/runtime/WorldRuntimeControlService.java")).replace("\r\n", "\n"); - int helperStart = source.indexOf("static void enableStudioEntitySpawning"); - int helperEnd = source.indexOf("public boolean applyNoonTimeLock", helperStart); - String helper = source.substring(helperStart, helperEnd); - - assertTrue(source.contains("enableStudioEntitySpawning(world);")); - assertTrue(helper.contains("setBooleanGameRule(world, true, \"DO_MOB_SPAWNING\"")); - assertTrue(helper.contains("setBooleanGameRule(world, true, \"DO_TRADER_SPAWNING\"")); - assertTrue(helper.contains("setBooleanGameRule(world, true, \"DO_PATROL_SPAWNING\"")); - assertTrue(helper.contains("setBooleanGameRule(world, true, \"DO_INSOMNIA\"")); - assertTrue(helper.contains("setBooleanGameRule(world, true, \"DO_WARDEN_SPAWNING\"")); - assertFalse(helper.contains("setBooleanGameRule(world, false, \"DO_MOB_SPAWNING\"")); - } - - @Test - public void standardStudioDefaultsToSpectatorMode() throws IOException { - String source = Files.readString(Path.of( - "src/main/java/art/arcane/iris/core/runtime/StudioOpenCoordinator.java")).replace("\r\n", "\n"); - - assertTrue(source.contains("request.openKind().teleportThroughStandardEntry()")); - assertTrue(source.contains("GameMode.SPECTATOR")); - } - @Test public void objectStudioDoesNotCancelEntitySpawns() { boolean hasSpawnCanceller = Arrays.stream(ObjectStudioSaveService.class.getDeclaredMethods()) diff --git a/core/src/test/java/art/arcane/iris/core/runtime/StudioOpenCoordinatorOpenKindTest.java b/core/src/test/java/art/arcane/iris/core/runtime/StudioOpenCoordinatorOpenKindTest.java index caa3c772f..d7bfdb834 100644 --- a/core/src/test/java/art/arcane/iris/core/runtime/StudioOpenCoordinatorOpenKindTest.java +++ b/core/src/test/java/art/arcane/iris/core/runtime/StudioOpenCoordinatorOpenKindTest.java @@ -5,9 +5,6 @@ import art.arcane.iris.core.tools.IrisCreator; import org.junit.Test; import java.io.File; -import java.nio.file.Files; -import java.nio.file.Path; -import java.util.List; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; @@ -86,210 +83,4 @@ public class StudioOpenCoordinatorOpenKindTest { assertEquals(StudioOpenCoordinator.StudioOpenKind.JIGSAW, request.openKind()); assertTrue(request.requestedAtNanos() > 0L); } - - @Test - public void nativeTeleportWaitsForCompletionWithoutAnArrivalDeadline() throws Exception { - String source = Files.readString(Path.of( - "src/main/java/art/arcane/iris/core/runtime/StudioOpenCoordinator.java")) - .replace("\r\n", "\n"); - int methodStart = source.indexOf("private void executeOpen("); - int delegation = source.indexOf("WorldRuntimeControlService.get().teleportInMode(", methodStart); - int completion = source.indexOf("nativeTeleportFuture.get();", delegation); - - assertTrue(delegation >= 0); - assertTrue(completion > delegation); - assertFalse(source.substring(methodStart, completion).contains("orTimeout(")); - assertFalse(source.substring(methodStart, completion).contains("deadlineNanos")); - } - - @Test - public void activeStudioTeleportIsSerializedWithoutAnArrivalDeadline() throws Exception { - String coordinator = Files.readString(Path.of( - "src/main/java/art/arcane/iris/core/runtime/StudioOpenCoordinator.java")) - .replace("\r\n", "\n"); - String service = Files.readString(Path.of( - "src/main/java/art/arcane/iris/core/service/StudioSVC.java")) - .replace("\r\n", "\n"); - int coordinatorStart = coordinator.indexOf( - "public CompletableFuture teleportPlayerToProject("); - int coordinatorEnd = coordinator.indexOf("private void executeOpen", coordinatorStart); - String coordinatorMethod = coordinator.substring(coordinatorStart, coordinatorEnd); - int serviceStart = service.indexOf( - "public CompletableFuture teleportToActiveProject(Player player)"); - int serviceEnd = service.indexOf("public void open(VolmitSender", serviceStart); - String serviceMethod = service.substring(serviceStart, serviceEnd); - int transitionAdmission = serviceMethod.indexOf("studioTransitions.submit(() ->"); - int projectCapture = serviceMethod.indexOf("IrisProject project = activeProject"); - int nativeDelegation = coordinatorMethod.indexOf( - "WorldRuntimeControlService.get().teleportInMode(player, entry, GameMode.SPECTATOR)"); - - assertTrue(transitionAdmission >= 0); - assertTrue(projectCapture > transitionAdmission); - assertFalse(serviceMethod.contains("orTimeout(")); - assertFalse(serviceMethod.contains("deadlineNanos")); - assertTrue(coordinatorMethod.contains( - "WorldRuntimeControlService.get().resolveEntryAnchor(world, provider)")); - assertTrue(coordinatorMethod.contains( - "project.getActiveOpenKind().teleportThroughStandardEntry()")); - assertFalse(coordinatorMethod.contains("requestChunkAsync(")); - assertFalse(coordinatorMethod.contains("getHighestBlockYAt(")); - assertTrue(nativeDelegation >= 0); - assertFalse(coordinatorMethod.contains("orTimeout(")); - assertFalse(coordinatorMethod.contains("deadlineNanos")); - } - - @Test - public void standardEntryDelegatesWithoutAnExplicitChunkOrSurfaceLookup() throws Exception { - String source = Files.readString(Path.of( - "src/main/java/art/arcane/iris/core/runtime/StudioOpenCoordinator.java")) - .replace("\r\n", "\n"); - - assertTrue(source.contains("Location entryLocation = entryAnchor;")); - assertFalse(source.contains("prepareStudioEntryChunks(")); - assertFalse(source.contains("findStudioEntryLocation")); - assertFalse(source.contains("EntryChunkResolution")); - assertFalse(source.contains("resolveSafeEntry(world, entryAnchor)")); - assertFalse(source.contains("getHighestBlockYAt(")); - } - - @Test - public void standardEntryBindsSpectatorToTheNativeTeleport() throws Exception { - String source = Files.readString(Path.of( - "src/main/java/art/arcane/iris/core/runtime/StudioOpenCoordinator.java")) - .replace("\r\n", "\n"); - String runtime = Files.readString(Path.of( - "src/main/java/art/arcane/iris/core/runtime/WorldRuntimeControlService.java")) - .replace("\r\n", "\n"); - int mode = runtime.indexOf("modeRestore.apply(gameMode)"); - int teleport = runtime.indexOf("teleporter.teleport(player, location)", mode); - - assertTrue(source.contains("WorldRuntimeControlService.get().teleportInMode(")); - int openKind = source.indexOf("request.project().setActiveOpenKind(request.openKind())"); - int provider = source.indexOf("request.project().setActiveProvider(provider)", openKind); - assertTrue(openKind >= 0); - assertTrue(provider > openKind); - assertTrue(source.contains("project.setActiveOpenKind(null)")); - assertTrue(mode >= 0); - assertTrue(teleport > mode); - assertTrue(runtime.contains("modeRestore.restore()")); - } - - @Test - public void studioTimingSeparatesOrderedLifecyclePhases() throws Exception { - String source = Files.readString(Path.of( - "src/main/java/art/arcane/iris/core/runtime/StudioOpenCoordinator.java")).replace("\r\n", "\n"); - int previous = -1; - for (String phase : List.of( - "resolve_dimension_and_cleanup", - "create_world_total", - "apply_world_rules", - "prepare_generator", - "resolve_entry_anchor", - "prepare_structure_rings", - "prepare_generation_caches", - "teleport_standard_entry", - "finalize_open")) { - int current = source.indexOf("\"" + phase + "\"", previous + 1); - assertTrue("Missing or out-of-order Studio timing phase " + phase, current > previous); - previous = current; - } - assertTrue(source.contains("long openStart = System.nanoTime();")); - } - - @Test - public void structureStateCompletesBeforeImmediateNativeTeleport() throws Exception { - String source = Files.readString(Path.of( - "src/main/java/art/arcane/iris/core/runtime/StudioOpenCoordinator.java")).replace("\r\n", "\n"); - int executeOpen = source.indexOf("private void executeOpen("); - int completionCall = source.indexOf("endStudioEntryBootstrap(entryWorld, entryProvider)", executeOpen); - int completionAwait = source.indexOf("entryBootstrap.get(", completionCall); - int cacheAwait = source.indexOf("irisEngine.awaitGenerationCacheWarm()", completionAwait); - int teleportStart = source.indexOf("WorldRuntimeControlService.get().teleportInMode(", cacheAwait); - int finalizeOpen = source.indexOf( - "updateStage(request, \"finalize_open\", 1.00D)", teleportStart); - int futureComplete = source.indexOf( - "future.complete(new StudioOpenResult(world, entryLocation))", finalizeOpen); - int methodStart = source.indexOf( - "private void endStudioEntryBootstrap(World world, PlatformChunkGenerator provider)"); - int methodEnd = source.indexOf("private void abandonStudioEntryBootstrap", methodStart); - String method = source.substring(methodStart, methodEnd); - int scheduled = method.indexOf("J.sfut(() ->"); - int claim = method.indexOf("activationClaim.compareAndSet(true, false)"); - int activation = method.indexOf("INMS.get().completeStudioStructureBootstrap(world)"); - int gateRelease = method.indexOf("bukkitGenerator::endStudioEntryBootstrap"); - - assertTrue(completionCall >= 0); - assertTrue(completionAwait > completionCall); - assertTrue(cacheAwait > completionAwait); - assertTrue(teleportStart > cacheAwait); - assertTrue(finalizeOpen > teleportStart); - assertTrue(futureComplete > finalizeOpen); - assertFalse(source.contains("requestChunkAsync(")); - assertTrue(scheduled >= 0); - assertTrue(claim > scheduled); - assertTrue(activation > claim); - int ringCompletion = method.indexOf("thenCompose(nativeActivation -> nativeActivation)"); - assertTrue(ringCompletion > activation); - assertTrue(gateRelease > ringCompletion); - assertTrue(source.contains("abandonStudioEntryBootstrap(world, e);")); - } - - @Test - public void failedOpenMarshalsRetainedStateAbandonmentToTheServerScheduler() throws Exception { - String source = Files.readString(Path.of( - "src/main/java/art/arcane/iris/core/runtime/StudioOpenCoordinator.java")).replace("\r\n", "\n"); - int methodStart = source.indexOf( - "private void abandonStudioEntryBootstrap(World world, Throwable failure)"); - int methodEnd = source.indexOf("private CompletableFuture cleanupFailedOpen", methodStart); - String method = source.substring(methodStart, methodEnd); - - assertTrue(method.contains("if (J.isPrimaryThread())")); - assertTrue(method.contains("CompletableFuture abandonment = J.sfut(")); - assertTrue(method.contains("abandonment.get(STUDIO_STRUCTURE_ACTIVATION_TIMEOUT_SECONDS")); - } - - @Test - public void queuedRestartDefersFailedOpenCleanupWithoutAcquiringALiveCloseLease() throws Exception { - String source = Files.readString(Path.of( - "src/main/java/art/arcane/iris/core/runtime/StudioOpenCoordinator.java")).replace("\r\n", "\n"); - int openCatch = source.indexOf("} catch (Throwable e) {"); - int restartCheck = source.indexOf( - ".active(LifecycleOperationCoordinator.Domain.SERVER_LIFECYCLE)", - openCatch); - int restartDeferral = source.indexOf( - "deferFailedOpenCleanupToRestart(", - restartCheck); - int liveCleanup = source.indexOf("cleanupFailedOpen(", restartDeferral); - int methodStart = source.indexOf( - "private void deferFailedOpenCleanupToRestart(", - restartDeferral); - int methodEnd = source.indexOf("private boolean transientWorldStorageExists", methodStart); - String method = source.substring(methodStart, methodEnd); - - assertTrue(restartCheck > openCatch); - assertTrue(restartDeferral > restartCheck); - assertTrue(liveCleanup > restartDeferral); - assertTrue(method.contains("queueStartupCleanup(")); - assertFalse(method.contains("closeWorldCoordinated(")); - } - - @Test - public void openFinalizerReturnsToTheServerThreadBeforeCompletion() throws Exception { - String source = Files.readString(Path.of( - "src/main/java/art/arcane/iris/core/runtime/StudioOpenCoordinator.java")).replace("\r\n", "\n"); - int finalizerCall = source.indexOf("runOpenFinalizer(request.onDone(), world);"); - int futureCompletion = source.indexOf( - "future.complete(new StudioOpenResult(world, entryLocation))", finalizerCall); - int methodStart = source.indexOf( - "private void runOpenFinalizer(Consumer finalizer, World world)"); - int methodEnd = source.indexOf("private long elapsedMillis", methodStart); - String method = source.substring(methodStart, methodEnd); - - assertTrue(finalizerCall >= 0); - assertTrue(futureCompletion > finalizerCall); - assertTrue(method.contains("if (J.isPrimaryThread())")); - assertTrue(method.contains("J.sfut(() -> finalizer.accept(world))")); - assertTrue(method.contains( - "completion.get(STUDIO_STRUCTURE_ACTIVATION_TIMEOUT_SECONDS, TimeUnit.SECONDS)")); - } } diff --git a/core/src/test/java/art/arcane/iris/core/runtime/StudioOpenCoordinatorSpawnStuckRegressionTest.java b/core/src/test/java/art/arcane/iris/core/runtime/StudioOpenCoordinatorSpawnStuckRegressionTest.java index 7eab779f5..732de03bd 100644 --- a/core/src/test/java/art/arcane/iris/core/runtime/StudioOpenCoordinatorSpawnStuckRegressionTest.java +++ b/core/src/test/java/art/arcane/iris/core/runtime/StudioOpenCoordinatorSpawnStuckRegressionTest.java @@ -2,12 +2,9 @@ package art.arcane.iris.core.runtime; import org.junit.Test; -import java.nio.file.Files; -import java.nio.file.Path; import java.util.Arrays; import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertTrue; public class StudioOpenCoordinatorSpawnStuckRegressionTest { @Test @@ -30,25 +27,4 @@ public class StudioOpenCoordinatorSpawnStuckRegressionTest { .anyMatch(m -> m.getName().equals("waitForEntryChunk")); assertFalse("waitForEntryChunk retry loop must be removed", found); } - - @Test - public void entryTeleportDoesNotIssueASecondChunkRequest() throws Exception { - String source = Files.readString(Path.of( - "src/main/java/art/arcane/iris/core/runtime/StudioOpenCoordinator.java")).replace("\r\n", "\n"); - - assertTrue(source.contains("WorldRuntimeControlService.get().teleportInMode(")); - assertFalse(source.contains("prepareStudioEntryChunks(")); - assertFalse(source.contains("requestChunkAsync(")); - } - - @Test - public void foliaEntryPathNeverReadsTerrainOnARegionThread() throws Exception { - String source = Files.readString(Path.of( - "src/main/java/art/arcane/iris/core/runtime/StudioOpenCoordinator.java")).replace("\r\n", "\n"); - - assertTrue(source.contains("resolveEntryAnchor(world, provider)")); - assertFalse(source.contains("findStudioEntryLocation")); - assertFalse(source.contains("getHighestBlockYAt(")); - assertFalse(source.contains("resolveSafeEntry(world, entryAnchor)")); - } } diff --git a/core/src/test/java/art/arcane/iris/core/service/JigsawStudioLifecycleTest.java b/core/src/test/java/art/arcane/iris/core/service/JigsawStudioLifecycleTest.java index 65bf2e3d6..0ee4480e9 100644 --- a/core/src/test/java/art/arcane/iris/core/service/JigsawStudioLifecycleTest.java +++ b/core/src/test/java/art/arcane/iris/core/service/JigsawStudioLifecycleTest.java @@ -23,9 +23,6 @@ import org.mockito.MockedStatic; import java.lang.reflect.Constructor; import java.lang.reflect.Field; -import java.io.IOException; -import java.nio.file.Files; -import java.nio.file.Path; import java.util.List; import java.util.Map; import java.util.Optional; @@ -84,23 +81,6 @@ public class JigsawStudioLifecycleTest { CreatureSpawnEvent.SpawnReason.SPAWNER)); } - @Test - public void committedStudioActivationDisablesNaturalMobSpawning() throws IOException { - String source = Files.readString(Path.of( - "src/main/java/art/arcane/iris/core/service/JigsawStudioService.java")).replace("\r\n", "\n"); - int registerStart = source.indexOf("public void register("); - int commitStart = source.indexOf("public void activationCommitted(", registerStart); - int commitEnd = source.indexOf("public void markChunkGenerated(", commitStart); - int helperStart = source.indexOf("static void disableNaturalStudioSpawning(", commitEnd); - String register = source.substring(registerStart, commitStart); - String commit = source.substring(commitStart, commitEnd); - String helper = source.substring(helperStart); - - assertFalse(register.contains("disableNaturalStudioSpawning(world)")); - assertTrue(commit.contains("disableNaturalStudioSpawning(world)")); - assertTrue(helper.contains("setGameRule(GameRules.SPAWN_MOBS, false)")); - } - @Test public void closeAuthorizationChecksOwnerDirtyStateAndSaveBarrierAtomically() { assertTrue(JigsawStudioActivation.tryBeginOpen(OWNER)); diff --git a/core/src/test/java/art/arcane/iris/core/service/PackDownloadProgressReporterTest.java b/core/src/test/java/art/arcane/iris/core/service/PackDownloadProgressReporterTest.java index 2cf34baec..22c2404b3 100644 --- a/core/src/test/java/art/arcane/iris/core/service/PackDownloadProgressReporterTest.java +++ b/core/src/test/java/art/arcane/iris/core/service/PackDownloadProgressReporterTest.java @@ -7,8 +7,6 @@ import art.arcane.volmlib.util.format.Form; import org.junit.Test; import org.mockito.ArgumentCaptor; -import java.nio.file.Files; -import java.nio.file.Path; import java.util.List; import static org.junit.Assert.assertEquals; @@ -182,24 +180,6 @@ public class PackDownloadProgressReporterTest { verify(sender, times(1)).sendMessage(anyString()); } - @Test - public void playerHudAlwaysShowsLoaderLaneAndActionBarWithCleanup() throws Exception { - String source = Files.readString(Path.of( - "src/main/java/art/arcane/iris/core/service/PackDownloadProgressReporter.java" - )).replace("\r\n", "\n"); - - assertFalse(source.contains("HudSlotRequest")); - assertFalse(source.contains("HudSurface")); - assertTrue(source.contains("J.ar(this::pulseHud, HUD_PULSE_TICKS)")); - assertTrue(source.contains("BukkitPlatform.hudLanes().show(")); - assertTrue(source.contains("sender.sendAction(snapshot.line())")); - assertTrue(source.contains("HUD_TERMINAL_TICKS, retiredCleanup")); - assertTrue(source.contains("BukkitPlatform.hudLanes().retire(playerId, hudLaneId)")); - assertTrue(source.contains("BukkitPlatform.hudLanes().hide(player, hudLaneId)")); - assertFalse(source.contains("J.runGlobal(cleanup)")); - assertTrue(source.contains("J.car(activeTaskId);")); - } - @Test public void allDownloadPhasesHaveLocalizedLabels() { for (PackDownloader.DownloadPhase phase : PackDownloader.DownloadPhase.values()) { diff --git a/core/src/test/java/art/arcane/iris/core/service/StudioSVCPackDownloadContractTest.java b/core/src/test/java/art/arcane/iris/core/service/StudioSVCPackDownloadContractTest.java index bc2cc0b88..118c51088 100644 --- a/core/src/test/java/art/arcane/iris/core/service/StudioSVCPackDownloadContractTest.java +++ b/core/src/test/java/art/arcane/iris/core/service/StudioSVCPackDownloadContractTest.java @@ -5,76 +5,9 @@ import art.arcane.iris.core.localization.IrisLanguage; import art.arcane.iris.core.localization.PackDownloadMessages; import org.junit.Test; -import java.nio.file.Files; -import java.nio.file.Path; - import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertTrue; public class StudioSVCPackDownloadContractTest { - @Test - public void downloadsUseReporterCompletionWithoutMutatingLiveDatapacks() throws Exception { - String source = Files.readString(Path.of("src/main/java/art/arcane/iris/core/service/StudioSVC.java")).replace("\r\n", "\n"); - - assertTrue(source.contains("reporter.succeed(result);")); - assertFalse(method(source, "public void downloadBuiltIn(VolmitSender sender, String key)") - .contains("ServerConfigurator.restart()")); - assertFalse(method(source, "public void downloadUrl(VolmitSender sender, String url)") - .contains("installDataPacksIfChanged")); - } - - @Test - public void downloadLeaseIsAcquiredBeforeUnconditionalIoDispatch() throws Exception { - String source = Files.readString(Path.of("src/main/java/art/arcane/iris/core/service/StudioSVC.java")).replace("\r\n", "\n"); - int mutationStart = source.indexOf("private void runPackMutation("); - int mutationEnd = source.indexOf("private void executePackMutation(", mutationStart); - String runPackMutation = source.substring(mutationStart, mutationEnd); - int leaseAcquisition = runPackMutation.indexOf("LifecycleOperationCoordinator.get().acquire("); - int executionTracking = runPackMutation.indexOf("new PackDownloadExecution("); - int ioDispatch = runPackMutation.indexOf("MultiBurst.ioBurst.submit("); - - assertTrue(leaseAcquisition >= 0); - assertTrue(executionTracking > leaseAcquisition); - assertTrue(ioDispatch > leaseAcquisition); - assertTrue(runPackMutation.contains("execution.bind(future);")); - assertTrue(runPackMutation.contains("execution.cancel();")); - assertTrue(runPackMutation.contains("finally")); - assertTrue(runPackMutation.contains("reporter.start();")); - assertTrue(runPackMutation.contains("reporter.executionComplete();")); - assertFalse(runPackMutation.contains("runOffPrimaryThread")); - } - - @Test - public void acceptedDownloadsRouteFeedbackProgressAndTerminalStatesThroughReporter() throws Exception { - String source = Files.readString(Path.of("src/main/java/art/arcane/iris/core/service/StudioSVC.java")).replace("\r\n", "\n"); - String builtIn = method(source, "public void downloadBuiltIn(VolmitSender sender, String key)"); - String remote = method(source, "public void downloadUrl(VolmitSender sender, String url)"); - String execute = method(source, "private void executePackMutation("); - - assertTrue(builtIn.contains("PackDownloadProgressReporter reporter")); - assertTrue(remote.contains("PackDownloadProgressReporter reporter")); - assertTrue(remote.contains("reporter::detail")); - assertTrue(remote.contains("\"remote-zip\", reporter")); - assertTrue(remote.contains("cancellation,")); - assertTrue(remote.contains("reporter")); - assertTrue(execute.contains("reporter.cancel();")); - assertTrue(execute.contains("reporter.fail(e);")); - } - - @Test - public void shutdownClosesAdmissionAndDrainsTrackedDownloadBeforeServiceTeardown() throws Exception { - String source = Files.readString(Path.of("src/main/java/art/arcane/iris/core/service/StudioSVC.java")).replace("\r\n", "\n"); - String onDisable = method(source, "public void onDisable()"); - String quiesce = method(source, "public void quiesceDownloadsForShutdown()"); - - assertTrue(onDisable.contains("quiesceDownloadsForShutdown();")); - assertTrue(quiesce.contains("downloadAdmissionOpen = false;")); - assertTrue(quiesce.contains("execution.cancel();")); - assertTrue(quiesce.contains("execution.await(")); - assertTrue(quiesce.contains("while (!execution.isComplete())")); - } - @Test public void stackedDownloadUsesLocalizedBusyMessage() { LifecycleOperationCoordinator.ActiveOperation download = new LifecycleOperationCoordinator.ActiveOperation( @@ -99,24 +32,4 @@ public class StudioSVCPackDownloadContractTest { StudioSVC.packMutationBusyMessage(worldCreation) ); } - - private static String method(String source, String signature) { - int start = source.indexOf(signature); - assertTrue("Missing source contract signature: " + signature, start >= 0); - int openBrace = source.indexOf('{', start); - assertTrue("Missing source contract method body: " + signature, openBrace >= 0); - int depth = 0; - for (int index = openBrace; index < source.length(); index++) { - char current = source.charAt(index); - if (current == '{') { - depth++; - } else if (current == '}') { - depth--; - if (depth == 0) { - return source.substring(start, index + 1); - } - } - } - throw new IllegalArgumentException("Unclosed source contract method: " + signature); - } } diff --git a/core/src/test/java/art/arcane/iris/core/service/StudioSVCWorldPackFeedbackContractTest.java b/core/src/test/java/art/arcane/iris/core/service/StudioSVCWorldPackFeedbackContractTest.java deleted file mode 100644 index 1b94cd041..000000000 --- a/core/src/test/java/art/arcane/iris/core/service/StudioSVCWorldPackFeedbackContractTest.java +++ /dev/null @@ -1,35 +0,0 @@ -package art.arcane.iris.core.service; - -import org.junit.Test; - -import java.nio.file.Files; -import java.nio.file.Path; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertFalse; - -public class StudioSVCWorldPackFeedbackContractTest { - @Test - public void persistentPackCopyUsesLifecycleProgressWithoutLegacySnapshotFeedback() throws Exception { - String source = Files.readString(Path.of( - "src/main/java/art/arcane/iris/core/service/StudioSVC.java" - )).replace("\r\n", "\n"); - - assertEquals(2, occurrences(source, "STUDIO_S_V_C_PACK_COPY_REQUIRES_ASYNC_THREAD")); - assertEquals(3, occurrences(source, "STUDIO_S_V_C_PACK_INSTALL_FAILED")); - assertFalse(source.contains("STUDIO_S_V_C_INSTALLING_PACKAGE")); - assertFalse(source.contains("Publishing snapshot")); - assertFalse(source.contains("sender.sendMessage(\"Iris refused to copy a pack")); - assertFalse(source.contains("sender.sendMessage(\"Failed to install studio pack")); - } - - private static int occurrences(String value, String match) { - int count = 0; - int offset = 0; - while ((offset = value.indexOf(match, offset)) >= 0) { - count++; - offset += match.length(); - } - return count; - } -} diff --git a/core/src/test/java/art/arcane/iris/core/service/StudioSVCWorldPackPublishTest.java b/core/src/test/java/art/arcane/iris/core/service/StudioSVCWorldPackPublishTest.java index 55be651ae..33ac1df61 100644 --- a/core/src/test/java/art/arcane/iris/core/service/StudioSVCWorldPackPublishTest.java +++ b/core/src/test/java/art/arcane/iris/core/service/StudioSVCWorldPackPublishTest.java @@ -172,27 +172,6 @@ public class StudioSVCWorldPackPublishTest { @Test public void replaceExistingRejectsSymbolicTargetBeforePublication() throws Exception { - String sourceCode = Files.readString(Path.of( - "src/main/java/art/arcane/iris/core/service/StudioSVC.java")).replace("\r\n", "\n"); - int install = sourceCode.indexOf("private IrisDimension installIntoDirectory("); - int initialTargetSafety = sourceCode.indexOf( - "requireSafePublicationTarget(target, replaceExisting)", - install); - int beginMutation = sourceCode.indexOf( - "PackValidationRegistry.beginRootMutation(target)", - initialTargetSafety); - int finalTargetSafety = sourceCode.indexOf( - "requireSafePublicationTarget(target, replaceExisting)", - beginMutation); - int publish = sourceCode.indexOf( - "AtomicDirectoryPublisher.publish(stage, target)", - finalTargetSafety); - assertTrue(install >= 0); - assertTrue(initialTargetSafety > install); - assertTrue(beginMutation > initialTargetSafety); - assertTrue(finalTargetSafety > beginMutation); - assertTrue(publish > finalTargetSafety); - Path root = temporaryFolder.newFolder("symbolic-replacement-target").toPath(); Path outside = root.resolve("outside-pack"); Path target = root.resolve("world/iris/pack"); @@ -305,27 +284,6 @@ public class StudioSVCWorldPackPublishTest { @Test public void replacementKeepsTargetUnauthorizedThroughPublishedFingerprintWindow() throws Exception { - String sourceCode = Files.readString(Path.of( - "src/main/java/art/arcane/iris/core/service/StudioSVC.java")).replace("\r\n", "\n"); - int install = sourceCode.indexOf("private IrisDimension installIntoDirectory("); - int beginMutation = sourceCode.indexOf("PackValidationRegistry.beginRootMutation(target)", install); - int publish = sourceCode.indexOf("AtomicDirectoryPublisher.publish(stage, target)", beginMutation); - int fingerprint = sourceCode.indexOf( - "ServerConfigurator.computePackTreeFingerprint(target.toFile())", - publish); - int stageValidation = sourceCode.indexOf( - "validatePublishedPack(target, source, copiedFingerprint, validationMutation)", - fingerprint); - int publishCommit = sourceCode.indexOf("publication.commit()", stageValidation); - int validationCommit = sourceCode.indexOf("validationMutation.commit()", publishCommit); - assertTrue(install >= 0); - assertTrue(beginMutation > install); - assertTrue(publish > beginMutation); - assertTrue(fingerprint > publish); - assertTrue(stageValidation > fingerprint); - assertTrue(publishCommit > stageValidation); - assertTrue(validationCommit > publishCommit); - Path root = temporaryFolder.newFolder("validation-publication-window").toPath(); Path sourcePack = root.resolve("source"); Path target = root.resolve("world/iris/pack"); @@ -454,26 +412,6 @@ public class StudioSVCWorldPackPublishTest { assertEquals("second", second.join()); } - @Test - public void productionWorldPublicationUsesImmutableGenerationHistory() throws Exception { - String source = Files.readString(Path.of( - "src/main/java/art/arcane/iris/core/service/StudioSVC.java" - )).replace("\r\n", "\n"); - int productionStart = source.indexOf("private IrisDimension publishGenerationHistory("); - int transientStart = source.indexOf("private IrisDimension installIntoDirectory(", productionStart); - String production = source.substring(productionStart, transientStart); - - assertTrue(production.contains("GenerationHistory.create(")); - assertTrue(production.contains("GenerationHistory.openIfPresent(dimensionRoot, worldSeed)")); - assertTrue(production.contains("GenerationHistory.adoptLegacyPack(")); - assertTrue(production.contains("history.stageUpdate(")); - assertTrue(production.contains("getGenerationTransitionWidthBlocks()")); - assertTrue(production.contains("history.activePackRoot()")); - assertFalse(production.contains("AtomicDirectoryPublisher.publish(")); - assertTrue(source.contains("installIntoTransientWorld(")); - assertTrue(source.contains("new File(dimensionRoot, \"iris/pack\")")); - } - private static void writeValidPack(Path packRoot) throws Exception { Files.createDirectories(packRoot.resolve("dimensions")); Files.createDirectories(packRoot.resolve("regions")); diff --git a/core/src/test/java/art/arcane/iris/core/tools/IrisPersistentWorldCreationContractTest.java b/core/src/test/java/art/arcane/iris/core/tools/IrisPersistentWorldCreationContractTest.java deleted file mode 100644 index 7e70ac12f..000000000 --- a/core/src/test/java/art/arcane/iris/core/tools/IrisPersistentWorldCreationContractTest.java +++ /dev/null @@ -1,75 +0,0 @@ -package art.arcane.iris.core.tools; - -import org.junit.Test; - -import java.nio.file.Files; -import java.nio.file.Path; - -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertTrue; - -public class IrisPersistentWorldCreationContractTest { - @Test - public void productionCreateFreezesIntoCurrentPlatformStorageBeforeWorldCreation() throws Exception { - String source = Files.readString(Path.of("src/main/java/art/arcane/iris/core/tools/IrisCreator.java")).replace("\r\n", "\n"); - int createStart = source.indexOf("private World createReserved("); - int createEnd = source.indexOf("static Player createTeleportTarget(", createStart); - String create = source.substring(createStart, createEnd); - - int dimensionRoot = create.indexOf("WorldCreatorCompat.persistentDimensionRoot(worldKey)"); - int levelRoot = create.indexOf("WorldCreatorCompat.persistentLevelRoot(worldKey)"); - int existingStorage = create.indexOf("Files.exists(storageRoot.toPath())"); - int freezePack = create.indexOf("studioService.installIntoWorld(sender, resolvedDimension, dimensionRoot, seed)"); - int persistentCreator = create.indexOf(".persistent(!studio && !benchmark)"); - int bukkitCreate = create.indexOf("INMS.get().createWorldAsync(wc, request)"); - int rollbackStorage = create.indexOf( - "rollbackWorldCreation(worldKey, world, stagedGenerator, storageRoot, bukkitRegistered, failure)" - ); - - assertTrue(dimensionRoot >= 0); - assertTrue(levelRoot > dimensionRoot); - assertTrue(existingStorage > levelRoot); - assertTrue(freezePack > existingStorage); - assertTrue(persistentCreator > freezePack); - assertTrue(bukkitCreate > persistentCreator); - assertTrue(rollbackStorage > bukkitCreate); - assertFalse(create.contains("copySeed")); - assertFalse(create.contains("level.dat")); - } - - @Test - public void persistentCreatorPreservesConfiguredNameAndCanonicalIdentity() throws Exception { - String source = Files.readString(Path.of("src/main/java/art/arcane/iris/core/tools/IrisWorldCreator.java")).replace("\r\n", "\n"); - int createStart = source.indexOf("public WorldCreator create()"); - int createEnd = source.indexOf("private World.Environment findEnvironment()", createStart); - String create = source.substring(createStart, createEnd); - - int persistentCreator = create.indexOf("WorldCreatorCompat.ofPersistentKey(worldKey)"); - int persistentStorage = create.indexOf("WorldCreatorCompat.persistentDimensionRoot(worldKey)"); - int canonicalIdentity = create.indexOf(".platformIdentity(worldKey.toString())"); - int configuredName = create.indexOf(".name(creator.name())"); - int history = create.indexOf("requireGenerationHistory(w.worldFolder(), seed)"); - int exactPack = create.indexOf("requireActivePack(generationHistory)"); - - assertTrue(persistentCreator >= 0); - assertTrue(persistentStorage > persistentCreator); - assertTrue(canonicalIdentity > persistentStorage); - assertTrue(configuredName > canonicalIdentity); - assertTrue(history > configuredName); - assertTrue(exactPack > history); - assertTrue(create.contains("new File(w.worldFolder(), \"iris/pack\")")); - } - - @Test - public void publicBukkitBackendRebuildKeepsExactFallbackWorldName() throws Exception { - String source = Files.readString(Path.of( - "src/main/java/art/arcane/iris/core/lifecycle/WorldLifecycleRequest.java" - )).replace("\r\n", "\n"); - int rebuildStart = source.indexOf("public WorldCreator toWorldCreator()"); - int rebuildEnd = source.indexOf("return creator;", rebuildStart); - String rebuild = source.substring(rebuildStart, rebuildEnd); - - assertTrue(rebuild.contains("WorldCreatorCompat.ofKey(worldKey, worldName)")); - assertFalse(rebuild.contains("WorldCreatorCompat.ofKey(worldKey)")); - } -} diff --git a/core/src/test/java/art/arcane/iris/core/tools/WorldCreationProgressReporterTest.java b/core/src/test/java/art/arcane/iris/core/tools/WorldCreationProgressReporterTest.java index cd0016599..d948d7930 100644 --- a/core/src/test/java/art/arcane/iris/core/tools/WorldCreationProgressReporterTest.java +++ b/core/src/test/java/art/arcane/iris/core/tools/WorldCreationProgressReporterTest.java @@ -4,11 +4,7 @@ import art.arcane.iris.core.localization.RuntimeProgressMessages; import art.arcane.iris.util.common.format.C; import org.junit.Test; -import java.nio.file.Files; -import java.nio.file.Path; - import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertSame; import static org.junit.Assert.assertTrue; @@ -79,20 +75,6 @@ public class WorldCreationProgressReporterTest { assertTrue(failed.contains("FAILED | Entering world")); } - @Test - public void playerProgressUsesTheEntityScheduledActionBarWithoutABossBar() throws Exception { - String source = Files.readString(Path.of( - "src/main/java/art/arcane/iris/core/tools/WorldCreationProgressReporter.java" - )).replace("\r\n", "\n"); - - assertFalse(source.contains("Bukkit.createBossBar(")); - assertFalse(source.contains("WORLD_CREATE_BOSSBAR_")); - assertFalse(source.contains("isProgressBossBar()")); - assertTrue(source.contains("RuntimeProgressMessages.WORLD_CREATE_LIFECYCLE_ACTION")); - assertTrue(source.contains("J.runEntity(sender.player(), guardedRender)")); - assertTrue(source.contains("J.runEntity(sender.player(), render)")); - } - private static int occurrences(String value, String match) { int count = 0; int offset = 0; diff --git a/core/src/test/java/art/arcane/iris/engine/EngineRuntimePublicationContractTest.java b/core/src/test/java/art/arcane/iris/engine/EngineRuntimePublicationContractTest.java deleted file mode 100644 index 8015b323a..000000000 --- a/core/src/test/java/art/arcane/iris/engine/EngineRuntimePublicationContractTest.java +++ /dev/null @@ -1,130 +0,0 @@ -package art.arcane.iris.engine; - -import org.junit.Test; - -import java.io.IOException; -import java.nio.file.Files; -import java.nio.file.Path; - -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertTrue; - -public class EngineRuntimePublicationContractTest { - @Test - public void worldManagerStartsOnlyAfterTheRuntimeSessionIsReady() throws IOException { - String source = Files.readString(Path.of( - "src/main/java/art/arcane/iris/engine/EngineRuntimeBuilder.java")).replace("\r\n", "\n"); - int publishStart = source.indexOf("void publishRuntime("); - int publishEnd = source.indexOf("private void scheduleRuntimeTasks", publishStart); - String publish = source.substring(publishStart, publishEnd); - - assertBefore(publish, "engine.runtime = next", "next.worldManager().start()"); - assertBefore(publish, "activateNextSession()", "next.worldManager().start()"); - assertBefore(publish, "engine.lifecycleState = LifecycleState.RUNNING", "next.worldManager().start()"); - assertBefore(publish, "engine.getClosing().set(false)", "next.worldManager().start()"); - assertBefore(publish, "openBackgroundTaskAdmission()", "next.worldManager().start()"); - } - - @Test - public void failedManagerStartClosesAdmissionBeforeRuntimeCleanup() throws IOException { - String source = Files.readString(Path.of( - "src/main/java/art/arcane/iris/engine/EngineRuntimeBuilder.java")).replace("\r\n", "\n"); - int publishStart = source.indexOf("void publishRuntime("); - int publishEnd = source.indexOf("private void scheduleRuntimeTasks", publishStart); - String publish = source.substring(publishStart, publishEnd); - - assertBefore(publish, "engine.getClosing().set(true)", "cleanupFailure = engine.shutdownSequence.closeRuntime(next, null)"); - assertBefore(publish, "closeBackgroundTaskAdmission()", "cleanupFailure = engine.shutdownSequence.closeRuntime(next, null)"); - assertBefore(publish, "sealAndAwait(", "cleanupFailure = engine.shutdownSequence.closeRuntime(next, null)"); - } - - @Test - public void dimensionStackRegistrationRunsAfterHostStaticObjects() throws IOException { - String builderSource = Files.readString(Path.of( - "src/main/java/art/arcane/iris/engine/EngineRuntimeBuilder.java")).replace("\r\n", "\n"); - int buildStart = builderSource.indexOf("private EngineRuntime buildRuntime("); - int buildEnd = builderSource.indexOf("GenerationRuntime buildDetachedGenerationRuntime(", buildStart); - String build = builderSource.substring(buildStart, buildEnd); - - assertBefore(build, "assembly.runtimeKernel.registerStaticObjects(engine, assembly.mode)", - "assembly.runtimeKernel.registerDimensionStack("); - - String kernelSource = Files.readString(Path.of( - "src/main/java/art/arcane/iris/engine/history/GenerationKernelV1.java")).replace("\r\n", "\n"); - assertBefore(kernelSource, "staticObjects.apply(engine, x, z, blocks)", - "dimensionStack.actuate(x, z, blocks, multicore, chunkContext)"); - assertBefore(kernelSource, "dimensionStack.actuate(x, z, blocks, multicore, chunkContext)", - "stackCustom.modify(x, z, blocks, multicore, chunkContext)"); - } - - @Test - public void detachedRuntimeBuildDoesNotCreateWorldOwnedServices() throws IOException { - String source = Files.readString(Path.of( - "src/main/java/art/arcane/iris/engine/EngineRuntimeBuilder.java")).replace("\r\n", "\n"); - int buildStart = source.indexOf("GenerationRuntime buildDetachedGenerationRuntime("); - int buildEnd = source.indexOf("void publishRuntime(", buildStart); - String build = source.substring(buildStart, buildEnd); - - assertTrue(build.contains("assembly.runtimeKernel.createComplex(engine, assembly.transitionPlan)")); - assertTrue(build.contains("assembly.runtimeKernel.createMantle(engine, assembly.mantleStorageDirectory)")); - assertTrue(build.contains("assembly.mantle.hotload()")); - assertTrue(build.contains("assembly.runtimeKernel.createMode(engine)")); - assertTrue(build.contains("assembly.runtimeKernel.createUpperContext(engine)")); - assertTrue(build.contains("assembly.runtimeKernel.registerStaticObjects(engine, assembly.mode)")); - assertFalse(build.contains("EngineEffectsProvider")); - assertFalse(build.contains("EngineWorldManagerProvider")); - assertFalse(build.contains("worldManager().start()")); - } - - @Test - public void runtimePublicationTransfersAnIdenticalMantleWithoutClosingIt() throws IOException { - String builderSource = Files.readString(Path.of( - "src/main/java/art/arcane/iris/engine/EngineRuntimeBuilder.java")).replace("\r\n", "\n"); - String shutdownSource = Files.readString(Path.of( - "src/main/java/art/arcane/iris/engine/EngineShutdownSequence.java")).replace("\r\n", "\n"); - - assertTrue(builderSource.contains("next.generation().mantle()")); - assertTrue(shutdownSource.contains("generationRuntime.mantle() != retainedMantle")); - } - - @Test - public void engineAndDetachedRuntimeAcceptExplicitMantleDirectories() throws IOException { - String source = Files.readString(Path.of( - "src/main/java/art/arcane/iris/engine/IrisEngine.java")).replace("\r\n", "\n"); - - assertTrue(source.contains("InitializationMode initializationMode,\n Path mantleStorageDirectory")); - assertTrue(source.contains("EngineTarget runtimeTarget,\n Path mantleStorageDirectory")); - assertTrue(source.contains("exclusive mantle storage directory")); - } - - @Test - public void mantleIoPinsTheRuntimeDataAcrossWorkerThreads() throws IOException { - String source = Files.readString(Path.of( - "src/main/java/art/arcane/iris/engine/IrisEngineMantle.java")).replace("\r\n", "\n"); - - assertTrue(source.contains("runtimeData::get")); - assertTrue(source.contains("runtimeData.set(Objects.requireNonNull(engine.getData()")); - assertFalse(source.contains("createDataAdapter(engine::getData)")); - } - - @Test - public void failedDetachedBuildReleasesTransferredTargetOwnership() throws IOException { - String source = Files.readString(Path.of( - "src/main/java/art/arcane/iris/engine/IrisEngine.java")).replace("\r\n", "\n"); - int buildStart = source.indexOf("public GenerationRuntimeBinding buildDetachedGenerationRuntime("); - int buildEnd = source.indexOf("public void closeDetachedGenerationRuntime(", buildStart); - String build = source.substring(buildStart, buildEnd); - - assertTrue(build.contains("detachedData.registerEngine(this)")); - assertTrue(build.contains("shutdownSequence.closeDetachedTarget(requiredTarget, null)")); - assertTrue(build.contains("shutdownSequence.closeDetachedGenerationRuntime(detached, null)")); - } - - private static void assertBefore(String source, String first, String second) { - int firstIndex = source.indexOf(first); - int secondIndex = source.indexOf(second); - assertTrue("Missing source contract token: " + first, firstIndex >= 0); - assertTrue("Missing source contract token: " + second, secondIndex >= 0); - assertTrue(first + " must occur before " + second, firstIndex < secondIndex); - } -} diff --git a/core/src/test/java/art/arcane/iris/engine/EngineShutdownOwnershipContractTest.java b/core/src/test/java/art/arcane/iris/engine/EngineShutdownOwnershipContractTest.java deleted file mode 100644 index bdadc9a7c..000000000 --- a/core/src/test/java/art/arcane/iris/engine/EngineShutdownOwnershipContractTest.java +++ /dev/null @@ -1,74 +0,0 @@ -package art.arcane.iris.engine; - -import org.junit.Test; - -import java.io.IOException; -import java.nio.file.Files; -import java.nio.file.Path; - -import static org.junit.Assert.assertTrue; - -public class EngineShutdownOwnershipContractTest { - @Test - public void attachedHistoryRouterClosesBeforeRuntimeOwnershipReleases() throws IOException { - String source = Files.readString(Path.of( - "src/main/java/art/arcane/iris/engine/EngineShutdownSequence.java")).replace("\r\n", "\n"); - int closeStart = source.indexOf("void close()"); - int routerClose = source.indexOf("engine::closeAttachedGenerationHistoryRuntimeRouter", closeStart); - int runtimeRelease = source.indexOf("releaseRuntime(failure)", routerClose); - - assertTrue(routerClose > closeStart); - assertTrue(runtimeRelease > routerClose); - } - - @Test - public void ownershipCloseMustSucceedBeforeRuntimeRelease() throws IOException { - String source = Files.readString(Path.of( - "src/main/java/art/arcane/iris/engine/EngineShutdownSequence.java")).replace("\r\n", "\n"); - int ownershipClose = source.indexOf("NativeStructureOwnershipStore.close(engine)"); - int ownershipGate = source.indexOf("if (ownershipFailure == null)", ownershipClose); - int runtimeRelease = source.indexOf("releaseRuntime(failure)", ownershipGate); - - assertTrue(ownershipClose >= 0); - assertTrue(ownershipGate > ownershipClose); - assertTrue(runtimeRelease > ownershipGate); - } - - @Test - public void failedConstructionKeepsMantleOpenWhileOwnershipWritesRemain() throws IOException { - String source = Files.readString(Path.of( - "src/main/java/art/arcane/iris/engine/EngineShutdownSequence.java")).replace("\r\n", "\n"); - int cleanupStart = source.indexOf("void cleanupFailedConstruction"); - int cleanupEnd = source.indexOf("Throwable closeAssembly", cleanupStart); - String cleanup = source.substring(cleanupStart, cleanupEnd); - int ownershipClose = cleanup.indexOf("NativeStructureOwnershipStore.close(engine)"); - int ownershipGate = cleanup.indexOf("if (ownershipFailure == null)", ownershipClose); - int runtimeRelease = cleanup.indexOf("releaseRuntime(cleanupFailure)", ownershipGate); - int targetRelease = cleanup.indexOf("releaseTarget(cleanupFailure)", runtimeRelease); - int closedPublication = cleanup.indexOf("engine.closed = true", ownershipGate); - - assertTrue(ownershipClose >= 0); - assertTrue(ownershipGate > ownershipClose); - assertTrue(runtimeRelease > ownershipGate); - assertTrue(targetRelease > runtimeRelease); - assertTrue(closedPublication > ownershipGate); - } - - @Test - public void detachedRuntimesCloseBeforeTheBaseRuntimeAndTarget() throws IOException { - String source = Files.readString(Path.of( - "src/main/java/art/arcane/iris/engine/EngineShutdownSequence.java")).replace("\r\n", "\n"); - int releaseStart = source.indexOf("private Throwable releaseRuntime("); - int releaseEnd = source.indexOf("private Throwable closeDetachedGenerationRuntimes(", releaseStart); - String release = source.substring(releaseStart, releaseEnd); - int detachedRelease = release.indexOf("closeDetachedGenerationRuntimes(null)"); - int detachedGate = release.indexOf("if (detachedFailure != null)", detachedRelease); - int baseRelease = release.indexOf("closeRuntime(engine.runtime, null)", detachedGate); - int targetRelease = source.indexOf("engine.publishedTarget::close", releaseEnd); - - assertTrue(detachedRelease >= 0); - assertTrue(detachedGate > detachedRelease); - assertTrue(baseRelease > detachedGate); - assertTrue(targetRelease > releaseEnd); - } -} diff --git a/core/src/test/java/art/arcane/iris/engine/NativeStructureBootstrapLifecycleContractTest.java b/core/src/test/java/art/arcane/iris/engine/NativeStructureBootstrapLifecycleContractTest.java deleted file mode 100644 index 46572646b..000000000 --- a/core/src/test/java/art/arcane/iris/engine/NativeStructureBootstrapLifecycleContractTest.java +++ /dev/null @@ -1,107 +0,0 @@ -package art.arcane.iris.engine; - -import org.junit.Test; - -import java.io.IOException; -import java.nio.file.Files; -import java.nio.file.Path; - -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertTrue; - -public class NativeStructureBootstrapLifecycleContractTest { - @Test - public void closeWaitsBeforeLifecycleMutationAndGenerationSeal() throws IOException { - String source = Files.readString(Path.of( - "src/main/java/art/arcane/iris/engine/EngineShutdownSequence.java")).replace("\r\n", "\n"); - int closeStart = source.indexOf("void close()"); - int closeEnd = source.indexOf("void cleanupFailedConstruction", closeStart); - String close = source.substring(closeStart, closeEnd); - - assertBefore(close, - "engine.awaitNativeStructureBootstrap(\"close\")", - "engine.lifecycleState = LifecycleState.CLOSING"); - assertBefore(close, - "engine.awaitNativeStructureBootstrap(\"close\")", - "sealAndAwait(\"close\""); - } - - @Test - public void fullAndComplexHotloadWaitBeforeLifecycleMutationAndGenerationSeal() throws IOException { - String source = Files.readString(Path.of( - "src/main/java/art/arcane/iris/engine/EngineHotloader.java")).replace("\r\n", "\n"); - int complexStart = source.indexOf("void hotloadComplex()"); - int fullStart = source.indexOf("void hotloadSilently()", complexStart); - String complex = source.substring(complexStart, fullStart); - int fullEnd = source.indexOf("private void broadcastStudioHotload", fullStart); - String full = source.substring(fullStart, fullEnd); - - assertBefore(complex, - "engine.awaitNativeStructureBootstrap(\"complex hotload\")", - "engine.lifecycleState = LifecycleState.HOTLOADING"); - assertBefore(complex, - "engine.awaitNativeStructureBootstrap(\"complex hotload\")", - "engine.sealForTransition(\"complex hotload\""); - assertBefore(full, - "engine.awaitNativeStructureBootstrap(\"hotload\")", - "engine.lifecycleState = LifecycleState.HOTLOADING"); - assertBefore(full, - "engine.awaitNativeStructureBootstrap(\"hotload\")", - "engine.sealForTransition(\"hotload\""); - } - - @Test - public void ringBootstrapStartsUnderTheSameLifecycleLock() throws IOException { - String source = Files.readString(Path.of( - "src/main/java/art/arcane/iris/engine/IrisEngine.java")).replace("\r\n", "\n"); - int start = source.indexOf("public CompletableFuture startNativeStructureBootstrap("); - int end = source.indexOf("void awaitNativeStructureBootstrap", start); - String method = source.substring(start, end); - - assertBefore(method, "synchronized (lifecycleLock)", - "nativeStructureBootstrapBarrier.start(claim, starter)"); - assertBefore(method, "requireRunning(\"prepare native structure placements\")", - "nativeStructureBootstrapBarrier.start(claim, starter)"); - assertBefore(method, "nativeStructureBootstrapBarrier.start(claim, starter)", - "activation.run()"); - } - - @Test - public void studioVolumeQueriesStayOutsideCachesUntilTheBootstrapGateReleases() throws IOException { - String engineSource = Files.readString(Path.of( - "src/main/java/art/arcane/iris/engine/IrisEngine.java")).replace("\r\n", "\n"); - int queryStart = engineSource.indexOf( - "public KList getNativeStructureVolumes("); - int queryEnd = engineSource.indexOf( - "public void setNativeStructureVolumeQueriesEnabled", queryStart); - String query = engineSource.substring(queryStart, queryEnd); - int setterEnd = engineSource.indexOf("public IrisEngineData getEngineData()", queryEnd); - String setter = engineSource.substring(queryEnd, setterEnd); - String generatorSource = Files.readString(Path.of( - "src/main/java/art/arcane/iris/engine/platform/BukkitChunkGenerator.java")).replace("\r\n", "\n"); - int releaseStart = generatorSource.indexOf("public void endStudioEntryBootstrap()"); - int releaseEnd = generatorSource.indexOf( - "public boolean isStudioEntryBootstrapActive()", releaseStart); - String release = generatorSource.substring(releaseStart, releaseEnd); - - assertTrue(engineSource.contains( - "new AtomicBoolean(!requiredMode.studio())")); - assertBefore(query, - "!nativeStructureVolumeQueriesEnabled.get()", - "nativeStructureVolumeMemo.volumes("); - assertBefore(setter, - "nativeStructureVolumeMemo.clear()", - "nativeStructureVolumeQueriesEnabled.set(true)"); - assertBefore(release, - "irisEngine.setNativeStructureVolumeQueriesEnabled(shouldGenerateNativeStructures(", - "studioEntryBootstrapActive.set(false)"); - } - - private static void assertBefore(String source, String first, String second) { - int firstIndex = source.indexOf(first); - int secondIndex = source.indexOf(second); - assertTrue("Missing source contract token: " + first, firstIndex >= 0); - assertTrue("Missing source contract token: " + second, secondIndex >= 0); - assertTrue(first + " must occur before " + second, firstIndex < secondIndex); - } -} diff --git a/core/src/test/java/art/arcane/iris/engine/platform/BukkitChunkGeneratorInitializationModeTest.java b/core/src/test/java/art/arcane/iris/engine/platform/BukkitChunkGeneratorInitializationModeTest.java index 53e97123a..0dcc26237 100644 --- a/core/src/test/java/art/arcane/iris/engine/platform/BukkitChunkGeneratorInitializationModeTest.java +++ b/core/src/test/java/art/arcane/iris/engine/platform/BukkitChunkGeneratorInitializationModeTest.java @@ -11,11 +11,8 @@ import art.arcane.iris.engine.object.StudioMode; import art.arcane.iris.engine.object.IrisDimension; import org.junit.Test; -import java.io.IOException; import java.lang.reflect.Field; import java.lang.reflect.Method; -import java.nio.file.Files; -import java.nio.file.Path; import java.util.concurrent.CompletableFuture; import java.util.concurrent.TimeUnit; @@ -108,19 +105,6 @@ public class BukkitChunkGeneratorInitializationModeTest { assertEquals(-64, BukkitChunkGenerator.authoringBaseHeight(-64, 0)); } - @Test - public void authoringStartupDoesNotPrefetchTerrainHydrology() throws IOException { - String source = Files.readString(Path.of( - "src/main/java/art/arcane/iris/engine/platform/BukkitChunkGenerator.java")); - int start = source.indexOf("private CompletableFuture prefetchSpawnHydrology("); - int end = source.indexOf("private void updateSpawnLocation(", start); - String prefetch = source.substring(start, end); - - assertTrue(prefetch.indexOf("if (usesFlatStudioTerrain())") >= 0); - assertTrue(prefetch.indexOf("if (usesFlatStudioTerrain())") - < prefetch.indexOf("engine.getComplex()")); - } - @Test public void runtimeAndOrdinaryStudioWarmGenerationCaches() { IrisEngine.InitializationMode runtime = @@ -180,5 +164,4 @@ public class BukkitChunkGeneratorInitializationModeTest { assertFalse(BukkitChunkGenerator.shouldPersistWorldRegistration(true)); assertTrue(BukkitChunkGenerator.shouldPersistWorldRegistration(false)); } - } diff --git a/core/src/test/java/art/arcane/iris/purity/CoreProcessStreamPurityGateTest.java b/core/src/test/java/art/arcane/iris/purity/CoreProcessStreamPurityGateTest.java new file mode 100644 index 000000000..10d786243 --- /dev/null +++ b/core/src/test/java/art/arcane/iris/purity/CoreProcessStreamPurityGateTest.java @@ -0,0 +1,91 @@ +package art.arcane.iris.purity; + +import art.arcane.iris.core.loader.IrisData; +import org.junit.Test; +import org.objectweb.asm.ClassReader; +import org.objectweb.asm.ClassVisitor; +import org.objectweb.asm.MethodVisitor; +import org.objectweb.asm.Opcodes; + +import java.io.InputStream; +import java.nio.file.Files; +import java.nio.file.Path; +import java.util.ArrayList; +import java.util.List; +import java.util.stream.Stream; + +import static org.junit.Assert.assertTrue; + +public class CoreProcessStreamPurityGateTest { + private static final String SYSTEM_OWNER = "java/lang/System"; + private static final String STACK_TRACE_METHOD = "printStackTrace"; + + @Test + public void coreProductionBytecodeNeverTouchesTheProcessStreams() throws Exception { + Path classes = Path.of(IrisData.class.getProtectionDomain().getCodeSource().getLocation().toURI()); + assertTrue("core classes must be a directory to scan, got " + classes, Files.isDirectory(classes)); + List violations = new ArrayList<>(); + int scanned = 0; + + try (Stream tree = Files.walk(classes)) { + for (Path file : tree.filter(candidate -> candidate.toString().endsWith(".class")).toList()) { + collectViolations(file, violations); + scanned++; + } + } + + assertTrue("the gate scanned only " + scanned + " core classes, so it proves nothing", scanned > 1000); + + assertTrue("Core production code must report through IrisLogging, never the process streams." + + " printStackTrace(PrintStream)/printStackTrace(PrintWriter) write to a caller-supplied" + + " sink and stay allowed:" + String.join("", violations), violations.isEmpty()); + } + + private static void collectViolations(Path classFile, List violations) throws Exception { + ClassReader reader; + try (InputStream input = Files.newInputStream(classFile)) { + reader = new ClassReader(input); + } + String owner = reader.getClassName(); + + reader.accept(new ClassVisitor(Opcodes.ASM9) { + @Override + public MethodVisitor visitMethod( + int access, + String name, + String descriptor, + String signature, + String[] exceptions + ) { + return new MethodVisitor(Opcodes.ASM9) { + @Override + public void visitFieldInsn(int opcode, String fieldOwner, String fieldName, String fieldDescriptor) { + if (opcode != Opcodes.GETSTATIC || !SYSTEM_OWNER.equals(fieldOwner)) { + return; + } + if ("out".equals(fieldName) || "err".equals(fieldName)) { + violations.add(report(owner, name, "System." + fieldName)); + } + } + + @Override + public void visitMethodInsn( + int opcode, + String methodOwner, + String methodName, + String methodDescriptor, + boolean isInterface + ) { + if (STACK_TRACE_METHOD.equals(methodName) && "()V".equals(methodDescriptor)) { + violations.add(report(owner, name, methodOwner.replace('/', '.') + "#printStackTrace()")); + } + } + }; + } + }, ClassReader.SKIP_DEBUG | ClassReader.SKIP_FRAMES); + } + + private static String report(String owner, String method, String detail) { + return "\n " + owner.replace('/', '.') + "#" + method + " -> " + detail; + } +} diff --git a/core/src/test/java/art/arcane/iris/purity/PackTypeBukkitPurityGateTest.java b/core/src/test/java/art/arcane/iris/purity/PackTypeBukkitPurityGateTest.java index c577d0a32..bdcea42cd 100644 --- a/core/src/test/java/art/arcane/iris/purity/PackTypeBukkitPurityGateTest.java +++ b/core/src/test/java/art/arcane/iris/purity/PackTypeBukkitPurityGateTest.java @@ -2,6 +2,11 @@ package art.arcane.iris.purity; import art.arcane.iris.engine.object.annotations.Snippet; import org.junit.Test; +import org.objectweb.asm.ClassReader; +import org.objectweb.asm.ClassVisitor; +import org.objectweb.asm.MethodVisitor; +import org.objectweb.asm.Opcodes; +import org.objectweb.asm.Type; import java.io.File; import java.lang.annotation.Annotation; @@ -10,7 +15,6 @@ import java.lang.reflect.Field; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Modifier; import java.net.URL; -import java.nio.charset.StandardCharsets; import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.Paths; @@ -22,8 +26,6 @@ import java.util.List; import java.util.Locale; import java.util.Set; import java.util.TreeSet; -import java.util.regex.Matcher; -import java.util.regex.Pattern; import java.util.stream.Stream; import java.util.zip.ZipEntry; import java.util.zip.ZipFile; @@ -74,13 +76,12 @@ public class PackTypeBukkitPurityGateTest { /** See {@link #theGateStillCatchesAClassThatNeedsBukkit()}. */ private static final String BUKKIT_DEPENDENT_CANARY = "art.arcane.iris.engine.object.IrisObjectRotation$Faces"; private static final String OBJECT_PACKAGE = "art/arcane/iris/engine/object"; - private static final Path IRIS_DATA_SOURCE = - Paths.get("src", "main", "java", "art", "arcane", "iris", "core", "loader", "IrisData.java"); + private static final String IRIS_DATA = "art.arcane.iris.core.loader.IrisData"; /** * Every type handed to {@code registerLoader} in {@code IrisData.hotloaded()} - i.e. every root * type Gson deserializes from a pack. Kept literal on purpose; {@link - * #registeredRootListMatchesIrisData()} fails if the source drifts away from it. + * #registeredRootListMatchesIrisData()} fails if the compiled registrations drift away from it. */ private static final List GSON_REGISTERED_ROOTS = List.of( "art.arcane.iris.engine.object.IrisLootTable", @@ -140,21 +141,52 @@ public class PackTypeBukkitPurityGateTest { @Test public void registeredRootListMatchesIrisData() throws Exception { - if (!Files.isRegularFile(IRIS_DATA_SOURCE)) { - return; - } - String source = Files.readString(IRIS_DATA_SOURCE, StandardCharsets.UTF_8); - Matcher matcher = Pattern.compile("registerLoader\\((\\w+)\\.class").matcher(source); - Set inSource = new TreeSet<>(); - while (matcher.find()) { - inSource.add(matcher.group(1)); - } + byte[] bytes = BukkitHidingClassLoader.readClassBytes(getClass().getClassLoader(), IRIS_DATA); + assertNotNull("no class bytes for " + IRIS_DATA, bytes); + + Set registered = new TreeSet<>(); + new ClassReader(bytes).accept(new ClassVisitor(Opcodes.ASM9) { + @Override + public MethodVisitor visitMethod( + int access, + String name, + String descriptor, + String signature, + String[] exceptions + ) { + return new MethodVisitor(Opcodes.ASM9) { + private String pendingRegistrant; + + @Override + public void visitLdcInsn(Object value) { + if (value instanceof Type type && type.getSort() == Type.OBJECT) { + pendingRegistrant = type.getClassName(); + } + } + + @Override + public void visitMethodInsn( + int opcode, + String owner, + String methodName, + String methodDescriptor, + boolean isInterface + ) { + if ("registerLoader".equals(methodName) && pendingRegistrant != null) { + registered.add(pendingRegistrant.substring(pendingRegistrant.lastIndexOf('.') + 1)); + } + pendingRegistrant = null; + } + }; + } + }, ClassReader.SKIP_DEBUG | ClassReader.SKIP_FRAMES); + Set inTest = new TreeSet<>(); for (String name : GSON_REGISTERED_ROOTS) { inTest.add(name.substring(name.lastIndexOf('.') + 1)); } assertEquals("IrisData registers a different set of pack roots than this gate covers - " - + "add the new type to GSON_REGISTERED_ROOTS", inTest, inSource); + + "add the new type to GSON_REGISTERED_ROOTS", inTest, registered); } @Test diff --git a/core/src/test/java/art/arcane/iris/spi/PacksFolderContractTest.java b/core/src/test/java/art/arcane/iris/spi/PacksFolderContractTest.java index 7d51b4d12..2242d8c31 100644 --- a/core/src/test/java/art/arcane/iris/spi/PacksFolderContractTest.java +++ b/core/src/test/java/art/arcane/iris/spi/PacksFolderContractTest.java @@ -1,21 +1,32 @@ package art.arcane.iris.spi; +import art.arcane.iris.core.service.StudioSVC; import org.junit.Rule; import org.junit.Test; import org.junit.rules.TemporaryFolder; +import org.objectweb.asm.ClassReader; +import org.objectweb.asm.ClassVisitor; +import org.objectweb.asm.MethodVisitor; +import org.objectweb.asm.Opcodes; import java.io.File; +import java.io.InputStream; import java.nio.file.Files; import java.nio.file.Path; +import java.util.ArrayList; import java.util.List; +import java.util.stream.Stream; import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; import static org.mockito.Answers.CALLS_REAL_METHODS; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.when; public class PacksFolderContractTest { + private static final String PLATFORM_OWNER = "art/arcane/iris/spi/IrisPlatform"; + private static final String PACKS_ROOT_NAME = StudioSVC.WORKSPACE_NAME; + @Rule public TemporaryFolder temporaryFolder = new TemporaryFolder(); @@ -29,24 +40,92 @@ public class PacksFolderContractTest { assertEquals(new File(data, "packs" + File.separator + "overworld"), platform.packsFolderNoCreate("overworld")); } - /** - * Source guard: nothing outside the SPI defaults and platform overrides may spell the packs - * root by hand. New code goes through packsFolder()/packsFolderNoCreate(). - */ @Test - public void noCallSiteResolvesThePacksRootByHand() throws Exception { - List roots = List.of( - Path.of("src/main/java"), - Path.of("../adapters/bukkit/plugin/src/main/java")); - for (Path root : roots) { - try (var stream = Files.walk(root)) { - for (Path file : stream.filter(p -> p.toString().endsWith(".java")).toList()) { - String text = Files.readString(file); - assertFalse(file + " must use packsFolder() instead of dataFolder(\"packs\")", - text.contains("dataFolder(\"packs\")")); - assertFalse(file + " must use packsFolderNoCreate() instead of the WORKSPACE_NAME indirection", - text.contains("dataFolderNoCreate(StudioSVC.WORKSPACE_NAME")); - } + public void noCompiledCallSiteResolvesThePacksRootByHand() throws Exception { + Path classes = Path.of(StudioSVC.class.getProtectionDomain().getCodeSource().getLocation().toURI()); + assertTrue("core classes must be a directory to scan, got " + classes, Files.isDirectory(classes)); + List violations = new ArrayList<>(); + int scanned = 0; + + try (Stream tree = Files.walk(classes)) { + for (Path file : tree.filter(candidate -> candidate.toString().endsWith(".class")).toList()) { + collectViolations(file, violations); + scanned++; + } + } + + assertTrue("the gate scanned only " + scanned + " core classes, so it proves nothing", scanned > 1000); + + assertTrue("These methods spell the packs root by hand instead of going through" + + " IrisPlatform.packsFolder()/packsFolderNoCreate():" + String.join("", violations), + violations.isEmpty()); + } + + private static void collectViolations(Path classFile, List violations) throws Exception { + ClassReader reader; + try (InputStream input = Files.newInputStream(classFile)) { + reader = new ClassReader(input); + } + String owner = reader.getClassName(); + if (owner.equals(PLATFORM_OWNER)) { + return; + } + + reader.accept(new ClassVisitor(Opcodes.ASM9) { + @Override + public MethodVisitor visitMethod( + int access, + String name, + String descriptor, + String signature, + String[] exceptions + ) { + return new PacksRootCallSite(owner, name, violations); + } + }, ClassReader.SKIP_DEBUG | ClassReader.SKIP_FRAMES); + } + + private static final class PacksRootCallSite extends MethodVisitor { + private final String owner; + private final String method; + private final List violations; + private boolean loadsPacksRootName; + private boolean resolvesDataFolder; + + private PacksRootCallSite(String owner, String method, List violations) { + super(Opcodes.ASM9); + this.owner = owner; + this.method = method; + this.violations = violations; + } + + @Override + public void visitLdcInsn(Object value) { + if (PACKS_ROOT_NAME.equals(value)) { + loadsPacksRootName = true; + } + } + + @Override + public void visitMethodInsn( + int opcode, + String methodOwner, + String methodName, + String methodDescriptor, + boolean isInterface + ) { + if (!PLATFORM_OWNER.equals(methodOwner)) { + return; + } + if ("dataFolder".equals(methodName) || "dataFolderNoCreate".equals(methodName)) { + resolvesDataFolder = true; + } + } + + @Override + public void visitEnd() { + if (loadsPacksRootName && resolvesDataFolder) { + violations.add("\n " + owner.replace('/', '.') + "#" + method); } } } diff --git a/core/src/test/java/art/arcane/iris/util/common/director/specialhandlers/StructureHandlerTest.java b/core/src/test/java/art/arcane/iris/util/common/director/specialhandlers/StructureHandlerTest.java index 8530e15f4..c74a36807 100644 --- a/core/src/test/java/art/arcane/iris/util/common/director/specialhandlers/StructureHandlerTest.java +++ b/core/src/test/java/art/arcane/iris/util/common/director/specialhandlers/StructureHandlerTest.java @@ -21,9 +21,6 @@ import art.arcane.volmlib.util.collection.KList; import art.arcane.volmlib.util.director.exceptions.DirectorParsingException; import org.junit.Test; -import java.io.IOException; -import java.nio.file.Files; -import java.nio.file.Path; import java.util.LinkedHashSet; import java.util.List; import java.util.Set; @@ -231,24 +228,6 @@ public class StructureHandlerTest { } } - @Test - public void completionUsesOneReachabilitySnapshotAndLocatableKeys() throws IOException { - Path sourcePath = Path.of( - "src/main/java/art/arcane/iris/util/common/director/specialhandlers/StructureHandler.java"); - String source = Files.readString(sourcePath).replace("\r\n", "\n"); - int methodStart = source.indexOf("public KList getPossibilities()"); - int methodEnd = source.indexOf("@Override\n public String toString", methodStart); - String method = source.substring(methodStart, methodEnd); - - assertEquals(1, occurrences(method, "StructureReachability.reachableKeys(activeEngine)")); - assertEquals(0, occurrences(method, "IrisStructureLocator.locatableKeys(activeEngine)")); - assertEquals(1, occurrences(method, "IrisStructureLocator.locatableEditableKeys(activeEngine)")); - assertTrue(method.indexOf("if (activeEngine == null)") - < method.indexOf("IrisPlatforms.get().structureHooks()")); - assertFalse(method.contains("INMS")); - assertFalse(method.contains("catch (")); - } - private static IrisNativeStructureDecision decision(NativeStructureGenerationStatus status) { return new IrisNativeStructureDecision(status, 0, null, false, null, null); } @@ -268,16 +247,6 @@ public class StructureHandlerTest { return placement; } - private static int occurrences(String source, String target) { - int count = 0; - int offset = 0; - while ((offset = source.indexOf(target, offset)) >= 0) { - count++; - offset += target.length(); - } - return count; - } - private static final class TestStructureHandler extends StructureHandler { private final Engine activeEngine; private final boolean nativeGenerationEnabled; diff --git a/core/src/test/java/art/arcane/iris/util/common/scheduling/JRegionFutureContractTest.java b/core/src/test/java/art/arcane/iris/util/common/scheduling/JRegionFutureContractTest.java deleted file mode 100644 index 470a3f737..000000000 --- a/core/src/test/java/art/arcane/iris/util/common/scheduling/JRegionFutureContractTest.java +++ /dev/null @@ -1,24 +0,0 @@ -package art.arcane.iris.util.common.scheduling; - -import org.junit.Test; - -import java.nio.file.Files; -import java.nio.file.Path; - -import static org.junit.Assert.assertTrue; - -public class JRegionFutureContractTest { - @Test - public void regionFutureSettlesEverySchedulerPath() throws Exception { - String source = Files.readString(Path.of( - "src/main/java/art/arcane/iris/util/common/scheduling/J.java")) - .replace("\r\n", "\n"); - int start = source.indexOf("public static CompletableFuture runRegionFuture("); - int end = source.indexOf("public static boolean runGlobal(", start); - String method = source.substring(start, end); - - assertTrue(method.contains("settle(future, runnable)")); - assertTrue(method.contains("future.completeExceptionally(")); - assertTrue(method.contains("return sfut(runnable);")); - } -}