1 # -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 # This file is part of the LibreOffice project.
5 # This Source Code Form is subject to the terms of the Mozilla Public
6 # License, v. 2.0. If a copy of the MPL was not distributed with this
7 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
20 print("pyuno not found: try to set PYTHONPATH and URE_BOOTSTRAP variables")
21 print("to something like:")
22 print(" PYTHONPATH=/installation/opt/program")
23 print(" URE_BOOTSTRAP=file:///installation/opt/program/fundamentalrc")
27 from com
.sun
.star
.document
import XDocumentEventListener
29 print("UNO API class not found: try to set URE_BOOTSTRAP variable")
30 print("to something like:")
31 print(" URE_BOOTSTRAP=file:///installation/opt/program/fundamentalrc")
35 from urllib
.parse
import quote
37 from urllib
import quote
41 def mkPropertyValue(name
, value
):
42 return uno
.createUnoStruct("com.sun.star.beans.PropertyValue", name
, 0, value
, 0)
46 class OfficeConnection(object):
48 def __init__(self
, args
):
56 self
.verbose
= self
.args
["verbose"]
60 prog
= self
.args
["programm"]
62 prog
= os
.getenv("SOFFICE_BIN")
64 raise Exception("SOFFICE_BIN must be set")
65 channel
= "pipe,name=pytest" + str(uuid
.uuid1())
67 userdir
= self
.args
["userdir"]
69 userdir
= "file:///tmp"
70 if not(userdir
.startswith("file://")):
71 raise Exception("--userdir must be file URL")
72 self
.soffice
= self
.bootstrap(prog
, userdir
, channel
)
73 return self
.connect(channel
)
75 def bootstrap(self
, soffice
, userdir
, channel
):
76 argv
= [ soffice
, "--accept=" + channel
+ ";urp",
77 "-env:UserInstallation=" + userdir
,
79 "--norestore", "--nologo", "--headless"]
80 if "--valgrind" in self
.args
:
81 argv
.append("--valgrind")
83 print ("starting LibreOffice with channel: ", channel
)
84 return subprocess
.Popen(argv
)
86 def connect(self
, channel
):
87 xLocalContext
= uno
.getComponentContext()
88 xUnoResolver
= xLocalContext
.ServiceManager
.createInstanceWithContext(
89 "com.sun.star.bridge.UnoUrlResolver", xLocalContext
)
90 url
= ("uno:%s;urp;StarOffice.ComponentContext" % channel
)
92 print("Connecting to: ", url
)
95 self
.xContext
= xUnoResolver
.resolve(url
)
97 # except com.sun.star.connection.NoConnectException
98 except pyuno
.getClass("com.sun.star.connection.NoConnectException"):
99 print("WARN: NoConnectException: sleeping...")
107 print("tearDown: calling terminate()...")
108 xMgr
= self
.xContext
.ServiceManager
109 xDesktop
= xMgr
.createInstanceWithContext(
110 "com.sun.star.frame.Desktop", self
.xContext
)
114 # except com.sun.star.lang.DisposedException:
115 except pyuno
.getClass("com.sun.star.beans.UnknownPropertyException"):
116 print("caught UnknownPropertyException")
117 pass # ignore, also means disposed
118 except pyuno
.getClass("com.sun.star.lang.DisposedException"):
119 print("caught DisposedException")
122 self
.soffice
.terminate()
123 ret
= self
.soffice
.wait()
127 # WTF 255 return value?
129 # raise Exception("Exit status indicates failure: " + str(ret))
132 def getContext(self
):
135 class UnoRemoteConnection
:
136 def __init__(self
, args
):
138 self
.connection
= None
139 def getContext(self
):
140 return self
.connection
.xContext
144 conn
= OfficeConnection(self
.args
)
146 self
.connection
= conn
147 def openEmptyWriterDoc(self
):
148 assert(self
.connection
)
149 smgr
= self
.getContext().ServiceManager
150 desktop
= smgr
.createInstanceWithContext("com.sun.star.frame.Desktop", self
.getContext())
151 props
= [("Hidden", True), ("ReadOnly", False)]
152 loadProps
= tuple([mkPropertyValue(name
, value
) for (name
, value
) in props
])
153 self
.xDoc
= desktop
.loadComponentFromURL("private:factory/swriter", "_blank", 0, loadProps
)
156 def checkProperties(self
, obj
, dict, test
):
157 for k
,v
in dict.items():
158 obj
.setPropertyValue(k
, v
)
159 value
= obj
.getPropertyValue(k
)
160 test
.assertEqual(value
, v
)
163 assert(self
.connection
)
167 self
.connection
.tearDown()
169 self
.connection
= None
172 def getContext(self
):
177 self
.xContext
= pyuno
.getComponentContext()
178 pyuno
.private_initTestEnvironment()
179 def openEmptyWriterDoc(self
):
180 assert(self
.xContext
)
181 smgr
= self
.getContext().ServiceManager
182 desktop
= smgr
.createInstanceWithContext("com.sun.star.frame.Desktop", self
.getContext())
183 props
= [("Hidden", True), ("ReadOnly", False)]
184 loadProps
= tuple([mkPropertyValue(name
, value
) for (name
, value
) in props
])
185 self
.xDoc
= desktop
.loadComponentFromURL("private:factory/swriter", "_blank", 0, loadProps
)
189 def openWriterTemplateDoc(self
, file):
190 assert(self
.xContext
)
191 smgr
= self
.getContext().ServiceManager
192 desktop
= smgr
.createInstanceWithContext("com.sun.star.frame.Desktop", self
.getContext())
193 props
= [("Hidden", True), ("ReadOnly", False), ("AsTemplate", True)]
194 loadProps
= tuple([mkPropertyValue(name
, value
) for (name
, value
) in props
])
195 path
= os
.getenv("TDOC")
197 # do not quote drive letter - it must be "X:"
198 url
= "file:///" + path
+ "/" + quote(file)
200 url
= "file://" + quote(path
) + "/" + quote(file)
201 self
.xDoc
= desktop
.loadComponentFromURL(url
, "_blank", 0, loadProps
)
205 def openBaseDoc(self
, file):
206 assert(self
.xContext
)
207 smgr
= self
.getContext().ServiceManager
208 desktop
= smgr
.createInstanceWithContext("com.sun.star.frame.Desktop", self
.getContext())
209 props
= [("Hidden", True), ("ReadOnly", False), ("AsTemplate", False)]
210 loadProps
= tuple([mkPropertyValue(name
, value
) for (name
, value
) in props
])
211 path
= os
.getenv("TDOC")
213 #do not quote drive letter - it must be "X:"
214 url
= "file:///" + path
+ "/" + quote(file)
216 url
= "file://" + quote(path
) + "/" + quote(file)
217 self
.xDoc
= desktop
.loadComponentFromURL(url
, "_blank", 0, loadProps
)
221 def openDoc(self
, file):
222 assert(self
.xContext
)
223 smgr
= self
.getContext().ServiceManager
224 desktop
= smgr
.createInstanceWithContext("com.sun.star.frame.Desktop", self
.getContext())
225 props
= [("Hidden", True), ("ReadOnly", False), ("AsTemplate", False)]
226 loadProps
= tuple([mkPropertyValue(name
, value
) for (name
, value
) in props
])
228 url
= "file:///" + file
230 url
= "file://" + file
231 self
.xDoc
= desktop
.loadComponentFromURL(url
, "_blank", 0, loadProps
)
235 def checkProperties(self
, obj
, dict, test
):
236 for k
,v
in dict.items():
237 obj
.setPropertyValue(k
, v
)
238 value
= obj
.getPropertyValue(k
)
239 test
.assertEqual(value
, v
)
241 def setProperties(self
, obj
, dict):
242 for k
,v
in dict.items():
243 obj
.setPropertyValue(k
, v
)
246 assert(self
.xContext
)
248 self
.xDoc
.close(True)
250 def simpleInvoke(connection
, test
):
253 test
.run(connection
.getContext())
255 connection
.postTest()
257 def retryInvoke(connection
, test
):
264 test
.run(connection
.getContext())
267 connection
.postTest()
268 except KeyboardInterrupt:
269 raise # Ctrl+C should work
271 print("retryInvoke: caught exception")
272 raise Exception("FAILED retryInvoke")
274 def runConnectionTests(connection
, invoker
, tests
):
278 invoker(connection
, test
)
280 connection
.tearDown()
284 if __name__
== "__main__":
285 parser
= argparse
.ArgumentParser("Help utilities for testing LibreOffice")
286 group
= parser
.add_mutually_exclusive_group()
287 group
.add_argument("-v", "--verbose", help="increase output verbosity", action
="store_true")
288 #parser.add_argument("p", type=str, help="programm name")
289 args
= parser
.parse_args()
292 con
= PersistentConnection({"verbose" : args
.verbose
})
293 print("starting soffice ... ", end
="")
297 print ("shutting down ... ", end
="")
301 # vim:set shiftwidth=4 softtabstop=4 expandtab: