Scaffolding for various unit tests

This commit is contained in:
austin 2023-04-11 17:56:11 -04:00
parent b01efa89e8
commit b167062585
39 changed files with 263 additions and 289 deletions

View File

@ -323,7 +323,7 @@
"movementStart" : 0,
"movementEnd" : 0,
"movementGoal" : 0,
"initialMove" : false
"initialMove" : true
}
],
"healthSystem" : {

View File

@ -323,7 +323,7 @@
"movementStart" : 0,
"movementEnd" : 0,
"movementGoal" : 0,
"initialMove" : false
"initialMove" : true
}
],
"healthSystem" : {

View File

@ -145,7 +145,7 @@
"movementStart" : 0,
"movementEnd" : 0,
"movementGoal" : 0,
"initialMove" : false
"initialMove" : true
}
],
"healthSystem" : {

View File

@ -309,6 +309,10 @@ public class Globals {
//
//Base engine creation flags
//
public static boolean HEADLESS = false;
//

View File

@ -54,6 +54,13 @@ public class Main {
//parse command line arguments
CLIParser.parseCLIArgs(args);
startUp();
mainLoop();
}
public static void startUp(){
//initialize logging interfaces
LoggerInterface.initLoggers();
@ -122,7 +129,7 @@ public class Main {
// TerrainViewer.runViewer();
//create the drawing context
if(Globals.RUN_CLIENT){
if(Globals.RUN_CLIENT && !Globals.HEADLESS){
Globals.renderingEngine = new RenderingEngine();
Globals.renderingEngine.createOpenglContext();
}
@ -150,14 +157,14 @@ public class Main {
// }
//create the audio context
if(Globals.RUN_CLIENT){
if(Globals.RUN_CLIENT && !Globals.HEADLESS){
Globals.audioEngine = new AudioEngine();
Globals.audioEngine.init();
// Globals.audioEngine.setGain(0.1f);
}
//init default resources
if(Globals.RUN_CLIENT){
if(Globals.RUN_CLIENT && !Globals.HEADLESS){
Globals.initDefaultGraphicalResources();
Globals.initDefaultAudioResources();
}
@ -175,16 +182,18 @@ public class Main {
}
//recapture the screen for rendering
if(Globals.RUN_CLIENT){
if(Globals.RUN_CLIENT && !Globals.HEADLESS){
LoggerInterface.loggerStartup.INFO("Recapture screen");
Globals.controlHandler.setShouldRecapture(true);
}
// RenderUtils.recaptureScreen();
}
///
/// C A M E R A C R E A T I O N
///
// Vector3f cameraRotationVector = new Vector3f();
public static void mainLoop(){
mainLoop(0);
}
public static void mainLoop(long maxFrames){
//main loop
while (running) {
@ -270,6 +279,10 @@ public class Main {
}
frameCount++;
if(maxFrames > 0 && frameCount > maxFrames){
running = false;
}
}
//
@ -289,7 +302,6 @@ public class Main {
if(Globals.RUN_CLIENT){
Globals.audioEngine.shutdown();
}
}
public static long getCurrentFrame(){

View File

@ -9,10 +9,14 @@ public class CLIParser {
public static void parseCLIArgs(String args[]){
List<String> argList = Arrays.asList(args);
for(String arg : argList){
if(arg.equals("--headless")){
Globals.RUN_CLIENT = false;
Globals.RUN_SERVER = true;
for(int i = 0; i < argList.size(); i++){
String argCurrent = argList.get(i);
switch(argCurrent){
case "--headless": {
Globals.RUN_CLIENT = false;
Globals.RUN_SERVER = true;
Globals.HEADLESS = true;
} break;
}
}
}

View File

@ -235,4 +235,12 @@ public class Scene {
}
}
/**
* Gets the list of all entities in the scene
* @return The list of all entities in the scene
*/
public List<Entity> getEntityList(){
return entityList;
}
}

View File

@ -20,14 +20,14 @@ public class LoggerInterface {
public static Logger loggerDB;
public static void initLoggers(){
loggerStartup = new Logger(LogLevel.INFO);
loggerNetworking = new Logger(LogLevel.INFO);
loggerFileIO = new Logger(LogLevel.INFO);
loggerGameLogic = new Logger(LogLevel.INFO);
loggerStartup = new Logger(LogLevel.WARNING);
loggerNetworking = new Logger(LogLevel.WARNING);
loggerFileIO = new Logger(LogLevel.WARNING);
loggerGameLogic = new Logger(LogLevel.WARNING);
loggerRenderer = new Logger(LogLevel.WARNING);
loggerEngine = new Logger(LogLevel.INFO);
loggerAuth = new Logger(LogLevel.INFO);
loggerDB = new Logger(LogLevel.INFO);
loggerEngine = new Logger(LogLevel.WARNING);
loggerAuth = new Logger(LogLevel.WARNING);
loggerDB = new Logger(LogLevel.WARNING);
loggerStartup.INFO("Initialized loggers");
}
}

View File

@ -14,7 +14,7 @@ public class NetUtils {
public static final int DEFAULT_PORT = 34251;
static int port = DEFAULT_PORT;
static String address = "127.0.0.1";
static String address = "localhost";
// public static EntityMessage createSpawnEntityMessage(Entity e){
// EntityMessage rVal = EntityMessage.constructCreateMessage(e.getId(), CreatureUtils.getCreatureType(e), 0.0f, 0.0f, 0.0f);
@ -35,6 +35,12 @@ public class NetUtils {
return address;
}
/**
* Sets the port the program attempts to use
* If the port is set to 0, and it is creating the server, it will create the socket with port 0.
* This causes Java to find any available port. The Server class then re-calls setPort to update the static port with the found port.
* @param port The port to use when doing any networking
*/
public static void setPort(int port) {
NetUtils.port = port;
}

View File

@ -48,6 +48,11 @@ public class Server implements Runnable{
initServer();
try {
serverSocket = new ServerSocket(port);
//if we set port to 0, java searches for any available port to open
//This then explicitly alerts NetUtils of the real port
if(port == 0){
NetUtils.setPort(serverSocket.getLocalPort());
}
} catch(BindException ex){
System.err.println("Failed to bind server socket!");
ex.printStackTrace();

View File

@ -6,6 +6,7 @@ import java.util.HashMap;
import java.util.Map;
import org.graalvm.polyglot.Context;
import org.graalvm.polyglot.Engine;
import org.graalvm.polyglot.Source;
import org.graalvm.polyglot.Value;
@ -21,8 +22,10 @@ public class ScriptEngine {
public void init(){
//init datastructures
sourceMap = new HashMap<String,Source>();
//create engine with flag to disable warning
Engine engine = Engine.newBuilder().option("engine.WarnInterpreterOnly", "false").build();
//create context
context = Context.create("js");
context = Context.newBuilder("js").engine(engine).build();
//read scripts into source map
readScriptsDirectory("/Scripts", FileUtils.getAssetFile("/Scripts"));
//create bindings

View File

@ -1,22 +0,0 @@
import junit.framework.TestCase;
import testingutils.MainLoop;
public class StartupTest extends TestCase {
public void testStartupHeadless(){
System.out.println("[Test] Startup Headless");
MainLoop.startup(true);
MainLoop.timedMainLoop(3);
}
public void testStartupGUI(){
System.out.println("[Test] Startup GUI");
MainLoop.startup(false);
MainLoop.timedMainLoop(10);
}
public void testEmpty() {
}
}

View File

@ -1,13 +1,42 @@
import java.util.Arrays;
import java.util.LinkedList;
import java.util.List;
import org.junit.runner.JUnitCore;
import org.junit.runner.Result;
import org.junit.runner.notification.Failure;
import entity.SpawningCreaturesTest;
import startup.StartupTest;
public class TestRunner {
static final List<Class> classes = Arrays.asList(new Class[]{
StartupTest.class,
SpawningCreaturesTest.class,
});
public static void main(String[] args){
Result result = JUnitCore.runClasses(StartupTest.class);
for(Failure failure : result.getFailures()){
boolean success = true;
List<Failure> failures = new LinkedList<Failure>();
//run tests
for(Class classObject : classes){
System.out.println("CLASS " + classObject.descriptorString());
Result result = JUnitCore.runClasses(classObject);
for(Failure failure : result.getFailures()){
failures.add(failure);
}
success = success && result.wasSuccessful();
}
//print failures
for(Failure failure : failures){
System.out.println(failure);
}
System.out.println("Testing was successful: " + result.wasSuccessful());
System.out.println("Testing was successful: " + success);
}
}

View File

@ -0,0 +1,5 @@
package db;
public class DBTest {
}

View File

@ -0,0 +1,5 @@
package entity;
public class InventoryStateTest {
}

View File

@ -0,0 +1,5 @@
package entity;
public class LifeStateTest {
}

View File

@ -0,0 +1,46 @@
package entity;
import org.joml.Vector3d;
import org.junit.Before;
import org.junit.Test;
import electrosphere.engine.Globals;
import electrosphere.engine.Main;
import electrosphere.entity.types.creature.CreatureUtils;
import electrosphere.net.NetUtils;
import testutils.TestEntityUtils;
public class SpawningCreaturesTest {
@Before
public void initEngine(){
System.out.println("[Test] Spawn many creatures");
Globals.RUN_CLIENT = false;
Globals.RUN_SERVER = true;
Globals.HEADLESS = true;
NetUtils.setPort(0);
Main.startUp();
}
// @Test
// public void testSpawnCreature(){
// System.out.println("[Test] Spawn creature");
// Globals.RUN_CLIENT = false;
// Globals.RUN_SERVER = true;
// NetUtils.setPort(0);
// Main.startUp();
// CreatureUtils.spawnBasicCreature("human", null);
// Main.mainLoop(1);
// assert TestEntityUtils.numberOfEntitiesInBox(new Vector3d(-1,-1,-1),new Vector3d(1,1,1)) == 1;
// }
@Test
public void testSpawnMultipleCreatures(){
for(int i = 0; i < 100; i++){
CreatureUtils.spawnBasicCreature("human", null);
}
Main.mainLoop(1);
assert TestEntityUtils.numberOfEntitiesInBox(new Vector3d(-1,-1,-1),new Vector3d(1,1,1)) == 100;
}
}

View File

@ -0,0 +1,5 @@
package networking;
public class NetworkingTest {
}

View File

@ -0,0 +1,5 @@
package physics;
public class PhysicsTest {
}

View File

@ -0,0 +1,5 @@
package script;
public class ScriptTest {
}

View File

@ -0,0 +1,36 @@
package startup;
import org.junit.Test;
import electrosphere.engine.Globals;
import electrosphere.engine.Main;
import electrosphere.net.NetUtils;
import junit.framework.TestCase;
public class StartupTest extends TestCase {
@Test
public void testStartupHeadless(){
System.out.println("[Test] Startup Headless");
Globals.RUN_CLIENT = false;
Globals.RUN_SERVER = true;
NetUtils.setPort(0);
Main.startUp();
Main.mainLoop(1);
}
@Test
public void testStartupGUI(){
System.out.println("[Test] Startup GUI");
Globals.RUN_CLIENT = false;
Globals.RUN_SERVER = true;
NetUtils.setPort(0);
Main.startUp();
Main.mainLoop(1);
}
@Test
public void testEmpty() {
System.out.println("[Test] Empty test");
}
}

View File

@ -1,237 +0,0 @@
package testingutils;
import static org.lwjgl.glfw.GLFW.glfwGetTime;
import java.util.concurrent.TimeUnit;
import electrosphere.audio.AudioEngine;
import electrosphere.controls.ControlHandler;
import electrosphere.engine.Globals;
import electrosphere.engine.LoadingThread;
import electrosphere.engine.cli.CLIParser;
import electrosphere.game.client.ClientFunctions;
import electrosphere.game.config.UserSettings;
import electrosphere.logger.LoggerInterface;
import electrosphere.renderer.RenderingEngine;
public class MainLoop {
//
//Visualization Controls
//
//These are used in calculating the time between frames for visualization (camera) control and such
static double deltaTime = 0.0f;
static double lastFrame = 0.0f;
static long frameCount = 0;
public static float deltaFrames = 0;
//target amount of time per frame
public static float targetFrameRate = 60.0f;
static float targetFramePeriod = 1.0f/targetFrameRate;
//framestep variable
static int framestep = 2;
public static void startup(boolean headless){
//
//
// I N I T I A L I Z A T I O N
//
//
//parse command line arguments
String[] args = new String[]{
"Renderer"
};
CLIParser.parseCLIArgs(args);
//initialize logging interfaces
LoggerInterface.initLoggers();
//load user settings
UserSettings.loadUserSettings();
//controls
if(Globals.RUN_CLIENT){
initControlHandler();
}
//init global variables
Globals.initGlobals();
//create the drawing context
if(Globals.RUN_CLIENT && !headless){
Globals.renderingEngine = new RenderingEngine();
Globals.renderingEngine.createOpenglContext();
}
//create the audio context
if(Globals.RUN_CLIENT && !headless){
Globals.audioEngine = new AudioEngine();
Globals.audioEngine.init();
// Globals.audioEngine.setGain(0.1f);
}
//init default resources
if(Globals.RUN_CLIENT && !headless){
Globals.initDefaultGraphicalResources();
Globals.initDefaultAudioResources();
}
//fire off a loading thread for the title menus/screen
LoggerInterface.loggerStartup.INFO("Fire off loading thread");
if(Globals.RUN_CLIENT){
LoadingThread serverThread = new LoadingThread(LoadingThread.LOAD_TITLE_MENU);
Globals.loadingThreadsList.add(serverThread);
serverThread.start();
} else {
LoadingThread clientThread = new LoadingThread(LoadingThread.LOAD_ARENA);
Globals.loadingThreadsList.add(clientThread);
clientThread.start();
}
//recapture the screen for rendering
if(Globals.RUN_CLIENT){
LoggerInterface.loggerStartup.INFO("Recapture screen");
Globals.controlHandler.setShouldRecapture(true);
}
}
public static void initControlHandler(){
LoggerInterface.loggerStartup.INFO("Initialize control handler");
Globals.controlHandler = ControlHandler.generateExampleControlsMap();
Globals.controlHandler.setCallbacks();
}
public static void run(MainLoop.MainLoopHaltingCallback haltingCallback){
//main loop
while (haltingCallback.shouldRun()) {
/*
Frame calculation
*/
double currentTime = glfwGetTime();
deltaTime = currentTime - lastFrame;
deltaFrames = targetFrameRate * (float)deltaTime;
lastFrame = currentTime;
///
/// A S S E T M A N A G E R S T U F F
///
if(Globals.RUN_CLIENT){
Globals.assetManager.loadAssetsInQueue();
}
///
/// C L I E N T N E T W O R K I N G S T U F F
///
//Why is this its own function? Just to get the networking code out of main()
if(Globals.RUN_CLIENT && Globals.clientConnection != null){
Globals.clientConnection.parseMessages();
}
//handle framestep
if(framestep == 1){
framestep = 0;
}
///
/// I N P U T C O N T R O L S
///
//Poll controls
if(Globals.RUN_CLIENT){
Globals.controlHandler.pollControls();
Globals.controlHandler.recaptureIfNecessary();
}
///
/// C L I E N T S I M U L A T I O N S T U F F
///
if(Globals.RUN_CLIENT && framestep > 0){
ClientFunctions.runBeforeSimulationFunctions();
}
if(Globals.microSimulation != null && Globals.microSimulation.isReady() && framestep > 0){
Globals.microSimulation.simulate();
}
if(Globals.RUN_CLIENT && framestep > 0){
ClientFunctions.runClientFunctions();
}
///
/// M A C R O S I M U L A T I O N S T U F F
///
if(Globals.macroSimulation != null && Globals.macroSimulation.isReady() && framestep > 0){
Globals.macroSimulation.simulate();
}
if(Globals.RUN_CLIENT){
Globals.renderingEngine.drawScreen();
}
if(deltaTime < targetFramePeriod){
sleep((int)(1000.0 * (targetFramePeriod - deltaTime)));
} else {
sleep(1);
}
frameCount++;
}
}
static void sleep(int i) {
try {
TimeUnit.MILLISECONDS.sleep(i);
} catch (InterruptedException ex) {
System.out.println("Sleep somehow interrupted?!");
}
}
static boolean shouldRun = true;
public static void timedMainLoop(int seconds){
Thread stopMainLoopThread = new Thread(new Runnable() {
@Override
public void run() {
try {
TimeUnit.SECONDS.sleep(3);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
shouldRun = false;
}});
stopMainLoopThread.start();
Globals.RUN_CLIENT = false;
MainLoopHaltingCallback haltingCallback = new MainLoop.MainLoopHaltingCallback() {
@Override
public boolean shouldRun() {
return shouldRun;
}};
MainLoop.run(haltingCallback);
}
public static abstract class MainLoopHaltingCallback {
public abstract boolean shouldRun();
}
}

View File

@ -0,0 +1,45 @@
package testutils;
import org.joml.Vector3d;
import electrosphere.engine.Globals;
import electrosphere.entity.Entity;
import electrosphere.entity.EntityUtils;
public class TestEntityUtils {
/**
* Returns the number of entities in the bounding box defined by boxMin and boxMax, noninclusive.
* @param boxMin The minimum point for the bounding box
* @param boxMax The maximum point for the bounding box
* @return The number of entities in the bounding box
*/
public static int numberOfEntitiesInBox(Vector3d boxMin, Vector3d boxMax){
double minX = boxMin.x < boxMax.x ? boxMin.x : boxMax.x;
double minY = boxMin.y < boxMax.y ? boxMin.y : boxMax.y;
double minZ = boxMin.z < boxMax.z ? boxMin.z : boxMax.z;
double maxX = boxMin.x > boxMax.x ? boxMin.x : boxMax.x;
double maxY = boxMin.y > boxMax.y ? boxMin.y : boxMax.y;
double maxZ = boxMin.z > boxMax.z ? boxMin.z : boxMax.z;
int accumulator = 0;
for(Entity entity : Globals.entityManager.getEntityList()){
if(EntityUtils.getPosition(entity) != null){
Vector3d position = EntityUtils.getPosition(entity);
if(
position.x > minX &&
position.x < maxX &&
position.y > minY &&
position.y < maxY &&
position.z > minZ &&
position.z < maxZ
){
accumulator++;
}
}
}
return accumulator;
}
}

View File

@ -0,0 +1,5 @@
package ui;
public class UICreationTest {
}