summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/corelib/plugin/qlibrary.cpp58
-rw-r--r--src/gui/gui.pro8
-rw-r--r--src/testlib/qtestcase.cpp33
-rw-r--r--src/widgets/widgets.pro8
4 files changed, 107 insertions, 0 deletions
diff --git a/src/corelib/plugin/qlibrary.cpp b/src/corelib/plugin/qlibrary.cpp
index 9eeb783b60..6a40b5b818 100644
--- a/src/corelib/plugin/qlibrary.cpp
+++ b/src/corelib/plugin/qlibrary.cpp
@@ -400,6 +400,60 @@ static bool qt_unix_query(const QString &library, uint *version, bool *debug, QL
#endif // Q_OS_UNIX && !Q_OS_MAC && !defined(Q_OS_SYMBIAN) && !defined(QT_NO_PLUGIN_CHECK)
+static void installCoverageTool(QLibraryPrivate *libPrivate)
+{
+#ifdef __COVERAGESCANNER__
+ /*
+ __COVERAGESCANNER__ is defined when Qt has been instrumented for code
+ coverage by TestCocoon. CoverageScanner is the name of the tool that
+ generates the code instrumentation.
+ This code is required here when code coverage analysis with TestCocoon
+ is enabled in order to allow the loading application to register the plugin
+ and then store its execution report. The execution report gathers information
+ about each part of the plugin's code that has been used when
+ the plugin was loaded by the launching application.
+ The execution report for the plugin will go to the same execution report
+ as the one defined for the application loading it.
+ */
+
+ int ret = __coveragescanner_register_library(libPrivate->fileName.toLocal8Bit());
+
+ if (qt_debug_component()) {
+ if (ret >= 0) {
+ qDebug("%s: coverage data for %s registered",
+ Q_FUNC_INFO,
+ qPrintable(libPrivate->fileName));
+ } else {
+ qWarning("%s: could not register %s: error %d; coverage data may be incomplete",
+ Q_FUNC_INFO,
+ qPrintable(libPrivate->fileName),
+ ret);
+ }
+ }
+#else
+ Q_UNUSED(libPrivate);
+#endif
+}
+
+static void releaseCoverageTool(QLibraryPrivate *libPrivate)
+{
+#ifdef __COVERAGESCANNER__
+ /*
+ __COVERAGESCANNER__ is defined when Qt has been instrumented for code
+ coverage by TestCocoon.
+ Here is the code to save the execution data.
+ See comments about initialization in QLibraryPrivate::load().
+ */
+ if (libPrivate->pHnd) {
+ __coveragescanner_save();
+ __coveragescanner_clear();
+ __coveragescanner_unregister_library(libPrivate->fileName.toLocal8Bit());
+ }
+#else
+ Q_UNUSED(libPrivate);
+#endif
+}
+
typedef QMap<QString, QLibraryPrivate*> LibraryMap;
struct LibraryData {
@@ -465,6 +519,8 @@ bool QLibraryPrivate::load()
lib->loadedLibs += this;
libraryRefCount.ref();
}
+
+ installCoverageTool(this);
}
return ret;
@@ -494,6 +550,8 @@ bool QLibraryPrivate::unload()
void QLibraryPrivate::release()
{
+ releaseCoverageTool(this);
+
QMutexLocker locker(qt_library_mutex());
if (!libraryRefCount.deref())
delete this;
diff --git a/src/gui/gui.pro b/src/gui/gui.pro
index 40888ade41..db045930a3 100644
--- a/src/gui/gui.pro
+++ b/src/gui/gui.pro
@@ -13,6 +13,14 @@ unix|win32-g++*:QMAKE_PKGCONFIG_REQUIRES = QtCore
load(qt_module_config)
+# Code coverage with TestCocoon
+# The following is required as extra compilers use $$QMAKE_CXX instead of $(CXX).
+# Without this, testcocoon.prf is read only after $$QMAKE_CXX is used by the
+# extra compilers.
+testcocoon {
+ load(testcocoon)
+}
+
HEADERS += $$QT_SOURCE_TREE/src/gui/qtguiversion.h
include(accessible/accessible.pri)
diff --git a/src/testlib/qtestcase.cpp b/src/testlib/qtestcase.cpp
index 4e0205ccbc..f01c588e6d 100644
--- a/src/testlib/qtestcase.cpp
+++ b/src/testlib/qtestcase.cpp
@@ -857,6 +857,35 @@ QT_BEGIN_NAMESPACE
QTouchEventSequence is called (ie when the object returned runs out of scope).
*/
+static void installCoverageTool(const char * appname, const char * testname)
+{
+#ifdef __COVERAGESCANNER__
+ // Install Coverage Tool
+ __coveragescanner_install(appname);
+ __coveragescanner_testname(testname);
+ __coveragescanner_clear();
+#else
+ Q_UNUSED(appname);
+ Q_UNUSED(testname);
+#endif
+}
+
+static void saveCoverageTool(const char * appname, bool testfailed)
+{
+#ifdef __COVERAGESCANNER__
+ // install again to make sure the filename is correct.
+ // without this, a plugin or similar may have changed the filename.
+ __coveragescanner_install(appname);
+ __coveragescanner_teststate(testfailed ? "FAILED" : "PASSED");
+ __coveragescanner_save();
+ __coveragescanner_testname("");
+ __coveragescanner_clear();
+#else
+ Q_UNUSED(appname);
+ Q_UNUSED(testfailed);
+#endif
+}
+
namespace QTest
{
static QObject *currentTestObject = 0;
@@ -1904,6 +1933,8 @@ int QTest::qExec(QObject *testObject, int argc, char **argv)
const QMetaObject *metaObject = testObject->metaObject();
QTEST_ASSERT(metaObject);
+ installCoverageTool(argv[0], metaObject->className());
+
QTestResult::setCurrentTestObject(metaObject->className());
qtest_qParseArgs(argc, argv, false);
#ifdef QTESTLIB_USE_VALGRIND
@@ -1954,6 +1985,8 @@ int QTest::qExec(QObject *testObject, int argc, char **argv)
}
#endif
+ saveCoverageTool(argv[0], QTestResult::failCount());
+
#ifdef QTESTLIB_USE_VALGRIND
if (QBenchmarkGlobalData::current->mode() == QBenchmarkGlobalData::CallgrindParentProcess)
return callgrindChildExitCode;
diff --git a/src/widgets/widgets.pro b/src/widgets/widgets.pro
index d0425cac25..8f6a9713f6 100644
--- a/src/widgets/widgets.pro
+++ b/src/widgets/widgets.pro
@@ -44,6 +44,14 @@ contains(DEFINES,QT_EVAL):include($$QT_SOURCE_TREE/src/corelib/eval.pri)
QMAKE_DYNAMIC_LIST_FILE = $$PWD/QtGui.dynlist
+# Code coverage with TestCocoon
+# The following is required as extra compilers use $$QMAKE_CXX instead of $(CXX).
+# Without this, testcocoon.prf is read only after $$QMAKE_CXX is used by the
+# extra compilers.
+testcocoon {
+ load(testcocoon)
+}
+
DEFINES += Q_INTERNAL_QAPP_SRC
INCLUDEPATH += ../3rdparty/harfbuzz/src