2003-01-27 15:27:53 +00:00
|
|
|
/*************************************************************************
|
|
|
|
|
*
|
|
|
|
|
* $RCSfile: ComplexTestCase.java,v $
|
|
|
|
|
*
|
2005-03-29 10:52:34 +00:00
|
|
|
* $Revision: 1.11 $
|
2003-01-27 15:27:53 +00:00
|
|
|
*
|
2005-03-29 10:52:34 +00:00
|
|
|
* last change: $Date: 2005-03-29 11:52:34 $
|
2003-01-27 15:27:53 +00:00
|
|
|
*
|
|
|
|
|
* The Contents of this file are made available subject to the terms of
|
|
|
|
|
* either of the following licenses
|
|
|
|
|
*
|
|
|
|
|
* - GNU Lesser General Public License Version 2.1
|
|
|
|
|
* - Sun Industry Standards Source License Version 1.1
|
|
|
|
|
*
|
|
|
|
|
* Sun Microsystems Inc., October, 2000
|
|
|
|
|
*
|
|
|
|
|
* GNU Lesser General Public License Version 2.1
|
|
|
|
|
* =============================================
|
|
|
|
|
* Copyright 2000 by Sun Microsystems, Inc.
|
|
|
|
|
* 901 San Antonio Road, Palo Alto, CA 94303, USA
|
|
|
|
|
*
|
|
|
|
|
* This library is free software; you can redistribute it and/or
|
|
|
|
|
* modify it under the terms of the GNU Lesser General Public
|
|
|
|
|
* License version 2.1, as published by the Free Software Foundation.
|
|
|
|
|
*
|
|
|
|
|
* This library is distributed in the hope that it will be useful,
|
|
|
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
|
|
|
* Lesser General Public License for more details.
|
|
|
|
|
*
|
|
|
|
|
* You should have received a copy of the GNU Lesser General Public
|
|
|
|
|
* License along with this library; if not, write to the Free Software
|
|
|
|
|
* Foundation, Inc., 59 Temple Place, Suite 330, Boston,
|
|
|
|
|
* MA 02111-1307 USA
|
|
|
|
|
*
|
|
|
|
|
*
|
|
|
|
|
* Sun Industry Standards Source License Version 1.1
|
|
|
|
|
* =================================================
|
|
|
|
|
* The contents of this file are subject to the Sun Industry Standards
|
|
|
|
|
* Source License Version 1.1 (the "License"); You may not use this file
|
|
|
|
|
* except in compliance with the License. You may obtain a copy of the
|
|
|
|
|
* License at http://www.openoffice.org/license.html.
|
|
|
|
|
*
|
|
|
|
|
* Software provided under this License is provided on an "AS IS" basis,
|
|
|
|
|
* WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
|
|
|
|
|
* WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
|
|
|
|
|
* MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
|
|
|
|
|
* See the License for the specific provisions governing your rights and
|
|
|
|
|
* obligations concerning the Software.
|
|
|
|
|
*
|
|
|
|
|
* The Initial Developer of the Original Code is: Sun Microsystems, Inc.
|
|
|
|
|
*
|
|
|
|
|
* Copyright: 2000 by Sun Microsystems, Inc.
|
|
|
|
|
*
|
|
|
|
|
* All Rights Reserved.
|
|
|
|
|
*
|
|
|
|
|
* Contributor(s): _______________________________________
|
|
|
|
|
*
|
|
|
|
|
*
|
|
|
|
|
************************************************************************/
|
|
|
|
|
|
|
|
|
|
package complexlib;
|
|
|
|
|
|
2005-03-29 10:52:34 +00:00
|
|
|
import java.lang.Class;
|
2003-01-27 15:27:53 +00:00
|
|
|
import java.lang.reflect.Method;
|
|
|
|
|
import share.DescEntry;
|
|
|
|
|
import lib.TestParameters;
|
2003-05-27 11:01:31 +00:00
|
|
|
import lib.StatusException;
|
2003-01-27 15:27:53 +00:00
|
|
|
import share.LogWriter;
|
|
|
|
|
import share.ComplexTest;
|
2003-04-01 08:18:04 +00:00
|
|
|
import java.io.PrintWriter;
|
2003-01-27 15:27:53 +00:00
|
|
|
|
|
|
|
|
|
2003-10-06 11:37:52 +00:00
|
|
|
/**
|
|
|
|
|
* Base class for all complex tests.
|
|
|
|
|
*/
|
|
|
|
|
public abstract class ComplexTestCase implements ComplexTest {
|
|
|
|
|
/** The test parameters **/
|
2003-11-18 15:13:44 +00:00
|
|
|
static protected TestParameters param = null;
|
2003-10-06 11:37:52 +00:00
|
|
|
/** Log writer **/
|
2003-11-18 15:13:44 +00:00
|
|
|
static protected LogWriter log = null;
|
2003-10-06 11:37:52 +00:00
|
|
|
/** Description entry **/
|
|
|
|
|
protected DescEntry subEntry = null;
|
|
|
|
|
/** State of the current test method **/
|
|
|
|
|
protected boolean state = true;
|
|
|
|
|
/** The message if the test did fail **/
|
|
|
|
|
protected String message = null;
|
|
|
|
|
/** Maximal time one method is allowed to execute
|
|
|
|
|
* Can be set with parameter 'ThreadTimeOut'
|
|
|
|
|
**/
|
|
|
|
|
protected int mThreadTimeOut = 0;
|
2003-11-18 15:13:44 +00:00
|
|
|
/** Continue a test even if it did fail **/
|
|
|
|
|
public static final boolean CONTINUE = true;
|
|
|
|
|
/** End a test if it did fail **/
|
|
|
|
|
public static final boolean BREAK = true;
|
2003-01-27 15:27:53 +00:00
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Call test. It is expected, that an environment is
|
|
|
|
|
* given to this test.
|
|
|
|
|
*
|
|
|
|
|
* @param method The name of the test method that should be called.
|
|
|
|
|
* @param environment The environment for the test.
|
|
|
|
|
*/
|
2003-03-18 14:55:08 +00:00
|
|
|
public void executeMethods(DescEntry entry, TestParameters environment) {
|
2003-01-27 15:27:53 +00:00
|
|
|
|
|
|
|
|
// get the environment
|
|
|
|
|
param = environment;
|
|
|
|
|
log = entry.Logger;
|
2003-10-06 11:37:52 +00:00
|
|
|
|
|
|
|
|
mThreadTimeOut = param.getInt("ThreadTimeOut");
|
|
|
|
|
if (mThreadTimeOut == 0) mThreadTimeOut = 300000;
|
2003-03-18 14:55:08 +00:00
|
|
|
|
|
|
|
|
// start with the before() method
|
2003-10-06 11:37:52 +00:00
|
|
|
boolean beforeWorked = true;
|
2003-03-18 14:55:08 +00:00
|
|
|
try {
|
2005-03-29 10:52:34 +00:00
|
|
|
Method before = this.getClass().getMethod("before",new Class[]{});
|
|
|
|
|
before.invoke(this, new Object[]{});
|
2003-03-18 14:55:08 +00:00
|
|
|
}
|
|
|
|
|
catch(java.lang.NoSuchMethodException e) {
|
|
|
|
|
// simply ignore
|
|
|
|
|
}
|
|
|
|
|
catch(java.lang.IllegalAccessException e) {
|
2003-10-06 11:37:52 +00:00
|
|
|
log.println("Cannot access the 'before()' method, although it" +
|
|
|
|
|
" is there. Is this ok?");
|
2003-03-18 14:55:08 +00:00
|
|
|
}
|
|
|
|
|
catch(java.lang.reflect.InvocationTargetException e) {
|
2003-10-06 11:37:52 +00:00
|
|
|
beforeWorked = false;
|
2003-03-18 14:55:08 +00:00
|
|
|
Throwable t = e.getTargetException();
|
2003-10-06 11:37:52 +00:00
|
|
|
if (!(t instanceof RuntimeException) || state) {
|
2003-05-27 11:01:31 +00:00
|
|
|
log.println(t.toString());
|
2003-10-06 11:37:52 +00:00
|
|
|
if ( message == null ) {
|
|
|
|
|
message = "Exception in before() method.\n\r" + t.getMessage();
|
|
|
|
|
}
|
|
|
|
|
state = false;
|
2003-05-27 11:01:31 +00:00
|
|
|
t.printStackTrace((PrintWriter)log);
|
|
|
|
|
}
|
2003-03-18 14:55:08 +00:00
|
|
|
}
|
2003-01-27 15:27:53 +00:00
|
|
|
|
2003-10-06 11:37:52 +00:00
|
|
|
|
2003-01-27 15:27:53 +00:00
|
|
|
//executeMethodTests
|
|
|
|
|
for (int i=0; i<entry.SubEntries.length; i++) {
|
|
|
|
|
subEntry = entry.SubEntries[i];
|
2003-10-06 11:37:52 +00:00
|
|
|
if (beforeWorked) {
|
|
|
|
|
state = true;
|
|
|
|
|
message = "";
|
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
// set all test methods on failed, if 'before()' did not work.
|
|
|
|
|
subEntry.State = message;
|
2003-03-18 14:55:08 +00:00
|
|
|
subEntry.hasErrorMsg = true;
|
2003-10-06 11:37:52 +00:00
|
|
|
subEntry.ErrorMsg = message;
|
2003-03-18 14:55:08 +00:00
|
|
|
continue;
|
|
|
|
|
}
|
2003-01-27 15:27:53 +00:00
|
|
|
Method testMethod = null;
|
|
|
|
|
try {
|
|
|
|
|
testMethod = this.getClass().getMethod(
|
2005-03-29 10:52:34 +00:00
|
|
|
subEntry.entryName, new Class[]{});
|
2003-10-06 11:37:52 +00:00
|
|
|
MethodThread th = new MethodThread(testMethod, this,
|
|
|
|
|
(java.io.PrintWriter)log);
|
2003-12-11 10:31:22 +00:00
|
|
|
log.println("Starting " + testMethod.getName());
|
2003-10-06 11:37:52 +00:00
|
|
|
th.start();
|
2005-02-02 12:55:31 +00:00
|
|
|
|
2003-10-06 11:37:52 +00:00
|
|
|
try {
|
2005-02-02 12:55:31 +00:00
|
|
|
// some tests are very dynamic in its exceution time so that
|
|
|
|
|
// a threadTimeOut fials. In this cases the logging mechanisim
|
|
|
|
|
// is a usefull way to detect that a office respective a test
|
|
|
|
|
// is running and not death.
|
|
|
|
|
// But way ThreadTimeOut?
|
|
|
|
|
// There exeitsts a complex test which uses no office. Therefore
|
|
|
|
|
// a logging mechanisim to detect a stalled test.
|
|
|
|
|
|
|
|
|
|
int lastPing = -1;
|
|
|
|
|
int newPing = 0;
|
|
|
|
|
|
2003-10-06 11:37:52 +00:00
|
|
|
int sleepingStep = 1000;
|
|
|
|
|
int factor = 0;
|
2005-02-02 12:55:31 +00:00
|
|
|
|
|
|
|
|
while(
|
|
|
|
|
th.isAlive() &&
|
|
|
|
|
(
|
|
|
|
|
lastPing != newPing ||
|
|
|
|
|
factor*sleepingStep<mThreadTimeOut
|
|
|
|
|
)
|
|
|
|
|
)
|
|
|
|
|
{
|
2003-10-06 11:37:52 +00:00
|
|
|
Thread.sleep(sleepingStep);
|
|
|
|
|
factor++;
|
2005-02-02 12:55:31 +00:00
|
|
|
// if a test starts the office itself it the watcher is a
|
|
|
|
|
// new one.
|
|
|
|
|
share.Watcher ow = (share.Watcher)
|
|
|
|
|
param.get("Watcher");
|
|
|
|
|
if (ow != null) {
|
|
|
|
|
lastPing = newPing;
|
|
|
|
|
newPing = ow.getPing();
|
|
|
|
|
//System.out.println("lastPing: '" + lastPing + "' newPing '" + newPing + "'");
|
|
|
|
|
factor = 0;
|
|
|
|
|
}
|
2003-10-06 11:37:52 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
catch(InterruptedException e) {}
|
|
|
|
|
if (th.isAlive()) {
|
|
|
|
|
log.println("Destroy " + testMethod.getName());
|
|
|
|
|
th.destroy();
|
|
|
|
|
subEntry.State="Test did sleep for " +
|
|
|
|
|
(mThreadTimeOut / 1000) +
|
|
|
|
|
" seconds and has been killed!";
|
2003-05-27 11:01:31 +00:00
|
|
|
subEntry.hasErrorMsg = true;
|
2003-10-06 11:37:52 +00:00
|
|
|
subEntry.ErrorMsg = subEntry.State;
|
2003-05-27 11:01:31 +00:00
|
|
|
continue;
|
2003-10-06 11:37:52 +00:00
|
|
|
} else {
|
2003-12-11 10:31:22 +00:00
|
|
|
log.println("Finished " + testMethod.getName());
|
2003-10-06 11:37:52 +00:00
|
|
|
if (th.hasErrorMessage()) {
|
2003-12-11 10:31:22 +00:00
|
|
|
subEntry.State=th.getErrorMessage();
|
2003-10-06 11:37:52 +00:00
|
|
|
subEntry.hasErrorMsg = true;
|
|
|
|
|
subEntry.ErrorMsg = subEntry.State;
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
}
|
2003-01-27 15:27:53 +00:00
|
|
|
}
|
|
|
|
|
catch(java.lang.Exception e) {
|
|
|
|
|
log.println(e.getClass().getName());
|
2003-03-18 14:55:08 +00:00
|
|
|
String msg = e.getMessage();
|
|
|
|
|
log.println("Message: " + msg);
|
2003-04-01 08:18:04 +00:00
|
|
|
e.printStackTrace((PrintWriter)log);
|
2003-01-27 15:27:53 +00:00
|
|
|
subEntry.State="SKIPPED.FAILED";
|
2003-03-18 14:55:08 +00:00
|
|
|
subEntry.hasErrorMsg = true;
|
|
|
|
|
subEntry.ErrorMsg = (msg == null?"":msg);
|
2003-01-27 15:27:53 +00:00
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
subEntry.State = (state?"PASSED.OK":message);
|
2003-03-18 14:55:08 +00:00
|
|
|
subEntry.hasErrorMsg = !state;
|
2003-01-27 15:27:53 +00:00
|
|
|
subEntry.ErrorMsg = message;
|
|
|
|
|
}
|
2003-03-18 14:55:08 +00:00
|
|
|
|
2003-10-06 11:37:52 +00:00
|
|
|
if (beforeWorked) {
|
2003-03-18 14:55:08 +00:00
|
|
|
// the after() method
|
|
|
|
|
try {
|
2005-03-29 10:52:34 +00:00
|
|
|
Method after = this.getClass().getMethod("after", new Class[]{});
|
|
|
|
|
after.invoke(this, new Object[]{});
|
2003-03-18 14:55:08 +00:00
|
|
|
}
|
|
|
|
|
catch(java.lang.NoSuchMethodException e) {
|
|
|
|
|
// simply ignore
|
|
|
|
|
}
|
|
|
|
|
catch(java.lang.IllegalAccessException e) {
|
|
|
|
|
// simply ignore
|
|
|
|
|
}
|
|
|
|
|
catch(java.lang.reflect.InvocationTargetException e) {
|
|
|
|
|
Throwable t = e.getTargetException();
|
2003-05-27 11:01:31 +00:00
|
|
|
if (!(t instanceof StatusException)) {
|
|
|
|
|
log.println(t.toString());
|
2003-10-06 11:37:52 +00:00
|
|
|
if ( message == null ) {
|
|
|
|
|
message = "Exception in after() method.\n\r" + t.getMessage();
|
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
message += "Exception in 'after()' method.\n\r" + t.getMessage();
|
|
|
|
|
}
|
|
|
|
|
log.println("Message: " + message);
|
2003-05-27 11:01:31 +00:00
|
|
|
t.printStackTrace((PrintWriter)log);
|
|
|
|
|
}
|
2003-03-18 14:55:08 +00:00
|
|
|
}
|
|
|
|
|
}
|
2003-01-27 15:27:53 +00:00
|
|
|
}
|
|
|
|
|
|
2003-10-06 11:37:52 +00:00
|
|
|
/**
|
|
|
|
|
* Implement this method in the Complex test.
|
|
|
|
|
* @return All test method names.
|
|
|
|
|
*/
|
2003-01-27 15:27:53 +00:00
|
|
|
public abstract String[] getTestMethodNames();
|
|
|
|
|
|
2003-10-06 11:37:52 +00:00
|
|
|
/**
|
|
|
|
|
* Return a name for the test or tested object.
|
|
|
|
|
* Override to give an own name.
|
|
|
|
|
* @return As default, the name of this class.
|
|
|
|
|
*/
|
2003-05-27 11:01:31 +00:00
|
|
|
public String getTestObjectName() {
|
|
|
|
|
return this.getClass().getName();
|
|
|
|
|
}
|
|
|
|
|
|
2003-10-06 11:37:52 +00:00
|
|
|
/**
|
|
|
|
|
* Assure that s is true.
|
|
|
|
|
* This function generates "Assure failed." as standard message.
|
|
|
|
|
* @param s The condition that should be true.
|
|
|
|
|
*/
|
2003-05-27 11:01:31 +00:00
|
|
|
protected void assure(boolean s) {
|
|
|
|
|
assure("Assure failed.", s, false);
|
|
|
|
|
}
|
2003-01-27 15:27:53 +00:00
|
|
|
|
2003-10-06 11:37:52 +00:00
|
|
|
/**
|
|
|
|
|
* Assure that s is true.
|
|
|
|
|
* The given message will be only evaluated, if s is false.
|
|
|
|
|
* @param msg The message that is evaluated.
|
|
|
|
|
* @param s The condition that should be true.
|
|
|
|
|
*/
|
2003-03-18 14:55:08 +00:00
|
|
|
protected void assure(String msg, boolean s) {
|
2003-05-27 11:01:31 +00:00
|
|
|
assure(msg, s, false);
|
|
|
|
|
}
|
|
|
|
|
|
2003-10-06 11:37:52 +00:00
|
|
|
/**
|
|
|
|
|
* Mark the currently executed method as failed.
|
|
|
|
|
* This function generates "Test did fail." as standard message.
|
|
|
|
|
*/
|
2003-05-27 11:01:31 +00:00
|
|
|
protected void failed() {
|
|
|
|
|
assure("Test did fail.", false, false);
|
|
|
|
|
}
|
|
|
|
|
|
2003-10-06 11:37:52 +00:00
|
|
|
/**
|
|
|
|
|
* Mark the currently executed method as failed.
|
|
|
|
|
* with the given message.
|
|
|
|
|
* @param msg The message of the failure.
|
|
|
|
|
*/
|
2003-05-27 11:01:31 +00:00
|
|
|
protected void failed(String msg) {
|
|
|
|
|
assure(msg, false, false);
|
|
|
|
|
}
|
|
|
|
|
|
2003-10-06 11:37:52 +00:00
|
|
|
/**
|
|
|
|
|
* Assure that s is true.
|
|
|
|
|
* The given message will be only evaluated, if s is false.
|
|
|
|
|
* Normally, assure() leaves the current test method, and the next one
|
|
|
|
|
* is executed. With the parameter 'cont' set to true, the current test
|
|
|
|
|
* method will continue.<br>
|
|
|
|
|
* The current method will of course marked as failed.
|
|
|
|
|
* @param msg The message that is evaluated.
|
|
|
|
|
* @param s The condition that should be true.
|
|
|
|
|
* @param cont Continue with test method, even if s is false.
|
|
|
|
|
*/
|
2003-05-27 11:01:31 +00:00
|
|
|
protected void assure(String msg, boolean s, boolean cont) {
|
2003-03-18 14:55:08 +00:00
|
|
|
state &= s;
|
|
|
|
|
if (!s) {
|
|
|
|
|
message += msg + "\r\n";
|
2003-01-27 15:27:53 +00:00
|
|
|
log.println(msg);
|
2003-05-27 11:01:31 +00:00
|
|
|
if (!cont) {
|
2003-12-11 10:31:22 +00:00
|
|
|
throw new AssureException(msg);
|
2003-05-27 11:01:31 +00:00
|
|
|
}
|
2003-01-27 15:27:53 +00:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2003-10-06 11:37:52 +00:00
|
|
|
/**
|
|
|
|
|
* Mark the currently executed method as failed.
|
|
|
|
|
* with the given message.
|
|
|
|
|
* The given message will be only evaluated, if s is false.
|
|
|
|
|
* With the parameter 'cont' set to true, the current test
|
|
|
|
|
* method will continue.<br>
|
|
|
|
|
* The current method will of course marked as failed.
|
|
|
|
|
* @param msg The message that is evaluated.
|
|
|
|
|
* @param cont Continue with test method, even if s is false.
|
|
|
|
|
*/
|
2003-05-27 11:01:31 +00:00
|
|
|
protected void failed(String msg, boolean cont) {
|
|
|
|
|
assure(msg, false, cont);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* @deprecated
|
|
|
|
|
*/
|
2003-01-27 15:27:53 +00:00
|
|
|
protected void addResult(String message, boolean state) {
|
|
|
|
|
String msg = message + " - " + state;
|
|
|
|
|
this.state &= state;
|
|
|
|
|
this.message += msg + "\r\n";
|
|
|
|
|
log.println(msg);
|
|
|
|
|
}
|
2003-12-11 10:31:22 +00:00
|
|
|
|
|
|
|
|
|
|
|
|
|
public class AssureException extends RuntimeException {
|
|
|
|
|
public AssureException(String msg) {
|
|
|
|
|
super(msg);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
}
|
2003-01-27 15:27:53 +00:00
|
|
|
}
|
2003-05-27 11:01:31 +00:00
|
|
|
|
|
|
|
|
|