Get testing working, add tests for blockstate cache rebuilds

This commit is contained in:
embeddedt 2023-07-06 19:26:44 -04:00
parent 03b2395782
commit ff39e9022b
No known key found for this signature in database
GPG Key ID: A69433EC199B5613
9 changed files with 120 additions and 41 deletions

View File

@ -25,6 +25,11 @@ public abstract class BlockStateBaseMixin implements IBlockState {
cacheInvalid = true;
}
@Override
public boolean isCacheInvalid() {
return cacheInvalid;
}
private BlockBehaviour.BlockStateBase.Cache generateCache(BlockBehaviour.BlockStateBase base) {
if(cacheInvalid) {
// Ensure that only one block's cache is built at a time

View File

@ -316,19 +316,21 @@ public class ModernFixEarlyConfig {
public static ModernFixEarlyConfig load(File file) {
ModernFixEarlyConfig config = new ModernFixEarlyConfig(file);
Properties props = new Properties();
if(file.exists()) {
try (FileInputStream fin = new FileInputStream(file)){
props.load(fin);
} catch (IOException e) {
throw new RuntimeException("Could not load config file", e);
if(!Boolean.getBoolean("modernfix.ignoreConfigForTesting")) {
if(file.exists()) {
try (FileInputStream fin = new FileInputStream(file)){
props.load(fin);
} catch (IOException e) {
throw new RuntimeException("Could not load config file", e);
}
config.readProperties(props);
}
config.readProperties(props);
}
try {
config.save();
} catch (IOException e) {
LOGGER.warn("Could not write configuration file", e);
try {
config.save();
} catch (IOException e) {
LOGGER.warn("Could not write configuration file", e);
}
}
return config;

View File

@ -3,4 +3,5 @@ package org.embeddedt.modernfix.duck;
public interface IBlockState {
void clearCache();
boolean isCacheInvalid();
}

View File

@ -1,5 +1,6 @@
plugins {
id "com.github.johnrengelman.shadow" version "7.1.2"
id 'com.adarshr.test-logger' version '3.2.0'
}
architectury {
@ -44,8 +45,8 @@ dependencies {
// Remove the next line if you don't want to depend on the API
// modApi "me.shedaniel:architectury-fabric:${rootProject.architectury_version}"
testImplementation(common(project(path: ":common", configuration: "namedElements"))) { transitive false }
shadowCommon(project(path: ":common", configuration: "transformProductionFabric")) { transitive false }
common(project(path: ":common", configuration: "namedElements")) { transitive false }
testImplementation(shadowCommon(project(path: ":common", configuration: "transformProductionFabric"))) { transitive false }
testImplementation(platform("org.junit:junit-bom:${project.junit_version}"))
testImplementation("org.junit.jupiter:junit-jupiter-api")
@ -66,6 +67,7 @@ test {
runDir.mkdir()
}
workingDir = runDir
systemProperty 'modernfix.ignoreConfigForTesting', 'true'
// inject our custom agent to fix #817
FileCollection agentFile = configurations.getByName("testAgent")

View File

@ -9,6 +9,10 @@ import org.embeddedt.modernfix.util.CommonModUtil;
public class ModernFixPreLaunchFabric implements PreLaunchEntrypoint {
@Override
public void onPreLaunch() {
if(ModernFixMixinPlugin.instance == null) {
System.err.println("Mixin plugin not loaded yet");
return;
}
if(ModernFixMixinPlugin.instance.isOptionEnabled("feature.spark_profile_launch.OnFabric")) {
CommonModUtil.runWithoutCrash(() -> SparkLaunchProfiler.start("launch"), "Failed to start profiler");
}

View File

@ -0,0 +1,58 @@
package net.minecraft.world.level.block.state;
import net.minecraft.core.BlockPos;
import net.minecraft.world.level.EmptyBlockGetter;
import net.minecraft.world.level.block.Blocks;
import org.embeddedt.modernfix.duck.IBlockState;
import org.embeddedt.modernfix.testing.util.BootstrapMinecraft;
import org.junit.jupiter.api.*;
import static org.junit.jupiter.api.Assertions.*;
@BootstrapMinecraft
@TestMethodOrder(MethodOrderer.OrderAnnotation.class)
public class BlockStateCacheTest {
@BeforeEach
public void rebuildCache() {
Blocks.rebuildCache();
}
/**
* Initially, the cache should be invalid, and null.
*/
@Test
@Order(1)
public void testCacheNullInitially() {
BlockState stoneBlock = Blocks.STONE.defaultBlockState();
assertTrue(((IBlockState)stoneBlock).isCacheInvalid());
assertNull(stoneBlock.cache);
}
/**
* When an API that needs the cache is called, it should be built and the invalid flag
* becomes false.
*/
@Test
@Order(2)
public void testCacheBuiltByRequest() {
BlockState stoneBlock = Blocks.STONE.defaultBlockState();
stoneBlock.getCollisionShape(EmptyBlockGetter.INSTANCE, BlockPos.ZERO);
assertFalse(((IBlockState)stoneBlock).isCacheInvalid());
assertNotNull(stoneBlock.cache);
}
/**
* When a second rebuild occurs, the invalid flag should be set to true, but the old cache
* is not set to null, in order to prevent NPEs if a second thread is accessing the cache
* when this takes place.
*/
@Test
@Order(3)
public void testCacheInvalidatedByLateRebuild() {
BlockState stoneBlock = Blocks.STONE.defaultBlockState();
stoneBlock.getCollisionShape(EmptyBlockGetter.INSTANCE, BlockPos.ZERO);
Blocks.rebuildCache();
assertTrue(((IBlockState)stoneBlock).isCacheInvalid());
assertNotNull(stoneBlock.cache);
}
}

View File

@ -1,28 +0,0 @@
/*
package org.embeddedt.modernfix.blocks;
import net.minecraft.DetectedVersion;
import net.minecraft.core.Registry;
import net.minecraft.resources.ResourceLocation;
import net.minecraft.server.Bootstrap;
import net.minecraft.world.item.Items;
import org.junit.Test;
import org.junit.jupiter.api.BeforeAll;
import static org.junit.jupiter.api.Assertions.*;
public class BlockStateCacheTest {
@BeforeAll
public static void setup() {
DetectedVersion.tryDetectVersion();
Bootstrap.bootStrap();
}
@Test
public void testItemRegistry() {
ResourceLocation location = Registry.ITEM.getKey(Items.DIAMOND);
assertEquals(location.toString(), "minecraft:diamond");
}
}
*/

View File

@ -0,0 +1,14 @@
package org.embeddedt.modernfix.testing.util;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import org.junit.jupiter.api.extension.ExtendWith;
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
@ExtendWith({ BootstrapMinecraftExtension.class })
public @interface BootstrapMinecraft {
}

View File

@ -0,0 +1,21 @@
package org.embeddedt.modernfix.testing.util;
import net.minecraft.DetectedVersion;
import net.minecraft.server.Bootstrap;
import org.junit.jupiter.api.extension.AfterAllCallback;
import org.junit.jupiter.api.extension.BeforeAllCallback;
import org.junit.jupiter.api.extension.Extension;
import org.junit.jupiter.api.extension.ExtensionContext;
public class BootstrapMinecraftExtension implements Extension, BeforeAllCallback, AfterAllCallback {
@Override
public void beforeAll(ExtensionContext context) throws Exception {
DetectedVersion.tryDetectVersion();
Bootstrap.bootStrap();
}
@Override
public void afterAll(ExtensionContext context) throws Exception {
}
}