test: Make all minecraft methods public during testing

This is meant to fix minecraft failing to access package private methods of itself due to changes in naming
This commit is contained in:
Linnea Gräf
2024-11-27 17:13:23 +01:00
parent c414881391
commit 312dffe044
7 changed files with 109 additions and 1 deletions

View File

@@ -214,6 +214,9 @@ val hotswap by configurations.creating {
val nonModImplentation by configurations.creating {
configurations.implementation.get().extendsFrom(this)
}
val testAgent by configurations.creating {
isVisible = false
}
val configuredSourceSet = createIsolatedSourceSet("configured",
@@ -306,6 +309,7 @@ dependencies {
testImplementation("io.kotest:kotest-runner-junit5:6.0.0.M1")
testAgent(project(":testagent", configuration = "shadow"))
implementation(project(":symbols"))
ksp(project(":symbols"))
@@ -371,11 +375,13 @@ tasks.test {
val wd = file("build/testWorkDir")
workingDir(wd)
dependsOn(downloadTestRepo)
dependsOn(testAgent)
doFirst {
wd.mkdirs()
wd.resolve("config").deleteRecursively()
systemProperty("firmament.testrepo",
downloadTestRepo.flatMap { it.outputDirectory.asFile }.map { it.absolutePath }.get())
jvmArgs("-javaagent:${testAgent.singleFile.absolutePath}")
}
systemProperty("jdk.attach.allowAttachSelf", "true")
jvmArgs("-XX:+EnableDynamicAgentLoading")

View File

@@ -85,6 +85,9 @@ basicMath = "0.6.1"
# Update from https://mvnrepository.com/artifact/net.lenni0451.classtransform/core
classtransform = "1.14.0"
# Update from https://mvnrepository.com/artifact/org.ow2.asm/asm/
asm = "9.7.1"
[libraries]
minecraft = { module = "com.mojang:minecraft", version.ref = "minecraft" }
fabric_loader = { module = "net.fabricmc:fabric-loader", version.ref = "fabric_loader" }
@@ -124,6 +127,8 @@ basicMath = { module = "me.shedaniel.cloth:basic-math", version.ref = "basicMath
classTransform-mixinsTranslator = { module = "net.lenni0451.classtransform:mixinstranslator", version.ref = "classtransform" }
classTransform-core = { module = "net.lenni0451.classtransform:core", version.ref = "classtransform" }
asm = { module = "org.ow2.asm:asm", version.ref = "asm" }
[bundles]
runtime_required = [
"rei_fabric",
@@ -145,4 +150,4 @@ kotlin_plugin_serialization = { id = "org.jetbrains.kotlin.plugin.serialization"
kotlin_plugin_powerassert = { id = "org.jetbrains.kotlin.plugin.power-assert", version.ref = "kotlin" }
kotlin_plugin_ksp = { id = "com.google.devtools.ksp", version.ref = "kotlin_ksp" }
loom = { id = "dev.architectury.loom", version.ref = "loom" }
shadow = { id = "com.github.johnrengelman.shadow",version="8.1.1" }
shadow = { id = "com.github.johnrengelman.shadow", version = "8.1.1" }

View File

@@ -37,3 +37,4 @@ rootProject.name = "Firmament"
include("symbols")
include("javaplugin")
include("testagent")

View File

@@ -0,0 +1,14 @@
plugins {
java
alias(libs.plugins.shadow)
}
dependencies {
implementation(libs.asm)
}
tasks.withType<Jar> {
val agentMain = "moe.nea.firmament.testagent.AgentMain"
manifest.attributes(
"Agent-Class" to agentMain,
"Premain-Class" to agentMain,
)
}

View File

@@ -0,0 +1,21 @@
package moe.nea.firmament.testagent;
import java.lang.instrument.Instrumentation;
public class AgentMain {
public static void premain(
String agentArgs, Instrumentation inst) {
System.out.println("Pre-Main Firmament Test Agent");
AgentMain.inject(inst);
}
public static void agentmain(
String agentArgs, Instrumentation inst) {
System.out.println("Injected Firmament Test Agent");
AgentMain.inject(inst);
}
private static void inject(Instrumentation inst) {
inst.addTransformer(new ProtectedToPublicClassTransformer(inst)); }
}

View File

@@ -0,0 +1,31 @@
package moe.nea.firmament.testagent;
import org.objectweb.asm.ClassVisitor;
import org.objectweb.asm.ClassWriter;
import org.objectweb.asm.FieldVisitor;
import org.objectweb.asm.MethodVisitor;
import org.objectweb.asm.Opcodes;
public class ProtectedToPublicClassRewriter extends ClassVisitor {
public ProtectedToPublicClassRewriter(ClassWriter writer) {
super(Opcodes.ASM9, writer);
}
int makePublic(int flags) {
if ((flags & Opcodes.ACC_PROTECTED) != 0)
return (flags & ~Opcodes.ACC_PROTECTED) | Opcodes.ACC_PUBLIC;
if ((flags & (Opcodes.ACC_PUBLIC | Opcodes.ACC_PROTECTED | Opcodes.ACC_PRIVATE)) == 0)
return flags | Opcodes.ACC_PUBLIC;
return flags;
}
@Override
public FieldVisitor visitField(int access, String name, String descriptor, String signature, Object value) {
return super.visitField(makePublic(access), name, descriptor, signature, value);
}
@Override
public MethodVisitor visitMethod(int access, String name, String descriptor, String signature, String[] exceptions) {
return super.visitMethod(makePublic(access), name, descriptor, signature, exceptions);
}
}

View File

@@ -0,0 +1,30 @@
package moe.nea.firmament.testagent;
import org.objectweb.asm.ClassReader;
import org.objectweb.asm.ClassWriter;
import java.lang.instrument.ClassFileTransformer;
import java.lang.instrument.IllegalClassFormatException;
import java.lang.instrument.Instrumentation;
import java.security.ProtectionDomain;
public class ProtectedToPublicClassTransformer implements ClassFileTransformer {
public ProtectedToPublicClassTransformer(Instrumentation inst) {
}
@Override
public byte[] transform(ClassLoader loader,
String className,
Class<?> classBeingRedefined,
ProtectionDomain protectionDomain,
byte[] classfileBuffer)
throws IllegalClassFormatException {
if (!className.startsWith("net/minecraft/")) return classfileBuffer;
if (classfileBuffer == null) return null;
var reader = new ClassReader(classfileBuffer);
var writer = new ClassWriter(0);
var transformer = new ProtectedToPublicClassRewriter(writer);
reader.accept(transformer, 0);
return writer.toByteArray();
}
}