/******************************************************************************* * Copyright (c) 2001, 2010 Mathew A. Nelson and Robocode contributors * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://robocode.sourceforge.net/license/epl-v10.html * * Contributors: * Pavel Savara * - Initial implementation *******************************************************************************/ package net.sf.robocode.test.helpers; import net.sf.robocode.io.Logger; import org.junit.After; import org.junit.Before; import org.junit.Test; import robocode.control.*; import robocode.control.events.*; import robocode.control.snapshot.IRobotSnapshot; import robocode.util.Utils; import java.io.File; import java.io.IOException; import java.util.Random; /** * @author Pavel Savara (original) */ public abstract class RobocodeTestBed extends BattleAdaptor { protected static final IRobocodeEngine engine; protected final BattlefieldSpecification battleFieldSpec = new BattlefieldSpecification(); protected static int errors = 0; protected static StringBuilder errorText = new StringBuilder(); protected static int messages = 0; protected static String robotsPath; public static boolean isDumpingPositions = false; public static boolean isDumpingTurns = false; public static boolean isDumpingOutput = true; public static boolean isDumpingErrors = true; public static boolean isDumpingMessages = true; static { System.setProperty("EXPERIMENTAL", "true"); System.setProperty("TESTING", "true"); System.setProperty("WORKINGDIRECTORY", "target/test-classes"); try { if (new File("").getAbsolutePath().endsWith("robocode.tests")) { robotsPath = new File("../robocode.tests.robots").getCanonicalPath(); } else if (new File("").getAbsolutePath().endsWith("robocode.dotnet.tests")) { robotsPath = new File("../../../robocode.tests.robots").getCanonicalPath(); } else { throw new Error("Unknown directory"); } } catch (IOException e) { e.printStackTrace(Logger.realErr); } System.setProperty("ROBOTPATH", robotsPath + "/target/classes"); engine = new RobocodeEngine(new BattleAdaptor() { public void onBattleMessage(BattleMessageEvent event) { if (isDumpingMessages) { Logger.realOut.println(event.getMessage()); } messages++; } public void onBattleError(BattleErrorEvent event) { if (isDumpingErrors) { Logger.realErr.println(event.getError()); } errorText.append("----------err #"); errorText.append(errors); errorText.append("--------------------------------------------------\n"); errorText.append(event.getError()); errorText.append("\n"); errors++; } }); } public RobocodeTestBed() { // silent when running in maven if (System.getProperty("surefire.test.class.path", null) != null) { isDumpingOutput = false; isDumpingErrors = false; isDumpingMessages = false; } errors = 0; messages = 0; } public void onTurnEnded(TurnEndedEvent event) { if (isDumpingTurns) { Logger.realOut.println("turn " + event.getTurnSnapshot().getTurn()); } for (IRobotSnapshot robot : event.getTurnSnapshot().getRobots()) { if (isDumpingPositions) { Logger.realOut.print(robot.getVeryShortName()); Logger.realOut.print(" X:"); Logger.realOut.print(robot.getX()); Logger.realOut.print(" Y:"); Logger.realOut.print(robot.getY()); Logger.realOut.print(" V:"); Logger.realOut.print(robot.getVelocity()); Logger.realOut.println(); } if (isDumpingOutput) { Logger.realOut.print(robot.getOutputStreamSnapshot()); } } } public void onBattleStarted(BattleStartedEvent event) { if (isDeterministic() && isCheckOnBattleStart()) { final Random random = Utils.getRandom(); if (event.getRobotsCount() == 2) { Assert.assertNear(0.98484154, random.nextDouble()); } } } public abstract String getRobotNames(); public int getNumRounds() { return 1; } public String getInitialPositions() { return null; } public int getExpectedRobotCount(String robotList) { return robotList.split("[\\s,;]+").length; } public boolean isDeterministic() { return true; } public boolean isCheckOnBattleStart() { return false; } @Before public void setup() { engine.addBattleListener(this); if (isDeterministic()) { RandomFactory.resetDeterministic(0); if (isCheckOnBattleStart()) { Assert.assertNear(0.730967, RandomFactory.getRandom().nextDouble()); } } errors = 0; errorText = new StringBuilder(); messages = 0; } @After public void tearDown() { engine.removeBattleListener(this); } @Test public void run() { runSetup(); runBattle(getRobotNames(), getNumRounds(), getInitialPositions()); runTeardown(); final int expectedErrors = getExpectedErrors(); if (errors != expectedErrors) { throw new AssertionError( "Number of errors " + errors + " is different than expected " + expectedErrors + "\n" + errorText + "======================================================================"); } } protected int getExpectedErrors() { return 0; } protected void runSetup() {} protected void runTeardown() {} protected void runBattle(String robotList, int numRounds, String initialPositions) { final RobotSpecification[] robotSpecifications = engine.getLocalRepository(robotList); if (getExpectedRobotCount(robotList) > 0) { Assert.assertNotNull("Robot were not loaded", robotSpecifications); Assert.assertEquals("Robot were not loaded", getExpectedRobotCount(robotList), robotSpecifications.length); engine.runBattle(new BattleSpecification(numRounds, battleFieldSpec, robotSpecifications), initialPositions, true); } } }