#1493: Improve reroute performance and add some tests

By: DerFrZocker <derrieple@gmail.com>
This commit is contained in:
CraftBukkit/Spigot
2024-10-15 21:05:19 +11:00
parent 8484d46297
commit 2a98825ddf
23 changed files with 1229 additions and 156 deletions

View File

@@ -2,20 +2,19 @@ package org.bukkit.craftbukkit.legacy;
import static org.junit.jupiter.api.Assertions.*;
import com.google.common.base.Joiner;
import com.google.common.base.Predicates;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.net.URI;
import java.net.URISyntaxException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.jar.JarFile;
import java.util.stream.Stream;
import org.bukkit.Bukkit;
import org.bukkit.craftbukkit.legacy.reroute.Reroute;
import org.bukkit.craftbukkit.legacy.reroute.RerouteBuilder;
import org.bukkit.craftbukkit.legacy.reroute.RerouteMethodData;
import org.bukkit.craftbukkit.util.ApiVersion;
import org.bukkit.craftbukkit.util.Commodore;
import org.bukkit.support.environment.Normal;
@@ -34,7 +33,7 @@ public class MaterialReroutingTest {
// Needs to be a bukkit class
private static final URI BUKKIT_CLASSES;
private static final Map<String, RerouteMethodData> MATERIAL_METHOD_REROUTE = RerouteBuilder.buildFromClass(MaterialRerouting.class);
private static final Reroute MATERIAL_METHOD_REROUTE = RerouteBuilder.create(Predicates.alwaysTrue()).forClass(MaterialRerouting.class).build();
static {
try {
@@ -95,7 +94,7 @@ public class MaterialReroutingTest {
}
}
if (!Commodore.rerouteMethods(Collections.emptySet(), ApiVersion.CURRENT, MATERIAL_METHOD_REROUTE, (methodNode.access & Opcodes.ACC_STATIC) != 0, classNode.name, methodNode.name, methodNode.desc, a -> { })) {
if (!Commodore.rerouteMethods(ApiVersion.CURRENT, MATERIAL_METHOD_REROUTE, (methodNode.access & Opcodes.ACC_STATIC) != 0, classNode.name, methodNode.name, methodNode.desc, a -> { })) {
missingReroute.add(methodNode.name + " " + methodNode.desc + " " + methodNode.signature);
}
}

View File

@@ -0,0 +1,76 @@
package org.bukkit.craftbukkit.legacy.reroute;
import static org.junit.jupiter.api.Assertions.*;
import com.google.common.base.Predicate;
import com.google.common.base.Predicates;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import org.objectweb.asm.Type;
public abstract class AbstractRerouteTest {
void test(Class<?> testClass, Map<String, RerouteMethodData> dataMap) {
test(testClass, Predicates.alwaysTrue(), dataMap);
}
void test(Class<?> testClass, Predicate<String> predicate, Map<String, RerouteMethodData> dataMap) {
test(testClass, Predicates.and(predicate), dataMap.entrySet().stream().map(entry -> new TestDataHolder(entry.getKey(), List.of(entry.getValue()))).toList());
}
void test(Class<?> testClass, Predicate<String> predicate, List<TestDataHolder> dataList) {
Reroute reroute = RerouteBuilder
.create(predicate)
.forClass(testClass)
.build();
assertEquals(dataList.size(), reroute.rerouteDataMap.size(), String.format("First layer reroute data amount are not the same. Expected: %s, Actual: %s", dataList, reroute.rerouteDataMap));
for (TestDataHolder testHolder : dataList) {
Reroute.RerouteDataHolder holder = reroute.rerouteDataMap.get(testHolder.methodKey());
assertEquals(testHolder.rerouteMethodDataList().size(), holder.rerouteMethodDataMap.size(), String.format("Second layer reroute data amount are not the same. Expected: %s, Actual: %s", testHolder.rerouteMethodDataList, holder.rerouteMethodDataMap));
for (RerouteMethodData testData : testHolder.rerouteMethodDataList()) {
RerouteMethodData actual = holder.rerouteMethodDataMap.get(testData.sourceOwner().getInternalName());
assertNotNull(actual, String.format("No reroute method data found for %s", testData));
check(actual, testData);
}
}
}
RerouteArgument create(String type, String sourceType, boolean injectPluginName, boolean injectPluginVersion, String injectCompatibility) {
return new RerouteArgument(Type.getType(type), Type.getType(sourceType), injectPluginName, injectPluginVersion, injectCompatibility);
}
List<RerouteArgument> create(RerouteArgument... arguments) {
return Arrays.asList(arguments);
}
RerouteMethodData create(String methodKey, String sourceDesc, String sourceOwner, String sourceName,
boolean staticReroute, String targetType, String targetOwner, String targetName,
List<RerouteArgument> arguments, String rerouteReturn, boolean isInBukkit,
RequirePluginVersionData requiredPluginVersion) {
return new RerouteMethodData(methodKey, Type.getType(sourceDesc), Type.getObjectType(sourceOwner), sourceName,
staticReroute, Type.getType(targetType), targetOwner, targetName, arguments, new RerouteReturn(Type.getType(rerouteReturn)), isInBukkit, requiredPluginVersion);
}
private void check(RerouteMethodData actual, RerouteMethodData expected) {
assertEquals(expected.methodKey(), actual.methodKey(), "Method key are not the same");
assertEquals(expected.sourceDesc(), actual.sourceDesc(), "Source desc are not the same");
assertEquals(expected.sourceOwner(), actual.sourceOwner(), "Source owner are not the same");
assertEquals(expected.sourceName(), actual.sourceName(), "Source name are not the same");
assertEquals(expected.staticReroute(), actual.staticReroute(), "Static reroute flag are not the same");
assertEquals(expected.targetType(), actual.targetType(), "Target type are not the same");
assertEquals(expected.targetOwner(), actual.targetOwner(), "Target owner are not the same");
assertEquals(expected.targetName(), actual.targetName(), "Target name are not the same");
assertEquals(expected.arguments().size(), actual.arguments().size(), "Arguments count are not the same");
assertEquals(expected.arguments(), actual.arguments(), "Arguments are not the same");
assertEquals(expected.rerouteReturn(), actual.rerouteReturn(), "Reroute return flag are not the same");
assertEquals(expected.isInBukkit(), actual.isInBukkit(), "In Bukkit flag are not the same");
assertEquals(expected.requiredPluginVersion(), actual.requiredPluginVersion(), "Required plugin version are not the same");
}
public record TestDataHolder(String methodKey, List<RerouteMethodData> rerouteMethodDataList) {
}
}

View File

@@ -0,0 +1,23 @@
package org.bukkit.craftbukkit.legacy.reroute;
import java.util.List;
import java.util.Map;
import org.bukkit.support.environment.Normal;
import org.junit.jupiter.api.Test;
@Normal
public class DoNotRerouteTest extends AbstractRerouteTest {
@Test
public void testDoNotReroute() {
test(DoNotRerouteTestData.class, Map.of());
}
public static class DoNotRerouteTestData {
@DoNotReroute
public static List<String> getList(Object o) {
return null;
}
}
}

View File

@@ -0,0 +1,55 @@
package org.bukkit.craftbukkit.legacy.reroute;
import static org.junit.jupiter.api.Assertions.*;
import com.google.common.base.Predicates;
import java.util.List;
import java.util.Map;
import org.bukkit.support.environment.Normal;
import org.junit.jupiter.api.Test;
@Normal
public class InjectCompatibilityTest extends AbstractRerouteTest {
@Test
public void testInjectCompatibility() {
test(InjectCompatibilityTestData.class, Map.of(
"()Ljava/util/List;getList", create(
"()Ljava/util/List;getList",
"()Ljava/util/List;",
"java/lang/Object",
"getList",
false,
"(Ljava/lang/Object;Z)Ljava/util/List;",
"org/bukkit/craftbukkit/legacy/reroute/InjectCompatibilityTest$InjectCompatibilityTestData",
"getList",
create(
create("Ljava/lang/Object;", "Ljava/lang/Object;", false, false, null),
create("Z", "Z", false, false, "test-value")
),
"Ljava/util/List;",
true,
null
)
)
);
}
@Test
public void testInjectCompatibilityIncorrectType() {
assertThrows(RuntimeException.class, () -> RerouteBuilder.create(Predicates.alwaysTrue()).forClass(InjectCompatibilityIncorrectTypeTestData.class).build());
}
public static class InjectCompatibilityTestData {
public static List<String> getList(Object o, @InjectCompatibility("test-value") boolean value) {
return null;
}
}
public static class InjectCompatibilityIncorrectTypeTestData {
public static List<String> getList(Object o, @InjectCompatibility("test-value") String value) {
return null;
}
}
}

View File

@@ -0,0 +1,55 @@
package org.bukkit.craftbukkit.legacy.reroute;
import static org.junit.jupiter.api.Assertions.*;
import com.google.common.base.Predicates;
import java.util.List;
import java.util.Map;
import org.bukkit.support.environment.Normal;
import org.junit.jupiter.api.Test;
@Normal
public class InjectPluginNameTest extends AbstractRerouteTest {
@Test
public void testInjectPluginName() {
test(InjectPluginNameTestData.class, Map.of(
"()Ljava/util/List;getList", create(
"()Ljava/util/List;getList",
"()Ljava/util/List;",
"java/lang/Object",
"getList",
false,
"(Ljava/lang/Object;Ljava/lang/String;)Ljava/util/List;",
"org/bukkit/craftbukkit/legacy/reroute/InjectPluginNameTest$InjectPluginNameTestData",
"getList",
create(
create("Ljava/lang/Object;", "Ljava/lang/Object;", false, false, null),
create("Ljava/lang/String;", "Ljava/lang/String;", true, false, null)
),
"Ljava/util/List;",
true,
null
)
)
);
}
@Test
public void testInjectPluginNameIncorrectType() {
assertThrows(RuntimeException.class, () -> RerouteBuilder.create(Predicates.alwaysTrue()).forClass(InjectPluginNameIncorrectTypeTestData.class).build());
}
public static class InjectPluginNameTestData {
public static List<String> getList(Object o, @InjectPluginName String value) {
return null;
}
}
public static class InjectPluginNameIncorrectTypeTestData {
public static List<String> getList(Object o, @InjectPluginName Object value) {
return null;
}
}
}

View File

@@ -0,0 +1,56 @@
package org.bukkit.craftbukkit.legacy.reroute;
import static org.junit.jupiter.api.Assertions.*;
import com.google.common.base.Predicates;
import java.util.List;
import java.util.Map;
import org.bukkit.craftbukkit.util.ApiVersion;
import org.bukkit.support.environment.Normal;
import org.junit.jupiter.api.Test;
@Normal
public class InjectPluginVersionTest extends AbstractRerouteTest {
@Test
public void testInjectPluginVersion() {
test(InjectPluginVersionTestData.class, Map.of(
"()Ljava/util/List;getList", create(
"()Ljava/util/List;getList",
"()Ljava/util/List;",
"java/lang/Object",
"getList",
false,
"(Ljava/lang/Object;Lorg/bukkit/craftbukkit/util/ApiVersion;)Ljava/util/List;",
"org/bukkit/craftbukkit/legacy/reroute/InjectPluginVersionTest$InjectPluginVersionTestData",
"getList",
create(
create("Ljava/lang/Object;", "Ljava/lang/Object;", false, false, null),
create("Lorg/bukkit/craftbukkit/util/ApiVersion;", "Lorg/bukkit/craftbukkit/util/ApiVersion;", false, true, null)
),
"Ljava/util/List;",
true,
null
)
)
);
}
@Test
public void testInjectPluginVersionIncorrectType() {
assertThrows(RuntimeException.class, () -> RerouteBuilder.create(Predicates.alwaysTrue()).forClass(InjectPluginVersionIncorrectTypeTestData.class).build());
}
public static class InjectPluginVersionTestData {
public static List<String> getList(Object o, @InjectPluginVersion ApiVersion value) {
return null;
}
}
public static class InjectPluginVersionIncorrectTypeTestData {
public static List<String> getList(Object o, @InjectPluginVersion String value) {
return null;
}
}
}

View File

@@ -0,0 +1,41 @@
package org.bukkit.craftbukkit.legacy.reroute;
import java.util.List;
import java.util.Map;
import org.bukkit.support.environment.Normal;
import org.junit.jupiter.api.Test;
@Normal
public class NotInBukkitTest extends AbstractRerouteTest {
@Test
public void testNotInBukkit() {
test(NotInBukkitTestData.class, Map.of(
"()Ljava/util/List;getList", create(
"()Ljava/util/List;getList",
"()Ljava/util/List;",
"java/lang/Object",
"getList",
false,
"(Ljava/lang/Object;)Ljava/util/List;",
"org/bukkit/craftbukkit/legacy/reroute/NotInBukkitTest$NotInBukkitTestData",
"getList",
create(
create("Ljava/lang/Object;", "Ljava/lang/Object;", false, false, null)
),
"Ljava/util/List;",
false,
null
)
)
);
}
public static class NotInBukkitTestData {
@NotInBukkit
public static List<String> getList(Object o) {
return null;
}
}
}

View File

@@ -0,0 +1,47 @@
package org.bukkit.craftbukkit.legacy.reroute;
import com.google.common.base.Predicates;
import java.util.List;
import java.util.Map;
import org.bukkit.support.environment.Normal;
import org.junit.jupiter.api.Test;
@Normal
public class RequireCompatibilityTest extends AbstractRerouteTest {
@Test
public void testRequireCompatibility() {
test(RequireCompatibilityTestData.class, Map.of(
"()Ljava/util/List;getList", create(
"()Ljava/util/List;getList",
"()Ljava/util/List;",
"java/lang/Object",
"getList",
false,
"(Ljava/lang/Object;)Ljava/util/List;",
"org/bukkit/craftbukkit/legacy/reroute/RequireCompatibilityTest$RequireCompatibilityTestData",
"getList",
create(
create("Ljava/lang/Object;", "Ljava/lang/Object;", false, false, null)
),
"Ljava/util/List;",
true,
null
)
)
);
}
@Test
public void testRequireCompatibilityNotPresent() {
test(RequireCompatibilityTestData.class, Predicates.alwaysFalse(), Map.of());
}
public static class RequireCompatibilityTestData {
@RequireCompatibility("test-value")
public static List<String> getList(Object o) {
return null;
}
}
}

View File

@@ -0,0 +1,121 @@
package org.bukkit.craftbukkit.legacy.reroute;
import static org.junit.jupiter.api.Assertions.*;
import java.lang.annotation.Annotation;
import org.bukkit.craftbukkit.util.ApiVersion;
import org.bukkit.support.environment.Normal;
import org.junit.jupiter.api.Test;
@Normal
public class RequirePluginVersionDataTest {
@Test
public void testSame() {
RequirePluginVersionData data = RequirePluginVersionData.create(new RequirePluginVersionImpl("", "1.21", "1.21"));
assertEquals(ApiVersion.getOrCreateVersion("1.21"), data.minInclusive());
assertEquals(ApiVersion.getOrCreateVersion("1.21"), data.maxInclusive());
}
@Test
public void testDifferent() {
RequirePluginVersionData data = RequirePluginVersionData.create(new RequirePluginVersionImpl("", "1.21", "1.23"));
assertEquals(ApiVersion.getOrCreateVersion("1.21"), data.minInclusive());
assertEquals(ApiVersion.getOrCreateVersion("1.23"), data.maxInclusive());
}
@Test
public void testValue() {
RequirePluginVersionData data = RequirePluginVersionData.create(new RequirePluginVersionImpl("1.42", "", ""));
assertEquals(ApiVersion.getOrCreateVersion("1.42"), data.minInclusive());
assertEquals(ApiVersion.getOrCreateVersion("1.42"), data.maxInclusive());
}
@Test
public void testValueAndMin() {
assertThrows(IllegalArgumentException.class, () -> RequirePluginVersionData.create(new RequirePluginVersionImpl("1.42", "1.52", "")));
}
@Test
public void testValueAndMax() {
assertThrows(IllegalArgumentException.class, () -> RequirePluginVersionData.create(new RequirePluginVersionImpl("1.42", "", "1.53")));
}
@Test
public void testValueAndMinMax() {
assertThrows(IllegalArgumentException.class, () -> RequirePluginVersionData.create(new RequirePluginVersionImpl("1.42", "1.51", "1.53")));
}
@Test
public void testMinNewerThanMax() {
assertThrows(IllegalArgumentException.class, () -> RequirePluginVersionData.create(new RequirePluginVersionImpl("", "1.59", "1.57")));
}
@Test
public void testOnlyMin() {
RequirePluginVersionData data = RequirePluginVersionData.create(new RequirePluginVersionImpl("", "1.44", ""));
assertEquals(ApiVersion.getOrCreateVersion("1.44"), data.minInclusive());
assertNull(data.maxInclusive());
}
@Test
public void testOnlyMax() {
RequirePluginVersionData data = RequirePluginVersionData.create(new RequirePluginVersionImpl("", "", "1.96"));
assertNull(data.minInclusive());
assertEquals(ApiVersion.getOrCreateVersion("1.96"), data.maxInclusive());
}
@Test
public void testExactData() {
RequirePluginVersionData data = new RequirePluginVersionData(ApiVersion.getOrCreateVersion("1.12"), ApiVersion.getOrCreateVersion("1.12"));
assertTrue(data.test(ApiVersion.getOrCreateVersion("1.12")));
assertFalse(data.test(ApiVersion.getOrCreateVersion("1.11")));
assertFalse(data.test(ApiVersion.getOrCreateVersion("1.13")));
}
@Test
public void testRangeData() {
RequirePluginVersionData data = new RequirePluginVersionData(ApiVersion.getOrCreateVersion("1.12"), ApiVersion.getOrCreateVersion("1.13"));
assertTrue(data.test(ApiVersion.getOrCreateVersion("1.12")));
assertTrue(data.test(ApiVersion.getOrCreateVersion("1.12.5")));
assertTrue(data.test(ApiVersion.getOrCreateVersion("1.13")));
assertFalse(data.test(ApiVersion.getOrCreateVersion("1.11")));
assertFalse(data.test(ApiVersion.getOrCreateVersion("1.14")));
}
@Test
public void testOlderOpenRangeData() {
RequirePluginVersionData data = new RequirePluginVersionData(null, ApiVersion.getOrCreateVersion("1.13"));
assertTrue(data.test(ApiVersion.getOrCreateVersion("1.1")));
assertTrue(data.test(ApiVersion.getOrCreateVersion("1.13")));
assertFalse(data.test(ApiVersion.getOrCreateVersion("1.14")));
}
@Test
public void testNewerOpenRangeData() {
RequirePluginVersionData data = new RequirePluginVersionData(ApiVersion.getOrCreateVersion("1.12"), null);
assertTrue(data.test(ApiVersion.getOrCreateVersion("1.12")));
assertTrue(data.test(ApiVersion.getOrCreateVersion("1.14")));
assertFalse(data.test(ApiVersion.getOrCreateVersion("1.11")));
}
private record RequirePluginVersionImpl(String value, String minInclusive, String maxInclusive) implements RequirePluginVersion {
@Override
public Class<? extends Annotation> annotationType() {
return null;
}
}
}

View File

@@ -0,0 +1,42 @@
package org.bukkit.craftbukkit.legacy.reroute;
import java.util.List;
import java.util.Map;
import org.bukkit.craftbukkit.util.ApiVersion;
import org.bukkit.support.environment.Normal;
import org.junit.jupiter.api.Test;
@Normal
public class RequirePluginVersionTest extends AbstractRerouteTest {
@Test
public void testRequirePluginVersion() {
test(RequirePluginVersionTestData.class, Map.of(
"()Ljava/util/List;getList", create(
"()Ljava/util/List;getList",
"()Ljava/util/List;",
"java/lang/Object",
"getList",
false,
"(Ljava/lang/Object;)Ljava/util/List;",
"org/bukkit/craftbukkit/legacy/reroute/RequirePluginVersionTest$RequirePluginVersionTestData",
"getList",
create(
create("Ljava/lang/Object;", "Ljava/lang/Object;", false, false, null)
),
"Ljava/util/List;",
true,
new RequirePluginVersionData(ApiVersion.getOrCreateVersion("1.42"), ApiVersion.getOrCreateVersion("1.42"))
)
)
);
}
public static class RequirePluginVersionTestData {
@RequirePluginVersion("1.42")
public static List<String> getList(Object o) {
return null;
}
}
}

View File

@@ -0,0 +1,71 @@
package org.bukkit.craftbukkit.legacy.reroute;
import java.util.List;
import java.util.Map;
import org.bukkit.support.environment.Normal;
import org.junit.jupiter.api.Test;
@Normal
public class RerouteArgumentTypeTest extends AbstractRerouteTest {
@Test
public void testRerouteArgumentType() {
test(RerouteArgumentTypeTestData.class, Map.of(
"()Ljava/util/List;getList", create(
"()Ljava/util/List;getList",
"()Ljava/util/List;",
"java/util/Map",
"getList",
false,
"(Ljava/lang/Object;)Ljava/util/List;",
"org/bukkit/craftbukkit/legacy/reroute/RerouteArgumentTypeTest$RerouteArgumentTypeTestData",
"getList",
create(
create("Ljava/lang/Object;", "Ljava/util/Map;", false, false, null)
),
"Ljava/util/List;",
true,
null
)
)
);
}
@Test
public void testRerouteArgumentTypeSecond() {
test(RerouteArgumentTypeSecondTestData.class, Map.of(
"(Ljava/lang/String;)Ljava/util/List;getList", create(
"(Ljava/lang/String;)Ljava/util/List;getList",
"(Ljava/lang/String;)Ljava/util/List;",
"java/lang/Object",
"getList",
false,
"(Ljava/lang/Object;Ljava/util/Map;)Ljava/util/List;",
"org/bukkit/craftbukkit/legacy/reroute/RerouteArgumentTypeTest$RerouteArgumentTypeSecondTestData",
"getList",
create(
create("Ljava/lang/Object;", "Ljava/lang/Object;", false, false, null),
create("Ljava/util/Map;", "Ljava/lang/String;", false, false, null)
),
"Ljava/util/List;",
true,
null
)
)
);
}
public static class RerouteArgumentTypeTestData {
public static List<String> getList(@RerouteArgumentType("java/util/Map") Object o) {
return null;
}
}
public static class RerouteArgumentTypeSecondTestData {
public static List<String> getList(Object o, @RerouteArgumentType("java/lang/String") Map<String, Object> map) {
return null;
}
}
}

View File

@@ -0,0 +1,221 @@
package org.bukkit.craftbukkit.legacy.reroute;
import static org.junit.jupiter.api.Assertions.*;
import com.google.common.base.Predicates;
import java.util.List;
import java.util.Map;
import java.util.logging.Logger;
import org.bukkit.support.environment.Normal;
import org.junit.jupiter.api.Test;
@Normal
public class RerouteBuilderTest extends AbstractRerouteTest {
@Test
public void testReroute() {
test(FirstTest.class, Map.of(
"()VtestReroute", create(
"()VtestReroute",
"()V",
"org/bukkit/craftbukkit/legacy/reroute/RerouteBuilderTest",
"testReroute",
false,
"(Lorg/bukkit/craftbukkit/legacy/reroute/RerouteBuilderTest;)V",
"org/bukkit/craftbukkit/legacy/reroute/RerouteBuilderTest$FirstTest",
"testReroute",
create(
create("Lorg/bukkit/craftbukkit/legacy/reroute/RerouteBuilderTest;", "Lorg/bukkit/craftbukkit/legacy/reroute/RerouteBuilderTest;", false, false, null)
),
"V",
true,
null
)
));
}
@Test
public void testInvalidMethods() {
test(InvalidMethodTest.class, Map.of());
}
@Test
public void testMultipleMethods() {
test(MultipleMethodTest.class, Map.of(
"()Ljava/util/List;getList", create(
"()Ljava/util/List;getList",
"()Ljava/util/List;",
"java/lang/Object",
"getList",
false,
"(Ljava/lang/Object;)Ljava/util/List;",
"org/bukkit/craftbukkit/legacy/reroute/RerouteBuilderTest$MultipleMethodTest",
"getList",
create(
create("Ljava/lang/Object;", "Ljava/lang/Object;", false, false, null)
),
"Ljava/util/List;",
true,
null
),
"(Ljava/util/Map;)Ljava/util/Map;getMap", create(
"(Ljava/util/Map;)Ljava/util/Map;getMap",
"(Ljava/util/Map;)Ljava/util/Map;",
"java/lang/String",
"getMap",
false,
"(Ljava/lang/String;Ljava/util/Map;)Ljava/util/Map;",
"org/bukkit/craftbukkit/legacy/reroute/RerouteBuilderTest$MultipleMethodTest",
"getMap",
create(
create("Ljava/lang/String;", "Ljava/lang/String;", false, false, null),
create("Ljava/util/Map;", "Ljava/util/Map;", false, false, null)
),
"Ljava/util/Map;",
true,
null
),
"(ZS)IgetInt", create(
"(ZS)IgetInt",
"(ZS)I",
"java/util/logging/Logger",
"getInt",
false,
"(Ljava/util/logging/Logger;ZS)I",
"org/bukkit/craftbukkit/legacy/reroute/RerouteBuilderTest$MultipleMethodTest",
"getInt",
create(
create("Ljava/util/logging/Logger;", "Ljava/util/logging/Logger;", false, false, null),
create("Z", "Z", false, false, null),
create("S", "S", false, false, null)
),
"I",
true,
null
)
)
);
}
@Test
public void testInterfaceRerouteClass() {
assertThrows(IllegalArgumentException.class, () -> RerouteBuilder.create(Predicates.alwaysTrue()).forClass(InterfaceTest.class).build());
}
@Test
public void testAnnotationRerouteClass() {
assertThrows(IllegalArgumentException.class, () -> RerouteBuilder.create(Predicates.alwaysTrue()).forClass(AnnotationTest.class).build());
}
@Test
public void testMissingOwner() {
assertThrows(RuntimeException.class, () -> RerouteBuilder.create(Predicates.alwaysTrue()).forClass(MissingOwnerTest.class).build());
}
@Test
public void testSameKey() {
test(SameKeyTest.class, Predicates.alwaysTrue(), List.of(
new TestDataHolder("()Ljava/util/List;getList", List.of(create(
"()Ljava/util/List;getList",
"()Ljava/util/List;",
"java/lang/Object",
"getList",
false,
"(Ljava/lang/Object;)Ljava/util/List;",
"org/bukkit/craftbukkit/legacy/reroute/RerouteBuilderTest$SameKeyTest",
"getList",
create(
create("Ljava/lang/Object;", "Ljava/lang/Object;", false, false, null)
),
"Ljava/util/List;",
true,
null
),
create(
"()Ljava/util/List;getList",
"()Ljava/util/List;",
"java/lang/String",
"getList",
false,
"(Ljava/lang/String;Ljava/lang/String;)Ljava/util/List;",
"org/bukkit/craftbukkit/legacy/reroute/RerouteBuilderTest$SameKeyTest",
"getList",
create(
create("Ljava/lang/String;", "Ljava/lang/String;", false, false, null),
create("Ljava/lang/String;", "Ljava/lang/String;", true, false, null)
),
"Ljava/util/List;",
true,
null
)
))
));
}
public static class FirstTest {
public static void testReroute(RerouteBuilderTest rerouteBuilderTest) {
}
}
public static class InvalidMethodTest {
public void testReroute(RerouteBuilderTest rerouteBuilderTest) {
}
static void testReroute2(RerouteBuilderTest rerouteBuilderTest) {
}
void testReroute3(RerouteBuilderTest rerouteBuilderTest) {
}
private static void testReroute4(RerouteBuilderTest rerouteBuilderTest) {
}
protected static void testReroute5(RerouteBuilderTest rerouteBuilderTest) {
}
}
public static class MultipleMethodTest {
public static List<String> getList(Object o) {
return null;
}
public static Map<String, String> getMap(String value, Map<String, String> map) {
return null;
}
public static int getInt(Logger logger, boolean bool, short s) {
return 0;
}
}
public interface InterfaceTest {
static List<String> getList(Object o) {
return null;
}
}
public @interface AnnotationTest {
}
public static class MissingOwnerTest {
public static List<String> getList() {
return null;
}
}
public class SameKeyTest {
public static List<String> getList(Object o) {
return null;
}
public static List<String> getList(String s, @InjectPluginName String name) {
return null;
}
}
}

View File

@@ -0,0 +1,41 @@
package org.bukkit.craftbukkit.legacy.reroute;
import java.util.List;
import java.util.Map;
import org.bukkit.support.environment.Normal;
import org.junit.jupiter.api.Test;
@Normal
public class RerouteMethodNameTest extends AbstractRerouteTest {
@Test
public void testRerouteMethodName() {
test(RerouteMethodNameTestData.class, Map.of(
"()Ljava/util/List;getMap", create(
"()Ljava/util/List;getMap",
"()Ljava/util/List;",
"java/lang/Object",
"getMap",
false,
"(Ljava/lang/Object;)Ljava/util/List;",
"org/bukkit/craftbukkit/legacy/reroute/RerouteMethodNameTest$RerouteMethodNameTestData",
"getList",
create(
create("Ljava/lang/Object;", "Ljava/lang/Object;", false, false, null)
),
"Ljava/util/List;",
true,
null
)
)
);
}
public static class RerouteMethodNameTestData {
@RerouteMethodName("getMap")
public static List<String> getList(Object o) {
return null;
}
}
}

View File

@@ -0,0 +1,41 @@
package org.bukkit.craftbukkit.legacy.reroute;
import java.util.List;
import java.util.Map;
import org.bukkit.support.environment.Normal;
import org.junit.jupiter.api.Test;
@Normal
public class RerouteReturnTypeTest extends AbstractRerouteTest {
@Test
public void testRerouteReturnType() {
test(RerouteReturnTypeTestData.class, Map.of(
"()Ljava/util/Map;getList", create(
"()Ljava/util/Map;getList",
"()Ljava/util/Map;",
"java/lang/Object",
"getList",
false,
"(Ljava/lang/Object;)Ljava/util/List;",
"org/bukkit/craftbukkit/legacy/reroute/RerouteReturnTypeTest$RerouteReturnTypeTestData",
"getList",
create(
create("Ljava/lang/Object;", "Ljava/lang/Object;", false, false, null)
),
"Ljava/util/List;",
true,
null
)
)
);
}
public static class RerouteReturnTypeTestData {
@RerouteReturnType("java/util/Map")
public static List<String> getList(Object o) {
return null;
}
}
}

View File

@@ -0,0 +1,41 @@
package org.bukkit.craftbukkit.legacy.reroute;
import java.util.List;
import java.util.Map;
import org.bukkit.support.environment.Normal;
import org.junit.jupiter.api.Test;
@Normal
public class RerouteStaticTest extends AbstractRerouteTest {
@Test
public void testStaticReroute() {
test(RerouteStaticTestData.class, Map.of(
"(Ljava/lang/Object;)Ljava/util/List;getList", create(
"(Ljava/lang/Object;)Ljava/util/List;getList",
"(Ljava/lang/Object;)Ljava/util/List;",
"java/util/Map",
"getList",
true,
"(Ljava/lang/Object;)Ljava/util/List;",
"org/bukkit/craftbukkit/legacy/reroute/RerouteStaticTest$RerouteStaticTestData",
"getList",
create(
create("Ljava/lang/Object;", "Ljava/lang/Object;", false, false, null)
),
"Ljava/util/List;",
true,
null
)
)
);
}
public static class RerouteStaticTestData {
@RerouteStatic("java/util/Map")
public static List<String> getList(Object o) {
return null;
}
}
}

View File

@@ -1,13 +1,13 @@
package org.bukkit.craftbukkit.legacy;
package org.bukkit.craftbukkit.legacy.reroute;
import static org.junit.jupiter.api.Assertions.*;
import com.google.common.base.Joiner;
import com.google.common.base.Predicates;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.util.HashMap;
import java.util.Map;
import java.util.stream.Stream;
import org.bukkit.craftbukkit.legacy.reroute.RerouteMethodData;
import org.bukkit.craftbukkit.util.Commodore;
import org.bukkit.support.environment.Normal;
import org.junit.jupiter.params.ParameterizedTest;
@@ -19,25 +19,28 @@ import org.objectweb.asm.Type;
public class RerouteValidationTest {
public static Stream<Arguments> data() {
return Commodore.REROUTES.stream().map(Arguments::of);
Commodore commodore = new Commodore(Predicates.alwaysTrue());
return commodore.getReroutes().stream().map(Arguments::of);
}
@ParameterizedTest
@MethodSource("data")
public void testReroutes(Map<String, RerouteMethodData> reroutes) {
public void testReroutes(Reroute reroute) {
Map<String, String> wrongReroutes = new HashMap<>();
String owner = null;
for (Map.Entry<String, RerouteMethodData> entry : reroutes.entrySet()) {
owner = entry.getValue().targetOwner();
if (!entry.getValue().isInBukkit()) {
continue;
}
for (Map.Entry<String, Reroute.RerouteDataHolder> value : reroute.rerouteDataMap.entrySet()) {
for (Map.Entry<String, RerouteMethodData> entry : value.getValue().rerouteMethodDataMap.entrySet()) {
owner = entry.getValue().targetOwner();
if (!entry.getValue().isInBukkit()) {
continue;
}
String error = isValid(entry.getKey(), entry.getValue());
String error = isValid(entry.getKey(), entry.getValue());
if (error != null) {
wrongReroutes.put(entry.getKey(), error);
if (error != null) {
wrongReroutes.put(entry.getKey(), error);
}
}
}