diff options
author | Luck <git@lucko.me> | 2024-09-03 00:11:24 +0100 |
---|---|---|
committer | Luck <git@lucko.me> | 2024-09-03 00:11:24 +0100 |
commit | 35b557af4fd1bc0ce0a5745716e898cd1300a08c (patch) | |
tree | 5927e55839d5dd1a0759db3a2fd54f9f8df5d032 | |
parent | 55b38397296813b66082ad935f773357c8ad5282 (diff) | |
download | spark-35b557af4fd1bc0ce0a5745716e898cd1300a08c.tar.gz spark-35b557af4fd1bc0ce0a5745716e898cd1300a08c.tar.bz2 spark-35b557af4fd1bc0ce0a5745716e898cd1300a08c.zip |
Improve unit tests
14 files changed, 568 insertions, 22 deletions
diff --git a/spark-common/src/main/java/me/lucko/spark/common/sampler/AbstractSampler.java b/spark-common/src/main/java/me/lucko/spark/common/sampler/AbstractSampler.java index 7453074..20e7973 100644 --- a/spark-common/src/main/java/me/lucko/spark/common/sampler/AbstractSampler.java +++ b/spark-common/src/main/java/me/lucko/spark/common/sampler/AbstractSampler.java @@ -23,14 +23,11 @@ package me.lucko.spark.common.sampler; import me.lucko.spark.common.SparkPlatform; import me.lucko.spark.common.command.sender.CommandSender; import me.lucko.spark.common.monitor.memory.GarbageCollectorStatistics; -import me.lucko.spark.common.platform.MetadataProvider; import me.lucko.spark.common.platform.SparkMetadata; -import me.lucko.spark.common.platform.serverconfig.ServerConfigProvider; import me.lucko.spark.common.sampler.aggregator.DataAggregator; import me.lucko.spark.common.sampler.node.MergeMode; import me.lucko.spark.common.sampler.node.ThreadNode; import me.lucko.spark.common.sampler.source.ClassSourceLookup; -import me.lucko.spark.common.sampler.source.SourceMetadata; import me.lucko.spark.common.sampler.window.ProtoTimeEncoder; import me.lucko.spark.common.sampler.window.WindowStatisticsCollector; import me.lucko.spark.common.util.classfinder.ClassFinder; @@ -42,7 +39,6 @@ import me.lucko.spark.proto.SparkSamplerProtos.SamplerMetadata; import java.util.Collection; import java.util.Comparator; import java.util.List; -import java.util.Locale; import java.util.Map; import java.util.concurrent.CompletableFuture; import java.util.concurrent.CopyOnWriteArrayList; diff --git a/spark-common/src/main/java/me/lucko/spark/common/sampler/window/ProfilingWindowUtils.java b/spark-common/src/main/java/me/lucko/spark/common/sampler/window/ProfilingWindowUtils.java index be6f08a..ca44b31 100644 --- a/spark-common/src/main/java/me/lucko/spark/common/sampler/window/ProfilingWindowUtils.java +++ b/spark-common/src/main/java/me/lucko/spark/common/sampler/window/ProfilingWindowUtils.java @@ -61,7 +61,7 @@ public enum ProfilingWindowUtils { /** * Gets a prune predicate that can be passed to {@link DataAggregator#pruneData(IntPredicate)}. * - * @return the prune predicate + * @return the prune predicate - returns true for windows that should be pruned */ public static IntPredicate keepHistoryBefore(int currentWindow) { // windows that were earlier than (currentWindow minus history size) should be pruned diff --git a/spark-common/src/main/java/me/lucko/spark/common/sampler/window/ProtoTimeEncoder.java b/spark-common/src/main/java/me/lucko/spark/common/sampler/window/ProtoTimeEncoder.java index fb4a4fc..db0800d 100644 --- a/spark-common/src/main/java/me/lucko/spark/common/sampler/window/ProtoTimeEncoder.java +++ b/spark-common/src/main/java/me/lucko/spark/common/sampler/window/ProtoTimeEncoder.java @@ -20,8 +20,8 @@ package me.lucko.spark.common.sampler.window; -import me.lucko.spark.common.sampler.async.jfr.Dictionary; import me.lucko.spark.common.sampler.node.ThreadNode; +import org.jetbrains.annotations.VisibleForTesting; import java.util.HashMap; import java.util.List; @@ -43,16 +43,10 @@ public class ProtoTimeEncoder { /** A map of key value -> index in the keys array */ private final Map<Integer, Integer> keysToIndex; - public ProtoTimeEncoder(LongToDoubleFunction valueTransformer, List<ThreadNode> sourceData) { + @VisibleForTesting + ProtoTimeEncoder(LongToDoubleFunction valueTransformer, IntStream keys) { this.valueTransformer = valueTransformer; - - // get an array of all keys that show up in the source data - this.keys = sourceData.stream() - .map(n -> n.getTimeWindows().stream().mapToInt(i -> i)) - .reduce(IntStream.empty(), IntStream::concat) - .distinct() - .sorted() - .toArray(); + this.keys = keys.distinct().sorted().toArray(); // construct a reverse index lookup this.keysToIndex = new HashMap<>(this.keys.length); @@ -61,6 +55,13 @@ public class ProtoTimeEncoder { } } + public ProtoTimeEncoder(LongToDoubleFunction valueTransformer, List<ThreadNode> sourceData) { + this(valueTransformer, sourceData.stream() + .map(n -> n.getTimeWindows().stream().mapToInt(i -> i)) + .reduce(IntStream.empty(), IntStream::concat) + ); + } + /** * Gets an array of the keys that could be encoded by this encoder. * @@ -71,7 +72,7 @@ public class ProtoTimeEncoder { } /** - * Encode a {@link Dictionary} (map) of times/durations into a double array. + * Encode a map of times/durations into a double array. * * @param times a dictionary of times (unix-time millis -> duration in microseconds) * @return the times encoded as a double array diff --git a/spark-common/src/test/java/me/lucko/spark/common/SparkPlatformTest.java b/spark-common/src/test/java/me/lucko/spark/common/SparkPlatformTest.java index 10da849..fb2ae5e 100644 --- a/spark-common/src/test/java/me/lucko/spark/common/SparkPlatformTest.java +++ b/spark-common/src/test/java/me/lucko/spark/common/SparkPlatformTest.java @@ -20,12 +20,20 @@ package me.lucko.spark.common; +import com.google.common.collect.ImmutableSet; +import me.lucko.spark.common.command.sender.CommandSender; import me.lucko.spark.test.plugin.TestSparkPlugin; +import net.kyori.adventure.text.Component; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.io.TempDir; import java.nio.file.Path; +import java.util.HashSet; +import java.util.Set; +import java.util.UUID; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertFalse; import static org.junit.jupiter.api.Assertions.assertTrue; public class SparkPlatformTest { @@ -37,4 +45,63 @@ public class SparkPlatformTest { } } + @Test + public void testPermissions(@TempDir Path directory) { + try (TestSparkPlugin plugin = new TestSparkPlugin(directory)) { + SparkPlatform platform = plugin.platform(); + + Set<String> permissions = platform.getAllSparkPermissions(); + assertEquals( + ImmutableSet.of( + "spark", + "spark.profiler", + "spark.tps", + "spark.ping", + "spark.healthreport", + "spark.tickmonitor", + "spark.gc", + "spark.gcmonitor", + "spark.heapsummary", + "spark.heapdump", + "spark.activity" + ), + permissions + ); + + TestCommandSender testSender = new TestCommandSender(); + assertFalse(platform.hasPermissionForAnyCommand(testSender)); + + testSender.permissions.add("spark.tps"); + assertTrue(platform.hasPermissionForAnyCommand(testSender)); + + testSender.permissions.clear(); + testSender.permissions.add("spark"); + assertTrue(platform.hasPermissionForAnyCommand(testSender)); + } + } + + private static final class TestCommandSender implements CommandSender { + private final Set<String> permissions = new HashSet<>(); + + @Override + public String getName() { + return "Test"; + } + + @Override + public UUID getUniqueId() { + return new UUID(0, 0); + } + + @Override + public void sendMessage(Component message) { + + } + + @Override + public boolean hasPermission(String permission) { + return this.permissions.contains(permission); + } + } + } diff --git a/spark-common/src/test/java/me/lucko/spark/common/sampler/node/NodeTest.java b/spark-common/src/test/java/me/lucko/spark/common/sampler/node/NodeTest.java new file mode 100644 index 0000000..7df9e59 --- /dev/null +++ b/spark-common/src/test/java/me/lucko/spark/common/sampler/node/NodeTest.java @@ -0,0 +1,199 @@ +/* + * This file is part of spark. + * + * Copyright (c) lucko (Luck) <luck@lucko.me> + * Copyright (c) contributors + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +package me.lucko.spark.common.sampler.node; + +import com.google.common.collect.ImmutableList; +import com.google.common.collect.ImmutableSet; +import me.lucko.spark.common.sampler.SamplerMode; +import me.lucko.spark.common.sampler.async.AsyncStackTraceElement; +import me.lucko.spark.common.sampler.window.ProtoTimeEncoder; +import me.lucko.spark.common.util.MethodDisambiguator; +import me.lucko.spark.proto.SparkSamplerProtos; +import org.junit.jupiter.api.Test; + +import java.util.Collection; +import java.util.concurrent.TimeUnit; + +import static org.junit.jupiter.api.Assertions.assertArrayEquals; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertTrue; + +public class NodeTest { + + private static final StackTraceNode.Describer<AsyncStackTraceElement> STACK_TRACE_DESCRIBER = (element, parent) -> new StackTraceNode.Description(element.getClassName(), element.getMethodName(), element.getMethodDescription()); + private static final int WINDOW = 10; + + private static final AsyncStackTraceElement NODE_0 = new AsyncStackTraceElement("java.lang.Thread", "run", "()V"); + private static final AsyncStackTraceElement NODE_1_1 = new AsyncStackTraceElement("test.Foo", "run", "()V"); + private static final AsyncStackTraceElement NODE_1_2_1 = new AsyncStackTraceElement("test.Foo", "example", "()V"); + private static final AsyncStackTraceElement NODE_2_1 = new AsyncStackTraceElement("test.Bar", "run", "()V"); + private static final AsyncStackTraceElement NODE_2_2_1 = new AsyncStackTraceElement("test.Bar", "example", "()V"); + + private static final AsyncStackTraceElement[] STACK_1 = {NODE_1_2_1, NODE_1_1, NODE_0}; + private static final AsyncStackTraceElement[] STACK_2 = {NODE_2_2_1, NODE_2_1, NODE_0}; + + @Test + public void testThreadLabels() { + ThreadNode node = new ThreadNode("Test Thread"); + assertEquals("Test Thread", node.getThreadGroup()); + assertEquals("Test Thread", node.getThreadLabel()); + + node.setThreadLabel("Test"); + assertEquals("Test", node.getThreadLabel()); + } + + @Test + public void testBasicLog() { + ThreadNode threadNode = new ThreadNode("Test Thread"); + assertEquals(0, threadNode.getTimeWindows().size()); + + threadNode.log(STACK_TRACE_DESCRIBER, STACK_1, TimeUnit.SECONDS.toMicros(1), WINDOW); + + Collection<StackTraceNode> children1 = threadNode.getChildren(); + assertEquals(1, children1.size()); + assertEquals(ImmutableSet.of(WINDOW), threadNode.getTimeWindows()); + + StackTraceNode node1 = children1.iterator().next(); + assertEquals(ImmutableSet.of(WINDOW), node1.getTimeWindows()); + assertEquals("java.lang.Thread", node1.getClassName()); + assertEquals("run", node1.getMethodName()); + assertEquals("()V", node1.getMethodDescription()); + assertEquals(StackTraceNode.NULL_LINE_NUMBER, node1.getLineNumber()); + assertEquals(StackTraceNode.NULL_LINE_NUMBER, node1.getParentLineNumber()); + assertEquals(TimeUnit.SECONDS.toMicros(1), node1.getTimeAccumulator(WINDOW).longValue()); + + threadNode.log(STACK_TRACE_DESCRIBER, STACK_2, TimeUnit.SECONDS.toMicros(1), WINDOW); + assertEquals(TimeUnit.SECONDS.toMicros(2), node1.getTimeAccumulator(WINDOW).longValue()); + + Collection<StackTraceNode> children2 = node1.getChildren(); + assertEquals(2, children2.size()); + + for (StackTraceNode node2 : children2) { + assertEquals(ImmutableSet.of(WINDOW), node2.getTimeWindows()); + assertEquals(TimeUnit.SECONDS.toMicros(1), node2.getTimeAccumulator(WINDOW).longValue()); + } + } + + @Test + public void testToProto() { + ThreadNode threadNode = new ThreadNode("Test Thread"); + threadNode.log(STACK_TRACE_DESCRIBER, STACK_1, TimeUnit.SECONDS.toMicros(1), WINDOW); + threadNode.log(STACK_TRACE_DESCRIBER, STACK_1, TimeUnit.SECONDS.toMicros(1), WINDOW + 1); + threadNode.log(STACK_TRACE_DESCRIBER, STACK_2, TimeUnit.SECONDS.toMicros(1), WINDOW + 1); + + ProtoTimeEncoder timeEncoder = new ProtoTimeEncoder(SamplerMode.EXECUTION.valueTransformer(), ImmutableList.of(threadNode)); + int[] keys = timeEncoder.getKeys(); + assertArrayEquals(new int[]{WINDOW, WINDOW + 1}, keys); + + SparkSamplerProtos.ThreadNode proto = threadNode.toProto( + MergeMode.sameMethod(new MethodDisambiguator(null)), + timeEncoder + ); + + SparkSamplerProtos.ThreadNode expected = SparkSamplerProtos.ThreadNode.newBuilder() + .setName("Test Thread") + .addTimes(1000) + .addTimes(2000) + .addChildren(SparkSamplerProtos.StackTraceNode.newBuilder() + .setClassName("test.Bar") + .setMethodDesc("()V") + .setMethodName("example") + .addTimes(0) + .addTimes(1000) + ) + .addChildren(SparkSamplerProtos.StackTraceNode.newBuilder() + .setClassName("test.Bar") + .setMethodDesc("()V") + .setMethodName("run") + .addTimes(0) + .addTimes(1000) + .addChildrenRefs(0) + ) + .addChildren(SparkSamplerProtos.StackTraceNode.newBuilder() + .setClassName("test.Foo") + .setMethodDesc("()V") + .setMethodName("example") + .addTimes(1000) + .addTimes(1000) + ) + .addChildren(SparkSamplerProtos.StackTraceNode.newBuilder() + .setClassName("test.Foo") + .setMethodDesc("()V") + .setMethodName("run") + .addTimes(1000) + .addTimes(1000) + .addChildrenRefs(2) + ) + .addChildren(SparkSamplerProtos.StackTraceNode.newBuilder() + .setClassName("java.lang.Thread") + .setMethodDesc("()V") + .setMethodName("run") + .addTimes(1000) + .addTimes(2000) + .addChildrenRefs(1) + .addChildrenRefs(3) + ) + .addChildrenRefs(4) + .build(); + + assertEquals(expected, proto); + } + + @Test + public void testRemoveTimeWindows() { + ThreadNode threadNode = new ThreadNode("Test Thread"); + threadNode.log(STACK_TRACE_DESCRIBER, STACK_1, TimeUnit.SECONDS.toMicros(1), WINDOW); + threadNode.log(STACK_TRACE_DESCRIBER, STACK_2, TimeUnit.SECONDS.toMicros(1), WINDOW + 1); + + StackTraceNode threadRunNode = threadNode.getChildren().iterator().next(); + Collection<StackTraceNode> fooBarNodes = threadRunNode.getChildren(); + + assertEquals(2, threadNode.getTimeWindows().size()); + assertEquals(2, threadRunNode.getChildren().size()); + assertEquals(2, threadRunNode.getTimeWindows().size()); + + for (StackTraceNode node : fooBarNodes) { + assertEquals(1, node.getTimeWindows().size()); + assertEquals(1, node.getChildren().size()); + assertEquals(1, node.getChildren().iterator().next().getTimeWindows().size()); + assertEquals(0, node.getChildren().iterator().next().getChildren().size()); + } + + assertFalse(threadNode.removeTimeWindowsRecursively(w -> w == WINDOW)); + assertEquals(1, threadNode.getTimeWindows().size()); + assertEquals(1, threadRunNode.getChildren().size()); + assertEquals(1, threadRunNode.getTimeWindows().size()); + + assertTrue(threadNode.removeTimeWindowsRecursively(w -> w == WINDOW + 1)); + assertEquals(0, threadNode.getTimeWindows().size()); + assertEquals(0, threadNode.getChildren().size()); + + // doesn't bother updating nested children that have been removed + for (StackTraceNode node : fooBarNodes) { + assertEquals(1, node.getTimeWindows().size()); + assertEquals(1, node.getChildren().size()); + assertEquals(1, node.getChildren().iterator().next().getTimeWindows().size()); + assertEquals(0, node.getChildren().iterator().next().getChildren().size()); + } + } + +} diff --git a/spark-common/src/test/java/me/lucko/spark/common/sampler/window/ProfilingWindowUtilsTest.java b/spark-common/src/test/java/me/lucko/spark/common/sampler/window/ProfilingWindowUtilsTest.java new file mode 100644 index 0000000..4161fe9 --- /dev/null +++ b/spark-common/src/test/java/me/lucko/spark/common/sampler/window/ProfilingWindowUtilsTest.java @@ -0,0 +1,68 @@ +/* + * This file is part of spark. + * + * Copyright (c) lucko (Luck) <luck@lucko.me> + * Copyright (c) contributors + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +package me.lucko.spark.common.sampler.window; + +import org.junit.jupiter.api.Test; + +import java.time.Instant; +import java.time.LocalDateTime; +import java.time.Month; +import java.time.ZoneOffset; +import java.util.concurrent.TimeUnit; +import java.util.function.IntPredicate; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertTrue; + +public class ProfilingWindowUtilsTest { + + @Test + public void testMillisToWindow() { + int baseWindow = 28532770; + Instant baseTime = LocalDateTime.of(2024, Month.APRIL, 1, 10, 10, 0).toInstant(ZoneOffset.UTC); + + assertEquals(TimeUnit.MILLISECONDS.toMinutes(baseTime.toEpochMilli()), baseWindow); // should scale with unix time + + assertEquals(baseWindow, ProfilingWindowUtils.unixMillisToWindow(baseTime.toEpochMilli())); + assertEquals(baseWindow, ProfilingWindowUtils.unixMillisToWindow(baseTime.plusMillis(1).toEpochMilli())); + assertEquals(baseWindow, ProfilingWindowUtils.unixMillisToWindow(baseTime.plusSeconds(1).toEpochMilli())); + assertEquals(baseWindow, ProfilingWindowUtils.unixMillisToWindow(baseTime.plusSeconds(59).toEpochMilli())); + assertEquals(baseWindow + 1, ProfilingWindowUtils.unixMillisToWindow(baseTime.plusSeconds(60).toEpochMilli())); + assertEquals(baseWindow + 1, ProfilingWindowUtils.unixMillisToWindow(baseTime.plusSeconds(61).toEpochMilli())); + assertEquals(baseWindow - 1, ProfilingWindowUtils.unixMillisToWindow(baseTime.minusMillis(1).toEpochMilli())); + assertEquals(baseWindow - 1, ProfilingWindowUtils.unixMillisToWindow(baseTime.minusSeconds(1).toEpochMilli())); + } + + @Test + public void testKeepHistoryBefore() { + IntPredicate predicate = ProfilingWindowUtils.keepHistoryBefore(100); + assertFalse(predicate.test(99)); + assertFalse(predicate.test(100)); + assertFalse(predicate.test(101)); + + assertFalse(predicate.test(40)); + assertTrue(predicate.test(39)); + assertTrue(predicate.test(0)); + assertTrue(predicate.test(-10)); + } + +} diff --git a/spark-common/src/test/java/me/lucko/spark/common/sampler/window/ProtoTimeEncoderTest.java b/spark-common/src/test/java/me/lucko/spark/common/sampler/window/ProtoTimeEncoderTest.java new file mode 100644 index 0000000..82dcb12 --- /dev/null +++ b/spark-common/src/test/java/me/lucko/spark/common/sampler/window/ProtoTimeEncoderTest.java @@ -0,0 +1,54 @@ +/* + * This file is part of spark. + * + * Copyright (c) lucko (Luck) <luck@lucko.me> + * Copyright (c) contributors + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +package me.lucko.spark.common.sampler.window; + +import com.google.common.collect.ImmutableMap; +import org.junit.jupiter.api.Test; + +import java.util.concurrent.atomic.LongAdder; +import java.util.stream.IntStream; + +import static org.junit.jupiter.api.Assertions.assertArrayEquals; +import static org.junit.jupiter.api.Assertions.assertThrows; +import static org.junit.jupiter.api.Assertions.assertTrue; + +public class ProtoTimeEncoderTest { + + @Test + public void testSimple() { + ProtoTimeEncoder encoder = new ProtoTimeEncoder(l -> l, IntStream.of(7, 1, 3, 5)); + assertArrayEquals(new int[]{1, 3, 5, 7}, encoder.getKeys()); + + assertArrayEquals(new double[]{0, 0, 0, 0}, encoder.encode(ImmutableMap.of())); + assertArrayEquals(new double[]{0, 100, 0, 0}, encoder.encode(ImmutableMap.of(3, longAdder(100)))); + assertArrayEquals(new double[]{0, 100, 200, 0}, encoder.encode(ImmutableMap.of(3, longAdder(100), 5, longAdder(200)))); + + RuntimeException ex = assertThrows(RuntimeException.class, () -> encoder.encode(ImmutableMap.of(9, longAdder(300)))); + assertTrue(ex.getMessage().startsWith("No index for key 9")); + } + + private static LongAdder longAdder(long l) { + LongAdder longAdder = new LongAdder(); + longAdder.add(l); + return longAdder; + } + +} diff --git a/spark-common/src/test/java/me/lucko/spark/common/tick/TickHookTest.java b/spark-common/src/test/java/me/lucko/spark/common/tick/TickHookTest.java new file mode 100644 index 0000000..f920262 --- /dev/null +++ b/spark-common/src/test/java/me/lucko/spark/common/tick/TickHookTest.java @@ -0,0 +1,69 @@ +/* + * This file is part of spark. + * + * Copyright (c) lucko (Luck) <luck@lucko.me> + * Copyright (c) contributors + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +package me.lucko.spark.common.tick; + +import com.google.common.collect.ImmutableList; +import org.junit.jupiter.api.Test; + +import java.util.ArrayList; +import java.util.List; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +public class TickHookTest { + + @Test + public void testAbstractHook() { + AbstractTickHook hook = new AbstractTickHook() { + @Override + public void start() { + + } + + @Override + public void close() { + + } + }; + + assertEquals(0, hook.getCurrentTick()); + + List<Integer> ticks = new ArrayList<>(); + TickHook.Callback callback = ticks::add; + + hook.addCallback(callback); + + hook.onTick(); + assertEquals(1, hook.getCurrentTick()); + assertEquals(ImmutableList.of(0), ticks); + + hook.onTick(); + assertEquals(2, hook.getCurrentTick()); + assertEquals(ImmutableList.of(0, 1), ticks); + + hook.removeCallback(callback); + + hook.onTick(); + assertEquals(3, hook.getCurrentTick()); + assertEquals(ImmutableList.of(0, 1), ticks); + } + +} diff --git a/spark-common/src/test/java/me/lucko/spark/common/tick/TickReporterTest.java b/spark-common/src/test/java/me/lucko/spark/common/tick/TickReporterTest.java new file mode 100644 index 0000000..f7402c5 --- /dev/null +++ b/spark-common/src/test/java/me/lucko/spark/common/tick/TickReporterTest.java @@ -0,0 +1,94 @@ +/* + * This file is part of spark. + * + * Copyright (c) lucko (Luck) <luck@lucko.me> + * Copyright (c) contributors + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +package me.lucko.spark.common.tick; + +import com.google.common.collect.ImmutableList; +import org.junit.jupiter.api.Test; + +import java.util.ArrayList; +import java.util.List; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertTrue; + +public class TickReporterTest { + + @Test + public void testAbstractReporter() { + AbstractTickReporter reporter = new AbstractTickReporter() { + @Override + public void start() { + + } + + @Override + public void close() { + + } + }; + + List<Double> durations = new ArrayList<>(); + TickReporter.Callback callback = durations::add; + + reporter.addCallback(callback); + + reporter.onTick(1.0); + assertEquals(ImmutableList.of(1.0), durations); + + reporter.onTick(2.0); + assertEquals(ImmutableList.of(1.0, 2.0), durations); + + reporter.removeCallback(callback); + + reporter.onTick(3.0); + assertEquals(ImmutableList.of(1.0, 2.0), durations); + } + + @Test + public void testSimpleReporter() { + SimpleTickReporter reporter = new SimpleTickReporter() { + @Override + public void start() { + + } + }; + + List<Double> durations = new ArrayList<>(); + TickReporter.Callback callback = durations::add; + + reporter.addCallback(callback); + + reporter.onStart(); + assertEquals(0, durations.size()); + + try { + Thread.sleep(10); + } catch (InterruptedException e) { + // ignore + } + + reporter.onEnd(); + + assertEquals(1, durations.size()); + assertTrue(durations.get(0) > 0); + } + +} diff --git a/spark-common/src/test/java/me/lucko/spark/common/util/MethodDisambiguatorTest.java b/spark-common/src/test/java/me/lucko/spark/common/util/MethodDisambiguatorTest.java index f0bea8f..ad2f1e1 100644 --- a/spark-common/src/test/java/me/lucko/spark/common/util/MethodDisambiguatorTest.java +++ b/spark-common/src/test/java/me/lucko/spark/common/util/MethodDisambiguatorTest.java @@ -20,9 +20,9 @@ package me.lucko.spark.common.util; -import me.lucko.spark.test.TestClass; import me.lucko.spark.common.util.MethodDisambiguator.MethodDescription; import me.lucko.spark.common.util.classfinder.FallbackClassFinder; +import me.lucko.spark.test.TestClass; import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.CsvSource; import org.junit.jupiter.params.provider.ValueSource; diff --git a/spark-fabric/src/main/java/me/lucko/spark/fabric/FabricWorldInfoProvider.java b/spark-fabric/src/main/java/me/lucko/spark/fabric/FabricWorldInfoProvider.java index eae9c86..5486cc2 100644 --- a/spark-fabric/src/main/java/me/lucko/spark/fabric/FabricWorldInfoProvider.java +++ b/spark-fabric/src/main/java/me/lucko/spark/fabric/FabricWorldInfoProvider.java @@ -21,7 +21,6 @@ package me.lucko.spark.fabric; import it.unimi.dsi.fastutil.longs.Long2ObjectOpenHashMap; -import java.lang.reflect.Method; import me.lucko.spark.common.platform.world.AbstractChunkInfo; import me.lucko.spark.common.platform.world.CountMap; import me.lucko.spark.common.platform.world.WorldInfoProvider; @@ -44,6 +43,7 @@ import net.minecraft.world.entity.ClientEntityManager; import net.minecraft.world.entity.EntityIndex; import net.minecraft.world.entity.EntityLookup; +import java.lang.reflect.Method; import java.util.HashMap; import java.util.List; diff --git a/spark-neoforge/src/main/java/me/lucko/spark/neoforge/NeoForgeWorldInfoProvider.java b/spark-neoforge/src/main/java/me/lucko/spark/neoforge/NeoForgeWorldInfoProvider.java index d172ecf..96a90c2 100644 --- a/spark-neoforge/src/main/java/me/lucko/spark/neoforge/NeoForgeWorldInfoProvider.java +++ b/spark-neoforge/src/main/java/me/lucko/spark/neoforge/NeoForgeWorldInfoProvider.java @@ -21,7 +21,6 @@ package me.lucko.spark.neoforge; import it.unimi.dsi.fastutil.longs.Long2ObjectOpenHashMap; -import java.lang.reflect.Method; import me.lucko.spark.common.platform.world.AbstractChunkInfo; import me.lucko.spark.common.platform.world.CountMap; import me.lucko.spark.common.platform.world.WorldInfoProvider; @@ -37,10 +36,11 @@ import net.minecraft.world.level.entity.EntityLookup; import net.minecraft.world.level.entity.LevelEntityGetter; import net.minecraft.world.level.entity.PersistentEntitySectionManager; import net.minecraft.world.level.entity.TransientEntitySectionManager; +import net.neoforged.fml.ModList; +import java.lang.reflect.Method; import java.util.HashMap; import java.util.List; -import net.neoforged.fml.ModList; public abstract class NeoForgeWorldInfoProvider implements WorldInfoProvider { diff --git a/spark-paper/src/main/java/me/lucko/spark/paper/api/PaperSparkModule.java b/spark-paper/src/main/java/me/lucko/spark/paper/api/PaperSparkModule.java index e796438..ce8b74a 100644 --- a/spark-paper/src/main/java/me/lucko/spark/paper/api/PaperSparkModule.java +++ b/spark-paper/src/main/java/me/lucko/spark/paper/api/PaperSparkModule.java @@ -26,7 +26,6 @@ import org.bukkit.command.CommandSender; import java.util.Collection; import java.util.List; -import java.util.Set; import java.util.logging.Logger; /** diff --git a/spark-sponge7/src/main/java/me/lucko/spark/sponge/Sponge7WorldInfoProvider.java b/spark-sponge7/src/main/java/me/lucko/spark/sponge/Sponge7WorldInfoProvider.java index 426ad47..1ded055 100644 --- a/spark-sponge7/src/main/java/me/lucko/spark/sponge/Sponge7WorldInfoProvider.java +++ b/spark-sponge7/src/main/java/me/lucko/spark/sponge/Sponge7WorldInfoProvider.java @@ -34,7 +34,6 @@ import org.spongepowered.api.world.World; import java.util.ArrayList; import java.util.HashMap; import java.util.List; -import java.util.Map; public class Sponge7WorldInfoProvider implements WorldInfoProvider { private final Server server; |