move Python tests in-process
This is nice to make them more easily debuggable. A series of crude hacks are employed to bootstrap enough services from python so the current tests run. This is only tested with system python3 on Fedora. Change-Id: I5e06741e55ead7fddec41ff776ff8ca5d2399469 Reviewed-on: https://gerrit.libreoffice.org/3215 Reviewed-by: David Ostrovsky <David.Ostrovsky@gmx.de> Tested-by: David Ostrovsky <David.Ostrovsky@gmx.de>
This commit is contained in:
committed by
David Ostrovsky
parent
0e68bac852
commit
ebeae438db
@@ -320,6 +320,47 @@ static PyObject* getComponentContext(
|
||||
return ret.getAcquired();
|
||||
}
|
||||
|
||||
static PyObject* initPoniesMode(
|
||||
SAL_UNUSED_PARAMETER PyObject*, SAL_UNUSED_PARAMETER PyObject*)
|
||||
{
|
||||
// this tries to bootstrap enough of the soffice from python to run
|
||||
// unit tests, which is only possible indirectly because pyuno is URE
|
||||
// so load "test" library and invoke a function there to do the work
|
||||
try
|
||||
{
|
||||
PyObject *const ctx(getComponentContext(0, 0));
|
||||
if (!ctx) { abort(); }
|
||||
Runtime const runtime;
|
||||
Any const a(runtime.pyObject2Any(ctx));
|
||||
Reference<XComponentContext> xContext;
|
||||
a >>= xContext;
|
||||
if (!xContext.is()) { abort(); }
|
||||
using com::sun::star::lang::XMultiServiceFactory;
|
||||
Reference<XMultiServiceFactory> const xMSF(
|
||||
xContext->getServiceManager(),
|
||||
com::sun::star::uno::UNO_QUERY_THROW);
|
||||
if (!xMSF.is()) { abort(); }
|
||||
char *const outdir = getenv("OUTDIR");
|
||||
if (!outdir) { abort(); }
|
||||
OStringBuffer libname(outdir);
|
||||
libname.append("/lib/");
|
||||
libname.append(SAL_DLLPREFIX "test" SAL_DLLEXTENSION);
|
||||
oslModule const mod( osl_loadModuleAscii(libname.getStr(),
|
||||
SAL_LOADMODULE_LAZY | SAL_LOADMODULE_GLOBAL) );
|
||||
if (!mod) { abort(); }
|
||||
oslGenericFunction const pFunc(
|
||||
osl_getAsciiFunctionSymbol(mod, "test_init"));
|
||||
if (!pFunc) { abort(); }
|
||||
// guess casting pFunc is undefined behavior but don't see a better way
|
||||
((void (SAL_CALL *)(XMultiServiceFactory*)) pFunc) (xMSF.get());
|
||||
}
|
||||
catch (const com::sun::star::uno::Exception & e)
|
||||
{
|
||||
abort();
|
||||
}
|
||||
return Py_None;
|
||||
}
|
||||
|
||||
PyObject * extractOneStringArg( PyObject *args, char const *funcName )
|
||||
{
|
||||
if( !PyTuple_Check( args ) || PyTuple_Size( args) != 1 )
|
||||
@@ -797,6 +838,7 @@ static PyObject *setCurrentContext(
|
||||
|
||||
struct PyMethodDef PyUNOModule_methods [] =
|
||||
{
|
||||
{"experimentalExtraMagic", initPoniesMode, METH_VARARGS, NULL},
|
||||
{"getComponentContext", getComponentContext, METH_VARARGS, NULL},
|
||||
{"_createUnoStructHelper", reinterpret_cast<PyCFunction>(createUnoStructHelper), METH_VARARGS | METH_KEYWORDS, NULL},
|
||||
{"getTypeByName", getTypeByName, METH_VARARGS, NULL},
|
||||
|
@@ -27,25 +27,83 @@ ifneq ($(DISABLE_PYTHON),TRUE)
|
||||
$(call gb_PythonTest_get_target,%) :
|
||||
$(call gb_Output_announce,$*,$(true),PYT,2)
|
||||
$(call gb_Helper_abbreviate_dirs,\
|
||||
mkdir -p $(dir $(call gb_PythonTest_get_target,$*)) && \
|
||||
(PYTHONPATH=$(SRCDIR)/unotest/source/python:$(DEVINSTALLDIR)/opt/program \
|
||||
SOFFICE_BIN=$(DEVINSTALLDIR)/opt/program/soffice \
|
||||
URE_BOOTSTRAP=file://$(DEVINSTALLDIR)/opt/program/fundamentalrc \
|
||||
$(gb_PythonTest_COMMAND) \
|
||||
$(CLASSES) > $@.log 2>&1 || \
|
||||
(cat $@.log \
|
||||
&& false)))
|
||||
$(CLEAN_CMD)
|
||||
mkdir -p $(dir $(call gb_PythonTest_get_target,$*)) && \
|
||||
(PYTHONPATH=$(SRCDIR)/unotest/source/python:$(DEVINSTALLDIR)/opt/program \
|
||||
UserInstallation="$(call gb_Helper_make_url,$(OUTDIR)/unittest)" \
|
||||
BRAND_BASE_DIR="$(call gb_Helper_make_url,$(OUTDIR)/unittest/install)" \
|
||||
CONFIGURATION_LAYERS="$(strip $(CONFIGURATION_LAYERS))" \
|
||||
UNO_TYPES="$(foreach item,$(UNO_TYPES),$(call gb_Helper_make_url,$(item)))" \
|
||||
UNO_SERVICES="$(foreach item,$(UNO_SERVICES),$(call gb_Helper_make_url,$(item)))" \
|
||||
$(foreach dir,URE_INTERNAL_LIB_DIR LO_LIB_DIR,\
|
||||
$(dir)="$(call gb_Helper_make_url,$(gb_CppunitTest_LIBDIR))") \
|
||||
$(gb_CppunitTest_GDBTRACE) $(gb_CppunitTest_VALGRINDTOOL) $(gb_PythonTest_COMMAND) \
|
||||
$(CLASSES) \
|
||||
$(if $(gb_CppunitTest__interactive),, \
|
||||
> $@.log 2>&1 \
|
||||
|| (cat $@.log && $(UNIT_FAILED_MSG) \
|
||||
$(if $(value gb_CppunitTest_postprocess), \
|
||||
&& $(call gb_CppunitTest_postprocess,$(gb_CppunitTest_CPPTESTCOMMAND),$@.core)) \
|
||||
&& false))))
|
||||
|
||||
# always use udkapi and URE services
|
||||
define gb_PythonTest_PythonTest
|
||||
$(call gb_PythonTest_get_target,$(1)) : T_CP :=
|
||||
$(call gb_PythonTest_get_target,$(1)) : CLASSES :=
|
||||
$(call gb_PythonTest_get_target,$(1)) : CONFIGURATION_LAYERS :=
|
||||
$(call gb_PythonTest_get_target,$(1)) : UNO_TYPES :=
|
||||
$(call gb_PythonTest_get_target,$(1)) : UNO_SERVICES :=
|
||||
|
||||
$(call gb_PythonTest_use_api,$(1),udkapi)
|
||||
$(call gb_PythonTest_use_rdb,$(1),ure/services)
|
||||
|
||||
$(eval $(call gb_Module_register_target,$(call gb_PythonTest_get_target,$(1)),$(call gb_PythonTest_get_clean_target,$(1))))
|
||||
$(call gb_Helper_make_userfriendly_targets,$(1),PythonTest)
|
||||
|
||||
endef
|
||||
|
||||
define gb_PythonTest_use_configuration
|
||||
$(call gb_PythonTest_get_target,$(1)) : \
|
||||
$(call gb_Configuration_get_target,registry) \
|
||||
$(call gb_Configuration_get_target,fcfg_langpack) \
|
||||
$(call gb_Package_get_target,test_unittest)
|
||||
$(call gb_PythonTest_get_target,$(1)) : CONFIGURATION_LAYERS += \
|
||||
xcsxcu:$(call gb_Helper_make_url,$(gb_Configuration_registry)) \
|
||||
module:$(call gb_Helper_make_url,$(gb_Configuration_registry)/spool) \
|
||||
xcsxcu:$(call gb_Helper_make_url,$(OUTDIR)/unittest/registry)
|
||||
|
||||
endef
|
||||
|
||||
define gb_PythonTest__use_api
|
||||
$(call gb_PythonTest_get_target,$(1)) : $(call gb_UnoApi_get_target,$(2))
|
||||
$(call gb_PythonTest_get_target,$(1)) : \
|
||||
UNO_TYPES += $(call gb_UnoApi_get_target,$(2))
|
||||
|
||||
endef
|
||||
|
||||
define gb_PythonTest_use_api
|
||||
$(foreach api,$(2),$(call gb_PythonTest__use_api,$(1),$(api)))
|
||||
endef
|
||||
|
||||
define gb_PythonTest_use_rdb
|
||||
$(call gb_PythonTest_get_target,$(1)) : $(call gb_Rdb_get_outdir_target,$(2))
|
||||
$(call gb_PythonTest_get_target,$(1)) : \
|
||||
UNO_SERVICES += $(call gb_Rdb_get_outdir_target,$(2))
|
||||
|
||||
endef
|
||||
|
||||
define gb_PythonTest_use_component
|
||||
$(call gb_PythonTest_get_target,$(1)) : \
|
||||
$(call gb_ComponentTarget_get_outdir_target,$(2))
|
||||
$(call gb_PythonTest_get_target,$(1)) : \
|
||||
UNO_SERVICES += $(call gb_ComponentTarget_get_outdir_target,$(2))
|
||||
|
||||
endef
|
||||
|
||||
define gb_PythonTest_use_components
|
||||
$(foreach component,$(call gb_CppunitTest__filter_not_built_components,$(2)),$(call gb_PythonTest_use_component,$(1),$(component)))
|
||||
|
||||
endef
|
||||
|
||||
define gb_PythonTest_add_classes
|
||||
$(call gb_PythonTest_get_target,$(1)) : CLASSES += $(2)
|
||||
|
||||
@@ -75,9 +133,13 @@ $(call gb_Helper_make_userfriendly_targets,$(1),PythonTest)
|
||||
|
||||
endef
|
||||
|
||||
gb_PythonTest_use_configuration :=
|
||||
gb_PythonTest_use_api :=
|
||||
gb_PythonTest_use_rdb :=
|
||||
gb_PythonTest_use_components :=
|
||||
gb_PythonTest_add_classes :=
|
||||
gb_PythonTest_add_class :=
|
||||
gb_JunitTest_use_customtarget :=
|
||||
gb_PythonTest_use_customtarget :=
|
||||
|
||||
endif # DISABLE_PYTHON
|
||||
# vim: set noet sw=4:
|
||||
|
@@ -9,6 +9,45 @@
|
||||
|
||||
$(eval $(call gb_PythonTest_PythonTest,sw_unoapi))
|
||||
|
||||
$(eval $(call gb_PythonTest_use_configuration,sw_unoapi))
|
||||
|
||||
$(eval $(call gb_PythonTest_use_api,sw_unoapi,offapi))
|
||||
|
||||
# FAIL: this brings in GconfBackend $(eval $(call gb_PythonTest_use_rdb,sw_unoapi,services))
|
||||
|
||||
$(eval $(call gb_PythonTest_use_components,sw_unoapi,\
|
||||
basic/util/sb \
|
||||
comphelper/util/comphelp \
|
||||
configmgr/source/configmgr \
|
||||
dbaccess/util/dba \
|
||||
fileaccess/source/fileacc \
|
||||
filter/source/config/cache/filterconfig1 \
|
||||
forms/util/frm \
|
||||
framework/util/fwk \
|
||||
i18npool/util/i18npool \
|
||||
oox/util/oox \
|
||||
package/source/xstor/xstor \
|
||||
package/util/package2 \
|
||||
sax/source/expatwrap/expwrap \
|
||||
sax/source/fastparser/fastsax \
|
||||
sw/util/sw \
|
||||
sw/util/swd \
|
||||
sw/util/msword \
|
||||
sw/util/vbaswobj \
|
||||
scripting/source/basprov/basprov \
|
||||
scripting/util/scriptframe \
|
||||
sfx2/util/sfx \
|
||||
sot/util/sot \
|
||||
svl/source/fsstor/fsstorage \
|
||||
toolkit/util/tk \
|
||||
ucb/source/core/ucb1 \
|
||||
ucb/source/ucp/file/ucpfile1 \
|
||||
ucb/source/ucp/tdoc/ucptdoc1 \
|
||||
unotools/util/utl \
|
||||
unoxml/source/rdf/unordf \
|
||||
unoxml/source/service/unoxml \
|
||||
))
|
||||
|
||||
$(eval $(call gb_PythonTest_add_classes,sw_unoapi,\
|
||||
$(SRCDIR)/sw/qa/unoapi/python/set_expression.py \
|
||||
$(SRCDIR)/sw/qa/unoapi/python/get_expression.py \
|
||||
|
@@ -1,5 +1,5 @@
|
||||
import unittest
|
||||
from org.libreoffice.unotest import UnoConnection
|
||||
from org.libreoffice.unotest import UnoNotConnection as UnoConnection
|
||||
|
||||
class TestGetExpression(unittest.TestCase):
|
||||
_unoCon = None
|
||||
|
@@ -1,5 +1,5 @@
|
||||
import unittest
|
||||
from org.libreoffice.unotest import UnoConnection
|
||||
from org.libreoffice.unotest import UnoNotConnection as UnoConnection
|
||||
|
||||
#@unittest.skip("that seems to work")
|
||||
class TestSetExpresion(unittest.TestCase):
|
||||
|
@@ -57,9 +57,10 @@ class OOO_DLLPUBLIC_TEST BootstrapFixture : public BootstrapFixtureBase
|
||||
{
|
||||
bool m_bNeedUCB;
|
||||
bool m_bAssertOnDialog;
|
||||
DECL_LINK( ImplInitFilterHdl, ConvertData* );
|
||||
|
||||
public:
|
||||
DECL_STATIC_LINK( BootstrapFixture, ImplInitFilterHdl, ConvertData* );
|
||||
|
||||
BootstrapFixture( bool bAssertOnDialog = true, bool bNeedUCB = true );
|
||||
virtual ~BootstrapFixture();
|
||||
|
||||
|
@@ -65,12 +65,13 @@ test::BootstrapFixture::BootstrapFixture( bool bAssertOnDialog, bool bNeedUCB )
|
||||
{
|
||||
}
|
||||
|
||||
void test::BootstrapFixture::setUp()
|
||||
extern "C"
|
||||
{
|
||||
test::BootstrapFixtureBase::setUp();
|
||||
|
||||
void test_init_impl(bool bAssertOnDialog, bool bNeedUCB,
|
||||
lang::XMultiServiceFactory * pSFactory)
|
||||
{
|
||||
// force locale (and resource files loaded) to en-US
|
||||
|
||||
OUString aLangISO( "en-US" );
|
||||
ResMgr::SetDefaultLocale( LanguageTag( aLangISO) );
|
||||
|
||||
@@ -82,19 +83,20 @@ void test::BootstrapFixture::setUp()
|
||||
if (Application::IsHeadlessModeRequested())
|
||||
Application::EnableHeadlessMode(true);
|
||||
|
||||
if( m_bAssertOnDialog )
|
||||
if (bAssertOnDialog)
|
||||
ErrorHandler::RegisterDisplay( aBasicErrorFunc );
|
||||
|
||||
// Make GraphicConverter work, normally done in desktop::Desktop::Main()
|
||||
Application::SetFilterHdl( LINK( this, test::BootstrapFixture, ImplInitFilterHdl ) );
|
||||
Application::SetFilterHdl(
|
||||
STATIC_LINK(0, test::BootstrapFixture, ImplInitFilterHdl));
|
||||
|
||||
if (m_bNeedUCB)
|
||||
if (bNeedUCB)
|
||||
{
|
||||
// initialise unconfigured UCB:
|
||||
uno::Reference<ucb::XUniversalContentBroker> xUcb(m_xSFactory->createInstance("com.sun.star.ucb.UniversalContentBroker"), uno::UNO_QUERY_THROW);
|
||||
uno::Reference<ucb::XContentProvider> xFileProvider(m_xSFactory->createInstance("com.sun.star.ucb.FileContentProvider"), uno::UNO_QUERY_THROW);
|
||||
uno::Reference<ucb::XUniversalContentBroker> xUcb(pSFactory->createInstance("com.sun.star.ucb.UniversalContentBroker"), uno::UNO_QUERY_THROW);
|
||||
uno::Reference<ucb::XContentProvider> xFileProvider(pSFactory->createInstance("com.sun.star.ucb.FileContentProvider"), uno::UNO_QUERY_THROW);
|
||||
xUcb->registerContentProvider(xFileProvider, "file", sal_True);
|
||||
uno::Reference<ucb::XContentProvider> xTdocProvider(m_xSFactory->createInstance("com.sun.star.ucb.TransientDocumentsContentProvider"), uno::UNO_QUERY);
|
||||
uno::Reference<ucb::XContentProvider> xTdocProvider(pSFactory->createInstance("com.sun.star.ucb.TransientDocumentsContentProvider"), uno::UNO_QUERY);
|
||||
if (xTdocProvider.is())
|
||||
{
|
||||
xUcb->registerContentProvider(xTdocProvider, "vnd.sun.star.tdoc", sal_True);
|
||||
@@ -102,6 +104,26 @@ void test::BootstrapFixture::setUp()
|
||||
}
|
||||
}
|
||||
|
||||
// this is called from pyuno
|
||||
SAL_DLLPUBLIC_EXPORT void test_init(lang::XMultiServiceFactory *pFactory)
|
||||
{
|
||||
try
|
||||
{
|
||||
::comphelper::setProcessServiceFactory(pFactory);
|
||||
test_init_impl(false, true, pFactory);
|
||||
}
|
||||
catch (...) { abort(); }
|
||||
}
|
||||
|
||||
} // extern "C"
|
||||
|
||||
void test::BootstrapFixture::setUp()
|
||||
{
|
||||
test::BootstrapFixtureBase::setUp();
|
||||
|
||||
test_init_impl(m_bAssertOnDialog, m_bNeedUCB, m_xSFactory.get());
|
||||
}
|
||||
|
||||
void test::BootstrapFixture::tearDown()
|
||||
{
|
||||
test::BootstrapFixtureBase::tearDown();
|
||||
@@ -111,7 +133,8 @@ test::BootstrapFixture::~BootstrapFixture()
|
||||
{
|
||||
}
|
||||
|
||||
IMPL_LINK( test::BootstrapFixture, ImplInitFilterHdl, ConvertData*, pData )
|
||||
IMPL_STATIC_LINK_NOINSTANCE(
|
||||
test::BootstrapFixture, ImplInitFilterHdl, ConvertData*, pData)
|
||||
{
|
||||
return GraphicFilter::GetGraphicFilter().GetFilterCallback().Call( pData );
|
||||
}
|
||||
|
@@ -161,6 +161,37 @@ class UnoConnection:
|
||||
finally:
|
||||
self.connection = None
|
||||
|
||||
class UnoNotConnection:
|
||||
def __init__(self, args):
|
||||
self.args = args
|
||||
def getContext(self):
|
||||
return self.xContext
|
||||
def getDoc(self):
|
||||
return self.xDoc
|
||||
def setUp(self):
|
||||
self.xContext = pyuno.getComponentContext()
|
||||
pyuno.experimentalExtraMagic()
|
||||
def openEmptyWriterDoc(self):
|
||||
assert(self.xContext)
|
||||
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)
|
||||
assert(self.xDoc)
|
||||
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.xContext)
|
||||
def tearDown(self):
|
||||
self.xDoc.close(True)
|
||||
|
||||
def simpleInvoke(connection, test):
|
||||
try:
|
||||
connection.preTest()
|
||||
|
Reference in New Issue
Block a user