Retire source-text tests

- Delete 22 test classes whose assertions only read production .java text and check call ordering or literal presence
- Remove 77 source-text assertion methods from 34 test classes that keep real behavioural coverage
- Replace the core process-stream source grep with an ASM gate over compiled core classes in CoreProcessStreamPurityGateTest
- Replace the packs-root source grep in PacksFolderContractTest with an ASM call-site gate over compiled core classes
- Replace the IrisData registered-root regex in PackTypeBukkitPurityGateTest with an ASM scan of the registerLoader class constants
- Trim six mixed tests down to their behavioural assertions and drop their source-text tails
- Drop the eight iris.*Source and three iris.moddedCommonSources test system properties now that nothing reads them
This commit is contained in:
Brian Neumann-Fopiano committed 2026-09-08 04:01:33 -04:00
1 parent 7841efed54
commit c75cfd387e
65 files changed
+245 -4273

No files matched your search

@@ -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.
* <p>
* 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<Path> files = Files.walk(Path.of("src/main/java"))) {
List<Path> 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");
}
}
@@ -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();
@@ -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 {
@@ -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<String, Long> 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"));
@@ -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);
}
}
@@ -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) {
@@ -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);
}
}
@@ -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<Path> 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;
@@ -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<Boolean> 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<Void> closeServerLevelAsync(");
int closeEnd = source.indexOf("private static CompletableFuture<Void> 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();
@@ -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(
@@ -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)"));
}
}
@@ -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<Void> 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);
}
}
@@ -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())
@@ -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<Boolean> teleportPlayerToProject(");
int coordinatorEnd = coordinator.indexOf("private void executeOpen", coordinatorStart);
String coordinatorMethod = coordinator.substring(coordinatorStart, coordinatorEnd);
int serviceStart = service.indexOf(
"public CompletableFuture<Boolean> 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<Void> cleanupFailedOpen", methodStart);
String method = source.substring(methodStart, methodEnd);
assertTrue(method.contains("if (J.isPrimaryThread())"));
assertTrue(method.contains("CompletableFuture<Void> 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<World> 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)"));
}
}
@@ -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)"));
}
}
@@ -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));
@@ -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()) {
@@ -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);
}
}
@@ -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;
}
}
@@ -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"));
@@ -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)"));
}
}
@@ -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;
@@ -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);
}
}
@@ -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);
}
}
@@ -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<Void> 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<NativeStructureVolume> 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);
}
}
@@ -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<Void> 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));
}
}
@@ -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<String> violations = new ArrayList<>();
int scanned = 0;
try (Stream<Path> 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<String> 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;
}
}
@@ -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<String> 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<String> 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<String> 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<String> 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
@@ -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<Path> 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<String> violations = new ArrayList<>();
int scanned = 0;
try (Stream<Path> 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<String> 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<String> violations;
private boolean loadsPacksRootName;
private boolean resolvesDataFolder;
private PacksRootCallSite(String owner, String method, List<String> 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);
}
}
}
@@ -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<String> 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;
@@ -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<Void> 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);"));
}
}