diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-07 09:06:44 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-07 09:06:44 +0000 |
commit | ed5640d8b587fbcfed7dd7967f3de04b37a76f26 (patch) | |
tree | 7a5f7c6c9d02226d7471cb3cc8fbbf631b415303 /qadevOOo/runner/lib | |
parent | Initial commit. (diff) | |
download | libreoffice-upstream/4%7.4.7.tar.xz libreoffice-upstream/4%7.4.7.zip |
Adding upstream version 4:7.4.7.upstream/4%7.4.7upstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'qadevOOo/runner/lib')
-rw-r--r-- | qadevOOo/runner/lib/DynamicClassLoader.java | 86 | ||||
-rw-r--r-- | qadevOOo/runner/lib/ExceptionStatus.java | 39 | ||||
-rw-r--r-- | qadevOOo/runner/lib/MultiMethodTest.java | 468 | ||||
-rw-r--r-- | qadevOOo/runner/lib/MultiPropertyTest.java | 533 | ||||
-rw-r--r-- | qadevOOo/runner/lib/RunState.java | 43 | ||||
-rw-r--r-- | qadevOOo/runner/lib/SimpleStatus.java | 97 | ||||
-rw-r--r-- | qadevOOo/runner/lib/Status.java | 128 | ||||
-rw-r--r-- | qadevOOo/runner/lib/StatusException.java | 65 | ||||
-rw-r--r-- | qadevOOo/runner/lib/TestCase.java | 170 | ||||
-rw-r--r-- | qadevOOo/runner/lib/TestEnvironment.java | 132 | ||||
-rw-r--r-- | qadevOOo/runner/lib/TestParameters.java | 206 | ||||
-rw-r--r-- | qadevOOo/runner/lib/TestResult.java | 88 |
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 ); + } + +} |