summaryrefslogtreecommitdiffstats
path: root/qadevOOo/runner/lib
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--qadevOOo/runner/lib/DynamicClassLoader.java86
-rw-r--r--qadevOOo/runner/lib/ExceptionStatus.java39
-rw-r--r--qadevOOo/runner/lib/MultiMethodTest.java468
-rw-r--r--qadevOOo/runner/lib/MultiPropertyTest.java533
-rw-r--r--qadevOOo/runner/lib/RunState.java43
-rw-r--r--qadevOOo/runner/lib/SimpleStatus.java97
-rw-r--r--qadevOOo/runner/lib/Status.java128
-rw-r--r--qadevOOo/runner/lib/StatusException.java65
-rw-r--r--qadevOOo/runner/lib/TestCase.java170
-rw-r--r--qadevOOo/runner/lib/TestEnvironment.java132
-rw-r--r--qadevOOo/runner/lib/TestParameters.java206
-rw-r--r--qadevOOo/runner/lib/TestResult.java88
12 files changed, 2055 insertions, 0 deletions
diff --git a/qadevOOo/runner/lib/DynamicClassLoader.java b/qadevOOo/runner/lib/DynamicClassLoader.java
new file mode 100644
index 000000000..5622221fb
--- /dev/null
+++ b/qadevOOo/runner/lib/DynamicClassLoader.java
@@ -0,0 +1,86 @@
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (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.apache.org/licenses/LICENSE-2.0 .
+ */
+
+package lib ;
+
+import java.lang.reflect.Constructor;
+
+/**
+ * @deprecated: moved to util package.
+ */
+@Deprecated
+public class DynamicClassLoader {
+
+ /**
+ * This method returns a class created by its name
+ * created by call to <code>Class.forName()</code>.<p>
+ * This method must be overridden if another loading
+ * policy is required for Component and Interface
+ * testing classes.
+ */
+ public static Class<?> forName(String className)
+ throws ClassNotFoundException {
+
+ return Class.forName(className) ;
+ }
+
+ public Object getInstance(String className)
+ throws IllegalArgumentException {
+ try {
+ Class<?> cls = DynamicClassLoader.forName(className);
+ return cls.newInstance();
+ } catch ( ClassNotFoundException e ) {
+ throw new IllegalArgumentException("Couldn't find " + className
+ + " " + e);
+ } catch ( IllegalAccessException e ) {
+ throw new IllegalArgumentException("Couldn't access " + className
+ + " " + e);
+ } catch ( InstantiationException e ) {
+ throw new IllegalArgumentException("Couldn't instantiate " +
+ className + " " + e);
+ }
+ }
+
+ public Object getInstance(String className, Object[] ctorArgs)
+ throws IllegalArgumentException {
+ try {
+ Class<?> cls = DynamicClassLoader.forName(className);
+ Class<?>[] ctorType = new Class[ctorArgs.length];
+ for(int i=0; i<ctorType.length; i++) {
+ ctorType[i] = ctorArgs[i].getClass();
+ }
+ Constructor<?> ctor = cls.getConstructor(ctorType);
+ return ctor.newInstance(ctorArgs);
+ } catch ( ClassNotFoundException e ) {
+ throw new IllegalArgumentException("Couldn't find " + className
+ + " " + e);
+ } catch ( IllegalAccessException e ) {
+ throw new IllegalArgumentException("Couldn't access " + className
+ + " " + e);
+ } catch ( NoSuchMethodException e ) {
+ throw new IllegalArgumentException("Couldn't find constructor for " + className
+ + " " + e);
+ } catch ( java.lang.reflect.InvocationTargetException e ) {
+ throw new IllegalArgumentException("Couldn't invoke " +
+ className + " " + e);
+ } catch ( InstantiationException e ) {
+ throw new IllegalArgumentException("Couldn't instantiate " +
+ className + " " + e);
+ }
+ }
+}
diff --git a/qadevOOo/runner/lib/ExceptionStatus.java b/qadevOOo/runner/lib/ExceptionStatus.java
new file mode 100644
index 000000000..d08557341
--- /dev/null
+++ b/qadevOOo/runner/lib/ExceptionStatus.java
@@ -0,0 +1,39 @@
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (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.apache.org/licenses/LICENSE-2.0 .
+ */
+
+package lib;
+
+/**
+ * The class implements Status behaviour for exception runstate Status objects.
+ */
+class ExceptionStatus extends Status {
+
+ /**
+ * Creates an instance of Status object with EXCEPTION runstate.
+ *
+ * @param t the exception an activity terminated with.
+ */
+ ExceptionStatus( Throwable t ) {
+ super(RunState.EXCEPTION, false/*bSuccessful*/);
+ String message = t.getMessage();
+ if (message != null)
+ runStateString = message;
+ else
+ runStateString = t.toString();
+ }
+} \ No newline at end of file
diff --git a/qadevOOo/runner/lib/MultiMethodTest.java b/qadevOOo/runner/lib/MultiMethodTest.java
new file mode 100644
index 000000000..81a87f3f4
--- /dev/null
+++ b/qadevOOo/runner/lib/MultiMethodTest.java
@@ -0,0 +1,468 @@
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (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.apache.org/licenses/LICENSE-2.0 .
+ */
+package lib;
+
+import java.io.PrintWriter;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.util.ArrayList;
+
+import share.DescEntry;
+import stats.Summarizer;
+
+import com.sun.star.uno.UnoRuntime;
+
+/**
+ * The class supports method based interface tests development.
+ *
+ * <p>There are some points that should be fulfilled in a subclass to work
+ * correctly in the multi-method framework:
+ *
+ * 1. each subclass should define a public field named oObj of type tested
+ * by the subclass, e.g. 'public XText oObj;'. That field will be initialized
+ * by the MultiMethodTest code with the instance of the interface to test.
+ * In a case of service testing the field type should be XPropertySet.
+ *
+ * 2. for the test of each method of the tested interface(or a property in the
+ * case of service testing) should be method with the following signature
+ * provided: 'public void _<method name>()', e.g. 'public void _getText()'.
+ * The methods will be called by MultiMethodText code using reflection API
+ * for each method in the interface description.
+ *
+ * 3. to set status for a call 'tRes.tested(String method,
+ * boolean result)' should be used. For example 'tRes.tested("getText()",
+ * true)'. Also 'tRes.assert(String assertion, boolean result)' call can
+ * be used. Note, that one can call the methods not necessarily from the
+ * test for the tested method, but from other method tests too (in the
+ * MultiMethodTest subclass). See also TestResult and MultiMethodTest.tRes
+ * documentation.
+ *
+ * 4. the before() and after() methods can be overridden to perform some
+ * actions, accordingly, before and after calling the test methods.
+ *
+ * 5. besides tRes, there are some fields initialized in the MultiMethodTest,
+ * that can be used for implementing tests:
+ *
+ * - tEnv contains the environment tested
+ * - tParam contains parameters of the test
+ * - log a writer to log information about the test
+ *
+ * @see TestResult
+ */
+@SuppressWarnings("unused")
+public class MultiMethodTest
+{
+
+ /**
+ * Contains the TestEnvironment being tested, to allow for tests to access
+ * it.
+ */
+ protected TestEnvironment tEnv;
+ /**
+ * Contains the TestParameters for the tests, to allow for tests to access
+ * it.
+ */
+ protected TestParameters tParam;
+ /**
+ * Contains the Description for the test
+ * it.
+ */
+ protected DescEntry entry;
+ /**
+ * Contains a writer to log an information about the interface testing, to
+ * allows for tests to access it.
+ */
+ protected PrintWriter log;
+ /**
+ * Contains the TestResult instance for the interface test to collect
+ * information about methods test.
+ */
+ protected TestResult tRes;
+ /**
+ * Contains names of the methods have been already called
+ */
+ private final ArrayList<String> methCalled = new ArrayList<String>(10);
+
+ /**
+ * Disposes the current test environment, which was corrupted by the test.
+ *
+ * @see #disposeEnvironment(TestEnvironment)
+ */
+ public void disposeEnvironment()
+ {
+ tEnv.dispose();
+ TestCase tCase = tEnv.getTestCase();
+ tCase.disposeTestEnvironment(tEnv, tParam);
+ }
+
+ /**
+ * Runs the interface test: its method tests. First, it initializes some
+ * of MultiMethodTest fields, like tRes, log, tEnv, etc. Then, it queries
+ * the tested interface and initializes 'oObj' field (defined in a
+ * subclass). Before calling method tests, before() method is called to allow
+ * initialization of s stuff before testing. Then, the method tests are
+ * called. After them, after() method is called, to allow cleaning up the
+ * stuff initialized in before() and test methods.
+ *
+ * @param entry the interface test state
+ * @param tEnv the environment to test
+ * @param tParam the parameters of the test
+ *
+ * @see #before
+ * @see #after
+ */
+ public TestResult run(DescEntry entry, TestEnvironment tEnv, TestParameters tParam)
+ {
+
+ log = (PrintWriter) entry.Logger;
+
+ this.tEnv = tEnv;
+ this.tParam = tParam;
+ // this.log = log;
+ this.entry = entry;
+ this.tRes = new TestResult();
+ Class<?> testedClass;
+
+ System.out.print("checking: [" + entry.longName + "]");
+
+ // defining a name of the class corresponding to the tested interface
+ // or service
+ String testedClassName;
+
+ testedClassName = getTestedClassName();
+
+ if (entry.EntryType.equals("service"))
+ {
+ testedClassName = "com.sun.star.beans.XPropertySet";
+ }
+
+ try
+ {
+ testedClass = Class.forName(testedClassName);
+ }
+ catch (ClassNotFoundException cnfE)
+ {
+ System.out.println();
+ cnfE.printStackTrace(log);
+ log.println("could not find a class : " + getTestedClassName());
+ return null;
+ }
+ System.out.println(" is iface: [" + testedClassName + "] testcode: [" + entry.entryName + "]");
+
+ Object oObj = UnoRuntime.queryInterface(testedClass, tEnv.getTestObject());
+
+ if (oObj == null)
+ {
+ if (entry.isOptional)
+ {
+ Summarizer.summarizeDown(entry, "Not supported but optional.OK");
+ }
+ else
+ {
+ Summarizer.summarizeDown(entry, "queryInterface returned null.FAILED");
+ entry.ErrorMsg = "queryInterface returned null";
+ entry.hasErrorMsg = true;
+ }
+
+ return null;
+ }
+
+ //setting the field oObj
+ try
+ {
+ setField("oObj", oObj);
+ }
+ catch (Exception e)
+ {
+ e.printStackTrace();
+ setSubStates(e.toString());
+ return tRes;
+ }
+
+ // to perform some stuff before all method tests
+ try
+ {
+ before();
+ }
+ catch (Exception e)
+ {
+ e.printStackTrace();
+ setSubStates(e.toString());
+ return tRes;
+ }
+
+ // executing methods tests
+ for (int i = 0; i < entry.SubEntryCount; i++)
+ {
+ DescEntry aSubEntry = entry.SubEntries[i];
+ try
+ {
+ final String sEntryName = aSubEntry.entryName;
+ executeMethod(sEntryName);
+ }
+ catch (Exception e)
+ {
+ log.println("Exception while checking: " + aSubEntry.entryName + " : " + e.getMessage());
+ }
+ }
+
+ // to perform some stuff after all method tests
+ try
+ {
+ after();
+ }
+ catch (Exception e)
+ {
+ }
+
+ return tRes;
+ }
+
+ /**
+ * Is called before calling method tests, but after initialization.
+ * Subclasses may override to perform actions before method tests.
+ */
+ protected void before() throws Exception
+ {
+ }
+
+ /**
+ * Is called after calling method tests. Subclasses may override
+ * to perform actions after method tests.
+ */
+ protected void after()
+ {
+ }
+
+ /**
+ * @return the name of the interface or the service tested.
+ */
+ protected String getTestedClassName()
+ {
+ String clsName = this.getClass().getName();
+
+ int firstDot = clsName.indexOf('.');
+ int lastDot = clsName.lastIndexOf('.');
+
+ String append = "com.sun.star.";
+
+ if (entry.longName.indexOf("::drafts::com::") > -1)
+ {
+ append = "drafts.com.sun.star.";
+ }
+
+ return append + clsName.substring(firstDot + 1, lastDot + 1) + clsName.substring(lastDot + 2);
+ }
+
+ /**
+ * Sets a method status.
+ *
+ * @param methName the method name to set status
+ * @param methStatus the status to set to the method
+ */
+ private void setStatus(String methName, Status methStatus)
+ {
+ tRes.tested(methName, methStatus);
+ }
+
+ /**
+ * sets the substates
+ */
+ private void setSubStates(String msg)
+ {
+ for (int k = 0; k < entry.SubEntryCount; k++)
+ {
+ entry.SubEntries[k].hasErrorMsg = true;
+ entry.SubEntries[k].ErrorMsg = msg;
+ if (entry.SubEntries[k].State.equals("UNKNOWN"))
+ {
+ entry.SubEntries[k].State = msg;
+ }
+ }
+
+ }
+
+ /**
+ * Checks if the <code>method</code> is optional in the service.
+ */
+ protected boolean isOptional(String _method)
+ {
+ for (int k = 0; k < entry.SubEntryCount; k++)
+ {
+ final String sName = entry.SubEntries[k].entryName;
+ if (sName.equals(_method))
+ {
+ final boolean bIsOptional = entry.SubEntries[k].isOptional;
+ return bIsOptional;
+ }
+ }
+ return false;
+ }
+
+ /**
+ * Checks if the <code>method</code> test has been already called.
+ */
+ private boolean isCalled(String method)
+ {
+ return methCalled.contains(method);
+ }
+
+ /**
+ * Calling of the method indicates that the <code>method</code> test should
+ * be called. The method checks this and if it is not called, calls it.
+ * If the method is failed or skipped, it throws StatusException.
+ */
+ protected void requiredMethod(String method)
+ {
+ log.println("starting required method: " + method);
+ executeMethod(method);
+ Status mtStatus = tRes.getStatusFor(method);
+
+ if (mtStatus != null && (!mtStatus.isCompleted() || mtStatus.isFailed()))
+ {
+ log.println("! Required method " + method + " failed");
+ throw new StatusException(mtStatus);
+ }
+ }
+
+ /**
+ * Checks if the <code>method</code> was called, and if not, call it.
+ * On contrary to requiredMethod(), he method doesn't check its status.
+ */
+ protected void executeMethod(String method)
+ {
+ if (!isCalled(method))
+ {
+ log.println("Execute: " + method);
+ callMethod(method);
+ log.println(method + ": " + tRes.getStatusFor(method));
+ log.println();
+ }
+ }
+
+ /**
+ * Just calls the <code>method</code> test.
+ */
+ private void callMethod(String method)
+ {
+ methCalled.add(method);
+ invokeTestMethod(getMethodFor(method), method);
+ }
+
+ /**
+ * Invokes a test method of the subclass using reflection API. Handles
+ * the method results and sets its status.
+ *
+ * @param meth the subclass' method to invoke
+ * @param methName the name of the method
+ */
+ protected void invokeTestMethod(Method meth, String methName)
+ {
+ if (meth == null)
+ {
+ setStatus(methName, Status.skipped(false));
+ }
+ else
+ {
+ Status stat;
+
+ try
+ {
+ meth.invoke(this, new Object[0]);
+ return;
+ }
+ catch (InvocationTargetException itE)
+ {
+ Throwable t = itE.getTargetException();
+
+ if (t instanceof StatusException)
+ {
+ stat = ((StatusException) t).getStatus();
+ }
+ else
+ {
+ t.printStackTrace(log);
+ stat = Status.exception(t);
+ }
+ }
+ catch (IllegalAccessException iaE)
+ {
+ iaE.printStackTrace(log);
+ stat = Status.exception(iaE);
+ }
+ catch (IllegalArgumentException iaE)
+ {
+ iaE.printStackTrace(log);
+ stat = Status.exception(iaE);
+ }
+ catch (ClassCastException ccE)
+ {
+ ccE.printStackTrace(log);
+ stat = Status.exception(ccE);
+ }
+
+ setStatus(methName, stat);
+ }
+ }
+
+ /**
+ * Finds a testing method for the <code>method</code> of the interface.
+ *
+ * @return the testing method, if found, <tt>null</tt> otherwise
+ */
+ private Method getMethodFor(String method)
+ {
+ String mName = "_" + method;
+
+ if (mName.endsWith("()"))
+ {
+ mName = mName.substring(0, mName.length() - 2);
+ }
+
+ final Class<?>[] paramTypes = new Class[0];
+
+ try
+ {
+ return this.getClass().getDeclaredMethod(mName, paramTypes);
+ }
+ catch (NoSuchMethodException nsmE)
+ {
+ return null;
+ }
+ }
+
+ /**
+ * @return the name of the interface tested
+ */
+ public String getInterfaceName()
+ {
+ String clName = this.getClass().getName();
+ return clName.substring(clName.lastIndexOf('.') + 1);
+ }
+
+ private void setField(String fieldName, Object value)
+ throws NoSuchFieldException, IllegalAccessException
+ {
+ this.getClass().getField(fieldName).set(this, value);
+ }
+
+ protected final void waitForEventIdle() {
+ util.utils.waitForEventIdle(tParam.getMSF());
+ }
+
+}
diff --git a/qadevOOo/runner/lib/MultiPropertyTest.java b/qadevOOo/runner/lib/MultiPropertyTest.java
new file mode 100644
index 000000000..54e7122c4
--- /dev/null
+++ b/qadevOOo/runner/lib/MultiPropertyTest.java
@@ -0,0 +1,533 @@
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (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.apache.org/licenses/LICENSE-2.0 .
+ */
+package lib;
+
+import com.sun.star.beans.Property;
+import com.sun.star.beans.PropertyAttribute;
+import com.sun.star.beans.PropertyVetoException;
+import com.sun.star.beans.XPropertySet;
+import com.sun.star.beans.XPropertySetInfo;
+import com.sun.star.beans.UnknownPropertyException;
+import com.sun.star.lang.IllegalArgumentException;
+import com.sun.star.lang.WrappedTargetException;
+import java.lang.reflect.Array;
+import java.lang.reflect.Field;
+import java.lang.reflect.Method;
+import java.lang.reflect.Modifier;
+
+import util.ValueChanger;
+import util.ValueComparer;
+import util.utils;
+
+/**
+ * MultiPropertyTest extends the functionality of MultiMethodTest to support
+ * services testing. Since, in most cases, service tests has one method testing
+ * most of its properties, the MultiPropertyTest provides unified version of
+ * the method: testProperty().
+ *
+ * <p>The testProperty() is called, when the MultiMethodTest's testing method
+ * is not found in the subclass. So, by defining such methods for properties
+ * the standard testing behaviour can be changed.
+ *
+ * <p>The testing behaviour also can be changed by overriding compare(),
+ * getNewVAlue() or toString(Object) methods, or by extending PropertyTester
+ * class.
+ *
+ * @see MultiMethodTest
+ * @see #testProperty(String)
+ * @see #testProperty(String, PropertyTester)
+ * @see #compare
+ * @see #toString(Object)
+ */
+public class MultiPropertyTest extends MultiMethodTest
+{
+
+ /**
+ * Contains a XPropertySet interface of the tested object. Is initialized
+ * in MultiMethodTest code.
+ */
+ public XPropertySet oObj;
+
+ /**
+ * Overrides MultiMethodTest.invokeTestMethod(). If the test for the
+ * <code>meth</code> is not available (<code>meth</code> == <tt>null</tt>)
+ * calls testProperty method for the method. Otherwise calls
+ * super.invokeTestMethod().
+ *
+ * @see MultiMethodTest#invokeTestMethod
+ */
+ @Override
+ protected void invokeTestMethod(Method meth, String methName)
+ {
+ if (meth != null)
+ {
+ super.invokeTestMethod(meth, methName);
+ }
+ else
+ {
+ testProperty(methName);
+ }
+ }
+
+ /**
+ * PropertyTester class defines how to test a property and defined
+ * to allow subclasses of MultiPropertyTest to change the testing
+ * behaviour more flexible, since the behaviour can be customized for
+ * each property separately, by providing subclass of PropertyTester
+ * and passing it to testProperty(String, PropertyTester method).
+ */
+ public class PropertyTester
+ {
+
+ /**
+ * The method defines the whole process of testing propName
+ * property.
+ *
+ * <p>First, it checks if the property exists(it maybe optional).
+ * Then, a value to set the property with is calculated with
+ * getNewValue method. Normally, the new value is calculated
+ * based on old value, but subclasses can override the behaviour
+ * (for example, if old value is null) and specify their own value.
+ * Then the property is set with that new value and the result(
+ * it maybe an exception too, for example a PropertyVetoException)
+ * is checked with checkResult method.
+ *
+ * @param propName - the property to test.
+ * @result - adds the result of testing propName property to
+ * MultiMethodTest.tRes.
+ */
+ protected void testProperty(String propName)
+ {
+ XPropertySetInfo info = oObj.getPropertySetInfo();
+
+ if (info != null)
+ {
+ final boolean bHasProperty = info.hasPropertyByName(propName);
+ if (!bHasProperty)
+ {
+ if (isOptional(propName) || entry.isOptional)
+ {
+ // skipping optional property test
+ log.println("Property '" + propName + "' is optional and not supported");
+ tRes.tested(propName, true);
+ return;
+ }
+ else
+ {
+ // cannot test the property
+ log.println("Tested XPropertySet does not contain'" + propName + "' property");
+ tRes.tested(propName, false);
+ return;
+ }
+ }
+ }
+
+ try
+ {
+ Object oldValue = oObj.getPropertyValue(propName);
+
+ if( (oldValue==null) || utils.isVoid(oldValue) )
+ {
+ // #i111560# method getNewValue() does not work with an empty oldValue
+ Property prop = info.getPropertyByName(propName);
+ if( (prop.Attributes & PropertyAttribute.MAYBEVOID) != 0 )
+ {
+ // todo: implement a new test independent from method getNewValue()
+ log.println("changing initially empty MAYBEVOID properties is not supported by the test framework so far - skip test of property: " + propName);
+ tRes.tested(propName, true);
+ return;
+ }
+ else
+ {
+ log.println( "property '"+propName+"' is not set but is not MAYBEVOID");
+ tRes.tested(propName, false);
+ return;
+ }
+ }
+
+ Object newValue;
+
+ // trying to create new value
+ try
+ {
+ newValue = getNewValue(propName, oldValue);
+ }
+ catch (java.lang.IllegalArgumentException e)
+ {
+ // skipping test since new value is not available
+ log.println("Cannot create new value for '" + propName + " : " + e.getMessage());
+ return;
+ }
+
+ // for an exception thrown during setting new value
+ // to pass it to checkResult method
+ Exception exception = null;
+
+ try
+ {
+ log.println("try to set:");
+ log.println("old = " + toString(oldValue));
+ log.println("new = " + toString(newValue));
+ oObj.setPropertyValue(propName, newValue);
+ }
+ catch (IllegalArgumentException e)
+ {
+ exception = e;
+ }
+ catch (PropertyVetoException e)
+ {
+ exception = e;
+ }
+ catch (WrappedTargetException e)
+ {
+ exception = e;
+ }
+ catch (UnknownPropertyException e)
+ {
+ exception = e;
+ }
+ catch (RuntimeException e)
+ {
+ exception = e;
+ }
+
+ // getting result value
+ Object resValue = oObj.getPropertyValue(propName);
+
+ // checking results
+ checkResult(propName, oldValue, newValue, resValue, exception);
+ }
+ catch (Exception e)
+ {
+ log.println("Exception occurred while testing property '" + propName + "'");
+ e.printStackTrace(log);
+ tRes.tested(propName, false);
+ }
+ }
+
+ /**
+ * The method checks result of setting a new value to the
+ * property based o the following arguments:
+ * @param propName - the property to test
+ * @param oldValue - the old value of the property, before changing it.
+ * @param newValue - the new value the property has been set with
+ * @param resValue - the value of the property after having changed it
+ * @param exception - if not null - the exception thrown by
+ * XPropertySet.setPropertyValue, else indicates
+ * normal method completion.
+ *
+ * <p>If the property is READ_ONLY, then either PropertyVetoException
+ * should be thrown or the value of property should not have changed
+ * (resValue is compared with oldValue with compare method).
+ *
+ * <p>If the property is not READ_ONLY, checks that the new value has
+ * been successfully set(resValue is compared with newValue with
+ * compare method).
+ *
+ * <p>If the exception is not null then(except the case of read-only
+ * property and PropertyVetoException above) it is rethrown to allow
+ * further catching it if needed.
+ *
+ * <p>Subclasses can override to change this behaviour.
+ */
+ protected void checkResult(String propName, Object oldValue,
+ Object newValue, Object resValue, Exception exception)
+ throws Exception
+ {
+ XPropertySetInfo info = oObj.getPropertySetInfo();
+ if (info == null)
+ {
+ log.println("Can't get XPropertySetInfo for property " + propName);
+ tRes.tested(propName, false);
+ return;
+ }
+ Property prop = info.getPropertyByName(propName);
+
+ boolean readOnly = (prop.Attributes & PropertyAttribute.READONLY) != 0;
+ boolean maybeVoid = (prop.Attributes & PropertyAttribute.MAYBEVOID) != 0;
+ //check get-set methods
+ if (maybeVoid)
+ {
+ log.println("Property " + propName + " is void");
+ }
+ if (readOnly)
+ {
+ log.println("Property " + propName + " is readOnly");
+ }
+ if (util.utils.isVoid(oldValue) && !maybeVoid)
+ {
+ log.println(propName + " is void, but it's not MAYBEVOID");
+ tRes.tested(propName, false);
+ }
+ else if (oldValue == null)
+ {
+ log.println(propName + " has null value, and therefore can't be changed");
+ tRes.tested(propName, true);
+ }
+ else if (readOnly)
+ {
+ // check if exception was thrown
+ if (exception != null)
+ {
+ if (exception instanceof PropertyVetoException)
+ {
+ // the change of read only prohibited - OK
+ log.println("Property is ReadOnly and wasn't changed");
+ log.println("Property '" + propName + "' OK");
+ tRes.tested(propName, true);
+ }
+ else if (exception instanceof IllegalArgumentException)
+ {
+ // the change of read only prohibited - OK
+ log.println("Property is ReadOnly and wasn't changed");
+ log.println("Property '" + propName + "' OK");
+ tRes.tested(propName, true);
+ }
+ else if (exception instanceof UnknownPropertyException)
+ {
+ // the change of read only prohibited - OK
+ log.println("Property is ReadOnly and wasn't changed");
+ log.println("Property '" + propName + "' OK");
+ tRes.tested(propName, true);
+ }
+ else if (exception instanceof RuntimeException)
+ {
+ // the change of read only prohibited - OK
+ log.println("Property is ReadOnly and wasn't changed");
+ log.println("Property '" + propName + "' OK");
+ tRes.tested(propName, true);
+ }
+ else
+ {
+ throw exception;
+ }
+ }
+ else
+ {
+ // if no exception - check that value
+ // has not changed
+ if (!compare(resValue, oldValue))
+ {
+ log.println("Read only property '" + propName + "' has changed");
+ log.println("result = " + toString(resValue));
+ tRes.tested(propName, false);
+ }
+ else
+ {
+ log.println("Read only property '" + propName + "' hasn't changed");
+ log.println("Property '" + propName + "' OK");
+ tRes.tested(propName, true);
+ }
+ }
+ }
+ else
+ {
+ if (exception == null)
+ {
+ // if no exception thrown
+ // check that the new value is set
+ if (!compare(resValue, newValue))
+ {
+ log.println("Value for '" + propName + "' hasn't changed as expected");
+ log.println("result = " + toString(resValue));
+ if (!compare(resValue, oldValue))
+ {
+ log.println("But it has changed.");
+ tRes.tested(propName, true);
+ }
+ else
+ {
+ tRes.tested(propName, false);
+ }
+ }
+ else
+ {
+ log.println("Property '" + propName + "' OK");
+ log.println("result = " + toString(resValue));
+ tRes.tested(propName, true);
+ }
+ }
+ else
+ {
+ throw exception;
+ }
+ }
+ }
+
+ /**
+ * The method produces new value of the property from the oldValue.
+ * It returns the result of ValueChanger.changePValue method.
+ * Subclasses can override the method to return their own value,
+ * when the changePValue behavior is not enough, for example,
+ * when oldValue is null.
+ */
+ protected Object getNewValue(String propName, Object oldValue)
+ throws java.lang.IllegalArgumentException
+ {
+ return ValueChanger.changePValue(oldValue, propName);
+ }
+
+ /**
+ * The method compares obj1 and obj2. It calls
+ * MultiPropertyTest.compare, but subclasses can override to change
+ * the behavior, since normally compare calls Object.equals method
+ * which is not appropriate in some cases(e.g., structs with equals
+ * not overridden).
+ */
+ protected boolean compare(Object obj1, Object obj2)
+ {
+ return MultiPropertyTest.this.compare(obj1, obj2);
+ }
+
+ /**
+ * The method returns a String representation of the obj. It calls
+ * MultipropertyTest.toString(Object), but subclasses can override
+ * to change the behavior.
+ */
+ protected String toString(Object obj)
+ {
+ return MultiPropertyTest.this.toString(obj);
+ }
+ }
+
+ /**
+ * Extension for <code>PropertyTester</code> which switches two
+ * different values. <code>getNewValue()</code> method of this
+ * class returns one of these two values depending on the
+ * old value, so new value is not equal to old value.
+ */
+ public class PropertyValueSwitcher extends PropertyTester
+ {
+
+ Object val1 = null;
+ Object val2 = null;
+
+ /**
+ * Constructs a property tester with two different values
+ * specified as parameters.
+ *
+ * @param val1 Not <code>null</code> value for the property
+ * tested.
+ * @param val2 Not <code>null</code> value for the property
+ * tested which differs from the first value.
+ */
+ public PropertyValueSwitcher(Object val1, Object val2)
+ {
+ this.val1 = val1;
+ this.val2 = val2;
+ }
+
+ /**
+ * Overridden method of <code>PropertyTester</code> which
+ * returns new value from two values specified.
+ *
+ * @return The second value if old value is equal to the first
+ * one, the first value otherwise.
+ */
+ @Override
+ protected Object getNewValue(String propName, Object old)
+ {
+ if (ValueComparer.equalValue(val1, old))
+ {
+ return val2;
+ }
+ else
+ {
+ return val1;
+ }
+ }
+ }
+
+ /**
+ * The method performs testing of propName property using propTester.
+ */
+ protected void testProperty(String propName, PropertyTester propTester)
+ {
+ propTester.testProperty(propName);
+ }
+
+ /**
+ * The method performs testing of propName property. It uses PropertyTester
+ * instance for testing.
+ */
+ protected void testProperty(String propName)
+ {
+ testProperty(propName, new PropertyTester());
+ }
+
+ /**
+ * Tests the property using <code>PropertyValueSwitcher</code>
+ * tester and two values for this property.
+ *
+ * @see PropertyValueSwitcher
+ */
+ protected void testProperty(String propName, Object val1, Object val2)
+ {
+ testProperty(propName, new PropertyValueSwitcher(val1, val2));
+ }
+
+ /**
+ * Compares two object. In the implementation calls obj1.equals(obj2).
+ */
+ protected boolean compare(Object obj1, Object obj2)
+ {
+ return ValueComparer.equalValue(obj1, obj2);
+ }
+
+ /**
+ * Gets string representation of the obj. In the implementation
+ * returns obj.toString().
+ */
+ protected String toString(Object obj)
+ {
+ if (obj == null) {
+ return "null";
+ }
+ StringBuilder s = new StringBuilder(obj.toString());
+ if (obj.getClass().isArray()) {
+ int n = Array.getLength(obj);
+ s.append('[').append(n).append("]{");
+ for (int i = 0; i != n; ++i) {
+ if (i != 0) {
+ s.append(", ");
+ }
+ s.append(toString(Array.get(obj, i)));
+ }
+ s.append('}');
+ } else if (ValueChanger.isStructure(obj)) {
+ s.append('{');
+ Field[] fields = obj.getClass().getFields();
+ boolean first = true;
+ for (int i = 0; i != fields.length; ++i) {
+ if ((fields[i].getModifiers() & Modifier.STATIC) == 0) {
+ if (!first) {
+ s.append(", ");
+ }
+ first = false;
+ try {
+ s.append(toString(fields[i].get(obj)));
+ } catch (IllegalAccessException e) {
+ throw new RuntimeException("unexpected " + e, e);
+ }
+ }
+ }
+ s.append('}');
+ }
+ return s.toString();
+ }
+}
diff --git a/qadevOOo/runner/lib/RunState.java b/qadevOOo/runner/lib/RunState.java
new file mode 100644
index 000000000..4b1eaa511
--- /dev/null
+++ b/qadevOOo/runner/lib/RunState.java
@@ -0,0 +1,43 @@
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (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.apache.org/licenses/LICENSE-2.0 .
+ */
+
+package lib;
+
+public enum RunState {
+
+ /**
+ * The constant represents COMPLETED runtime state.
+ */
+ COMPLETED,
+
+ /**
+ * The constant represents EXCEPTION runtime state.
+ */
+ EXCEPTION,
+
+ /**
+ * The constant represents SKIPPED runtime state.
+ */
+ SKIPPED,
+
+ /**
+ * This is a private indicator for a user defined runtime state
+ */
+ USER_DEFINED
+
+}
diff --git a/qadevOOo/runner/lib/SimpleStatus.java b/qadevOOo/runner/lib/SimpleStatus.java
new file mode 100644
index 000000000..177bfb3f7
--- /dev/null
+++ b/qadevOOo/runner/lib/SimpleStatus.java
@@ -0,0 +1,97 @@
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (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.apache.org/licenses/LICENSE-2.0 .
+ */
+
+package lib;
+
+/**
+ * The class is a simple implementation of Status class. It implements simple
+ * Status behaviour: its state, reason and log are defined when creating
+ * the SimpleSTatus instance.
+ */
+class SimpleStatus {
+
+ /**
+ * The field is holding state of the status.
+ */
+ private final boolean bSuccessful;
+
+ /**
+ * The field is holding reason of the status.
+ */
+ private final RunState runState;
+
+ /**
+ * This is the run state: either SKIPPED, COMPLETED, etc.
+ * or user defined. Deriving classes can overwrite it for own run states.
+ */
+ protected String runStateString;
+
+ /**
+ * The constructor initialize state and reason field.
+ */
+ protected SimpleStatus( RunState runState, boolean bSuccessful ) {
+ this.bSuccessful = bSuccessful;
+ this.runState = runState;
+ if ( runState == RunState.COMPLETED ) {
+ runStateString = "COMPLETED";
+ } else if ( runState == RunState.SKIPPED ) {
+ runStateString = "SKIPPED";
+ } else if ( runState == RunState.EXCEPTION ) {
+ runStateString = "EXCEPTION";
+ } else {
+ runStateString = "UNKNOWN";
+ }
+ }
+
+ /**
+ * The constructor initialize state and reason field.
+ */
+ protected SimpleStatus(String runStateString, boolean bSuccessful) {
+ this.bSuccessful = bSuccessful;
+ this.runState = RunState.USER_DEFINED;
+ this.runStateString = runStateString;
+ }
+
+ public boolean isSuccessful() {
+ return bSuccessful;
+ }
+
+ /**
+ * getRunState() implementation. Just returns th runState field value.
+ */
+ public RunState getRunState() {
+ return runState;
+ }
+
+ /**
+ * getReason implementation. Just returns the reason field value.
+ */
+ public String getRunStateString() {
+ return runStateString;
+ }
+
+ /**
+ * Get the result: passed or failed.
+ */
+ public String getStateString() {
+ if (bSuccessful)
+ return "OK";
+ return "FAILED";
+
+ }
+}
diff --git a/qadevOOo/runner/lib/Status.java b/qadevOOo/runner/lib/Status.java
new file mode 100644
index 000000000..ae7f97ecf
--- /dev/null
+++ b/qadevOOo/runner/lib/Status.java
@@ -0,0 +1,128 @@
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (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.apache.org/licenses/LICENSE-2.0 .
+ */
+
+package lib;
+
+/**
+ * Status represents a result of a testing activity performed. The result is
+ * described in two ways: state and runtime state. The state describes if the
+ * activity was successful (OK state) or not (FAILED state). The runtime state
+ * describes what happened during the activity: the test can be:
+ * - COMPLETED - the activity completed normally (although it can complete with
+ * FAILED state)
+ * - SKIPPED - the activity was not performed because of a reason (it also can
+ * has OK or FAILED state)
+ * - EXCEPTION - the activity was abnormally terminated because of an
+ * unexpected exception. It always has a FAILED state.
+ * - EXCLUDED - the activity is expected to fail. The state represents how
+ * the state really completed: OK or FAILED.
+ * - other variants are not formalized now and can be represented by
+ * Status.failed() method. They always have a FAILED state.
+ */
+public class Status extends SimpleStatus {
+
+ /**
+ * Construct a status: use runState and state
+ * @param runState either COMPLETED, SKIPPED, etc.
+ * @param bSuccessful OK or FAILED.
+ */
+ public Status(RunState runState, boolean bSuccessful ) {
+ super(runState, bSuccessful);
+ }
+
+ /**
+ * Construct a status: use own message and state.
+ * @param message An own message for the status.
+ * @param bSuccessful OK or FAILED.
+ */
+ public Status(String message, boolean state) {
+ super( message, state );
+ }
+
+ /**
+ * This is a factory method for creating a Status representing normal
+ * activity termination.
+ *
+ * @param bSuccessful describes a test state (OK if state == true, FAILED
+ * otherwise).
+ */
+ public static Status passed( boolean bSuccessful ) {
+ return new Status(RunState.COMPLETED, bSuccessful );
+ }
+
+ /**
+ * This is a factory method for creating a Status representing an exception
+ * activity termination. The Status always has FAILED state.
+ *
+ * @param t the exception with that the activity completed.
+ */
+ public static Status exception( Throwable t ) {
+ return new ExceptionStatus( t );
+ }
+
+ /**
+ * This is a factory method for creating a Status representing a skipped
+ * activity.
+ *
+ * @param state describes a test state (OK if state == true, FAILED
+ * otherwise).
+ */
+ public static Status skipped( boolean bSuccessful ) {
+ return new Status( RunState.SKIPPED, bSuccessful );
+ }
+
+
+
+ /**
+ * Creates a Status representing an activity failed for an arbitrary reason.
+ * It always has FAILED state.
+ *
+ * @param reason describes why the activity failed
+ */
+ public static Status failed(final String reason) {
+ return new Status(reason, false/*bSuccessful*/);
+ }
+
+ /**
+ * The method returns a human-readable description of the status.
+ * The Status implementation of the method returns the status state
+ * description and appends to it the reason, for example:
+ * "FAILED.The getLabel works wrong", "COMPLETED.OK".
+ */
+ @Override
+ public String toString() {
+ String str = getRunStateString() + "." + getStateString();
+
+ return str;
+ }
+
+ /**
+ * Checks whether the status runstate is completed.
+ */
+ public boolean isCompleted() {
+ return getRunState() == RunState.COMPLETED;
+ }
+
+ /**
+ * Checks whether the status state is failed.
+ */
+ public boolean isFailed() {
+ return !isSuccessful();
+ }
+
+}
diff --git a/qadevOOo/runner/lib/StatusException.java b/qadevOOo/runner/lib/StatusException.java
new file mode 100644
index 000000000..98ca686af
--- /dev/null
+++ b/qadevOOo/runner/lib/StatusException.java
@@ -0,0 +1,65 @@
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (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.apache.org/licenses/LICENSE-2.0 .
+ */
+
+package lib;
+
+/**
+ * StatusException is used to pass a Status object from a test code which is
+ * terminated abnormally. In many cases this is because of an exception thrown,
+ * but that can also be any other event that hinders the test execution.
+ */
+public class StatusException extends RuntimeException {
+ /**
+ * The Status contained in the StatusException.
+ */
+ private final Status status;
+
+ /**
+ * Constructs a StatusException containing an exception Status.
+ *
+ * @param message the message of the StatusException
+ * @param t the exception of the exception Status
+ */
+ public StatusException( String message, Throwable t ) {
+ super( message, t );
+ status = Status.exception( t );
+ }
+
+ /**
+ * Constructs a StatusException containing an exception Status.
+ */
+ public StatusException( Throwable t, Status st ) {
+ super( t );
+ this.status = st;
+ }
+
+ /**
+ * Creates a StatusException containing a Status.
+ */
+ public StatusException( Status st ) {
+ super( st.getRunStateString() );
+ status = st;
+ }
+
+ /**
+ * @return a status contained in the StatusException.
+ */
+ public Status getStatus() {
+ return status;
+ }
+}
diff --git a/qadevOOo/runner/lib/TestCase.java b/qadevOOo/runner/lib/TestCase.java
new file mode 100644
index 000000000..e5a628a2a
--- /dev/null
+++ b/qadevOOo/runner/lib/TestCase.java
@@ -0,0 +1,170 @@
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (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.apache.org/licenses/LICENSE-2.0 .
+ */
+
+package lib;
+
+import java.io.PrintWriter;
+
+/**
+ * <code>TestCase</code> represent a factory for <code>TestEnvironment</code>s
+ * creation and disposing for a given implementation object. The
+ * <code>TestEnvironment</code> contains an instance of the implementation
+ * object and all additional objects needed to perform tests on the object.
+ *
+ * <p>The <code>TestCase</code> provides four methods for its subclasses to
+ * define its functionality: <code>initialize()</code>, <code>cleanup()</code>,
+ * <code>createTestEnvironment()</code> and <code>disposeTestEnvironment()</code>.
+ * The first two are intended to initialize and cleanup common objects shared
+ * among all instances of <code>TestEnvironment</code> produced by the
+ * <code>TestCase</code>, and they are called at the beginning and at the end of
+ * the <code>TestCase</code> lifecycle accordingly.
+ *
+ * <p>The other two are intended to produce and dispose
+ * <code>TestEnvironment</code> instances. The
+ * <code>createTestEnvironment()</code> is called to create a
+ * <code>TestEnvironment</code> instance and the
+ * <code>disposeTestEnvironment()</code> is called when the instance is not used
+ * anymore.
+ *
+ * @see lib.TestEnvironment
+ */
+public abstract class TestCase {
+
+ /**
+ * Specifies the PrintWriter to log information.
+ */
+ protected PrintWriter log;
+
+ /**
+ * Sets the log to write information during testing.
+ */
+ public void setLogWriter( PrintWriter log ) {
+ this.log = log;
+ }
+
+ /**
+ * Initializes the <code>TestCase</code>. Calls <code>initialize()</code>
+ * method.
+ *
+ * @param tParam test parameters.
+ */
+ public final void initializeTestCase( TestParameters tParam ) throws Exception {
+ initialize( tParam, log );
+ }
+
+ /**
+ * Called while the <code>TestCase</code> initialization. In the
+ * implementation does nothing. Subclasses can override to initialize
+ * objects shared among all <code>TestEnvironment</code>s.
+ *
+ * @param tParam test parameters
+ * @param log writer to log information while testing
+ *
+ * @see #initializeTestCase
+ */
+ protected void initialize( TestParameters tParam, PrintWriter log ) throws Exception {
+ }
+
+
+ /**
+ * Cleans up the <code>TestCase</code>. Calls <code>cleanup()</code>.
+ *
+ * @param tParam test parameters
+ */
+ public final void cleanupTestCase( TestParameters tParam ) {
+ cleanup( tParam, log );
+ }
+
+ /**
+ * Called while the <code>TestCase</code> cleanup. In the implementation
+ * does nothing. Subclasses can override to cleanup objects shared among
+ * all <code>TestEnvironment</code>s.
+ *
+ * @param tParam test parameters
+ * @param log writer to log information while testing
+ *
+ * @see #cleanupTestCase
+ */
+ protected void cleanup( TestParameters tParam, PrintWriter log ) {
+ }
+
+ /**
+ * Creates a <code>TestEnvironment</code> containing an instance of the
+ * implementation object and related objects needed to perform test.
+ *
+ * @param tParam test parameters
+ *
+ * @return the created <code>TestEnvironment</code>
+ *
+ * @see #createTestEnvironment
+ * @see lib.TestEnvironment
+ */
+ public synchronized TestEnvironment getTestEnvironment( TestParameters tParam ) {
+ TestEnvironment tEnv = null;
+ try {
+ tEnv = createTestEnvironment( tParam, log );
+ System.out.println("Environment created");
+ if (tEnv != null) {
+ tEnv.setTestCase(this);
+ }
+ } catch (Exception e) {
+ String message = e.getMessage();
+ if (message == null)
+ message = e.toString();
+ System.out.println("Exception while getting Environment "+message);
+ e.printStackTrace();
+ cleanup(tParam, log);
+ }
+ return tEnv;
+ }
+
+ /**
+ * Disposes the <code>TestEnvironment</code> when it is not needed anymore.
+ *
+ * @param tEnv the environment to dispose
+ * @param tParam test parameters
+ */
+ public synchronized void disposeTestEnvironment( TestEnvironment tEnv,
+ TestParameters tParam ) {
+ cleanup( tParam, log );
+ }
+
+ /**
+ * Called to create an instance of <code>TestEnvironment</code> with an
+ * object to test and related objects. Subclasses should implement this
+ * method to provide the implementation and related objects. The method is
+ * called from <code>getTestEnvironment()</code>.
+ *
+ * @param tParam test parameters
+ * @param log writer to log information while testing
+ *
+ * @see TestEnvironment
+ * @see #getTestEnvironment
+ */
+ protected abstract TestEnvironment createTestEnvironment(
+ TestParameters tParam, PrintWriter log ) throws Exception;
+
+ /**
+ * @return the name of the object
+ */
+ public String getObjectName() {
+ String clName = this.getClass().getName();
+ return clName.substring( clName.lastIndexOf('.') + 1 );
+ }
+
+}
diff --git a/qadevOOo/runner/lib/TestEnvironment.java b/qadevOOo/runner/lib/TestEnvironment.java
new file mode 100644
index 000000000..bba50c18f
--- /dev/null
+++ b/qadevOOo/runner/lib/TestEnvironment.java
@@ -0,0 +1,132 @@
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (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.apache.org/licenses/LICENSE-2.0 .
+ */
+
+package lib;
+import com.sun.star.uno.XInterface;
+
+import java.util.HashMap;
+
+
+/**
+ * The class contains an instance of a given implementation object and
+ * auxiliary objects associated with it and required for the object testing.
+ *
+ * @see TestCase
+ */
+
+public final class TestEnvironment {
+ /**
+ * Contains object relations - auxiliary objects associated with the
+ * tested object and required for testing.
+ */
+ private final HashMap<String, Object> relations = new HashMap<String, Object>(10);
+
+ /**
+ * An instance of the tested implementation object.
+ */
+ private final XInterface testObject;
+
+ /**
+ * Indicates that the testObject is in invalid state and should not be
+ * used for testing anymore.
+ */
+ private boolean disposed = false;
+
+ /**
+ * A reference to TestCase which has created the test environment.
+ */
+ private TestCase tCase;
+
+ /**
+ * Creates an instance of test environment with testObject.
+ *
+ * @param testObject object to test
+ *
+ * @throws java.lang.IllegalArgumentException if the testObject is
+ * <tt>null</tt>.
+ */
+ public TestEnvironment( XInterface testObject ) {
+ if (testObject == null) {
+ throw new IllegalArgumentException(
+ "Couldn't create a test object");
+ }
+ this.testObject = testObject;
+ }
+
+ /**
+ * @return the object to test.
+ */
+ public XInterface getTestObject() {
+ return testObject;
+ }
+
+ /**
+ * Adds to the environment an auxiliary object required for testing.
+ *
+ * @param name a name to reference the auxiliary object
+ *
+ * @param relation the auxiliary object related to the tested one
+ */
+ public void addObjRelation( String name, Object relation) {
+ relations.put( name, relation );
+ }
+
+ /**
+ * Returns an auxiliary object referenced by tname.
+ *
+ * @param name a name of the object relation
+ *
+ * @return the auxiliary object(object relation)
+ */
+ public Object getObjRelation( String name ) {
+ return relations.get( name );
+ }
+
+ /**
+ * Sets the <code>TestCase</code> that created the environment.
+ */
+ public void setTestCase( TestCase tCase) {
+ this.tCase = tCase;
+ }
+
+ /**
+ * @return the <code>TestCase</code> created the environment.
+ */
+ public TestCase getTestCase() {
+ return tCase;
+ }
+
+ /**
+ * Makes the environment invalid, i.e. it should not be used for
+ * testing anymore.
+ */
+ public void dispose() {
+ disposed = true;
+ }
+
+ /**
+ * Checks if the environment has been disposed.
+ *
+ * @return <tt>true</tt< if it has been disposed, <tt>false</tt> otherwise.
+ *
+ * @see #dispose()
+ */
+ public boolean isDisposed() {
+ return disposed;
+ }
+}
diff --git a/qadevOOo/runner/lib/TestParameters.java b/qadevOOo/runner/lib/TestParameters.java
new file mode 100644
index 000000000..04467a9c8
--- /dev/null
+++ b/qadevOOo/runner/lib/TestParameters.java
@@ -0,0 +1,206 @@
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (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.apache.org/licenses/LICENSE-2.0 .
+ */
+
+package lib;
+
+import java.util.HashMap;
+
+import util.PropertyName;
+
+import com.sun.star.beans.XPropertySet;
+import com.sun.star.lang.XMultiServiceFactory;
+import com.sun.star.uno.XComponentContext;
+
+/**
+ * TestParameters describes a parameters (in a form of pairs: name, value) to
+ * be passed to tests and which may affect the test behaviour. That can be,
+ * for example, standard paths, connection strings, etc. The TestParameters
+ * also provides XMultiServiceFactory for the test (tests).
+ */
+public class TestParameters extends HashMap<String,Object> {
+
+ /**
+ * The ConnectionString for Office Connection<br>
+ * default is 'socket,host=localhost,port=8100'
+ */
+ private static final String DefaultConnectionString = "socket,host=localhost,port=8100";
+
+ /**
+ * The Path to the test documents that are loaded during the test <br>
+ */
+ private static final String DefaultTestDocumentPath = "unknown";
+
+ /**
+ * 'true' is a debug information should be written, 'false' elsewhere
+ * these will be provided by the framework.<br>
+ * Debug information will always be written on standard out.<br>
+ * default is true
+ */
+ private static final boolean DebugIsActive = false;
+
+ /**
+ * Wrapper around "get()" with some debug output
+ * @param key A key of this table.
+ * @return The value of this key.
+ * @see java.util.HashMap
+ */
+ @Override
+ public Object get(Object key) {
+ Object val = super.get(key);
+ if (val == null && DebugIsActive) {
+ System.out.print("Have been asked for key \""+key.toString());
+ System.out.println("\" which is not part of params.");
+ }
+ return val;
+ }
+
+ /**
+ * Special get method for boolean values: for convenience.
+ * Will return 'false' if the value is not of "Boolean" type.
+ * @param key A key of this table.
+ * @return The value of this key, cast to a boolean type.
+ */
+ public boolean getBool(Object key) {
+ final Object val = super.get(key);
+ if (val == null) {
+ return false;
+ }
+ if (val instanceof String) {
+ String sVal = (String)val;
+ if (sVal.equalsIgnoreCase("true") ||
+ sVal.equalsIgnoreCase("yes")) {
+ return true;
+ }
+ else if (sVal.equalsIgnoreCase("false") ||
+ sVal.equalsIgnoreCase("no")) {
+ return false;
+ }
+ }
+ else if (val instanceof Boolean)
+ return ((Boolean)val).booleanValue();
+ return false;
+ }
+
+ /**
+ * Special get method for integer values: for convenience.
+ * Will return 0 if the value cannot be interpreted as Integer.
+ * @param key A key of this table.
+ * @return The value of this key, cast to an int type.
+ */
+ public int getInt(Object key) {
+ Object val = super.get(key);
+ if ( val != null ) {
+ if (val instanceof Integer) {
+ return ((Integer)val).intValue();
+ }
+ else {
+ try {
+ if ( val instanceof String ) {
+ Integer nr = Integer.valueOf((String)val);
+ if (nr.intValue() > 0) return nr.intValue();
+ }
+ } catch ( java.lang.NumberFormatException nfe) {}
+ }
+ }
+ return 0;
+ }
+
+
+ /**
+ * Wrapper around "put()"
+ * @param key A key of this table.
+ * @param val The value of the key.
+ * @return The value of this key.
+ * @see java.util.HashMap
+ */
+ @Override
+ public Object put(String key, Object val) {
+ return super.put(key,val);
+ }
+
+ /**
+ * Constructor, defaults for Parameters are set.
+ */
+ public TestParameters() {
+ //fill the propertyset
+ String user = System.getProperty("user.name");
+ if ( user != null)
+ {
+ String PipeConnectionString = "pipe,name=" + user;
+ put(PropertyName.PIPE_CONNECTION_STRING,PipeConnectionString);
+ put(PropertyName.USE_PIPE_CONNECTION, Boolean.TRUE);
+ }
+ put(PropertyName.CONNECTION_STRING, DefaultConnectionString);
+ put(PropertyName.TEST_BASE, "java_fat");
+ put(PropertyName.TEST_DOCUMENT_PATH, DefaultTestDocumentPath);
+ put(PropertyName.LOGGING_IS_ACTIVE, Boolean.TRUE);
+ put(PropertyName.DEBUG_IS_ACTIVE, Boolean.valueOf(DebugIsActive));
+ put(PropertyName.OUT_PRODUCER, "stats.SimpleOutProducer");
+ put(PropertyName.OFFICE_PROVIDER, "helper.OfficeProvider");
+ put(PropertyName.LOG_WRITER, "stats.SimpleLogWriter");
+ put(PropertyName.APP_EXECUTION_COMMAND, "");
+ put(PropertyName.TIME_OUT, Integer.valueOf(3000000));
+ put(PropertyName.THREAD_TIME_OUT, Integer.valueOf(3000000));
+ put(PropertyName.AUTO_RESTART, Boolean.FALSE);
+
+ // get the operating system
+ put(PropertyName.UNORC_NAME, getUnoRcName());
+
+ //For compatibility Reasons
+ System.setProperty("DOCPTH", DefaultTestDocumentPath);
+ }
+
+ /**
+ * @return a XMultiServiceFactory to be used by a test (tests).
+ */
+ public XMultiServiceFactory getMSF() {
+ Object ret = null;
+ ret = get("ServiceFactory");
+ return (XMultiServiceFactory) ret;
+ }
+
+ public XComponentContext getComponentContext() {
+ Object context = get( "ComponentContext" );
+ if ( context == null )
+ {
+ XPropertySet factoryProps = com.sun.star.uno.UnoRuntime.queryInterface(
+ XPropertySet.class, getMSF() );
+ try
+ {
+ context = com.sun.star.uno.UnoRuntime.queryInterface(
+ XComponentContext.class, factoryProps.getPropertyValue( "DefaultContext" ) );
+ put( "ComponentContext", context );
+ }
+ catch( com.sun.star.beans.UnknownPropertyException e ) { }
+ catch( com.sun.star.lang.WrappedTargetException e ) { }
+ }
+ return (XComponentContext)context;
+ }
+
+ /**
+ * @return The uno rc file name uno.ini for windows and unorc for everything else
+ */
+ private String getUnoRcName() {
+ String osname = System.getProperty ("os.name").toLowerCase ();
+ if (osname.indexOf ("windows")>-1) {
+ return "uno.ini";
+ }
+ return "unorc";
+ }
+
+}// finish class TestParameters
diff --git a/qadevOOo/runner/lib/TestResult.java b/qadevOOo/runner/lib/TestResult.java
new file mode 100644
index 000000000..5a1f4898b
--- /dev/null
+++ b/qadevOOo/runner/lib/TestResult.java
@@ -0,0 +1,88 @@
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (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.apache.org/licenses/LICENSE-2.0 .
+ */
+
+package lib;
+
+import java.util.HashMap;
+
+/**
+ * The class supports interface tests development and Status calculation.
+ */
+public class TestResult {
+ /**
+ * Contains methods having been tested and their results.
+ */
+ private HashMap<String, Status> testedMethods = new HashMap<String, Status>();
+
+ /**
+ * The method makes method tested with the result, i.e. it adds to its
+ * state OK (if result == true) or FAILED (if result == false) status
+ * and makes the state of the method completed. It's equal to
+ * tested(method, Status(result)) call.
+ *
+ * @param method refers to the method which was tested
+ * @param result the result of testing the method
+ *
+ * @return the result value
+ *
+ * @throw java.lang.IllegalArgumentException if the method is not
+ * available in the interface.
+ *
+ * @see #tested(String, Status)
+ */
+ public boolean tested( String method, boolean result) {
+ System.out.println("Method "+method+" finished with state "+(result?"OK":"FAILED"));
+ return tested( method, Status.passed( result ) );
+ }
+
+ /**
+ * The method makes the method tested with the status, i.e. it adds the
+ * status to its state and makes it completed.
+ *
+ * @param method refers to the method which was tested
+ * @param status describes the result of testing the method
+ * @return <tt>true</tt> if status is OK, <tt>false</tt> otherwise.
+ *
+ * @throw java.lang.IllegalArgumentException if the method is not
+ * available in the interface.
+ */
+ public boolean tested( String method, Status status ) {
+ testedMethods.put(method,status);
+ return true;
+ }
+
+ /**
+ * @return <tt>true</tt> if the method belongs to the interface tested,
+ * <tt>false</tt> otherwise.
+ */
+ public boolean hasMethod( String method ) {
+ return testedMethods.containsKey( method );
+ }
+
+ /**
+ * @return status of testing the method, if it is available (was set by
+ * the tested or assert method), <tt>null</tt> otherwise.
+ *
+ * @see #tested(String, boolean)
+ * @see #tested(String, Status)
+ */
+ public Status getStatusFor( String method ) {
+ return testedMethods.get( method );
+ }
+
+}