diff --git a/repos/libports/lib/import/import-qt5_test.mk b/repos/libports/lib/import/import-qt5_test.mk
new file mode 100644
index 0000000000..7a079ceb01
--- /dev/null
+++ b/repos/libports/lib/import/import-qt5_test.mk
@@ -0,0 +1,15 @@
+IMPORT_QT5_INC=$(call select_from_repositories,lib/import/import-qt5.inc)
+
+include $(IMPORT_QT5_INC)
+
+ifeq ($(CONTRIB_DIR),)
+QT5_TEST_INC_DIR := $(realpath $(call select_from_repositories,include/QtTest)/..)
+else
+QT5_TEST_INC_DIR := $(QT5_PORT_DIR)/include
+endif
+
+QT5_INC_DIR += $(QT5_TEST_INC_DIR)
+QT5_INC_DIR += $(QT5_TEST_INC_DIR)/QtTest
+QT5_INC_DIR += $(QT5_TEST_INC_DIR)/QtTest/$(QT_VERSION)
+QT5_INC_DIR += $(QT5_TEST_INC_DIR)/QtTest/$(QT_VERSION)/QtTest
+QT5_INC_DIR += $(QT5_TEST_INC_DIR)/QtTest/$(QT_VERSION)/QtTest/private
diff --git a/repos/libports/lib/mk/qt5_test.mk b/repos/libports/lib/mk/qt5_test.mk
new file mode 100644
index 0000000000..352e0194ad
--- /dev/null
+++ b/repos/libports/lib/mk/qt5_test.mk
@@ -0,0 +1,11 @@
+include $(call select_from_repositories,lib/import/import-qt5_test.mk)
+
+SHARED_LIB = yes
+
+include $(REP_DIR)/lib/mk/qt5_test_generated.inc
+
+include $(REP_DIR)/lib/mk/qt5.inc
+
+LIBS += qt5_core
+
+CC_CXX_WARN_STRICT =
diff --git a/repos/libports/lib/mk/qt5_test_generated.inc b/repos/libports/lib/mk/qt5_test_generated.inc
new file mode 100644
index 0000000000..936874e94f
--- /dev/null
+++ b/repos/libports/lib/mk/qt5_test_generated.inc
@@ -0,0 +1,58 @@
+QT_DEFINES += -DQT_NO_CAST_TO_ASCII -DQT_NO_CAST_FROM_ASCII -DQT_NO_FOREACH -DQT_NO_DATASTREAM -DQT_BUILD_TESTLIB_LIB -DQT_BUILDING_QT -DQT_ASCII_CAST_WARNINGS -DQT_MOC_COMPAT -DQT_USE_QSTRINGBUILDER -DQT_DEPRECATED_WARNINGS -DQT_DISABLE_DEPRECATED_BEFORE=0x050000 -D_LARGEFILE64_SOURCE -D_LARGEFILE_SOURCE -DQT_NO_DEBUG -DQT_CORE_LIB
+
+QT_INCPATH += \
+ qtbase/src/testlib \
+ qtbase/include \
+ qtbase/include/QtTest \
+ qtbase/include/QtTest/5.8.0 \
+ qtbase/include/QtTest/5.8.0/QtTest \
+ qtbase/include/QtCore/5.8.0 \
+ qtbase/include/QtCore/5.8.0/QtCore \
+ qtbase/include/QtCore \
+ qtbase/mkspecs/genode-g++
+
+QT_SOURCES += \
+ qtestcase.cpp \
+ qtestlog.cpp \
+ qtesttable.cpp \
+ qtestdata.cpp \
+ qtestresult.cpp \
+ qasciikey.cpp \
+ qplaintestlogger.cpp \
+ qxmltestlogger.cpp \
+ qsignaldumper.cpp \
+ qabstracttestlogger.cpp \
+ qbenchmark.cpp \
+ qbenchmarkmeasurement.cpp \
+ qbenchmarkvalgrind.cpp \
+ qbenchmarkevent.cpp \
+ qbenchmarkperfevents.cpp \
+ qbenchmarkmetric.cpp \
+ qcsvbenchmarklogger.cpp \
+ qteamcitylogger.cpp \
+ qtestelement.cpp \
+ qtestelementattribute.cpp \
+ qtestmouse.cpp \
+ qtestxunitstreamer.cpp \
+ qxunittestlogger.cpp \
+ qtestblacklist.cpp \
+ moc_qtesteventloop.cpp
+
+QT_VPATH += \
+ qtbase/src/testlib \
+
+# some source files need to be generated by moc from other source/header files before
+# they get #included again by the original source file in the compiling stage
+
+# source files generated from existing header files ('moc_%.cpp: %.h' rule in import-qt5.inc)
+# extracted from 'compiler_moc_header_make_all' target
+
+COMPILER_MOC_HEADER_MAKE_ALL_FILES = \
+ moc_qtesteventloop.cpp
+
+# source files generated from existing source files ('%.moc: %.cpp' rule in import-qt5.inc)
+# extracted from 'compiler_moc_source_make_all' rule
+
+COMPILER_MOC_SOURCE_MAKE_ALL_FILES = \
+
+
diff --git a/repos/libports/ports/qt5.hash b/repos/libports/ports/qt5.hash
index 2cc8ec419c..5e989fb3c2 100644
--- a/repos/libports/ports/qt5.hash
+++ b/repos/libports/ports/qt5.hash
@@ -1 +1 @@
-3099fb1bfb0735393056a59c20530cf1c07bf546
+b079ed010149c64065cc3e72d2821e3c1caf2b6a
diff --git a/repos/libports/ports/qt5.port b/repos/libports/ports/qt5.port
index 031727d4aa..873adb4a1e 100644
--- a/repos/libports/ports/qt5.port
+++ b/repos/libports/ports/qt5.port
@@ -20,7 +20,7 @@ SHA(${QTSCRIPTCLASSIC}) := 6a4c4ada6f0064f6c5d7663602a37c99250ed6c7398b1775f95de
DIR(${QTSCRIPTCLASSIC}) := src/lib/qt5/${QTSCRIPTCLASSIC}
URL(symbols) := https://github.com/cproc/genode-symbols.git
-REV(symbols) := 732fb1b64a0e8e704d5a8a4fb5458be3df068751
+REV(symbols) := c8b59b3e9372b6ac713b5407bfd1affb840ccb2f
DIR(symbols) := lib/symbols
@@ -123,6 +123,9 @@ $(BUILD_DIR)/qtbase/src/printsupport/Makefile: $(BUILD_DIR)/qtbase/src/Makefile
$(BUILD_DIR)/qtbase/src/sql/Makefile: $(BUILD_DIR)/qtbase/src/Makefile
$(call generate_makefile, $(QT5_CONTRIB_DIR)/qtbase/src/sql/sql.pro)
+$(BUILD_DIR)/qtbase/src/testlib/Makefile: $(BUILD_DIR)/qtbase/src/Makefile
+ $(call generate_makefile, $(QT5_CONTRIB_DIR)/qtbase/src/testlib/testlib.pro)
+
$(BUILD_DIR)/qtbase/src/widgets/Makefile: $(BUILD_DIR)/qtbase/src/Makefile
$(call generate_makefile, $(QT5_CONTRIB_DIR)/qtbase/src/widgets/widgets.pro)
@@ -271,6 +274,12 @@ include/QtSql: $(BUILD_DIR)/qtbase/src/sql/Makefile
$(VERBOSE)cp $(QT5_CONTRIB_DIR)/qtbase/src/sql/qtsql-config.h $@/
$(VERBOSE)cp $(QT5_CONTRIB_DIR)/qtbase/src/sql/qtsql-config_p.h $@/$(VERSION)/QtSql/private/
+include/QtTest: $(BUILD_DIR)/qtbase/src/testlib/Makefile
+ $(VERBOSE)$(MSG_GENERATE)$@
+ $(VERBOSE)make -f $< INSTALL_ROOT=$(CURDIR) install_class_headers $(OUTPUT_FILTER)
+ $(VERBOSE)make -f $< INSTALL_ROOT=$(CURDIR) install_targ_headers $(OUTPUT_FILTER)
+ $(VERBOSE)make -f $< INSTALL_ROOT=$(CURDIR) install_private_headers $(OUTPUT_FILTER)
+
include/QtWidgets: $(BUILD_DIR)/qtbase/src/widgets/Makefile
$(VERBOSE)$(MSG_GENERATE)$@
$(VERBOSE)make -f $< INSTALL_ROOT=$(CURDIR) install_class_headers $(OUTPUT_FILTER)
@@ -503,6 +512,7 @@ qt5_headers: include/QtCore \
include/QtPlatformHeaders \
include/QtPrintSupport \
include/QtSql \
+ include/QtTest \
include/QtWidgets \
include/QtXml \
include/QtScript \
diff --git a/repos/libports/recipes/api/qt5_test/content.mk b/repos/libports/recipes/api/qt5_test/content.mk
new file mode 100644
index 0000000000..2eb53b7a43
--- /dev/null
+++ b/repos/libports/recipes/api/qt5_test/content.mk
@@ -0,0 +1,23 @@
+MIRROR_FROM_REP_DIR := lib/import/import-qt5_test.mk \
+ lib/import/import-qt5.inc
+
+content: $(MIRROR_FROM_REP_DIR)
+
+$(MIRROR_FROM_REP_DIR):
+ $(mirror_from_rep_dir)
+
+PORT_DIR := $(call port_dir,$(REP_DIR)/ports/qt5)
+
+MIRROR_FROM_PORT_DIR := include/QtTest \
+ lib/symbols/qt5_test
+
+content: $(MIRROR_FROM_PORT_DIR)
+
+$(MIRROR_FROM_PORT_DIR):
+ mkdir -p $(dir $@)
+ cp -r $(PORT_DIR)/$@ $(dir $@)
+
+content: LICENSE
+
+LICENSE:
+ cp $(PORT_DIR)/src/lib/qt5/qt5/LICENSE.LGPLv3 $@
diff --git a/repos/libports/recipes/api/qt5_test/hash b/repos/libports/recipes/api/qt5_test/hash
new file mode 100644
index 0000000000..14c94303a2
--- /dev/null
+++ b/repos/libports/recipes/api/qt5_test/hash
@@ -0,0 +1 @@
+2018-08-13 308d9f5623aede592bc9af587a879a95b62ef933
diff --git a/repos/libports/recipes/src/qt5_test/api b/repos/libports/recipes/src/qt5_test/api
new file mode 100644
index 0000000000..10efd13e6e
--- /dev/null
+++ b/repos/libports/recipes/src/qt5_test/api
@@ -0,0 +1 @@
+qt5_test
diff --git a/repos/libports/recipes/src/qt5_test/content.mk b/repos/libports/recipes/src/qt5_test/content.mk
new file mode 100644
index 0000000000..08d49f0102
--- /dev/null
+++ b/repos/libports/recipes/src/qt5_test/content.mk
@@ -0,0 +1,27 @@
+MIRROR_FROM_REP_DIR := lib/mk/qt5_test.mk \
+ lib/mk/qt5_test_generated.inc \
+ lib/mk/qt5.inc \
+
+content: $(MIRROR_FROM_REP_DIR) src/lib/qt5_test/target.mk
+
+$(MIRROR_FROM_REP_DIR):
+ $(mirror_from_rep_dir)
+
+src/lib/qt5_test/target.mk:
+ mkdir -p $(dir $@)
+ echo "LIBS = qt5_test" > $@
+
+PORT_DIR := $(call port_dir,$(REP_DIR)/ports/qt5)
+
+MIRROR_FROM_PORT_DIR := src/lib/qt5/qt5/qtbase/src/testlib
+
+content: $(MIRROR_FROM_PORT_DIR)
+
+$(MIRROR_FROM_PORT_DIR):
+ mkdir -p $(dir $@)
+ cp -r $(PORT_DIR)/$@ $(dir $@)
+
+content: LICENSE
+
+LICENSE:
+ cp $(PORT_DIR)/src/lib/qt5/qt5/LICENSE.LGPLv3 $@
diff --git a/repos/libports/recipes/src/qt5_test/hash b/repos/libports/recipes/src/qt5_test/hash
new file mode 100644
index 0000000000..24a9515d30
--- /dev/null
+++ b/repos/libports/recipes/src/qt5_test/hash
@@ -0,0 +1 @@
+2018-08-13 8730cb4f9525a9d2959fde927065448e6b369b63
diff --git a/repos/libports/recipes/src/qt5_test/used_apis b/repos/libports/recipes/src/qt5_test/used_apis
new file mode 100644
index 0000000000..173fddbe0a
--- /dev/null
+++ b/repos/libports/recipes/src/qt5_test/used_apis
@@ -0,0 +1,4 @@
+base
+libc
+qt5_core
+stdcxx
diff --git a/repos/libports/recipes/src/qt5_testqstring/content.mk b/repos/libports/recipes/src/qt5_testqstring/content.mk
new file mode 100644
index 0000000000..d4fcccd53a
--- /dev/null
+++ b/repos/libports/recipes/src/qt5_testqstring/content.mk
@@ -0,0 +1,22 @@
+MIRROR_FROM_REP_DIR := src/app/qt5/examples/testqstring \
+ src/app/qt5/tmpl/target_defaults.inc \
+ src/app/qt5/tmpl/target_final.inc
+
+content: $(MIRROR_FROM_REP_DIR) LICENSE
+
+$(MIRROR_FROM_REP_DIR):
+ $(mirror_from_rep_dir)
+
+PORT_DIR := $(call port_dir,$(REP_DIR)/ports/qt5)
+
+MIRROR_FROM_PORT_DIR := src/lib/qt5/qt5/qtbase/examples/qtestlib/tutorial1
+
+content: $(MIRROR_FROM_PORT_DIR)
+
+$(MIRROR_FROM_PORT_DIR):
+ mkdir -p $(dir $@)
+ cp -r $(PORT_DIR)/$@ $(dir $@)
+
+LICENSE:
+ cp $(GENODE_DIR)/LICENSE $@
+
diff --git a/repos/libports/recipes/src/qt5_testqstring/hash b/repos/libports/recipes/src/qt5_testqstring/hash
new file mode 100644
index 0000000000..0456a8794d
--- /dev/null
+++ b/repos/libports/recipes/src/qt5_testqstring/hash
@@ -0,0 +1 @@
+2018-08-13 f94e5b93b5b3b9ae6ed99631d5378fb66b848936
diff --git a/repos/libports/recipes/src/qt5_testqstring/used_apis b/repos/libports/recipes/src/qt5_testqstring/used_apis
new file mode 100644
index 0000000000..3124dfead7
--- /dev/null
+++ b/repos/libports/recipes/src/qt5_testqstring/used_apis
@@ -0,0 +1,11 @@
+base
+libc
+mesa
+qt5_component
+qt5_core
+qt5_gui
+qt5_qjpeg
+qt5_qpa_nitpicker
+qt5_test
+qt5_widgets
+stdcxx
diff --git a/repos/libports/run/qt5_testqstring.run b/repos/libports/run/qt5_testqstring.run
new file mode 100644
index 0000000000..c0914ba0af
--- /dev/null
+++ b/repos/libports/run/qt5_testqstring.run
@@ -0,0 +1,69 @@
+source ${genode_dir}/repos/libports/run/qt5_common.inc
+
+import_from_depot [depot_user]/src/qt5_component \
+ [depot_user]/src/qt5_test \
+ [depot_user]/src/qt5_widgets \
+ [depot_user]/src/qt5_testqstring
+
+#
+# Build
+#
+
+append build_components [qt5_build_components feature]
+
+build $build_components
+
+
+#
+# Generate config
+#
+
+append config {
+
+ }
+append config [qt5_parent_provides feature]
+append config {
+
+
+
+
+ }
+
+append config [qt5_start_nodes feature]
+
+append config {
+
+
+
+
+
+
+ 2018-01-01 00:01
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+}
+
+install_config $config
+
+#
+# Boot modules
+#
+
+append boot_modules [qt5_boot_modules feature]
+
+build_boot_image $boot_modules
+
+run_genode_until " Finished testing of TestQString" 30
diff --git a/repos/libports/src/app/qt5/examples/testqstring/target.mk b/repos/libports/src/app/qt5/examples/testqstring/target.mk
new file mode 100644
index 0000000000..ec237858c3
--- /dev/null
+++ b/repos/libports/src/app/qt5/examples/testqstring/target.mk
@@ -0,0 +1,18 @@
+QT5_PORT_DIR := $(call select_from_ports,qt5)
+QT5_CONTRIB_DIR := $(QT5_PORT_DIR)/src/lib/qt5/qt5
+
+QMAKE_PROJECT_PATH = $(QT5_CONTRIB_DIR)/qtbase/examples/qtestlib/tutorial1
+QMAKE_PROJECT_FILE = $(QMAKE_PROJECT_PATH)/tutorial1.pro
+
+vpath % $(QMAKE_PROJECT_PATH)
+
+# 'testqstring.cpp' includes 'testqstring.moc'
+testqstring.o: testqstring.moc
+
+include $(call select_from_repositories,src/app/qt5/tmpl/target_defaults.inc)
+
+include $(call select_from_repositories,src/app/qt5/tmpl/target_final.inc)
+
+LIBS += qt5_component
+
+CC_CXX_WARN_STRICT =
diff --git a/repos/libports/src/app/qt5/tmpl/target_final.inc b/repos/libports/src/app/qt5/tmpl/target_final.inc
index 4573cc9f75..e21499886b 100644
--- a/repos/libports/src/app/qt5/tmpl/target_final.inc
+++ b/repos/libports/src/app/qt5/tmpl/target_final.inc
@@ -45,6 +45,11 @@ LIBS += qt5_scriptclassic
endif
endif
+# QtTest
+ifeq ($(findstring testlib, $(QT)), testlib)
+LIBS += qt5_test
+endif
+
# QtXml
ifeq ($(findstring xml, $(QT)), xml)
LIBS += qt5_xml
diff --git a/repos/libports/src/lib/qt5/patches/qtbase_generated.patch b/repos/libports/src/lib/qt5/patches/qtbase_generated.patch
index 5e886bf08c..1bb8924e86 100644
--- a/repos/libports/src/lib/qt5/patches/qtbase_generated.patch
+++ b/repos/libports/src/lib/qt5/patches/qtbase_generated.patch
@@ -22,6 +22,7 @@ From: Christian Prochaska
.../include/QtPrintSupport/QtPrintSupportDepends | 4 +
.../include/QtPrintSupport/qtprintsupport-config.h | 1
qtbase/include/QtSql/QtSqlDepends | 2 +
+ qtbase/include/QtTest/QtTestDepends | 4 +
.../5.8.0/QtWidgets/private/qtwidgets-config_p.h | 1
qtbase/include/QtWidgets/QtWidgetsDepends | 3 +
qtbase/include/QtWidgets/qtwidgets-config.h | 1
@@ -45,7 +46,7 @@ From: Christian Prochaska
qtbase/src/widgets/qtwidgets-config_p.h | 1
qtbase/src/xml/qtxml-config.h | 1
qtbase/src/xml/qtxml-config_p.h | 0
- 41 files changed, 368 insertions(+)
+ 42 files changed, 372 insertions(+)
create mode 100644 qtbase/include/QtCore/5.8.0/QtCore/private/qconfig_p.h
create mode 100644 qtbase/include/QtCore/5.8.0/QtCore/private/qtcore-config_p.h
create mode 100644 qtbase/include/QtCore/QtConfig
@@ -64,6 +65,7 @@ From: Christian Prochaska
create mode 100644 qtbase/include/QtPrintSupport/QtPrintSupportDepends
create mode 100644 qtbase/include/QtPrintSupport/qtprintsupport-config.h
create mode 100644 qtbase/include/QtSql/QtSqlDepends
+ create mode 100644 qtbase/include/QtTest/QtTestDepends
create mode 100644 qtbase/include/QtWidgets/5.8.0/QtWidgets/private/qtwidgets-config_p.h
create mode 100644 qtbase/include/QtWidgets/QtWidgetsDepends
create mode 100644 qtbase/include/QtWidgets/qtwidgets-config.h
@@ -223,6 +225,16 @@ index 0000000..42eb220
@@ -0,0 +1,2 @@
+/* This file was generated by qmake with the info from /src/sql/sql.pro. */
+#include
+diff --git a/qtbase/include/QtTest/QtTestDepends b/qtbase/include/QtTest/QtTestDepends
+new file mode 100644
+index 0000000..64e448e
+--- /dev/null
++++ b/qtbase/include/QtTest/QtTestDepends
+@@ -0,0 +1,4 @@
++/* This file was generated by qmake with the info from /src/testlib/testlib.pro. */
++#ifdef __cplusplus /* create empty PCH in C mode */
++#include
++#endif
diff --git a/qtbase/include/QtWidgets/5.8.0/QtWidgets/private/qtwidgets-config_p.h b/qtbase/include/QtWidgets/5.8.0/QtWidgets/private/qtwidgets-config_p.h
new file mode 100644
index 0000000..9a6332d
diff --git a/repos/libports/src/lib/qt5/patches/qtbase_genode.patch b/repos/libports/src/lib/qt5/patches/qtbase_genode.patch
index 90e92a677f..7693281daf 100644
--- a/repos/libports/src/lib/qt5/patches/qtbase_genode.patch
+++ b/repos/libports/src/lib/qt5/patches/qtbase_genode.patch
@@ -29,9 +29,10 @@ Genode-specific adaptations
.../evdevkeyboard/qevdevkeyboard_defaultmap_p.h | 4 +
.../input/evdevkeyboard/qevdevkeyboardhandler.cpp | 17 ++++++
.../input/evdevkeyboard/qevdevkeyboardhandler_p.h | 2 +
+ qtbase/src/testlib/qtestcase.cpp | 2 -
qtbase/src/widgets/dialogs/qfiledialog.cpp | 2 -
qtbase/src/widgets/styles/qstylefactory.cpp | 7 +++
- 27 files changed, 196 insertions(+), 9 deletions(-)
+ 28 files changed, 197 insertions(+), 10 deletions(-)
diff --git a/qtbase/src/corelib/codecs/qtextcodec.cpp b/qtbase/src/corelib/codecs/qtextcodec.cpp
index 0c9036a..0dac7c1 100644
@@ -623,6 +624,19 @@ index 1ec4915..fed7024 100644
KeycodeAction processKeycode(quint16 keycode, bool pressed, bool autorepeat);
private:
+diff --git a/qtbase/src/testlib/qtestcase.cpp b/qtbase/src/testlib/qtestcase.cpp
+index 1c13f8e..f89b55c 100644
+--- a/qtbase/src/testlib/qtestcase.cpp
++++ b/qtbase/src/testlib/qtestcase.cpp
+@@ -1391,7 +1391,7 @@ FatalSignalHandler::FatalSignalHandler()
+
+ // tvOS/watchOS both define SA_ONSTACK (in sys/signal.h) but mark sigaltstack() as
+ // unavailable (__WATCHOS_PROHIBITED __TVOS_PROHIBITED in signal.h)
+-#if defined(SA_ONSTACK) && !defined(Q_OS_TVOS) && !defined(Q_OS_WATCHOS)
++#if defined(SA_ONSTACK) && !defined(Q_OS_TVOS) && !defined(Q_OS_WATCHOS) && !defined(Q_OS_GENODE)
+ // Let the signal handlers use an alternate stack
+ // This is necessary if SIGSEGV is to catch a stack overflow
+ # if defined(Q_CC_GNU) && defined(Q_OF_ELF)
diff --git a/qtbase/src/widgets/dialogs/qfiledialog.cpp b/qtbase/src/widgets/dialogs/qfiledialog.cpp
index 74875fa..2f6410e 100644
--- a/qtbase/src/widgets/dialogs/qfiledialog.cpp