diff --git a/buildNumber.properties b/buildNumber.properties
index 262667a2..2d1d14b9 100644
--- a/buildNumber.properties
+++ b/buildNumber.properties
@@ -1,3 +1,3 @@
#maven.buildNumber.plugin properties file
-#Mon Aug 19 09:32:22 EDT 2024
-buildNumber=260
+#Mon Aug 19 12:41:14 EDT 2024
+buildNumber=276
diff --git a/docs/src/progress/renderertodo.md b/docs/src/progress/renderertodo.md
index 56a400f4..380b9a06 100644
--- a/docs/src/progress/renderertodo.md
+++ b/docs/src/progress/renderertodo.md
@@ -612,6 +612,8 @@ Small oit shader work
(08/19/2024)
Disable cloud ring
+Undo oit shader work to fix build pipeline
+Testing rearchitecting
# TODO
diff --git a/pom.xml b/pom.xml
index 6f114c08..df9902e5 100644
--- a/pom.xml
+++ b/pom.xml
@@ -290,6 +290,9 @@
natives-linux
+
+
+ fast
@@ -377,6 +380,9 @@
natives-windows
+
+
+ fast
@@ -406,6 +412,21 @@
+
+
+
+
+
+
+ integration
+
+
+ fast,integration
+
+
+
+
+
@@ -417,6 +438,8 @@
+
+
org.apache.maven.plugins
maven-shade-plugin
@@ -439,6 +462,9 @@
+
+
+
org.codehaus.mojo
exec-maven-plugin
@@ -488,6 +514,9 @@
-->
+
+
+
org.codehaus.mojo
buildnumber-maven-plugin
diff --git a/src/test/java/annotations/FastTest.java b/src/test/java/annotations/FastTest.java
new file mode 100644
index 00000000..c66b9a82
--- /dev/null
+++ b/src/test/java/annotations/FastTest.java
@@ -0,0 +1,26 @@
+package annotations;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.Target;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.ElementType;
+
+import java.util.concurrent.TimeUnit;
+
+import org.junit.jupiter.api.Tag;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.Timeout;
+import org.junit.jupiter.api.Timeout.ThreadMode;
+
+/**
+ * A fast test that does not depend on setup/shutdown -- A unit test
+ */
+
+@Target({ ElementType.TYPE, ElementType.METHOD })
+@Retention(RetentionPolicy.RUNTIME)
+@Tag("fast")
+@Test
+@Timeout( value = 20, unit = TimeUnit.MILLISECONDS, threadMode = ThreadMode.SAME_THREAD )
+public @interface FastTest {
+
+}
diff --git a/src/test/java/annotations/IntegrationSetup.java b/src/test/java/annotations/IntegrationSetup.java
new file mode 100644
index 00000000..3998f62d
--- /dev/null
+++ b/src/test/java/annotations/IntegrationSetup.java
@@ -0,0 +1,21 @@
+package annotations;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Tag;
+
+
+/**
+ * Used to flag work that should be done before each integration test
+ */
+@Target({ ElementType.TYPE, ElementType.METHOD })
+@Retention(RetentionPolicy.RUNTIME)
+@BeforeEach
+@Tag("integration")
+public @interface IntegrationSetup {
+
+}
diff --git a/src/test/java/annotations/IntegrationTeardown.java b/src/test/java/annotations/IntegrationTeardown.java
new file mode 100644
index 00000000..5c4e50e2
--- /dev/null
+++ b/src/test/java/annotations/IntegrationTeardown.java
@@ -0,0 +1,20 @@
+package annotations;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+import org.junit.jupiter.api.AfterEach;
+import org.junit.jupiter.api.Tag;
+
+/**
+ * Flags for work to be done tearing down after running an integration test
+ */
+@Target({ ElementType.TYPE, ElementType.METHOD })
+@Retention(RetentionPolicy.RUNTIME)
+@AfterEach
+@Tag("integration")
+public @interface IntegrationTeardown {
+
+}
diff --git a/src/test/java/annotations/IntegrationTest.java b/src/test/java/annotations/IntegrationTest.java
new file mode 100644
index 00000000..8c125369
--- /dev/null
+++ b/src/test/java/annotations/IntegrationTest.java
@@ -0,0 +1,26 @@
+package annotations;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.Target;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.ElementType;
+
+import java.util.concurrent.TimeUnit;
+
+import org.junit.jupiter.api.Tag;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.Timeout;
+import org.junit.jupiter.api.Timeout.ThreadMode;
+
+/**
+ * An integration test. Has defaults for timeout on the test
+ */
+
+@Target({ ElementType.TYPE, ElementType.METHOD })
+@Retention(RetentionPolicy.RUNTIME)
+@Tag("integration")
+@Test
+@Timeout( value = 2, unit = TimeUnit.MINUTES, threadMode = ThreadMode.SAME_THREAD )
+public @interface IntegrationTest {
+
+}
diff --git a/src/test/java/db/DBTest.java b/src/test/java/db/DBTest.java
deleted file mode 100644
index 666cd098..00000000
--- a/src/test/java/db/DBTest.java
+++ /dev/null
@@ -1,5 +0,0 @@
-package db;
-
-public class DBTest {
-
-}
diff --git a/src/test/java/entity/InventoryStateTest.java b/src/test/java/electrosphere/entity/InventoryStateTest.java
similarity index 58%
rename from src/test/java/entity/InventoryStateTest.java
rename to src/test/java/electrosphere/entity/InventoryStateTest.java
index ff64c5f1..2020e168 100644
--- a/src/test/java/entity/InventoryStateTest.java
+++ b/src/test/java/electrosphere/entity/InventoryStateTest.java
@@ -1,4 +1,4 @@
-package entity;
+package electrosphere.entity;
public class InventoryStateTest {
diff --git a/src/test/java/entity/LifeStateTest.java b/src/test/java/electrosphere/entity/LifeStateTest.java
similarity index 55%
rename from src/test/java/entity/LifeStateTest.java
rename to src/test/java/electrosphere/entity/LifeStateTest.java
index 170d56e7..730a3264 100644
--- a/src/test/java/entity/LifeStateTest.java
+++ b/src/test/java/electrosphere/entity/LifeStateTest.java
@@ -1,4 +1,4 @@
-package entity;
+package electrosphere.entity;
public class LifeStateTest {
diff --git a/src/test/java/entity/SpawningCreaturesTest.java b/src/test/java/electrosphere/entity/SpawningCreaturesTest.java
similarity index 95%
rename from src/test/java/entity/SpawningCreaturesTest.java
rename to src/test/java/electrosphere/entity/SpawningCreaturesTest.java
index 408c9c3c..e5b5c649 100644
--- a/src/test/java/entity/SpawningCreaturesTest.java
+++ b/src/test/java/electrosphere/entity/SpawningCreaturesTest.java
@@ -1,4 +1,4 @@
-package entity;
+package electrosphere.entity;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
@@ -13,6 +13,7 @@ public class SpawningCreaturesTest {
@BeforeEach
public void initEngine(){
+ LoggerInterface.initLoggers();
LoggerInterface.loggerEngine.INFO("[Test] Spawn many creatures");
Globals.RUN_CLIENT = true;
Globals.RUN_SERVER = true;
diff --git a/src/test/java/electrosphere/renderer/ui/elements/WindowIntegrationTest.java b/src/test/java/electrosphere/renderer/ui/elements/WindowIntegrationTest.java
deleted file mode 100644
index 41e0af92..00000000
--- a/src/test/java/electrosphere/renderer/ui/elements/WindowIntegrationTest.java
+++ /dev/null
@@ -1,56 +0,0 @@
-package electrosphere.renderer.ui.elements;
-
-import java.awt.image.BufferedImage;
-
-import org.junit.jupiter.api.AfterEach;
-import org.junit.jupiter.api.BeforeEach;
-import org.junit.jupiter.api.Tag;
-import org.junit.jupiter.api.Test;
-
-import electrosphere.engine.Globals;
-import electrosphere.engine.Main;
-import electrosphere.menu.WindowUtils;
-import electrosphere.menu.mainmenu.MenuGeneratorsUITesting;
-import electrosphere.renderer.RenderingEngine;
-import testutils.TestEngineUtils;
-
-/**
- * Integration tests for the window class
- */
-public class WindowIntegrationTest {
-
- @BeforeEach
- @Tag("integration")
- /**
- * Initializes the engine
- */
- public void initEngine(){
- TestEngineUtils.initGraphicalEngine();
- }
-
- @Test
- @Tag("integration")
- /**
- * Tests creating a window
- */
- public void testCreateWindow(){
- //create ui testing window
- TestEngineUtils.simulateFrames(1);
- WindowUtils.replaceMainMenuContents(MenuGeneratorsUITesting.createUITestMenu());
- TestEngineUtils.simulateFrames(1);
- BufferedImage screenshot = RenderingEngine.defaultFramebuffer.getPixels(Globals.renderingEngine.getOpenGLState());
-
- }
-
- @AfterEach
- @Tag("integration")
- /**
- * Shuts down the engine
- */
- public void closeEngine(){
- Main.shutdown();
- }
-
-
-
-}
diff --git a/src/test/java/electrosphere/renderer/ui/elements/WindowTest.java b/src/test/java/electrosphere/renderer/ui/elements/WindowTest.java
new file mode 100644
index 00000000..400ac003
--- /dev/null
+++ b/src/test/java/electrosphere/renderer/ui/elements/WindowTest.java
@@ -0,0 +1,27 @@
+package electrosphere.renderer.ui.elements;
+
+import annotations.IntegrationTest;
+import electrosphere.menu.WindowUtils;
+import electrosphere.menu.mainmenu.MenuGeneratorsUITesting;
+import template.RenderingTestTemplate;
+import testutils.TestEngineUtils;
+
+/**
+ * Tests for the window class
+ */
+public class WindowTest extends RenderingTestTemplate {
+
+ /**
+ * Tests creating a window
+ */
+ @IntegrationTest
+ public void testCreateWindow(){
+ //create ui testing window
+ TestEngineUtils.simulateFrames(1);
+ WindowUtils.replaceMainMenuContents(MenuGeneratorsUITesting.createUITestMenu());
+ TestEngineUtils.simulateFrames(1);
+ // TestRenderingUtils.saveTestRender("./test/java/electrosphere/renderer/ui/elements/window.png");
+ this.checkRender("Basic", "./test/java/electrosphere/renderer/ui/elements/window.png");
+ }
+
+}
diff --git a/src/test/java/electrosphere/renderer/ui/elements/WindowUnitTest.java b/src/test/java/electrosphere/renderer/ui/elements/WindowUnitTest.java
deleted file mode 100644
index d7ae1809..00000000
--- a/src/test/java/electrosphere/renderer/ui/elements/WindowUnitTest.java
+++ /dev/null
@@ -1,10 +0,0 @@
-package electrosphere.renderer.ui.elements;
-
-/**
- * Unit testing the window class
- */
-public class WindowUnitTest {
-
-
-
-}
diff --git a/src/test/java/startup/StartupTest.java b/src/test/java/integration/StartupTest.java
similarity index 82%
rename from src/test/java/startup/StartupTest.java
rename to src/test/java/integration/StartupTest.java
index c9462e0d..2256360e 100644
--- a/src/test/java/startup/StartupTest.java
+++ b/src/test/java/integration/StartupTest.java
@@ -1,16 +1,15 @@
-package startup;
-
-import org.junit.jupiter.api.Test;
+package integration;
+import annotations.IntegrationSetup;
+import annotations.IntegrationTest;
import electrosphere.engine.Globals;
-import electrosphere.engine.Main;
import electrosphere.engine.profiler.Profiler;
import electrosphere.logger.LoggerInterface;
import electrosphere.net.NetUtils;
public class StartupTest {
- @Test
+ @IntegrationSetup
public void testStartupHeadless(){
LoggerInterface.loggerEngine.INFO("[Test] Startup Headless");
Globals.RUN_CLIENT = false;
@@ -22,7 +21,7 @@ public class StartupTest {
// Main.mainLoop(1);
}
- @Test
+ @IntegrationTest
public void testEmpty() {
LoggerInterface.loggerEngine.INFO("[Test] Empty test");
}
diff --git a/src/test/java/networking/NetworkingTest.java b/src/test/java/networking/NetworkingTest.java
deleted file mode 100644
index e7e4a378..00000000
--- a/src/test/java/networking/NetworkingTest.java
+++ /dev/null
@@ -1,5 +0,0 @@
-package networking;
-
-public class NetworkingTest {
-
-}
diff --git a/src/test/java/physics/PhysicsTest.java b/src/test/java/physics/PhysicsTest.java
deleted file mode 100644
index ebfe64cb..00000000
--- a/src/test/java/physics/PhysicsTest.java
+++ /dev/null
@@ -1,5 +0,0 @@
-package physics;
-
-public class PhysicsTest {
-
-}
diff --git a/src/test/java/script/ScriptTest.java b/src/test/java/script/ScriptTest.java
deleted file mode 100644
index c8411719..00000000
--- a/src/test/java/script/ScriptTest.java
+++ /dev/null
@@ -1,5 +0,0 @@
-package script;
-
-public class ScriptTest {
-
-}
diff --git a/src/test/java/template/RenderingTestTemplate.java b/src/test/java/template/RenderingTestTemplate.java
new file mode 100644
index 00000000..2af58d49
--- /dev/null
+++ b/src/test/java/template/RenderingTestTemplate.java
@@ -0,0 +1,52 @@
+package template;
+
+import java.io.File;
+
+import annotations.IntegrationSetup;
+import annotations.IntegrationTeardown;
+import electrosphere.engine.Main;
+import testutils.TestEngineUtils;
+import testutils.TestRenderingUtils;
+
+/**
+ * A test class that involves testing renders
+ */
+public abstract class RenderingTestTemplate {
+
+ /**
+ * Initializes the engine
+ */
+ @IntegrationSetup
+ public void initEngine(){
+ TestEngineUtils.initGraphicalEngine();
+ }
+
+ /**
+ * Shuts down the engine
+ */
+ @IntegrationTeardown
+ public void closeEngine(){
+ Main.shutdown();
+ }
+
+ /**
+ * Checks the most recent render versus an existing image
+ * @param renderName The name associated with the render
+ * @param existingRenderPath The path to the existing image
+ */
+ public void checkRender(String renderName, String existingRenderPath){
+ //of the format "electrosphere.renderer.ui.elements.WindowTest"
+ String canonicalName = this.getClass().getCanonicalName();
+
+ //check the render
+ TestRenderingUtils.assertEqualsRender(existingRenderPath, () -> {
+
+ //on failure, save the failed render
+ String failureSavePath = "./.testcache/" + canonicalName + "-" + renderName + ".png";
+ File saveFile = new File(failureSavePath);
+ System.err.println("[[ATTACHMENT|" + saveFile.getAbsolutePath() + "]]");
+ TestRenderingUtils.saveTestRender(failureSavePath);
+ });
+ }
+
+}
diff --git a/src/test/java/testutils/TestRenderingUtils.java b/src/test/java/testutils/TestRenderingUtils.java
new file mode 100644
index 00000000..d986f8ed
--- /dev/null
+++ b/src/test/java/testutils/TestRenderingUtils.java
@@ -0,0 +1,66 @@
+package testutils;
+
+import java.awt.image.BufferedImage;
+import java.io.File;
+import java.io.IOException;
+
+import javax.imageio.ImageIO;
+
+import static org.junit.jupiter.api.Assertions.*;
+
+import electrosphere.engine.Globals;
+import electrosphere.renderer.RenderingEngine;
+
+/**
+ * Utilities for comparing renders
+ */
+public class TestRenderingUtils {
+
+ /**
+ * Asserts that the most recent render matches the image stored at the provided filepath
+ * @param existingRenderPath The filepath of the existing render
+ */
+ public static void assertEqualsRender(String existingRenderPath, Runnable onFailure){
+ BufferedImage testData = null;
+ try {
+ testData = ImageIO.read(new File(existingRenderPath));
+ } catch (IOException e){
+ fail("Failed to read existing image path " + existingRenderPath);
+ }
+ BufferedImage screenshot = RenderingEngine.defaultFramebuffer.getPixels(Globals.renderingEngine.getOpenGLState());
+ //check basic data
+ if(testData.getWidth() != screenshot.getWidth()){
+ onFailure.run();
+ }
+ assertEquals(testData.getHeight(), screenshot.getHeight());
+ if(testData.getWidth() != screenshot.getWidth()){
+ onFailure.run();
+ }
+ assertEquals(testData.getHeight(), screenshot.getHeight());
+
+ //pixel-by-pixel check
+ for(int x = 0; x < testData.getWidth(); x++){
+ for(int y = 0; y < testData.getHeight(); y++){
+ if(testData.getRGB(x, y) != screenshot.getRGB(x, y)){
+ onFailure.run();
+ }
+ assertEquals(testData.getRGB(x, y),screenshot.getRGB(x, y));
+ }
+ }
+ }
+
+ /**
+ * Used for saving a copy of the current render (ie for generating test data)
+ * @param existingRenderPath The filepath of the existing render
+ */
+ public static void saveTestRender(String existingRenderPath){
+ BufferedImage screenshot = RenderingEngine.defaultFramebuffer.getPixels(Globals.renderingEngine.getOpenGLState());
+ try {
+ ImageIO.write(screenshot, "png", new File(existingRenderPath));
+ } catch (IOException e) {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ }
+ }
+
+}
diff --git a/test/java/electrosphere/renderer/ui/elements/window.png b/test/java/electrosphere/renderer/ui/elements/window.png
new file mode 100644
index 00000000..dd6ee3d0
Binary files /dev/null and b/test/java/electrosphere/renderer/ui/elements/window.png differ