package com.cardshifter.core; import com.cardshifter.ai.AIs; import com.cardshifter.ai.ScoringAI; import com.cardshifter.core.game.ModCollection; import com.cardshifter.core.modloader.ECSModTest; import com.cardshifter.core.modloader.GroovyMod; import com.cardshifter.modapi.actions.ECSAction; import com.cardshifter.modapi.ai.CardshifterAI; import com.cardshifter.modapi.base.ECSGame; import com.cardshifter.modapi.base.ECSGameState; import com.cardshifter.modapi.base.ECSMod; import com.cardshifter.modapi.base.Entity; import com.cardshifter.modapi.players.Players; import junit.framework.Test; import junit.framework.TestCase; import junit.framework.TestSuite; import net.zomis.cardshifter.ecs.config.ConfigComponent; import org.apache.log4j.PropertyConfigurator; import java.io.File; import java.util.ArrayList; import java.util.Collections; import java.util.List; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertTrue; import static org.junit.Assert.fail; /** * Created by Simon on 6/3/2015. */ public class TestUtils { ModCollection createModCollection() { ModCollection mods = new ModCollection(); mods.loadExternal(new File("../test-resources/mods").toPath()); return mods.loadDefault(); } TestSuite testSuite() { PropertyConfigurator.configure(getClass().getClassLoader().getResource("log4j.properties")); TestSuite suite = new TestSuite(); ModCollection mods = createModCollection(); System.out.println("Mods found " + mods.getAvailableMods().size()); suite.addTest(new TestCase("Testing mods " + mods.getAvailableMods()) { @Override protected void runTest() throws Throwable { assertNotSame(0, mods.getAvailableMods().size()); assertNotNull("TestMod not found", mods.getModFor("TestMod")); } }); for (String modName : mods.getAvailableMods()) { System.out.println("Adding tests for " + modName); suite.addTest(createSuite(mods, modName)); } return suite; } private Test createSuite(ModCollection mods, String modName) { TestSuite suite = new TestSuite(modName); ECSMod mod = mods.getModFor(modName); if (mod instanceof GroovyMod) { GroovyMod groovyMod = (GroovyMod) mod; List<ECSModTest> tests = groovyMod.testList(); if (tests == null) { suite.addTest(untestedMod(modName)); return suite; } tests.add(sequencialPlayTest(mods, modName)); tests.add(multithreadedPlayTest(mods, modName)); for (ECSModTest test : tests) { suite.addTest(createTest(mods, modName, test)); } } return suite; } private ECSModTest sequencialPlayTest(ModCollection mods, String modName) { ECSModTest modTest = new ECSModTest("quick play", new Runnable() { @Override public void run() { ECSMod mod = mods.getModFor(modName); ECSGame game = new ECSGame(); CardshifterAI ai = new ScoringAI(AIs.fighter()); mod.declareConfiguration(game); List<Entity> players = Players.getPlayersInGame(game); for (Entity entity : players) { ai.configure(entity, entity.getComponent(ConfigComponent.class)); } mod.setupGame(game); game.startGame(); while (!game.isGameOver()) { boolean performed = false; for (Entity entity : players) { ECSAction action = ai.getAction(entity); if (action != null) { boolean doSomething = action.perform(entity); if (doSomething) { System.out.println(entity + " performed " + action); } performed = performed || doSomething; } } assertTrue("No player perfored any action: " + players, performed); } } }); return modTest; } private ECSModTest multithreadedPlayTest(ModCollection mods, String modName) { ECSModTest modTest = new ECSModTest("multithreaded test", new Runnable() { @Override public void run() { // Logger.getRootLogger().addAppender(new ConsoleAppender(new PatternLayout("%c %m\n"), "System.out")); ECSMod mod = mods.getModFor(modName); ECSGame game = new ECSGame(); CardshifterAI ai = new ScoringAI(AIs.fighter()); mod.declareConfiguration(game); List<Entity> players = Players.getPlayersInGame(game); for (Entity entity : players) { ai.configure(entity, entity.getComponent(ConfigComponent.class)); } mod.setupGame(game); game.startGame(); List<Throwable> errors = Collections.synchronizedList(new ArrayList<>()); List<Thread> threads = new ArrayList<>(); for (Entity player : players) { Thread thread = new Thread(() -> { try { while (!game.isGameOver()) { ECSAction action = ai.getAction(player); if (action != null && action.perform(player)) { System.out.println(player + " performed " + action); } } } catch (Exception ex) { ex.printStackTrace(); errors.add(ex); } }, "AI Thread for " + modName + " " + player); threads.add(thread); } for (Thread th : threads) { th.start(); } for (Thread th : threads) { try { th.join(); } catch (InterruptedException e) { fail("Thread interrupted"); } } assertTrue("Errors occured: " + errors, errors.isEmpty()); assertTrue(game.isGameOver()); } }); return modTest; } private Test untestedMod(String modName) { return new TestCase(modName) { @Override protected void runTest() throws Throwable { fail("mod does not contain a 'test.groovy' file: " + modName); } }; } private Test createTest(ModCollection mods, String modName, ECSModTest test) { return new TestCase(test.getName()) { private ECSMod mod; @Override protected void setUp() throws Exception { mod = mods.getModFor(modName); } @Override protected void runTest() throws Throwable { test.getRunnable().run(); } @Override protected void tearDown() throws Exception { } }; } public TestSuite testCreateSuite() { System.out.println(new File("").getAbsolutePath()); TestSuite suite = new TestSuite(); ModCollection mods = createModCollection(); System.out.println("Mods found " + mods.getAvailableMods().size()); suite.addTest(new TestCase("Mods available " + mods.getAvailableMods()) { @Override protected void runTest() throws Throwable { assertNotSame(0, mods.getAvailableMods().size()); } }); for (String modName : mods.getAvailableMods()) { System.out.println("Adding tests for " + modName); suite.addTest(new TestCase(modName) { @Override protected void runTest() throws Throwable { ECSMod mod = mods.getModFor(modName); ECSGame game = new ECSGame(); CardshifterAI ai = new ScoringAI(AIs.fighter()); mod.declareConfiguration(game); List<Entity> players = Players.getPlayersInGame(game); for (Entity entity : players) { ai.configure(entity, entity.getComponent(ConfigComponent.class)); } mod.setupGame(game); game.startGame(); assertEquals(ECSGameState.RUNNING, game.getGameState()); for (int i = 0; i < 5; i++) { boolean performed = false; for (Entity entity : players) { ECSAction action = ai.getAction(entity); if (action != null) { boolean doSomething = action.perform(entity); if (doSomething) { System.out.println(entity + " performed " + action); } performed = performed || doSomething; } } assertTrue("No player perfored any action: " + players, performed); } } }); } return suite; } }