Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -384,7 +384,7 @@ internal object BlockListener : MultiListener {
} else {
Rebar.logger.severe("Error when handling block(${block.key}, ${block.block.location}) ticking: ${e.localizedMessage}")
}
e.printStackTrace()
if (RebarConfig.FULL_ERROR_STACK_TRACES) e.printStackTrace()
blockErrMap[block] = blockErrMap[block]?.plus(1) ?: 1
if (blockErrMap[block]!! > RebarConfig.ALLOWED_BLOCK_ERRORS) {
BlockStorage.makePhantom(block)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,12 @@ object RebarConfig {
@JvmField
val ALLOWED_ENTITY_ERRORS = config.getOrThrow("allowed-entity-errors", ConfigAdapter.INTEGER)

/**
* Mutable so that they can be disabled/enabled live for things like tests, etc.
*/
@JvmField
var FULL_ERROR_STACK_TRACES = config.getOrThrow("full-error-stack-traces", ConfigAdapter.BOOLEAN)

@JvmField
val FLUID_TICK_INTERVAL = config.getOrThrow("fluid-tick-interval", ConfigAdapter.INTEGER)

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,17 +14,17 @@ internal object EntityListener : MultiListener {
@JvmSynthetic
internal fun logEventHandleErr(event: Event, e: Exception, entity: RebarEntity<*>) {
Rebar.logger.severe("Error when handling entity(${entity.key}, ${entity.uuid}, ${entity.entity.location}) event handler ${event.javaClass.simpleName}: ${e.localizedMessage}")
e.printStackTrace()
if (RebarConfig.FULL_ERROR_STACK_TRACES) e.printStackTrace()
entityErrMap[entity.uuid] = entityErrMap[entity.uuid]?.plus(1) ?: 1
if (entityErrMap[entity.uuid]!! > RebarConfig.ALLOWED_ENTITY_ERRORS) {
entity.entity.remove()
}
}

@JvmSynthetic
internal fun logEventHandleErrTicking(e: Exception, entity: RebarEntity<*>) {
internal fun logTickingErr(e: Exception, entity: RebarEntity<*>) {
Rebar.logger.severe("Error when handling ticking entity(${entity.key}, ${entity.uuid}, ${entity.entity.location}): ${e.localizedMessage}")
e.printStackTrace()
if (RebarConfig.FULL_ERROR_STACK_TRACES) e.printStackTrace()
entityErrMap[entity.uuid] = entityErrMap[entity.uuid]?.plus(1) ?: 1
if (entityErrMap[entity.uuid]!! > RebarConfig.ALLOWED_ENTITY_ERRORS) {
entity.entity.remove()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -132,7 +132,7 @@ interface RebarTickingEntity {
tickingEntity.tick()
} catch (e: Exception) {
withContext(Rebar.mainThreadDispatcher) {
EntityListener.logEventHandleErrTicking(e, tickingEntity as RebarEntity<*>)
EntityListener.logTickingErr(e, tickingEntity as RebarEntity<*>)
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -127,6 +127,7 @@ class GameTest(
} catch (e: Throwable) {
result = GameTestFailException(gameTest, "An exception occurred", e)
}
gameTest.config.cleanup.accept(gameTest)
for (entity in gameTest.world.getNearbyEntities(gameTest.boundingBox)) {
if (entity !is Player) {
entity.remove()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ class GameTestConfig(
private val key: NamespacedKey,
val size: Int,
val setUp: Consumer<GameTest>,
val cleanup: Consumer<GameTest>,
val delayTicks: Long,
val timeoutTicks: Long,
val positionOverride: BlockPosition?
Expand All @@ -31,6 +32,7 @@ class GameTestConfig(
class Builder(val key: NamespacedKey) {
private var size by Delegates.notNull<Int>()
private var setUp: Consumer<GameTest> = Consumer {}
private var cleanup: Consumer<GameTest> = Consumer {}
private var delayTicks = 0L
private var timeoutTicks = 5L * 60 * 20
private var positionOverride: BlockPosition? = null
Expand All @@ -47,6 +49,13 @@ class GameTestConfig(
*/
fun setUp(setUp: Consumer<GameTest>): Builder = apply { this.setUp = setUp }

/**
* Runs after test ends
*/
fun cleanup(cleanup: Consumer<GameTest>): Builder = apply {
this.cleanup = cleanup
}

/**
* Delay in ticks before the test starts. Defaults to 0.
*/
Expand All @@ -62,7 +71,7 @@ class GameTestConfig(
*/
fun positionOverride(position: BlockPosition): Builder = apply { this.positionOverride = position }

fun build() = GameTestConfig(key, size, setUp, delayTicks, timeoutTicks, positionOverride)
fun build() = GameTestConfig(key, size, setUp, cleanup, delayTicks, timeoutTicks, positionOverride)
}

/**
Expand Down
3 changes: 3 additions & 0 deletions rebar/src/main/resources/config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,9 @@ allowed-block-errors: 5
# The number of errors a entity can throw before it is disabled
allowed-entity-errors: 5

# When a block or entity errors, should the full error stack trace be printed in the console or just the error message & context?
full-error-stack-traces: true

# The interval (in Minecraft ticks) between fluid network ticks
fluid-tick-interval: 5

Expand Down
19 changes: 10 additions & 9 deletions test/src/main/java/io/github/pylonmc/rebar/test/RebarTest.java
Original file line number Diff line number Diff line change
@@ -1,12 +1,13 @@
package io.github.pylonmc.rebar.test;

import io.github.pylonmc.rebar.addon.RebarAddon;
import io.github.pylonmc.rebar.config.RebarConfig;
import io.github.pylonmc.rebar.test.base.Test;
import io.github.pylonmc.rebar.test.base.TestResult;
import io.github.pylonmc.rebar.test.block.Blocks;
import io.github.pylonmc.rebar.test.entity.Entities;
import io.github.pylonmc.rebar.test.fluid.Fluids;
import io.github.pylonmc.rebar.test.item.Items;
import io.github.pylonmc.rebar.test.block.TestBlocks;
import io.github.pylonmc.rebar.test.entity.TestEntities;
import io.github.pylonmc.rebar.test.fluid.TestFluids;
import io.github.pylonmc.rebar.test.item.TestItems;
import io.github.pylonmc.rebar.test.test.block.*;
import io.github.pylonmc.rebar.test.test.entity.EntityEventErrorTest;
import io.github.pylonmc.rebar.test.test.entity.EntityStorageChunkReloadTest;
Expand Down Expand Up @@ -112,10 +113,10 @@ private static void run() {

try {
// TODO get rid of these and convert registration to static blocks
Blocks.register();
Items.register();
Entities.register();
Fluids.register();
TestBlocks.register();
TestItems.register();
TestEntities.register();
TestFluids.register();
} catch (Exception e) {
instance().getLogger().severe("Failed to set up tests");
e.printStackTrace();
Expand All @@ -130,7 +131,7 @@ private static void run() {
List<Test> tests = TestUtil.runSync(RebarTest::initTests).join();

List<TestResult> results = tests.stream()
.map(Test::run)
.map(Test::start)
.toList();

List<NamespacedKey> succeeded = results.stream()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,11 @@


public interface Test {
default TestResult start() {
RebarTest.instance().getLogger().log(Level.INFO, "Test %s started".formatted(getKey()));
return run();
}

TestResult run();

default NamespacedKey getKey() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,9 @@
import org.bukkit.NamespacedKey;


public final class Blocks {
public final class TestBlocks {

private Blocks() {}
private TestBlocks() {}

public static final NamespacedKey SIMPLE_BLOCK_KEY = RebarTest.key("simple_block");

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,8 +30,8 @@ public TestRebarSimpleMultiblock(Block block, PersistentDataContainer pdc) {
@Override
public @NotNull Map<Vector3i, MultiblockComponent> getComponents() {
return Map.of(
new Vector3i(1, 1, 4), MultiblockComponent.of(Blocks.SIMPLE_BLOCK_KEY),
new Vector3i(2, -1, 0), MultiblockComponent.of(Blocks.SIMPLE_BLOCK_KEY)
new Vector3i(1, 1, 4), MultiblockComponent.of(TestBlocks.SIMPLE_BLOCK_KEY),
new Vector3i(2, -1, 0), MultiblockComponent.of(TestBlocks.SIMPLE_BLOCK_KEY)
);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
import io.github.pylonmc.rebar.block.RebarBlock;
import io.github.pylonmc.rebar.block.base.RebarTickingBlock;
import io.github.pylonmc.rebar.block.context.BlockCreateContext;
import io.github.pylonmc.rebar.config.RebarConfig;
import io.github.pylonmc.rebar.test.RebarTest;
import org.bukkit.NamespacedKey;
import org.bukkit.block.Block;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
import io.github.pylonmc.rebar.fluid.RebarFluid;
import io.github.pylonmc.rebar.fluid.VirtualFluidPoint;
import io.github.pylonmc.rebar.test.RebarTest;
import io.github.pylonmc.rebar.test.fluid.Fluids;
import io.github.pylonmc.rebar.test.fluid.TestFluids;
import lombok.Getter;
import org.bukkit.NamespacedKey;
import org.bukkit.block.Block;
Expand Down Expand Up @@ -63,8 +63,8 @@ public double getAmount() {

private RebarFluid getFluidType() {
return Map.of(
LAVA_CONSUMER_KEY, Fluids.LAVA,
WATER_CONSUMER_KEY, Fluids.WATER
LAVA_CONSUMER_KEY, TestFluids.LAVA,
WATER_CONSUMER_KEY, TestFluids.WATER
).get(getKey());
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
import io.github.pylonmc.rebar.fluid.RebarFluid;
import io.github.pylonmc.rebar.fluid.VirtualFluidPoint;
import io.github.pylonmc.rebar.test.RebarTest;
import io.github.pylonmc.rebar.test.fluid.Fluids;
import io.github.pylonmc.rebar.test.fluid.TestFluids;
import kotlin.Pair;
import lombok.Getter;
import org.bukkit.NamespacedKey;
Expand Down Expand Up @@ -72,8 +72,8 @@ public void onFluidRemoved(@NotNull RebarFluid fluid, double amount) {

private RebarFluid getFluidType() {
return Map.of(
LAVA_PRODUCER_KEY, Fluids.LAVA,
WATER_PRODUCER_KEY, Fluids.WATER
LAVA_PRODUCER_KEY, TestFluids.LAVA,
WATER_PRODUCER_KEY, TestFluids.WATER
).get(getKey());
}
}
Original file line number Diff line number Diff line change
@@ -1,18 +1,20 @@
package io.github.pylonmc.rebar.test.entity;

import io.github.pylonmc.rebar.entity.RebarEntity;
import io.github.pylonmc.rebar.entity.base.RebarDamageableEntity;
import io.github.pylonmc.rebar.entity.base.RebarInteractEntity;
import io.github.pylonmc.rebar.test.RebarTest;
import org.bukkit.Location;
import org.bukkit.NamespacedKey;
import org.bukkit.entity.LivingEntity;
import org.bukkit.entity.Skeleton;
import org.bukkit.event.EventPriority;
import org.bukkit.event.entity.EntityDamageEvent;
import org.bukkit.event.player.PlayerInteractEntityEvent;
import org.jetbrains.annotations.NotNull;


public class EntityEventError extends RebarEntity<LivingEntity> implements RebarInteractEntity {
public class EntityEventError extends RebarEntity<LivingEntity> implements RebarDamageableEntity {

public static final NamespacedKey KEY = RebarTest.key("entity_event_error");

Expand All @@ -26,7 +28,7 @@ public EntityEventError(@NotNull LivingEntity entity) {
}

@Override
public void onInteract(@NotNull PlayerInteractEntityEvent event, @NotNull EventPriority priority) {
public void onDamage(@NotNull EntityDamageEvent event, @NotNull EventPriority priority) {
throw new RuntimeException("This exception is thrown as part of a test");
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,9 @@
import org.bukkit.entity.LivingEntity;


public final class Entities {
public final class TestEntities {

private Entities() {}
private TestEntities() {}

public static void register() {
RebarEntity.register(SimpleEntity.KEY, LivingEntity.class, SimpleEntity.class);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
import org.bukkit.Material;


public class Fluids {
public class TestFluids {

public static final RebarFluid WATER = new RebarFluid(RebarTest.key("water"), Material.CYAN_CONCRETE);
public static final RebarFluid LAVA = new RebarFluid(RebarTest.key("lava"), Material.ORANGE_CONCRETE)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,15 +3,17 @@
import io.github.pylonmc.rebar.item.RebarItem;
import io.github.pylonmc.rebar.item.builder.ItemStackBuilder;
import io.github.pylonmc.rebar.test.RebarTest;
import io.github.pylonmc.rebar.test.block.TestBlocks;
import io.github.pylonmc.rebar.test.block.TestRebarSimpleMultiblock;
import io.papermc.paper.datacomponent.DataComponentTypes;
import net.kyori.adventure.text.Component;
import org.bukkit.Material;
import org.bukkit.NamespacedKey;
import org.bukkit.inventory.ItemStack;

public final class Items {
public final class TestItems {

private Items() {}
private TestItems() {}

public static final NamespacedKey STICKY_STICK_KEY = RebarTest.key("sticky_stick");
public static final ItemStack STICKY_STICK_STACK = ItemStackBuilder.rebar(Material.STICK, STICKY_STICK_KEY)
Expand All @@ -21,5 +23,7 @@ private Items() {}
public static void register() {
RebarItem.register(RebarItem.class, STICKY_STICK_STACK);
RebarItem.register(OminousBlazePower.class, OminousBlazePower.STACK);
RebarItem.register(RebarItem.class, ItemStackBuilder.rebar(Material.AMETHYST_BLOCK, TestBlocks.SIMPLE_BLOCK_KEY).build());
RebarItem.register(RebarItem.class, ItemStackBuilder.rebar(Material.AMETHYST_BLOCK, TestRebarSimpleMultiblock.KEY).build());
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -19,13 +19,18 @@ public BlockEventErrorTest(){
super(new GameTestConfig.Builder(new NamespacedKey(RebarTest.instance(), "block_event_error_test"))
.size(1)
.setUp(test -> {
RebarConfig.FULL_ERROR_STACK_TRACES = false;
Block block = BlockStorage.placeBlock(test.location(), BlockEventError.KEY).getBlock();
Entity theRinger = test.location().getWorld().spawn(test.location().clone().add(1, 0, 0), Skeleton.class);
for(int i = 0; i < RebarConfig.ALLOWED_BLOCK_ERRORS + 1; i++){
new BellRingEvent(block, BlockFace.EAST, theRinger).callEvent();
}
test.succeedWhen(() -> BlockStorage.get(block) instanceof PhantomBlock);
})
.cleanup(test -> {
BlockStorage.breakBlock(test.location());
RebarConfig.FULL_ERROR_STACK_TRACES = true;
})
.build()
);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
import io.github.pylonmc.rebar.gametest.GameTestConfig;
import io.github.pylonmc.rebar.test.RebarTest;
import io.github.pylonmc.rebar.test.base.GameTest;
import io.github.pylonmc.rebar.test.block.Blocks;
import io.github.pylonmc.rebar.test.block.TestBlocks;
import org.bukkit.NamespacedKey;

import static org.assertj.core.api.Assertions.assertThat;
Expand All @@ -16,7 +16,7 @@ public BlockStorageAddTest() {
super(new GameTestConfig.Builder(new NamespacedKey(RebarTest.instance(), "block_storage_add_test"))
.size(1)
.setUp((test) -> {
BlockStorage.placeBlock(test.location(), Blocks.SIMPLE_BLOCK_KEY);
BlockStorage.placeBlock(test.location(), TestBlocks.SIMPLE_BLOCK_KEY);

RebarBlock rebarBlock = BlockStorage.get(test.location());

Expand All @@ -26,6 +26,8 @@ public BlockStorageAddTest() {

assertThat(BlockStorage.getAs(RebarBlock.class, test.location()))
.isNotNull();

BlockStorage.breakBlock(test.location());
})
.build());
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
import io.github.pylonmc.rebar.block.RebarBlock;
import io.github.pylonmc.rebar.block.RebarBlockSchema;
import io.github.pylonmc.rebar.test.base.AsyncTest;
import io.github.pylonmc.rebar.test.block.Blocks;
import io.github.pylonmc.rebar.test.block.TestBlocks;
import io.github.pylonmc.rebar.test.util.TestUtil;
import org.bukkit.Chunk;
import org.bukkit.block.Block;
Expand All @@ -18,7 +18,7 @@ public class BlockStorageFilledChunkTest extends AsyncTest {

@Override
public void test() {
Chunk chunk = TestUtil.getRandomChunk(true).join();
Chunk chunk = TestUtil.getRandomChunk(false).join();

List<Block> blocks = new ArrayList<>();
for (int x = 0; x < 16; x++) {
Expand All @@ -29,10 +29,9 @@ public void test() {
}
}

TestUtil.loadChunk(chunk).join();
TestUtil.runSync(() -> {
for (Block block : blocks) {
BlockStorage.placeBlock(block, Blocks.SIMPLE_BLOCK_KEY);
BlockStorage.placeBlock(block, TestBlocks.SIMPLE_BLOCK_KEY);
}
}).join();
TestUtil.unloadChunk(chunk).join();
Expand All @@ -46,7 +45,7 @@ public void test() {

assertThat(rebarBlock.getSchema())
.extracting(RebarBlockSchema::getKey)
.isEqualTo(Blocks.SIMPLE_BLOCK_KEY);
.isEqualTo(TestBlocks.SIMPLE_BLOCK_KEY);
}
TestUtil.unloadChunk(chunk).join();
}
Expand Down
Loading
Loading