001: /*
002: * Licensed to the Apache Software Foundation (ASF) under one or more
003: * contributor license agreements. See the NOTICE file distributed with
004: * this work for additional information regarding copyright ownership.
005: * The ASF licenses this file to You under the Apache License, Version 2.0
006: * (the "License"); you may not use this file except in compliance with
007: * the License. You may obtain a copy of the License at
008: *
009: * http://www.apache.org/licenses/LICENSE-2.0
010: *
011: * Unless required by applicable law or agreed to in writing, software
012: * distributed under the License is distributed on an "AS IS" BASIS,
013: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014: * See the License for the specific language governing permissions and
015: * limitations under the License.
016: *
017: */
018:
019: package org.apache.tools.ant.taskdefs;
020:
021: import org.apache.tools.ant.util.JavaEnvUtils;
022: import junit.framework.*;
023: import java.io.*;
024:
025: /**
026: * Simple testcase for the ExecuteWatchdog class.
027: *
028: */
029: public class ExecuteWatchdogTest extends TestCase {
030:
031: private final static long TIME_OUT = 5000;
032:
033: private final static String TEST_CLASSPATH = getTestClassPath();
034:
035: private final static int CLOCK_ERROR = 200;
036: private final static long TIME_OUT_TEST = TIME_OUT - CLOCK_ERROR;
037:
038: private ExecuteWatchdog watchdog;
039:
040: public ExecuteWatchdogTest(String name) {
041: super (name);
042: }
043:
044: protected void setUp() {
045: watchdog = new ExecuteWatchdog(TIME_OUT);
046: }
047:
048: /**
049: * Dangerous method to obtain the classpath for the test. This is
050: * severely tighted to the build.xml properties.
051: */
052: private static String getTestClassPath() {
053: String classpath = System.getProperty("build.tests");
054: if (classpath == null) {
055: System.err
056: .println("WARNING: 'build.tests' property is not available !");
057: classpath = System.getProperty("java.class.path");
058: }
059:
060: return classpath;
061: }
062:
063: private Process getProcess(long timetorun) throws Exception {
064: String[] cmdArray = { JavaEnvUtils.getJreExecutable("java"),
065: "-classpath", TEST_CLASSPATH,
066: TimeProcess.class.getName(), String.valueOf(timetorun) };
067: //System.out.println("Testing with classpath: " + System.getProperty("java.class.path"));
068: return Runtime.getRuntime().exec(cmdArray);
069: }
070:
071: private String getErrorOutput(Process p) throws Exception {
072: BufferedReader err = new BufferedReader(new InputStreamReader(p
073: .getErrorStream()));
074: StringBuffer buf = new StringBuffer();
075: String line;
076: while ((line = err.readLine()) != null) {
077: buf.append(line);
078: }
079: return buf.toString();
080: }
081:
082: private int waitForEnd(Process p) throws Exception {
083: int retcode = p.waitFor();
084: if (retcode != 0) {
085: String err = getErrorOutput(p);
086: if (err.length() > 0) {
087: System.err.println("ERROR:");
088: System.err.println(err);
089: }
090: }
091: return retcode;
092: }
093:
094: public void testNoTimeOut() throws Exception {
095: Process process = getProcess(TIME_OUT / 2);
096: watchdog.start(process);
097: int retCode = waitForEnd(process);
098: assertTrue("process should not have been killed", !watchdog
099: .killedProcess());
100: assertFalse(Execute.isFailure(retCode));
101: }
102:
103: // test that the watchdog ends the process
104: public void testTimeOut() throws Exception {
105: Process process = getProcess(TIME_OUT * 2);
106: long now = System.currentTimeMillis();
107: watchdog.start(process);
108: int retCode = process.waitFor();
109: long elapsed = System.currentTimeMillis() - now;
110: assertTrue("process should have been killed", watchdog
111: .killedProcess());
112: // assertTrue("return code is invalid: " + retCode, retCode!=0);
113: assertTrue("elapse time of " + elapsed
114: + " ms is less than timeout value of " + TIME_OUT_TEST
115: + " ms", elapsed >= TIME_OUT_TEST);
116: assertTrue("elapse time of " + elapsed
117: + " ms is greater than run value of " + (TIME_OUT * 2)
118: + " ms", elapsed < TIME_OUT * 2);
119: }
120:
121: // test a process that runs and failed
122: public void testFailed() throws Exception {
123: Process process = getProcess(-1); // process should abort
124: watchdog.start(process);
125: int retCode = process.waitFor();
126: assertTrue("process should not have been killed", !watchdog
127: .killedProcess());
128: assertTrue("return code is invalid: " + retCode, retCode != 0);
129: }
130:
131: public void testManualStop() throws Exception {
132: final Process process = getProcess(TIME_OUT * 2);
133: watchdog.start(process);
134:
135: // I assume that starting this takes less than TIME_OUT/2 ms...
136: Thread thread = new Thread() {
137: public void run() {
138: try {
139: process.waitFor();
140: } catch (InterruptedException e) {
141: // not very nice but will do the job
142: fail("process interrupted in thread");
143: }
144: }
145: };
146: thread.start();
147:
148: // wait for TIME_OUT/2, there should be about TIME_OUT/2 ms remaining before timeout
149: thread.join(TIME_OUT / 2);
150:
151: // now stop the watchdog.
152: watchdog.stop();
153:
154: // wait for the thread to die, should be the end of the process
155: thread.join();
156:
157: // process should be dead and well finished
158: assertEquals(0, process.exitValue());
159: assertTrue("process should not have been killed", !watchdog
160: .killedProcess());
161: }
162: }
|