pyuno,unotest,xmlsecurity: copy GPG test files for UITtest
The problem was that running UITest_xmlsecurity_gpg changed the files in test/signing-keys/ ... prevent that by copying the directory in that test, which is more complicated than initially expected. Change-Id: Ie3be922e0b2e9dae49f9a70e35ad5270c90b4fc4 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/171322 Reviewed-by: Thorsten Behrens <thorsten.behrens@allotropia.de> Reviewed-by: Michael Stahl <michael.stahl@allotropia.de> Tested-by: Jenkins
This commit is contained in:
parent
e3d5b3a5ea
commit
8ed755cfb0
10 changed files with 168 additions and 30 deletions
|
@ -98,8 +98,8 @@ public:
|
|||
|
||||
// note: there is no tearDownX509
|
||||
void setUpX509(const test::Directories& rDirectories, const OUString& rTestName);
|
||||
void setUpGpg(const test::Directories& rDirectories, const OUString& rTestName);
|
||||
void tearDownGpg();
|
||||
static void setUpGpg(const test::Directories& rDirectories, std::u16string_view rTestName);
|
||||
static void tearDownGpg();
|
||||
|
||||
static bool IsValid(const css::uno::Reference<css::security::XCertificate>& cert,
|
||||
const css::uno::Reference<css::xml::crypto::XSecurityEnvironment>& env);
|
||||
|
@ -113,9 +113,6 @@ protected:
|
|||
|
||||
private:
|
||||
std::unique_ptr<BasicDLL> mpDll;
|
||||
#if HAVE_GPGCONF_SOCKETDIR
|
||||
OString m_gpgconfCommandPrefix;
|
||||
#endif
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
@ -222,6 +222,7 @@ struct RuntimeCargo
|
|||
css::uno::Reference< css::beans::XIntrospection > xIntrospection;
|
||||
PyRef dictUnoModule;
|
||||
osl::Module testModule;
|
||||
osl::Module unoTestModule;
|
||||
bool valid;
|
||||
ExceptionClassMap exceptionMap;
|
||||
ClassSet interfaceSet;
|
||||
|
|
|
@ -383,6 +383,65 @@ static PyObject* deinitTestEnvironment(
|
|||
return Py_None;
|
||||
}
|
||||
|
||||
static PyObject* initTestEnvironmentGPG(
|
||||
SAL_UNUSED_PARAMETER PyObject*, PyObject* args)
|
||||
{
|
||||
// this tries to set up certificate stores for unit tests
|
||||
// which is only possible indirectly because pyuno is URE
|
||||
// so load "unotest" library and invoke a function there to do the work
|
||||
Runtime const runtime;
|
||||
osl::Module & rModule(runtime.getImpl()->cargo->unoTestModule);
|
||||
assert(!rModule.is());
|
||||
try
|
||||
{
|
||||
char *const testlib = getenv("UNOTEST_LIB");
|
||||
if (!testlib) { abort(); }
|
||||
#ifdef _WIN32
|
||||
OString const libname = OString(testlib, strlen(testlib))
|
||||
.replaceAll(OString('/'), OString('\\'));
|
||||
#else
|
||||
OString const libname(testlib, strlen(testlib));
|
||||
#endif
|
||||
|
||||
rModule.load(OStringToOUString(libname, osl_getThreadTextEncoding()),
|
||||
SAL_LOADMODULE_LAZY | SAL_LOADMODULE_GLOBAL);
|
||||
if (!rModule.is()) { abort(); }
|
||||
oslGenericFunction const pFunc(rModule.getFunctionSymbol("test_init_gpg"));
|
||||
if (!pFunc) { abort(); }
|
||||
char * pTestDirURL;
|
||||
if (!PyArg_ParseTuple(args, "s", &pTestDirURL)) { abort(); }
|
||||
OUString const testDirURL(OUString::createFromAscii(pTestDirURL));
|
||||
reinterpret_cast<void (SAL_CALL *)(OUString const&)>(pFunc)(testDirURL);
|
||||
}
|
||||
catch (const css::uno::Exception &)
|
||||
{
|
||||
abort();
|
||||
}
|
||||
return Py_None;
|
||||
}
|
||||
|
||||
static PyObject* deinitTestEnvironmentGPG(
|
||||
SAL_UNUSED_PARAMETER PyObject*, SAL_UNUSED_PARAMETER PyObject*)
|
||||
{
|
||||
Runtime const runtime;
|
||||
osl::Module & rModule(runtime.getImpl()->cargo->unoTestModule);
|
||||
if (rModule.is())
|
||||
{
|
||||
try
|
||||
{
|
||||
oslGenericFunction const pFunc(
|
||||
rModule.getFunctionSymbol("test_deinit_gpg"));
|
||||
if (!pFunc) { abort(); }
|
||||
reinterpret_cast<void (SAL_CALL *)()>(pFunc)();
|
||||
}
|
||||
catch (const css::uno::Exception &)
|
||||
{
|
||||
abort();
|
||||
}
|
||||
}
|
||||
return Py_None;
|
||||
}
|
||||
|
||||
PyObject * extractOneStringArg( PyObject *args, char const *funcName )
|
||||
{
|
||||
if( !PyTuple_Check( args ) || PyTuple_Size( args) != 1 )
|
||||
|
@ -852,6 +911,8 @@ struct PyMethodDef PyUNOModule_methods [] =
|
|||
{
|
||||
{"private_initTestEnvironment", initTestEnvironment, METH_VARARGS, nullptr},
|
||||
{"private_deinitTestEnvironment", deinitTestEnvironment, METH_VARARGS, nullptr},
|
||||
{"private_initTestEnvironmentGPG", initTestEnvironmentGPG, METH_VARARGS, nullptr},
|
||||
{"private_deinitTestEnvironmentGPG", deinitTestEnvironmentGPG, METH_VARARGS, nullptr},
|
||||
{"getComponentContext", getComponentContext, METH_VARARGS, nullptr},
|
||||
#if defined __clang__
|
||||
#pragma clang diagnostic push
|
||||
|
|
|
@ -41,9 +41,6 @@ gb_UITest_COMMAND = $(ICECREAM_RUN) $(gb_CppunitTest_coredumpctl_run) $(gb_Cppun
|
|||
|
||||
gb_TEST_ENV_VARS += LIBO_LANG=C
|
||||
|
||||
# GNUPGHOME is needed for tests using the LibreOffice GPG features.
|
||||
gb_TEST_ENV_VARS += GNUPGHOME="$(SRCDIR)/test/signing-keys"
|
||||
|
||||
.PHONY : $(call gb_UITest_get_clean_target,%)
|
||||
$(call gb_UITest_get_clean_target,%) :
|
||||
$(call gb_Helper_abbreviate_dirs,\
|
||||
|
@ -51,6 +48,9 @@ $(call gb_UITest_get_clean_target,%) :
|
|||
|
||||
ifneq ($(DISABLE_PYTHON),TRUE)
|
||||
|
||||
# dlopening unotest requires this
|
||||
gb_UITest_PRECOMMAND = $(gb_PythonTest_PRECOMMAND)
|
||||
|
||||
# qadevOOo/qa/registrymodifications.xcu is copied to user profile directory to ensure en_US locale;
|
||||
# this might be overwritten later when gb_UITest_use_config is set
|
||||
.PHONY : $(call gb_UITest_get_target,%)
|
||||
|
@ -73,6 +73,7 @@ else
|
|||
$(DEFS) \
|
||||
$(if $(filter WNT,$(OS)),SAL_LOG_FILE="$(dir $(call gb_UITest_get_target,$*))/soffice.out.log") \
|
||||
TEST_LIB=$(call gb_Library_get_target,test) \
|
||||
UNOTEST_LIB=$(call gb_Library_get_target,unotest) \
|
||||
URE_BOOTSTRAP=vnd.sun.star.pathname:$(call gb_Helper_get_rcfile,$(INSTROOT)/$(LIBO_ETC_FOLDER)/fundamental) \
|
||||
PYTHONPATH="$(PYPATH)" \
|
||||
TestUserDir="$(call gb_Helper_make_url,$(dir $(call gb_UITest_get_target,$*)))" \
|
||||
|
|
|
@ -24,7 +24,7 @@ except ImportError:
|
|||
|
||||
def signal_handler(signal_num, frame):
|
||||
signal_name = signal.Signals(signal_num).name
|
||||
print(f'Signal handler called with signal {signal_name} ({signal_num})', flush=True)
|
||||
#print(f'Signal handler called with signal {signal_name} ({signal_num})', flush=True)
|
||||
|
||||
class OfficeConnection:
|
||||
def __init__(self, args):
|
||||
|
|
|
@ -145,27 +145,61 @@ void MacrosTest::setUpX509(const test::Directories& rDirectories, const OUString
|
|||
#endif
|
||||
}
|
||||
|
||||
void MacrosTest::setUpGpg(const test::Directories& rDirectories, const OUString& rTestName)
|
||||
#if HAVE_GPGCONF_SOCKETDIR
|
||||
// mutable global should be tolerable in test lib
|
||||
static OString g_gpgconfCommandPrefix;
|
||||
#endif
|
||||
|
||||
extern "C" {
|
||||
|
||||
SAL_DLLPUBLIC_EXPORT
|
||||
void test_init_gpg(OUString const& rTargetDir)
|
||||
{
|
||||
OUString aSourceDir = rDirectories.getURLFromSrc(u"/test/signing-keys/");
|
||||
OUString aTargetDir
|
||||
= rDirectories.getURLFromWorkdir(Concat2View("CppunitTest/" + rTestName + ".test.user"));
|
||||
const char* pSrcRoot = getenv("SRC_ROOT");
|
||||
if (!pSrcRoot)
|
||||
{
|
||||
abort();
|
||||
}
|
||||
OUString const srcRootPath(OUString(pSrcRoot, strlen(pSrcRoot), osl_getThreadTextEncoding()));
|
||||
OUString const sourcePath(srcRootPath + "/test/signing-keys/");
|
||||
OUString aSourceDir;
|
||||
osl::FileBase::RC e = osl::FileBase::getFileURLFromSystemPath(sourcePath, aSourceDir);
|
||||
if (osl::FileBase::E_None != e)
|
||||
{
|
||||
abort();
|
||||
}
|
||||
|
||||
OUString aTargetPath;
|
||||
osl::FileBase::getSystemPathFromFileURL(aTargetDir, aTargetPath);
|
||||
osl::FileBase::getSystemPathFromFileURL(rTargetDir, aTargetPath);
|
||||
|
||||
auto const rc = osl::Directory::create(rTargetDir);
|
||||
if (osl::FileBase::E_None != rc && osl::FileBase::E_EXIST != rc)
|
||||
{
|
||||
SAL_WARN("test", "creating target dir failed, aborting");
|
||||
abort();
|
||||
}
|
||||
|
||||
// Make gpg use our own defined setup & keys
|
||||
osl::File::copy(aSourceDir + "pubring.gpg", aTargetDir + "/pubring.gpg");
|
||||
osl::File::copy(aSourceDir + "random_seed", aTargetDir + "/random_seed");
|
||||
osl::File::copy(aSourceDir + "secring.gpg", aTargetDir + "/secring.gpg");
|
||||
osl::File::copy(aSourceDir + "trustdb.gpg", aTargetDir + "/trustdb.gpg");
|
||||
if (osl::FileBase::E_None
|
||||
!= osl::File::copy(aSourceDir + "pubring.gpg", rTargetDir + "/pubring.gpg")
|
||||
|| osl::FileBase::E_None
|
||||
!= osl::File::copy(aSourceDir + "random_seed", rTargetDir + "/random_seed")
|
||||
|| osl::FileBase::E_None
|
||||
!= osl::File::copy(aSourceDir + "secring.gpg", rTargetDir + "/secring.gpg")
|
||||
|| osl::FileBase::E_None
|
||||
!= osl::File::copy(aSourceDir + "trustdb.gpg", rTargetDir + "/trustdb.gpg"))
|
||||
{
|
||||
SAL_WARN("test", "copying files failed, aborting");
|
||||
abort();
|
||||
}
|
||||
|
||||
// note: this doesn't work for UITest because "os.environ" is a copy :(
|
||||
OUString gpgHomeVar(u"GNUPGHOME"_ustr);
|
||||
osl_setEnvironment(gpgHomeVar.pData, aTargetPath.pData);
|
||||
|
||||
#if HAVE_GPGCONF_SOCKETDIR
|
||||
auto const ldPath = std::getenv("LIBO_LD_PATH");
|
||||
m_gpgconfCommandPrefix
|
||||
g_gpgconfCommandPrefix
|
||||
= ldPath == nullptr ? OString() : OString::Concat("LD_LIBRARY_PATH=") + ldPath + " ";
|
||||
OString path;
|
||||
bool ok = aTargetPath.convertToString(&path, osl_getThreadTextEncoding(),
|
||||
|
@ -173,32 +207,53 @@ void MacrosTest::setUpGpg(const test::Directories& rDirectories, const OUString&
|
|||
| RTL_UNICODETOTEXT_FLAGS_INVALID_ERROR);
|
||||
// if conversion fails, at least provide a best-effort conversion in the message here, for
|
||||
// context
|
||||
CPPUNIT_ASSERT_MESSAGE(OUStringToOString(aTargetPath, RTL_TEXTENCODING_UTF8).getStr(), ok);
|
||||
m_gpgconfCommandPrefix += "GNUPGHOME=" + path + " " GPGME_GPGCONF;
|
||||
if (!ok)
|
||||
{
|
||||
SAL_WARN("test", "converting path failed, aborting: " << aTargetPath);
|
||||
abort();
|
||||
}
|
||||
g_gpgconfCommandPrefix += "GNUPGHOME=" + path + " " GPGME_GPGCONF;
|
||||
// HAVE_GPGCONF_SOCKETDIR is only defined in configure.ac for Linux for now, so (a) std::system
|
||||
// behavior will conform to POSIX (and the relevant env var to set is named LD_LIBRARY_PATH), and
|
||||
// (b) gpgconf --create-socketdir should return zero:
|
||||
OString cmd = m_gpgconfCommandPrefix + " --create-socketdir";
|
||||
OString cmd = g_gpgconfCommandPrefix + " --create-socketdir";
|
||||
int res = std::system(cmd.getStr());
|
||||
CPPUNIT_ASSERT_EQUAL_MESSAGE(cmd.getStr(), 0, res);
|
||||
if (res != 0)
|
||||
{
|
||||
SAL_WARN("test", "invoking gpgconf failed, aborting: " << cmd);
|
||||
abort();
|
||||
}
|
||||
#else
|
||||
(void)this;
|
||||
(void)rTargetDir;
|
||||
#endif
|
||||
}
|
||||
|
||||
void MacrosTest::tearDownGpg()
|
||||
SAL_DLLPUBLIC_EXPORT void test_deinit_gpg()
|
||||
{
|
||||
#if HAVE_GPGCONF_SOCKETDIR
|
||||
// HAVE_GPGCONF_SOCKETDIR is only defined in configure.ac for Linux for now, so (a) std::system
|
||||
// behavior will conform to POSIX, and (b) gpgconf --remove-socketdir should return zero:
|
||||
OString cmd = m_gpgconfCommandPrefix + " --remove-socketdir";
|
||||
CPPUNIT_ASSERT(!g_gpgconfCommandPrefix.isEmpty());
|
||||
OString cmd = g_gpgconfCommandPrefix + " --remove-socketdir";
|
||||
int res = std::system(cmd.getStr());
|
||||
CPPUNIT_ASSERT_EQUAL_MESSAGE(cmd.getStr(), 0, res);
|
||||
#else
|
||||
(void)this;
|
||||
g_gpgconfCommandPrefix.clear();
|
||||
#endif
|
||||
}
|
||||
|
||||
} // extern "C"
|
||||
|
||||
void MacrosTest::setUpGpg(const test::Directories& rDirectories,
|
||||
std::u16string_view const rTestName)
|
||||
{
|
||||
OUString aTargetDir = rDirectories.getURLFromWorkdir(
|
||||
Concat2View("CppunitTest/" + OUString(rTestName.data(), rTestName.size()) + ".test.user"));
|
||||
|
||||
return test_init_gpg(aTargetDir);
|
||||
}
|
||||
|
||||
void MacrosTest::tearDownGpg() { return test_deinit_gpg(); }
|
||||
|
||||
namespace
|
||||
{
|
||||
struct Valid
|
||||
|
|
|
@ -17,4 +17,7 @@ $(eval $(call gb_UITest_set_defs,xmlsecurity_gpg, \
|
|||
TDOC="$(SRCDIR)/xmlsecurity/qa/uitest/data" \
|
||||
))
|
||||
|
||||
# oneprocess prevents setting GNUPGHOME
|
||||
$(eval $(call gb_UITest_avoid_oneprocess,xmlsecurity_gpg))
|
||||
|
||||
# vim: set noet sw=4 ts=4:
|
||||
|
|
|
@ -9,8 +9,11 @@
|
|||
|
||||
from uitest.framework import UITestCase
|
||||
from libreoffice.uno.propertyvalue import mkPropertyValues
|
||||
import pyuno
|
||||
|
||||
from tempfile import TemporaryDirectory
|
||||
from urllib.parse import urljoin, urlparse
|
||||
from urllib.request import url2pathname
|
||||
import os.path
|
||||
|
||||
|
||||
|
@ -19,6 +22,23 @@ import os.path
|
|||
# Requires the environment variable GNUPGHOME to be set correctly.
|
||||
# See solenv/gbuild/UITest.mk
|
||||
class GpgEncryptTest(UITestCase):
|
||||
|
||||
# should this be setUp() or setUpClass()?
|
||||
# as setUp(), any test's change to the files should be overwritten before
|
||||
# the next test, which could be an advantage.
|
||||
def setUp(self):
|
||||
testdir = os.getenv("TestUserDir")
|
||||
certdir = urljoin(testdir, "signing-keys")
|
||||
# this sets GNUPGHOME so do it before starting soffice
|
||||
pyuno.private_initTestEnvironmentGPG(certdir)
|
||||
# ugly: set var here again because "os.environ" is a copy :(
|
||||
os.environ["GNUPGHOME"] = url2pathname(urlparse(certdir).path)
|
||||
super().setUp()
|
||||
|
||||
def tearDown(self):
|
||||
super().tearDown()
|
||||
pyuno.private_deinitTestEnvironmentGPG()
|
||||
|
||||
def test_gpg_encrypt(self):
|
||||
# TODO: Maybe deduplicate with sw/qa/uitest/writer_tests8/save_with_password_test_policy.py
|
||||
with TemporaryDirectory() as tempdir:
|
||||
|
|
|
@ -92,7 +92,7 @@ void SigningTest::setUp()
|
|||
UnoApiXmlTest::setUp();
|
||||
|
||||
MacrosTest::setUpX509(m_directories, u"xmlsecurity_signing"_ustr);
|
||||
MacrosTest::setUpGpg(m_directories, u"xmlsecurity_signing"_ustr);
|
||||
MacrosTest::setUpGpg(m_directories, std::u16string_view(u"xmlsecurity_signing"));
|
||||
|
||||
// Initialize crypto after setting up the environment variables.
|
||||
mxSEInitializer = xml::crypto::SEInitializer::create(m_xContext);
|
||||
|
|
|
@ -57,7 +57,7 @@ void SigningTest2::setUp()
|
|||
UnoApiXmlTest::setUp();
|
||||
|
||||
MacrosTest::setUpX509(m_directories, u"xmlsecurity_signing2"_ustr);
|
||||
MacrosTest::setUpGpg(m_directories, u"xmlsecurity_signing2"_ustr);
|
||||
MacrosTest::setUpGpg(m_directories, std::u16string_view(u"xmlsecurity_signing2"));
|
||||
|
||||
// Initialize crypto after setting up the environment variables.
|
||||
mxSEInitializer = xml::crypto::SEInitializer::create(m_xContext);
|
||||
|
|
Loading…
Reference in a new issue