1 /************************************************************************* 2 * 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * Copyright 2000, 2010 Oracle and/or its affiliates. 6 * 7 * OpenOffice.org - a multi-platform office productivity suite 8 * 9 * This file is part of OpenOffice.org. 10 * 11 * OpenOffice.org is free software: you can redistribute it and/or modify 12 * it under the terms of the GNU Lesser General Public License version 3 13 * only, as published by the Free Software Foundation. 14 * 15 * OpenOffice.org is distributed in the hope that it will be useful, 16 * but WITHOUT ANY WARRANTY; without even the implied warranty of 17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 * GNU Lesser General Public License version 3 for more details 19 * (a copy is included in the LICENSE file that accompanied this code). 20 * 21 * You should have received a copy of the GNU Lesser General Public License 22 * version 3 along with OpenOffice.org. If not, see 23 * <http://www.openoffice.org/license.html> 24 * for a copy of the LGPLv3 License. 25 * 26 ************************************************************************/ 27 package complexlib; 28 29 import java.lang.reflect.Method; 30 import share.DescEntry; 31 import lib.TestParameters; 32 import lib.StatusException; 33 import share.LogWriter; 34 import share.ComplexTest; 35 import java.io.PrintWriter; 36 37 /** 38 * Base class for all complex tests. 39 */ 40 public abstract class ComplexTestCase extends Assurance implements ComplexTest 41 { 42 43 /** The test parameters **/ 44 protected static TestParameters param = null; 45 /** Log writer **/ 46 protected static LogWriter log = null; 47 /** 48 * The method name which will be written into f.e. the data base 49 **/ 50 protected String mTestMethodName = null; 51 /** Maximal time one method is allowed to execute 52 * Can be set with parameter 'ThreadTimeOut' 53 **/ 54 protected int m_nThreadTimeOut = 0; 55 /** Continue a test even if it did fail **/ 56 // public static final boolean CONTINUE = true; 57 58 /** End a test if it did fail **/ 59 public static final boolean BREAK = true; 60 61 private boolean m_bBeforeCalled; 62 63 /** 64 * is called before the real test starts 65 */ 66 private void before() 67 { 68 try 69 { 70 Method before = this.getClass().getMethod("before", new Class[] {} ); 71 before.invoke(this, new Object[] {} ); 72 73 // beforeWorked = false; 74 m_bBeforeCalled = true; 75 } 76 catch (java.lang.NoSuchMethodException e) 77 { 78 // simply ignore 79 int dummy = 0; 80 m_bBeforeCalled = true; 81 } 82 catch (java.lang.IllegalAccessException e) 83 { 84 log.println("Cannot access the 'before()' method, although it" + " is there. Is this ok?"); 85 } 86 catch (java.lang.reflect.InvocationTargetException e) 87 { 88 Throwable t = e.getTargetException(); 89 if (!(t instanceof RuntimeException) || state) 90 { 91 log.println(t.toString()); 92 if (message == null) 93 { 94 message = "Exception in before() method.\n\r" + t.getMessage(); 95 } 96 state = false; 97 t.printStackTrace((PrintWriter) log); 98 } 99 } 100 101 } 102 103 /** Description entry **/ 104 // protected DescEntry subEntry = null; 105 106 private void test_method(DescEntry _entry) 107 { 108 109 m_nThreadTimeOut = param.getInt("ThreadTimeOut"); 110 if (m_nThreadTimeOut == 0) 111 { 112 m_nThreadTimeOut = 300000; 113 } 114 115 for (int i = 0; i < _entry.SubEntries.length; i++) 116 { 117 118 DescEntry subEntry = _entry.SubEntries[i]; 119 if (m_bBeforeCalled) 120 { 121 state = true; 122 message = ""; 123 } 124 else 125 { 126 // set all test methods on failed, if 'before()' did not work. 127 subEntry.State = message; 128 subEntry.hasErrorMsg = true; 129 subEntry.ErrorMsg = message; 130 continue; 131 } 132 Method testMethod = null; 133 try 134 { 135 String entryName = subEntry.entryName; 136 Object[] parameter = null; 137 138 if (entryName.indexOf("(") != -1) 139 { 140 String sParameter = (entryName.substring(entryName.indexOf("(") + 1, entryName.indexOf(")"))); 141 mTestMethodName = entryName; 142 parameter = new String[] { sParameter }; 143 entryName = entryName.substring(0, entryName.indexOf("(")); 144 testMethod = this.getClass().getMethod(entryName, new Class[] { String.class }); 145 } 146 else 147 { 148 testMethod = this.getClass().getMethod(entryName, new Class[] {} ); 149 mTestMethodName = entryName; 150 } 151 152 MethodThread th = new MethodThread(testMethod, this, parameter, (java.io.PrintWriter) log); 153 log.println("Starting " + mTestMethodName); 154 th.start(); 155 156 try 157 { 158 // some tests are very dynamic in its exceution time so that 159 // a threadTimeOut fials. In this cases the logging mechanisim 160 // is a usefull way to detect that a office respective a test 161 // is running and not death. 162 // But way ThreadTimeOut? 163 // There exeitsts a complex test which uses no office. Therefore 164 // a logging mechanisim to detect a stalled test. 165 int lastPing = -1; 166 int newPing = 0; 167 168 int sleepingStep = 1000; 169 int factor = 0; 170 171 while (th.isAlive() && (lastPing != newPing || factor * sleepingStep < m_nThreadTimeOut)) 172 { 173 Thread.sleep(sleepingStep); 174 factor++; 175 // if a test starts the office itself it the watcher is a 176 // new one. 177 share.Watcher ow = (share.Watcher) param.get("Watcher"); 178 if (ow != null) 179 { 180 lastPing = newPing; 181 newPing = ow.getPing(); 182 //System.out.println("lastPing: '" + lastPing + "' newPing '" + newPing + "'"); 183 factor = 0; 184 } 185 } 186 } 187 catch (InterruptedException e) 188 { 189 } 190 if (th.isAlive()) 191 { 192 log.println("Destroy " + mTestMethodName); 193 th.destroy(); 194 subEntry.State = "Test did sleep for " + (m_nThreadTimeOut / 1000) + " seconds and has been killed!"; 195 subEntry.hasErrorMsg = true; 196 subEntry.ErrorMsg = subEntry.State; 197 continue; 198 } 199 else 200 { 201 log.println("Finished " + mTestMethodName); 202 if (th.hasErrorMessage()) 203 { 204 subEntry.State = th.getErrorMessage(); 205 subEntry.hasErrorMsg = true; 206 subEntry.ErrorMsg = subEntry.State; 207 continue; 208 } 209 } 210 } 211 catch (java.lang.Exception e) 212 { 213 log.println(e.getClass().getName()); 214 String msg = e.getMessage(); 215 log.println("Message: " + msg); 216 e.printStackTrace((PrintWriter) log); 217 subEntry.State = "SKIPPED.FAILED"; 218 subEntry.hasErrorMsg = true; 219 subEntry.ErrorMsg = (msg == null ? "" : msg); 220 continue; 221 } 222 subEntry.State = (state ? "PASSED.OK" : message); 223 subEntry.hasErrorMsg = !state; 224 subEntry.ErrorMsg = message; 225 } 226 } 227 228 /** 229 * after() is called after the test is done 230 */ 231 private void after() 232 { 233 if (m_bBeforeCalled) 234 { 235 // the after() method 236 try 237 { 238 Method after = this.getClass().getMethod("after", new Class[] {}); 239 after.invoke(this, new Object[] {} ); 240 } 241 catch (java.lang.NoSuchMethodException e) 242 { 243 // simply ignore 244 } 245 catch (java.lang.IllegalAccessException e) 246 { 247 // simply ignore 248 } 249 catch (java.lang.reflect.InvocationTargetException e) 250 { 251 Throwable t = e.getTargetException(); 252 if (!(t instanceof StatusException)) 253 { 254 log.println(t.toString()); 255 if (message == null) 256 { 257 message = "Exception in after() method.\n\r" + t.getMessage(); 258 } 259 else 260 { 261 message += "Exception in \'after()\' method.\n\r" + t.getMessage(); 262 } 263 log.println("Message: " + message); 264 t.printStackTrace((PrintWriter) log); 265 } 266 } 267 } 268 269 } 270 271 272 273 /** 274 * Call test. It is expected, that an environment is 275 * given to this test. 276 * 277 * @param entry The name of the test method that should be called. 278 * @param environment The environment for the test. 279 */ 280 public void executeMethods(DescEntry entry, TestParameters environment) 281 { 282 m_bBeforeCalled = false; 283 284 // get the environment 285 param = environment; 286 log = entry.Logger; 287 288 289 // start with the before() method 290 before(); 291 292 //executeMethodTests 293 test_method(entry); 294 295 // cleanup 296 after(); 297 } 298 299 300 /** 301 * Implement this method in the Complex test. 302 * @return All test method names. 303 */ 304 public abstract String[] getTestMethodNames(); 305 306 /** 307 * Return a name for the test or tested object. 308 * Override to give an own name. 309 * @return As default, the name of this class. 310 */ 311 public String getTestObjectName() 312 { 313 return this.getClass().getName(); 314 } 315 } 316