Skip to content
This repository was archived by the owner on Oct 4, 2024. It is now read-only.

Commit faa9512

Browse files
committed
Implement logging test failures, and failing the gradle task
1 parent 75bc33a commit faa9512

File tree

7 files changed

+91
-33
lines changed

7 files changed

+91
-33
lines changed

src/integrationTest/java/io/github/opencubicchunks/cubicchunks/test/IntegrationTests.java

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@ public static final class LightingIntegrationTest {
4141
private TestState state = TestState.NONE;
4242
private boolean finished = false;
4343
private BlockPos failurePos = null;
44+
private Throwable throwable = null;
4445

4546
public LightingIntegrationTest(
4647
String testName, long seed,
@@ -67,6 +68,10 @@ public Optional<BlockPos> getFailurePos() {
6768
return Optional.ofNullable(this.failurePos);
6869
}
6970

71+
public Optional<Throwable> getThrown() {
72+
return Optional.ofNullable(this.throwable);
73+
}
74+
7075
@Override
7176
public String toString() {
7277
return "LightingIntegrationTest[" +
@@ -82,11 +87,10 @@ public TestContext(ServerLevel level) {
8287
this.level = level;
8388
}
8489

85-
public void fail() {
86-
if (!finished) {
87-
finished = true;
88-
state = TestState.FAIL;
89-
}
90+
public void fail(Throwable t) {
91+
finished = true;
92+
state = TestState.FAIL;
93+
throwable = t;
9094
}
9195

9296
public void pass() {

src/integrationTest/java/io/github/opencubicchunks/cubicchunks/test/mixin/server/MixinMinecraftServer_TestRunner.java

Lines changed: 30 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
package io.github.opencubicchunks.cubicchunks.test.mixin.server;
22

33
import java.io.IOException;
4+
import java.io.PrintWriter;
5+
import java.io.StringWriter;
46
import java.io.UncheckedIOException;
57
import java.nio.file.Files;
68
import java.nio.file.Path;
@@ -18,10 +20,9 @@
1820
import io.github.opencubicchunks.cubicchunks.test.IntegrationTests;
1921
import io.github.opencubicchunks.cubicchunks.test.LevelTestRunner;
2022
import io.github.opencubicchunks.cubicchunks.test.ServerTestRunner;
23+
import io.github.opencubicchunks.cubicchunks.test.util.IndentingStringBuilder;
2124
import it.unimi.dsi.fastutil.Pair;
2225
import it.unimi.dsi.fastutil.objects.ObjectObjectImmutablePair;
23-
import net.minecraft.CrashReport;
24-
import net.minecraft.ReportedException;
2526
import net.minecraft.core.BlockPos;
2627
import net.minecraft.core.Holder;
2728
import net.minecraft.core.Registry;
@@ -145,25 +146,46 @@ private void unloadLevelWhenTestFinish(BooleanSupplier hasTimeLeft, CallbackInfo
145146
}
146147

147148
if (this.incompleteTests.isEmpty()) {
148-
if (IntegrationTests.FREEZE_FAILING_WORLDS && !failedTests.isEmpty()) {
149+
if (IntegrationTests.FREEZE_FAILING_WORLDS && !this.failedTests.isEmpty()) {
149150
if (!this.isFrozen) {
150151
this.isFrozen = true;
151152
CubicChunks.LOGGER.info("Tests complete! Holding failing worlds open");
152153
}
153154
} else {
154155
CubicChunks.LOGGER.info("Tests complete! Exiting...");
155-
if (!failedTests.isEmpty()) {
156-
CrashReport crashReport = new CrashReport("Failed tests!", new Exception("Some exception"));
157-
throw new ReportedException(crashReport);
156+
this.halt(false);
157+
if (!this.failedTests.isEmpty()) {
158+
CubicChunks.LOGGER.warn(testFailureInformation(this.failedTests));
159+
System.exit(-1);
158160
} else {
159161
CubicChunks.LOGGER.info("No failed tests!");
162+
System.exit(0);
160163
}
161-
162-
this.halt(false);
163164
}
164165
}
165166
}
166167

168+
private static String testFailureInformation(Collection<IntegrationTests.LightingIntegrationTest> failedTests) {
169+
IndentingStringBuilder s = new IndentingStringBuilder(4)
170+
.append("Failed Tests: ").append(failedTests.size()).appendNewLine().appendNewLine();
171+
172+
for (IntegrationTests.LightingIntegrationTest test : failedTests) {
173+
s.append("Failure: ").append(test.testName).appendNewLine().indent();
174+
175+
Optional<Throwable> thrown = test.getThrown();
176+
thrown.ifPresent(throwable -> {
177+
StringWriter sw = new StringWriter();
178+
PrintWriter pw = new PrintWriter(sw);
179+
throwable.printStackTrace(pw);
180+
181+
s.append(sw)
182+
.unIndent().appendNewLine();
183+
});
184+
}
185+
186+
return s.toString();
187+
}
188+
167189
/**
168190
* @author NotStirred
169191
* @reason By default, the player is spawned in the overworld. Instead spawn the player in the first error location, or some valid world
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
package io.github.opencubicchunks.cubicchunks.test.mixin.server;
2+
3+
import net.minecraft.server.level.ServerLevel;
4+
import net.minecraft.util.ProgressListener;
5+
import org.jetbrains.annotations.Nullable;
6+
import org.spongepowered.asm.mixin.Mixin;
7+
import org.spongepowered.asm.mixin.Overwrite;
8+
9+
@Mixin(ServerLevel.class)
10+
public class MixinServerLevel_NoSave {
11+
/**
12+
* @author NotStirred
13+
* @reason Integration tests shouldn't save worlds
14+
*/
15+
@Overwrite
16+
public void save(@Nullable ProgressListener progress, boolean flush, boolean skipSave) {
17+
18+
}
19+
}

src/integrationTest/java/io/github/opencubicchunks/cubicchunks/test/mixin/server/MixinServerLevel_TestRunner.java

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,11 @@ public class MixinServerLevel_TestRunner implements LevelTestRunner {
2323
this.context = integrationTest.new TestContext((ServerLevel) (Object) this);
2424
this.testStarted = true;
2525

26-
this.test.setup.accept(this.context);
26+
try {
27+
this.test.setup.accept(this.context);
28+
} catch (Throwable t) {
29+
this.context.fail(t);
30+
}
2731
}
2832

2933
@Override public boolean testFinished() {
@@ -49,7 +53,11 @@ private void tickTest(BooleanSupplier b, CallbackInfo ci) {
4953
}
5054

5155
if (this.test != null && !this.test.isFinished()) {
52-
this.test.tick.accept(this.context);
56+
try {
57+
this.test.tick.accept(this.context);
58+
} catch (Throwable t) {
59+
this.context.fail(t);
60+
}
5361
}
5462
}
5563

@@ -58,7 +66,11 @@ private void handleTestFinished(BooleanSupplier b, CallbackInfo ci) {
5866
if (this.test != null) {
5967
if (!this.teardownComplete && this.test.isFinished() && this.test.getState() != IntegrationTests.TestState.FAIL) {
6068
this.teardownComplete = true;
61-
this.test.teardown.accept(this.context);
69+
try {
70+
this.test.teardown.accept(this.context);
71+
} catch (Throwable t) {
72+
this.context.fail(t);
73+
}
6274
}
6375
}
6476
}

src/integrationTest/java/io/github/opencubicchunks/cubicchunks/test/tests/PlaceholderTests.java

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,6 @@
77
import io.github.opencubicchunks.cubicchunks.server.level.CubicDistanceManager;
88
import io.github.opencubicchunks.cubicchunks.test.IntegrationTests.LightingIntegrationTest;
99
import io.github.opencubicchunks.cubicchunks.world.level.chunk.CubeStatus;
10-
import net.minecraft.core.BlockPos;
1110
import net.minecraft.server.level.TicketType;
1211
import net.minecraft.util.Unit;
1312
import net.minecraft.world.level.chunk.ChunkStatus;
@@ -46,8 +45,7 @@ public static void register(Collection<LightingIntegrationTest> lightingTests) {
4645
context -> {
4746
System.out.println("Test 1 tick");
4847
if (ticksPassed.getAndIncrement() == 30) {
49-
context.fail();
50-
context.setFailurePos(new BlockPos(50, 50, 50));
48+
context.pass();
5149
}
5250
},
5351
context -> {

src/integrationTest/resources/cubicchunks.mixins.integration_test.json

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,11 +17,13 @@
1717
"server.MixinDedicatedServer_DisableNetwork",
1818
"server.MixinDistanceManager_PreventPlayerTickets",
1919
"server.MixinLevelRenderer_NoLightUpdates",
20+
"server.MixinMain",
2021
"server.MixinMinecraftServer_TestRunner",
2122
"server.MixinPlayerLists_SetSpectatorOnJoin",
2223
"server.MixinPlayerLists_TestRenderDistance",
2324
"server.MixinServerChunkCache_NoSave",
2425
"server.MixinServerGamePacketListenerImpl_NoChunkLoad",
26+
"server.MixinServerLevel_NoSave",
2527
"server.MixinServerLevel_TestRunner",
2628
"server.MixinServerPlayer_NoChunkLoad",
2729
"server.MixinServerPlayer_NoTick",

src/main/java/io/github/opencubicchunks/cubicchunks/mixin/core/common/ticket/MixinDistanceManager.java

Lines changed: 15 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
import com.google.common.collect.ImmutableList;
77
import com.google.common.collect.ImmutableSet;
88
import com.google.common.collect.Sets;
9+
import io.github.opencubicchunks.cc_core.annotation.UsedFromASM;
910
import io.github.opencubicchunks.cc_core.api.CubePos;
1011
import io.github.opencubicchunks.cc_core.api.CubicConstants;
1112
import io.github.opencubicchunks.cc_core.utils.Coords;
@@ -51,20 +52,20 @@ public abstract class MixinDistanceManager implements CubicDistanceManager, Vert
5152
private boolean isCubic;
5253

5354
// fields below used from ASM
54-
final Long2ObjectMap<ObjectSet<ServerPlayer>> playersPerCube = new Long2ObjectOpenHashMap<>();
55-
final Long2ObjectOpenHashMap<SortedArraySet<Ticket<?>>> cubeTickets = new Long2ObjectOpenHashMap<>();
56-
private final CubeTicketTracker cubeTicketTracker = new CubeTicketTracker(this);
57-
58-
private final FixedPlayerDistanceCubeTracker naturalSpawnCubeCounter = new FixedPlayerDistanceCubeTracker(this, 8 / CubicConstants.DIAMETER_IN_SECTIONS);
59-
private final CubeTickingTracker tickingCubeTicketsTracker = new CubeTickingTracker();
60-
private final CubicPlayerTicketTracker cubicPlayerTicketManager = new CubicPlayerTicketTracker(this, MathUtil.ceilDiv(33, CubicConstants.DIAMETER_IN_SECTIONS));
61-
final Set<ChunkHolder> cubesToUpdateFutures = Sets.newHashSet();
62-
CubeTaskPriorityQueueSorter cubeTicketThrottler;
63-
ProcessorHandle<CubeTaskPriorityQueueSorter.Message<Runnable>> cubeTicketThrottlerInput;
64-
ProcessorHandle<CubeTaskPriorityQueueSorter.Release> cubeTicketThrottlerReleaser;
65-
final LongSet cubeTicketsToRelease = new LongOpenHashSet();
66-
67-
private long cubeTicketTickCounter;
55+
@UsedFromASM final Long2ObjectMap<ObjectSet<ServerPlayer>> playersPerCube = new Long2ObjectOpenHashMap<>();
56+
@UsedFromASM final Long2ObjectOpenHashMap<SortedArraySet<Ticket<?>>> cubeTickets = new Long2ObjectOpenHashMap<>();
57+
@UsedFromASM private final CubeTicketTracker cubeTicketTracker = new CubeTicketTracker(this);
58+
59+
@UsedFromASM private final FixedPlayerDistanceCubeTracker naturalSpawnCubeCounter = new FixedPlayerDistanceCubeTracker(this, 8 / CubicConstants.DIAMETER_IN_SECTIONS);
60+
@UsedFromASM private final CubeTickingTracker tickingCubeTicketsTracker = new CubeTickingTracker();
61+
@UsedFromASM private final CubicPlayerTicketTracker cubicPlayerTicketManager = new CubicPlayerTicketTracker(this, MathUtil.ceilDiv(33, CubicConstants.DIAMETER_IN_SECTIONS));
62+
@UsedFromASM final Set<ChunkHolder> cubesToUpdateFutures = Sets.newHashSet();
63+
@UsedFromASM CubeTaskPriorityQueueSorter cubeTicketThrottler;
64+
@UsedFromASM ProcessorHandle<CubeTaskPriorityQueueSorter.Message<Runnable>> cubeTicketThrottlerInput;
65+
@UsedFromASM ProcessorHandle<CubeTaskPriorityQueueSorter.Release> cubeTicketThrottlerReleaser;
66+
@UsedFromASM final LongSet cubeTicketsToRelease = new LongOpenHashSet();
67+
68+
@UsedFromASM private long cubeTicketTickCounter;
6869

6970
@Shadow abstract void addTicket(long position, Ticket<?> ticket);
7071

0 commit comments

Comments
 (0)