diff options
author | David Ostrovsky <david@ostrovsky.org> | 2013-03-30 22:10:48 +0100 |
---|---|---|
committer | David Ostrovsky <David.Ostrovsky@gmx.de> | 2013-04-09 05:52:23 +0000 |
commit | 0e68bac85293e2d60fa6db3e46de8b74ab5d502b (patch) | |
tree | 17b4edeb6bfbce3724de003a87718d6b8f895642 /unotest | |
parent | d64b5cc1c3d232ba42479fe0a3c186ecabd25144 (diff) |
set up python unit test infrastructure
Extract boostraping code from convwatch.py to unotest.py. Use python builtin
unittest module as unit test framework. Specify the unit test modules in make
file. Another option would be to use discover mode of unittest module.
Add __pycache__ to global .gitignore to keep the source directory clean.
Another option would be to deliver the unit tests to workdir prior to test
execution.
Currently only system python3 is supported.
Change-Id: I2692817673f786e950e1176a17c7675f989755b6
Reviewed-on: https://gerrit.libreoffice.org/3214
Reviewed-by: David Ostrovsky <David.Ostrovsky@gmx.de>
Tested-by: David Ostrovsky <David.Ostrovsky@gmx.de>
Diffstat (limited to 'unotest')
-rw-r--r-- | unotest/source/python/org/__init__.py | 0 | ||||
-rw-r--r-- | unotest/source/python/org/libreoffice/__init__.py | 0 | ||||
-rw-r--r-- | unotest/source/python/org/libreoffice/unotest.py | 215 |
3 files changed, 215 insertions, 0 deletions
diff --git a/unotest/source/python/org/__init__.py b/unotest/source/python/org/__init__.py new file mode 100644 index 000000000000..e69de29bb2d1 --- /dev/null +++ b/unotest/source/python/org/__init__.py diff --git a/unotest/source/python/org/libreoffice/__init__.py b/unotest/source/python/org/libreoffice/__init__.py new file mode 100644 index 000000000000..e69de29bb2d1 --- /dev/null +++ b/unotest/source/python/org/libreoffice/__init__.py diff --git a/unotest/source/python/org/libreoffice/unotest.py b/unotest/source/python/org/libreoffice/unotest.py new file mode 100644 index 000000000000..c5cfa596ee53 --- /dev/null +++ b/unotest/source/python/org/libreoffice/unotest.py @@ -0,0 +1,215 @@ +# -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +# +# 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/. +# + +import subprocess +import time +import uuid +import argparse +import os + +try: + import pyuno + import uno +except ImportError: + print("pyuno not found: try to set PYTHONPATH and URE_BOOTSTRAP variables") + print("PYTHONPATH=/installation/opt/program") + print("URE_BOOTSTRAP=file:///installation/opt/program/fundamentalrc") + raise + +try: + from com.sun.star.document import XDocumentEventListener +except ImportError: + print("UNO API class not found: try to set URE_BOOTSTRAP variable") + print("URE_BOOTSTRAP=file:///installation/opt/program/fundamentalrc") + raise + +### utilities ### + +def mkPropertyValue(name, value): + return uno.createUnoStruct("com.sun.star.beans.PropertyValue", name, 0, value, 0) + +### UNO utilities ### + +class OfficeConnection(object): + + def __init__(self, args): + self.args = args + self.soffice = None + self.xContext = None + self.channel = None + + def setUp(self): + try: + self.verbose = self.args["verbose"] + except KeyError: + self.verbose = False + try: + prog = self.args["programm"] + except KeyError: + prog = os.getenv("SOFFICE_BIN") + if not (prog): + raise Exception("SOFFICE_BIN must be set") + channel = "pipe,name=pytest" + str(uuid.uuid1()) + try: + userdir = self.args["userdir"] + except KeyError: + userdir = "file:///tmp" + if not(userdir.startswith("file://")): + raise Exception("--userdir must be file URL") + self.soffice = self.bootstrap(prog, userdir, channel) + return self.connect(channel) + + def bootstrap(self, soffice, userdir, channel): + argv = [ soffice, "--accept=" + channel + ";urp", + "-env:UserInstallation=" + userdir, + "--quickstart=no", "--nofirststartwizard", + "--norestore", "--nologo", "--headless"] + if "--valgrind" in self.args: + argv.append("--valgrind") + if self.verbose: + print ("starting LibreOffice with channel: ", channel) + return subprocess.Popen(argv) + + def connect(self, channel): + xLocalContext = uno.getComponentContext() + xUnoResolver = xLocalContext.ServiceManager.createInstanceWithContext( + "com.sun.star.bridge.UnoUrlResolver", xLocalContext) + url = ("uno:%s;urp;StarOffice.ComponentContext" % channel) + if self.verbose: + print("Connecting to: ", url) + while True: + try: + self.xContext = xUnoResolver.resolve(url) + return self.xContext +# except com.sun.star.connection.NoConnectException + except pyuno.getClass("com.sun.star.connection.NoConnectException"): + print("WARN: NoConnectException: sleeping...") + time.sleep(1) + + def tearDown(self): + if self.soffice: + if self.xContext: + try: + if self.verbose: + print("tearDown: calling terminate()...") + xMgr = self.xContext.ServiceManager + xDesktop = xMgr.createInstanceWithContext( + "com.sun.star.frame.Desktop", self.xContext) + xDesktop.terminate() + if self.verbose: + print("...done") +# except com.sun.star.lang.DisposedException: + except pyuno.getClass("com.sun.star.beans.UnknownPropertyException"): + print("caught UnknownPropertyException") + pass # ignore, also means disposed + except pyuno.getClass("com.sun.star.lang.DisposedException"): + print("caught DisposedException") + pass # ignore + else: + self.soffice.terminate() + ret = self.soffice.wait() + self.xContext = None + self.socket = None + self.soffice = None +# WTF 255 return value? +# if ret != 0: +# raise Exception("Exit status indicates failure: " + str(ret)) +# return ret + + def getContext(self): + return self.xContext + +class UnoConnection: + def __init__(self, args): + self.args = args + self.connection = None + def getContext(self): + return self.connection.xContext + def getDoc(self): + return self.xDoc + def setUp(self): + conn = OfficeConnection(self.args) + conn.setUp() + self.connection = conn + def openEmptyWriterDoc(self): + assert(self.connection) + smgr = self.getContext().ServiceManager + desktop = smgr.createInstanceWithContext("com.sun.star.frame.Desktop", self.getContext()) + props = [("Hidden", True), ("ReadOnly", False)] + loadProps = tuple([mkPropertyValue(name, value) for (name, value) in props]) + self.xDoc = desktop.loadComponentFromURL("private:factory/swriter", "_blank", 0, loadProps) + return self.xDoc + + def checkProperties(self, obj, dict, test): + for k,v in dict.items(): + obj.setPropertyValue(k, v) + value = obj.getPropertyValue(k) + test.assertEqual(value, v) + + def postTest(self): + assert(self.connection) + def tearDown(self): + if self.connection: + try: + self.connection.tearDown() + finally: + self.connection = None + +def simpleInvoke(connection, test): + try: + connection.preTest() + test.run(connection.getContext()) + finally: + connection.postTest() + +def retryInvoke(connection, test): + tries = 5 + while tries > 0: + try: + tries -= 1 + try: + connection.preTest() + test.run(connection.getContext()) + return + finally: + connection.postTest() + except KeyboardInterrupt: + raise # Ctrl+C should work + except: + print("retryInvoke: caught exception") + raise Exception("FAILED retryInvoke") + +def runConnectionTests(connection, invoker, tests): + try: + connection.setUp() + for test in tests: + invoker(connection, test) + finally: + connection.tearDown() + +### tests ### + +if __name__ == "__main__": + parser = argparse.ArgumentParser("Help utilities for testing LibreOffice") + group = parser.add_mutually_exclusive_group() + group.add_argument("-v", "--verbose", help="increase output verbosity", action="store_true") + #parser.add_argument("p", type=str, help="programm name") + args = parser.parse_args() + if args.verbose: + verbose = True + con = PersistentConnection({"verbose" : args.verbose}) + print("starting soffice ... ", end="") + con.setUp() + print("done") + con.get + print ("shutting down ... ", end="") + con.tearDown() + print("done") + +# vim:set shiftwidth=4 softtabstop=4 expandtab: |