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
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)