Kaydet (Commit) ebeae438 authored tarafından Michael Stahl's avatar Michael Stahl Kaydeden (comit) David Ostrovsky

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/3215Reviewed-by: 's avatarDavid Ostrovsky <David.Ostrovsky@gmx.de>
Tested-by: 's avatarDavid Ostrovsky <David.Ostrovsky@gmx.de>
üst 0e68bac8
...@@ -320,6 +320,47 @@ static PyObject* getComponentContext( ...@@ -320,6 +320,47 @@ static PyObject* getComponentContext(
return ret.getAcquired(); 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 ) PyObject * extractOneStringArg( PyObject *args, char const *funcName )
{ {
if( !PyTuple_Check( args ) || PyTuple_Size( args) != 1 ) if( !PyTuple_Check( args ) || PyTuple_Size( args) != 1 )
...@@ -797,6 +838,7 @@ static PyObject *setCurrentContext( ...@@ -797,6 +838,7 @@ static PyObject *setCurrentContext(
struct PyMethodDef PyUNOModule_methods [] = struct PyMethodDef PyUNOModule_methods [] =
{ {
{"experimentalExtraMagic", initPoniesMode, METH_VARARGS, NULL},
{"getComponentContext", getComponentContext, METH_VARARGS, NULL}, {"getComponentContext", getComponentContext, METH_VARARGS, NULL},
{"_createUnoStructHelper", reinterpret_cast<PyCFunction>(createUnoStructHelper), METH_VARARGS | METH_KEYWORDS, NULL}, {"_createUnoStructHelper", reinterpret_cast<PyCFunction>(createUnoStructHelper), METH_VARARGS | METH_KEYWORDS, NULL},
{"getTypeByName", getTypeByName, METH_VARARGS, NULL}, {"getTypeByName", getTypeByName, METH_VARARGS, NULL},
......
...@@ -27,25 +27,83 @@ ifneq ($(DISABLE_PYTHON),TRUE) ...@@ -27,25 +27,83 @@ ifneq ($(DISABLE_PYTHON),TRUE)
$(call gb_PythonTest_get_target,%) : $(call gb_PythonTest_get_target,%) :
$(call gb_Output_announce,$*,$(true),PYT,2) $(call gb_Output_announce,$*,$(true),PYT,2)
$(call gb_Helper_abbreviate_dirs,\ $(call gb_Helper_abbreviate_dirs,\
mkdir -p $(dir $(call gb_PythonTest_get_target,$*)) && \ mkdir -p $(dir $(call gb_PythonTest_get_target,$*)) && \
(PYTHONPATH=$(SRCDIR)/unotest/source/python:$(DEVINSTALLDIR)/opt/program \ (PYTHONPATH=$(SRCDIR)/unotest/source/python:$(DEVINSTALLDIR)/opt/program \
SOFFICE_BIN=$(DEVINSTALLDIR)/opt/program/soffice \ UserInstallation="$(call gb_Helper_make_url,$(OUTDIR)/unittest)" \
URE_BOOTSTRAP=file://$(DEVINSTALLDIR)/opt/program/fundamentalrc \ BRAND_BASE_DIR="$(call gb_Helper_make_url,$(OUTDIR)/unittest/install)" \
$(gb_PythonTest_COMMAND) \ CONFIGURATION_LAYERS="$(strip $(CONFIGURATION_LAYERS))" \
$(CLASSES) > $@.log 2>&1 || \ UNO_TYPES="$(foreach item,$(UNO_TYPES),$(call gb_Helper_make_url,$(item)))" \
(cat $@.log \ UNO_SERVICES="$(foreach item,$(UNO_SERVICES),$(call gb_Helper_make_url,$(item)))" \
&& false))) $(foreach dir,URE_INTERNAL_LIB_DIR LO_LIB_DIR,\
$(CLEAN_CMD) $(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 define gb_PythonTest_PythonTest
$(call gb_PythonTest_get_target,$(1)) : T_CP := $(call gb_PythonTest_get_target,$(1)) : T_CP :=
$(call gb_PythonTest_get_target,$(1)) : CLASSES := $(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)))) $(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) $(call gb_Helper_make_userfriendly_targets,$(1),PythonTest)
endef 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 define gb_PythonTest_add_classes
$(call gb_PythonTest_get_target,$(1)) : CLASSES += $(2) $(call gb_PythonTest_get_target,$(1)) : CLASSES += $(2)
...@@ -75,9 +133,13 @@ $(call gb_Helper_make_userfriendly_targets,$(1),PythonTest) ...@@ -75,9 +133,13 @@ $(call gb_Helper_make_userfriendly_targets,$(1),PythonTest)
endef endef
gb_PythonTest_use_configuration :=
gb_PythonTest_use_api :=
gb_PythonTest_use_rdb :=
gb_PythonTest_use_components :=
gb_PythonTest_add_classes := gb_PythonTest_add_classes :=
gb_PythonTest_add_class := gb_PythonTest_add_class :=
gb_JunitTest_use_customtarget := gb_PythonTest_use_customtarget :=
endif # DISABLE_PYTHON endif # DISABLE_PYTHON
# vim: set noet sw=4: # vim: set noet sw=4:
...@@ -9,6 +9,45 @@ ...@@ -9,6 +9,45 @@
$(eval $(call gb_PythonTest_PythonTest,sw_unoapi)) $(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,\ $(eval $(call gb_PythonTest_add_classes,sw_unoapi,\
$(SRCDIR)/sw/qa/unoapi/python/set_expression.py \ $(SRCDIR)/sw/qa/unoapi/python/set_expression.py \
$(SRCDIR)/sw/qa/unoapi/python/get_expression.py \ $(SRCDIR)/sw/qa/unoapi/python/get_expression.py \
......
import unittest import unittest
from org.libreoffice.unotest import UnoConnection from org.libreoffice.unotest import UnoNotConnection as UnoConnection
class TestGetExpression(unittest.TestCase): class TestGetExpression(unittest.TestCase):
_unoCon = None _unoCon = None
......
import unittest import unittest
from org.libreoffice.unotest import UnoConnection from org.libreoffice.unotest import UnoNotConnection as UnoConnection
#@unittest.skip("that seems to work") #@unittest.skip("that seems to work")
class TestSetExpresion(unittest.TestCase): class TestSetExpresion(unittest.TestCase):
......
...@@ -57,9 +57,10 @@ class OOO_DLLPUBLIC_TEST BootstrapFixture : public BootstrapFixtureBase ...@@ -57,9 +57,10 @@ class OOO_DLLPUBLIC_TEST BootstrapFixture : public BootstrapFixtureBase
{ {
bool m_bNeedUCB; bool m_bNeedUCB;
bool m_bAssertOnDialog; bool m_bAssertOnDialog;
DECL_LINK( ImplInitFilterHdl, ConvertData* );
public: public:
DECL_STATIC_LINK( BootstrapFixture, ImplInitFilterHdl, ConvertData* );
BootstrapFixture( bool bAssertOnDialog = true, bool bNeedUCB = true ); BootstrapFixture( bool bAssertOnDialog = true, bool bNeedUCB = true );
virtual ~BootstrapFixture(); virtual ~BootstrapFixture();
......
...@@ -65,12 +65,13 @@ test::BootstrapFixture::BootstrapFixture( bool bAssertOnDialog, bool bNeedUCB ) ...@@ -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 // force locale (and resource files loaded) to en-US
OUString aLangISO( "en-US" ); OUString aLangISO( "en-US" );
ResMgr::SetDefaultLocale( LanguageTag( aLangISO) ); ResMgr::SetDefaultLocale( LanguageTag( aLangISO) );
...@@ -82,19 +83,20 @@ void test::BootstrapFixture::setUp() ...@@ -82,19 +83,20 @@ void test::BootstrapFixture::setUp()
if (Application::IsHeadlessModeRequested()) if (Application::IsHeadlessModeRequested())
Application::EnableHeadlessMode(true); Application::EnableHeadlessMode(true);
if( m_bAssertOnDialog ) if (bAssertOnDialog)
ErrorHandler::RegisterDisplay( aBasicErrorFunc ); ErrorHandler::RegisterDisplay( aBasicErrorFunc );
// Make GraphicConverter work, normally done in desktop::Desktop::Main() // 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: // initialise unconfigured UCB:
uno::Reference<ucb::XUniversalContentBroker> xUcb(m_xSFactory->createInstance("com.sun.star.ucb.UniversalContentBroker"), 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(m_xSFactory->createInstance("com.sun.star.ucb.FileContentProvider"), 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); 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()) if (xTdocProvider.is())
{ {
xUcb->registerContentProvider(xTdocProvider, "vnd.sun.star.tdoc", sal_True); xUcb->registerContentProvider(xTdocProvider, "vnd.sun.star.tdoc", sal_True);
...@@ -102,6 +104,26 @@ void test::BootstrapFixture::setUp() ...@@ -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() void test::BootstrapFixture::tearDown()
{ {
test::BootstrapFixtureBase::tearDown(); test::BootstrapFixtureBase::tearDown();
...@@ -111,7 +133,8 @@ test::BootstrapFixture::~BootstrapFixture() ...@@ -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 ); return GraphicFilter::GetGraphicFilter().GetFilterCallback().Call( pData );
} }
......
...@@ -161,6 +161,37 @@ class UnoConnection: ...@@ -161,6 +161,37 @@ class UnoConnection:
finally: finally:
self.connection = None 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): def simpleInvoke(connection, test):
try: try:
connection.preTest() connection.preTest()
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment