View Javadoc

1   package cz.cuni.amis.pogamut.ut2004.bot;
2   
3   import java.util.concurrent.TimeUnit;
4   
5   import cz.cuni.amis.pogamut.ut2004.bot.impl.UT2004Bot;
6   import cz.cuni.amis.pogamut.ut2004.bot.params.UT2004BotParameters;
7   import cz.cuni.amis.pogamut.ut2004.server.exception.UCCStartException;
8   import cz.cuni.amis.pogamut.ut2004.test.UT2004Test;
9   import cz.cuni.amis.pogamut.ut2004.utils.UCCWrapperConf;
10  import cz.cuni.amis.utils.StopWatch;
11  
12  /**
13   * UT2004Bot test - it allows you to easily specify the game type and map name the bot should run 
14   * at + specify a timeout for the test.
15   * <p><p>
16   * Just use one of the {@link UT2004BotTest#startTest(Class)} methods 
17   * 
18   * @author Jimmy
19   */
20  public abstract class UT2004BotTest extends UT2004Test {
21  
22  	/**
23       * Starts UCC server according to params obtained from {@link UT2004BotTest#getGameType()} and
24       * {@link UT2004BotTest#getMapName()}.
25       *
26       * @throws cz.cuni.amis.pogamut.ut2004.server.exceptions.UCCStartException
27       */
28      @Override
29  	public void startUCC(UCCWrapperConf uccConf) throws UCCStartException {
30          uccConf.setMapName(getMapName());
31          uccConf.setGameType(getGameType());
32          super.startUCC(uccConf);
33      }
34      
35      /**
36       * @return game type that the UCC should start for the test
37       */
38      protected String getGameType() {
39      	return "BotDeathMatch";
40      }
41      
42      /**
43       * @return the map the UCC should load for the test
44       */
45      protected String getMapName() {
46      	return "DM-Flux2";
47      }
48      
49      /**
50       * Starts the test.
51       * <p><p>
52       * Test bot will be controlled by 'controllerClass'.
53       * <p><p>
54       * The test will timeout after 1 minutes.
55       * 
56       * @param controllerClass
57       */
58      protected void startTest(Class<? extends UT2004BotTestController> controllerClass) {
59  		startTest(controllerClass, 1);
60      }
61          
62      /**
63       * Starts the test.
64       * <p><p>
65       * Test bot will be controlled by 'controllerClass'.
66       * <p><p>
67       * The test will timeout after 'latchWaitMinutes'.
68       * 
69       * @param controllerClass
70       * @param latchWaitMinutes
71       */
72  	protected void startTest(Class<? extends UT2004BotTestController> controllerClass, double latchWaitMinutes) {
73      	startTest(controllerClass, latchWaitMinutes, null);
74  	}
75  	
76  	/**
77       * Starts the test.
78       * <p><p>
79       * Test bot will be controlled by 'controllerClass'.
80       * <p><p>
81       * The test will timeout after 'latchWaitMinutes'.
82       * <p><p>
83       * The test will lauch 'agentsCount' of bots of 'controllerClass' creating empty {@link UT2004BotParameters} for every one of them.
84       * 
85       * @param controllerClass
86       * @param latchWaitMinutes
87       * @param agentsCount
88       */
89  	protected void startTest(Class<? extends UT2004BotTestController> controllerClass, double latchWaitMinutes, int agentsCount) {
90  		UT2004BotParameters[] params = new UT2004BotParameters[agentsCount];
91  		for (int i = 0; i < agentsCount; ++i) {
92  			params[i] = new UT2004BotParameters();
93  		}
94      	startTest(controllerClass, latchWaitMinutes, params);
95  	}
96  	
97  	/**
98  	 * Starts the test.
99       * <p><p>
100      * Test bot will be controlled by 'controllerClass' and will be configured with 'params.
101      * <p><p>
102      * The test will timeout after 'latchWaitMinutes'.
103      * 
104      * TODO: [Jimmy] in the case of more bots, we should hook listeners to failure flags of bots to end the test case as early as possible
105      * 
106 	 * @param controllerClass
107 	 * @param params
108 	 * @param latchWaitMinutes
109 	 */
110     protected void startTest(Class<? extends UT2004BotTestController> controllerClass, double latchWaitMinutes, UT2004BotParameters... params) {
111     	int numParams = (params == null || params.length == 0 ? 0 : params.length);
112     	int numBots = numParams == 0 ? 1 : numParams;
113     	
114     	UT2004Bot bots[];
115     	
116     	if (params == null || params.length == 0) {
117     		bots = new UT2004Bot[1];
118     		bots[0] = startUTBot(controllerClass);
119     	} else {
120     		bots = startAllUTBots(controllerClass, params).toArray(new UT2004Bot[0]);
121     	}
122     	
123     	long timeoutInMillis = (long)(latchWaitMinutes * 60 * 1000);
124     	
125     	StopWatch watches = new StopWatch();
126     	
127     	for (int i = 0; i < numBots; ++i) {
128     		UT2004BotTestController controller = (UT2004BotTestController) bots[i].getController();
129     		try {
130     			controller.getTestLatch().await((long)(timeoutInMillis - watches.check()), TimeUnit.MILLISECONDS);
131     		} catch (Exception ex) {
132     			ex.printStackTrace();
133     			for (int j = i; j < numBots; ++j) bots[j].kill();
134     			Throwable throwable = controller.getLogicModule().getLogicException();
135     			throw new RuntimeException("Test failed, bot did not finished.", throwable);
136     		}
137     		if (timeoutInMillis - watches.check() < 0) {
138     			controller.timeout();
139     		}
140     		bots[i].kill();
141     		if (controller.isFailure()) {
142     			for (int j = i+1; j < numBots; ++j) bots[j].kill();
143     			if (controller.getMessage() != null) {
144     				System.out.println("[ERROR] " + controller.getMessage());
145     			}
146     			
147 				String exceptionMessage = "Test has failed!";
148     			if(controller.getMessage() == null)
149     				exceptionMessage += " " + controller.getMessage();
150 				throw new RuntimeException(exceptionMessage, controller.getCause());
151     			
152     		} else {
153     			if (controller.getMessage() != null) {
154     				System.out.println("[OK] " + controller.getMessage());
155     			}
156     		}
157     	}
158     	
159     	System.out.println("---/// TEST OK ///---");    	
160 	}
161  
162 }