/* -*- 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/. * * This file incorporates work covered by the following license notice: * * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed * with this work for additional information regarding copyright * ownership. The ASF licenses this file to you under the Apache * License, Version 2.0 (the "License"); you may not use this file * except in compliance with the License. You may obtain a copy of * the License at http://www.apache.org/licenses/LICENSE-2.0 .
*/
std::string convertLazy(std::u16string_view s16) {
OString s8(OUStringToOString(s16, osl_getThreadTextEncoding()));
static_assert(sizeof (sal_Int32) <= sizeof (std::string::size_type), "must be at least the same size"); // ensure following cast is legitimate return std::string(s8);
}
//Output how long each test took class TimingListener
: public CppUnit::TestListener
{ public:
TimingListener()
: m_nStartTime(0)
{
}
TimingListener(const TimingListener&) = delete;
TimingListener& operator=(const TimingListener&) = delete;
bool addRecursiveTests(const std::vector<std::string>& test_names, CppUnit::Test* pTest, CppUnit::TestRunner& rRunner)
{ bool ret(false); for (int i = 0; i < pTest->getChildTestCount(); ++i)
{
CppUnit::Test* pNewTest = pTest->getChildTestAt(i);
ret |= addRecursiveTests(test_names, pNewTest, rRunner); if (std::any_of(test_names.begin(), test_names.end(), test_name_compare(pNewTest->getName())))
{
rRunner.addTest(pNewTest);
ret = true;
}
} return ret;
}
//Allow the whole uniting testing framework to be run inside a "Protector" //which knows about uno exceptions, so it can print the content of the //exception before falling over and dying class CPPUNIT_API ProtectedFixtureFunctor
: public CppUnit::Functor
{ private: const std::string &testlib; const std::string &args;
std::vector<CppUnit::Protector *> &protectors;
CppUnit::TestResult &result; public:
ProtectedFixtureFunctor(const std::string& testlib_, const std::string &args_, std::vector<CppUnit::Protector*> &protectors_, CppUnit::TestResult &result_)
: testlib(testlib_)
, args(args_)
, protectors(protectors_)
, result(result_)
{
}
ProtectedFixtureFunctor(const ProtectedFixtureFunctor&) = delete;
ProtectedFixtureFunctor& operator=(const ProtectedFixtureFunctor&) = delete; bool run() const
{ #ifdef DISABLE_DYNLOADING
// NOTE: Running cppunit unit tests on iOS was something I did // only very early (several years ago) when starting porting // this stuff to iOS. The complicated mechanisms to do build // such unit test single executables have surely largely // bit-rotted or been semi-intentionally broken since. This // stuff here left for information only. --tml 2014.
// For iOS cppunit plugins aren't really "plugins" (shared // libraries), but just static archives. In the real main // program of a cppunit app, which calls the lo_main() that // the SAL_IMPLEMENT_MAIN() below expands to, we specifically // call the initialize methods of the CppUnitTestPlugIns that // we statically link to the app executable. #else // The PlugInManager instance is deliberately leaked, so that the dynamic libraries it loads // are never unloaded (which could make e.g. pointers from other libraries' static data // structures to const data in those libraries, like some static OUString cache pointing at // a const OUStringLiteral, become dangling by the time those static data structures are // destroyed during exit): auto manager = new CppUnit::PlugInManager; try {
manager->load(testlib, args);
} catch (const CppUnit::DynamicLibraryManagerException &e) {
std::cerr << "DynamicLibraryManagerException: \"" << e.what() << "\"\n"; constchar *pPath = getenv ("PATH"); const size_t nPathLen = pPath ? strlen(pPath) : 0; #ifdef _WIN32 if (nPathLen > 256)
{
std::cerr << "Windows has significant build problems with long PATH variables ";
std::cerr << "please check your PATH variable and re-autogen.\n";
} #endif
std::cerr << "Path (length: " << nPathLen << ") is '" << pPath << "'\n"; returnfalse;
} #endif
for (size_t i = 0; i < protectors.size(); ++i)
result.pushProtector(protectors[i]);
// set this to track down files created before first test method
std::string lib = testlib.substr(testlib.rfind('/')+1); #ifdef WIN32
_putenv_s("LO_TESTNAME", lib.c_str()); #else
setenv("LO_TESTNAME", lib.c_str(), true); #endif constchar* pVal = getenv("CPPUNIT_TEST_NAME");
staticbool main2()
{ bool ok = false;
OUString path;
#ifdef _WIN32 //Disable Dr-Watson in order to crash simply without popup dialogs under //windows
DWORD dwMode = SetErrorMode(SEM_NOGPFAULTERRORBOX);
SetErrorMode(SEM_NOGPFAULTERRORBOX|dwMode); #ifdef _DEBUG // These functions are present only in the debugging runtime
_CrtSetReportMode(_CRT_WARN, _CRTDBG_MODE_DEBUG|_CRTDBG_MODE_FILE);
_CrtSetReportFile(_CRT_WARN, _CRTDBG_FILE_STDERR);
_CrtSetReportMode(_CRT_ERROR, _CRTDBG_MODE_DEBUG|_CRTDBG_MODE_FILE);
_CrtSetReportFile(_CRT_ERROR, _CRTDBG_FILE_STDERR);
_CrtSetReportMode(_CRT_ASSERT, _CRTDBG_MODE_DEBUG|_CRTDBG_MODE_FILE);
_CrtSetReportFile(_CRT_ASSERT, _CRTDBG_FILE_STDERR); #endif // Create a desktop, to avoid popups interfering with active user session, // because on Windows, we don't use svp vcl plugin for unit testing
sal::systools::maybeCreateTestDesktop(); #endif
for (;;)
{ //get next call from stack bool result = StackWalk64
( #ifdef _M_AMD64
IMAGE_FILE_MACHINE_AMD64, #elifdefined _M_ARM64
IMAGE_FILE_MACHINE_ARM64, #else
IMAGE_FILE_MACHINE_I386, #endif
process,
thread,
&stack,
ctx,
nullptr,
SymFunctionTableAccess64,
SymGetModuleBase64,
nullptr
);
if( !result ) break;
//get symbol name for address
pSymbol->SizeOfStruct = sizeof(SYMBOL_INFO);
pSymbol->MaxNameLen = MAX_SYM_NAME + 1; if (SymFromAddr(process, stack.AddrPC.Offset, nullptr, pSymbol))
printf("\tat %s", pSymbol->Name); else
printf("\tat unknown (Error in SymFromAddr=%#08lx)", GetLastError());
DWORD disp; //try to get line if (SymGetLineFromAddr64(process, stack.AddrPC.Offset, &disp, &line))
{
printf(" in %s: line: %lu:\n", line.FileName, line.LineNumber);
} else
{ //failed to get line
printf(", address 0x%0I64X", stack.AddrPC.Offset);
HMODULE hModule = nullptr;
GetModuleHandleEx(GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS | GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT, reinterpret_cast<LPCTSTR>(stack.AddrPC.Offset), &hModule);
char sModule[256]; //at least print module name if (hModule != nullptr)
GetModuleFileNameA(hModule, sModule, std::size(sModule));
printf (" in %s\n", sModule);
}
}
}
// The exception filter function: staticLONG WINAPI ExpFilter(EXCEPTION_POINTERS* ex)
{ // we only want this active on the Jenkins tinderboxes
printf("*** Exception 0x%lx occurred ***\n\n",ex->ExceptionRecord->ExceptionCode);
printStack(ex->ContextRecord); return EXCEPTION_EXECUTE_HANDLER;
}
SAL_IMPLEMENT_MAIN()
{ // catch the kind of signal that is thrown when an assert fails, and log a stacktrace
signal(SIGABRT, AbortSignalHandler);
bool ok = false; // This magic kind of Windows-specific exception handling has to be in its own function // because it cannot be in a function that has objects with destructors.
__try
{
ok = main2();
}
__except (ExpFilter(GetExceptionInformation()))
{
} return ok ? EXIT_SUCCESS : EXIT_FAILURE;
}
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung ist noch experimentell.