Merge branch 'tizen' into security-manager 36/119636/1
authorKrzysztof Jackiewicz <k.jackiewicz@samsung.com>
Sat, 18 Mar 2017 07:57:24 +0000 (08:57 +0100)
committerKrzysztof Jackiewicz <k.jackiewicz@samsung.com>
Sat, 18 Mar 2017 08:01:04 +0000 (09:01 +0100)
Change-Id: I12966cd0f6a6d0a38ddd73400918989e470c9e72

packaging/security-tests.spec
src/framework/config.cmake
src/framework/include/dpl/test/safe_cleanup.h [new file with mode: 0644]
src/framework/src/safe_cleanup.cpp [new file with mode: 0644]
src/framework/src/test_runner.cpp
src/framework/src/test_runner_child.cpp
tests/CMakeLists.txt
tests/cleanup/CMakeLists.txt [new file with mode: 0644]
tests/cleanup/cleanup_test.sh [new file with mode: 0755]
tests/cleanup/expected_results.txt [new file with mode: 0644]
tests/cleanup/test_cases_cleanup.cpp [new file with mode: 0644]

index 20b1139..f981779 100644 (file)
@@ -31,6 +31,7 @@ BuildRequires: pkgconfig(libgum) >= 1.0.5
 BuildRequires: pkgconfig(security-privilege-manager)
 Requires: perf
 Requires: gdb
+Requires: diffutils
 
 %global ckm_test_dir %{?TZ_SYS_SHARE:%TZ_SYS_SHARE/ckm-test/}%{!?TZ_SYS_SHARE:/usr/share/ckm-test/}
 %global ckm_rw_data_dir %{?TZ_SYS_DATA:%TZ_SYS_DATA/ckm/}%{!?TZ_SYS_DATA:/opt/data/ckm/}
@@ -102,8 +103,12 @@ echo "security-tests postinst done ..."
 /usr/lib/security-tests/cynara-tests/plugins/multiple-policy/*
 /usr/lib/security-tests/cynara-tests/plugins/test-agent/*
 /usr/bin/security-tests-inner-test
+/usr/bin/security-tests-cleanup-test
+/usr/bin/cleanup_test.sh
 /usr/bin/libwebappenc-tests
 %{_prefix}/share/yaca-test
+%dir %{_prefix}/share/security-tests-cleanup-test
+%{_prefix}/share/security-tests-cleanup-test/*
 
 %postun
 id -u security_test_user 1>/dev/null 2>&1 && gum-utils -o -d --uid=`id -u security_test_user`
index 791e546..374d323 100644 (file)
@@ -41,6 +41,7 @@ SET(DPL_FRAMEWORK_TEST_SOURCES
     ${PROJECT_SOURCE_DIR}/src/framework/src/test_runner_child.cpp
     ${PROJECT_SOURCE_DIR}/src/framework/src/test_runner.cpp
     ${PROJECT_SOURCE_DIR}/src/framework/src/test_runner_multiprocess.cpp
+    ${PROJECT_SOURCE_DIR}/src/framework/src/safe_cleanup.cpp
 )
 
 IF(DPL_WITH_DLOG)
diff --git a/src/framework/include/dpl/test/safe_cleanup.h b/src/framework/include/dpl/test/safe_cleanup.h
new file mode 100644 (file)
index 0000000..2aca009
--- /dev/null
@@ -0,0 +1,70 @@
+/*
+ *  Copyright (c) 2017 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ *  Licensed 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
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License
+ */
+/*
+ * @file       safe_cleanup.h
+ * @author     Krzysztof Jackiewicz (k.jackiewicz@samsung.com)
+ * @version    1.0
+ */
+
+#pragma once
+
+#include <string>
+#include <functional>
+
+/*
+ * Utility that is intended for use in destructors of so called "scoped objects"
+ * or RAII objects. When a test finishes or fails the stack is unwinded some of
+ * such objects' destructors still perform actions that may report an
+ * error/throw an exception. If we just surround these actions with try/catch
+ * block we'll lose information about errors in these destructors. If we let
+ * destructors throw it may lead to program termination (unhandled exception
+ * during stack unwind caused by another exception).
+ *
+ * To prevent program termination and still get the information about errors in
+ * destructors surround the throwing code in your RAII object destructor like
+ * this:
+ *
+ * struct ThrowingRAII {
+ *     ~ThrowingRAII() {
+ *         SafeCleanup::run([]{
+ *             cleanup_code_that_may_throw();
+ *         });
+ *     }
+ * };
+ *
+ * Framework will take care of displaying all exceptions catched this way after
+ * test case is finished.
+ */
+namespace SafeCleanup {
+
+/*
+ * Remove all collected exceptions from the internal list. To be used by
+ * framework only. Function is NOT thread safe.
+ */
+void reset();
+
+/*
+ * Dump exceptions collected during test. To be used by framework only. Function
+ * is NOT thread safe.
+ */
+std::string dump();
+
+/**
+ * Run cleanup code that may throw an exception. Function is thread safe.
+ */
+void run(const std::function<void()>& snippet);
+
+} // namespace SafeCleanup
diff --git a/src/framework/src/safe_cleanup.cpp b/src/framework/src/safe_cleanup.cpp
new file mode 100644 (file)
index 0000000..cfdbedb
--- /dev/null
@@ -0,0 +1,70 @@
+/*
+ *  Copyright (c) 2017 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ *  Licensed 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
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License
+ */
+/*
+ * @file       safe_cleanup.cpp
+ * @author     Krzysztof Jackiewicz (k.jackiewicz@samsung.com)
+ * @version    1.0
+ */
+
+#include <dpl/test/safe_cleanup.h>
+
+#include <sstream>
+#include <exception>
+#include <vector>
+#include <mutex>
+
+#include <dpl/test/test_failed.h>
+#include <dpl/gdbbacktrace.h>
+
+namespace {
+
+std::vector<std::string> g_errors;
+std::mutex g_mutex;
+
+void pushError(const std::string& msg)
+{
+    std::lock_guard<std::mutex> guard(g_mutex);
+    g_errors.push_back(msg);
+}
+
+} // anonymous namespace
+
+void SafeCleanup::reset()
+{
+    g_errors.clear();
+}
+std::string SafeCleanup::dump()
+{
+    std::ostringstream os;
+    for(const auto& e : g_errors)
+        os << e << std::endl;
+    g_errors.clear();
+
+    return os.str();
+}
+
+void SafeCleanup::run(const std::function<void()>& snippet)
+{
+    try {
+        snippet();
+    } catch (const DPL::Test::TestFailed& e) {
+        pushError(e.GetMessage());
+    } catch (...) {
+        std::ostringstream is;
+        is << "Unknown exception:" << DPL::gdbbacktrace();
+        pushError(is.str());
+    }
+}
index f4a625f..ec67029 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014-2015 Samsung Electronics Co., Ltd All Rights Reserved
+ * Copyright (c) 2014-2017 Samsung Electronics Co., Ltd All Rights Reserved
  *
  *    Licensed under the Apache License, Version 2.0 (the "License");
  *    you may not use this file except in compliance with the License.
@@ -25,6 +25,7 @@
 #include <dpl/test/test_ignored.h>
 #include <dpl/test/test_runner.h>
 #include <dpl/test/test_results_collector.h>
+#include <dpl/test/safe_cleanup.h>
 #include <dpl/exception.h>
 #include <dpl/scoped_free.h>
 #include <dpl/log/log.h>
@@ -244,6 +245,8 @@ void TestRunner::RunTestCase(TestCasePtr testCase)
         return;
     }
 
+    SafeCleanup::reset();
+
     std::string testReason;
     TestResult::FailStatus testStatus = TryCatch(std::bind(&TestCase::Test, testCase),
                                                  testReason);
@@ -253,12 +256,19 @@ void TestRunner::RunTestCase(TestCasePtr testCase)
                                                    finishReason);
     finishReason = getConcatedFailReason(finishReason);
 
+    std::string cleanupReason = SafeCleanup::dump();
+
     switch (finishStatus) {
         case TestResult::FailStatus::FAILED:
             testStatus = TestResult::FailStatus::FAILED;
             if (!testReason.empty())
                 testReason += "\n";
             testReason += finishReason;
+            if (!cleanupReason.empty()) {
+                if (!testReason.empty())
+                    testReason += "\n";
+                testReason += cleanupReason;
+            }
             break;
         case TestResult::FailStatus::IGNORED:
             if (testStatus == TestResult::FailStatus::NONE)
@@ -267,6 +277,13 @@ void TestRunner::RunTestCase(TestCasePtr testCase)
                 testReason += "\n";
             testReason += finishReason;
         case TestResult::FailStatus::NONE:
+            if (!cleanupReason.empty()) {
+                if (!testReason.empty())
+                    testReason += "\n";
+                testReason += cleanupReason;
+                if (testStatus == TestResult::FailStatus::NONE)
+                    testStatus = TestResult::FailStatus::FAILED;
+            }
             break;
         default:
             Assert(false && "Unhandled fail status");
index c0cd93f..1516334 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013-2015 Samsung Electronics Co., Ltd All Rights Reserved
+ * Copyright (c) 2013-2017 Samsung Electronics Co., Ltd All Rights Reserved
  *
  *    Licensed under the Apache License, Version 2.0 (the "License");
  *    you may not use this file except in compliance with the License.
@@ -26,6 +26,7 @@
 #include <dpl/test/test_runner.h>
 #include <dpl/test/test_runner_child.h>
 #include <dpl/test/test_results_collector.h>
+#include <dpl/test/safe_cleanup.h>
 #include <dpl/binary_queue.h>
 #include <dpl/exception.h>
 #include <dpl/scoped_free.h>
@@ -349,6 +350,8 @@ void RunChildProc(const std::function<void(void)> &testFunc)
 
         pipe.setUsage(PipeWrapper::WRITEONLY);
 
+        SafeCleanup::reset();
+
         int code;
         std::string msg;
         switch (TryCatch(testFunc, msg)) {
@@ -365,6 +368,18 @@ void RunChildProc(const std::function<void(void)> &testFunc)
                 Assert(false && "Unhandled fail status");
         }
 
+        std::string cleanup;
+        if (code != CHILD_TEST_IGNORED)
+        {
+            cleanup = SafeCleanup::dump();
+            if (!cleanup.empty()) {
+                code = CHILD_TEST_FAIL;
+                if (!msg.empty())
+                    msg += '\n';
+                msg += cleanup;
+            }
+        }
+
         if (allowLogs) {
             closeOutput();
         }
index b1b4d87..37ad4de 100644 (file)
@@ -1,4 +1,4 @@
-# Copyright (c) 2015 Samsung Electronics Co., Ltd All Rights Reserved
+# Copyright (c) 2015-2017 Samsung Electronics Co., Ltd All Rights Reserved
 #
 #    Licensed under the Apache License, Version 2.0 (the "License");
 #    you may not use this file except in compliance with the License.
@@ -61,3 +61,5 @@ INSTALL(TARGETS ${INNER_TARGET_TEST}
                 WORLD_READ
                 WORLD_EXECUTE
     )
+
+ADD_SUBDIRECTORY(cleanup)
\ No newline at end of file
diff --git a/tests/cleanup/CMakeLists.txt b/tests/cleanup/CMakeLists.txt
new file mode 100644 (file)
index 0000000..03b7b2d
--- /dev/null
@@ -0,0 +1,64 @@
+# Copyright (c) 2017 Samsung Electronics Co., Ltd All Rights Reserved
+#
+#    Licensed 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
+#
+#    Unless required by applicable law or agreed to in writing, software
+#    distributed under the License is distributed on an "AS IS" BASIS,
+#    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+#    See the License for the specific language governing permissions and
+#    limitations under the License.
+#
+
+cmake_minimum_required(VERSION 2.8.3)
+
+SET(CLEANUP_TARGET_TEST "security-tests-cleanup-test")
+
+#files to compile
+SET(CLEANUP_TARGET_TEST_SOURCES
+    ${PROJECT_SOURCE_DIR}/tests/cleanup/test_cases_cleanup.cpp
+    )
+
+#header directories
+INCLUDE_DIRECTORIES(
+    ${PROJECT_SOURCE_DIR}/src/framework/include/
+    ${PROJECT_SOURCE_DIR}/src/
+    )
+
+#output format
+ADD_EXECUTABLE(${CLEANUP_TARGET_TEST} ${CLEANUP_TARGET_TEST_SOURCES})
+
+#linker directories
+TARGET_LINK_LIBRARIES(${CLEANUP_TARGET_TEST}
+    tests-common
+    dpl-test-framework
+    )
+
+#place for output file
+INSTALL(TARGETS ${CLEANUP_TARGET_TEST}
+    DESTINATION /usr/bin
+    PERMISSIONS OWNER_READ
+                OWNER_WRITE
+                OWNER_EXECUTE
+                GROUP_READ
+                GROUP_EXECUTE
+                WORLD_READ
+                WORLD_EXECUTE
+    )
+
+INSTALL(FILES ${CMAKE_CURRENT_SOURCE_DIR}/cleanup_test.sh
+    DESTINATION /usr/bin
+    PERMISSIONS OWNER_READ
+                OWNER_WRITE
+                OWNER_EXECUTE
+                GROUP_READ
+                GROUP_EXECUTE
+                WORLD_READ
+                WORLD_EXECUTE
+    )
+
+INSTALL(FILES ${CMAKE_CURRENT_SOURCE_DIR}/expected_results.txt
+    DESTINATION  "${SHARE_INSTALL_PREFIX}/${CLEANUP_TARGET_TEST}/")
diff --git a/tests/cleanup/cleanup_test.sh b/tests/cleanup/cleanup_test.sh
new file mode 100755 (executable)
index 0000000..9582d4b
--- /dev/null
@@ -0,0 +1,17 @@
+#!/bin/bash
+
+EXPECTED=/usr/share/security-tests-cleanup-test/expected_results.txt
+OUTPUT=/tmp/cleanup_test_output.txt
+
+>| $OUTPUT
+for TEST in `security-tests-cleanup-test --list | cut -d':' -f3`
+do
+    echo $TEST | tee -a $OUTPUT
+    security-tests-cleanup-test --regexp=$TEST 2>/dev/null | grep "Assertion failed\|Unknown exception\|Ignored test" | rev | cut -d' ' -f1,2 | rev | sed 's/\x1B\[0;33m//' |tee -a $OUTPUT
+    echo | tee -a $OUTPUT
+done
+
+diff $EXPECTED $OUTPUT && echo "[SUCCESS] Result matches expectations" && exit
+
+echo "[FAILED] Result is different than expected ($EXPECTED != $OUTPUT)"
+exit 1
diff --git a/tests/cleanup/expected_results.txt b/tests/cleanup/expected_results.txt
new file mode 100644 (file)
index 0000000..9e4ca78
--- /dev/null
@@ -0,0 +1,82 @@
+cl0010_same_process_no_fixture_success
+[dtor] DPL::Test::TestFailed
+Unknown exception:
+
+cl0020_same_process_no_fixture_fail
+[test] DPL::Test::TestFailed
+[dtor] DPL::Test::TestFailed
+Unknown exception:
+
+cl0030_same_process_fixture_success
+[dtor] DPL::Test::TestFailed
+Unknown exception:
+[fixture] DPL::Test::TestFailed
+Unknown exception:
+
+cl0040_same_process_fixture_fail
+[test] DPL::Test::TestFailed
+[dtor] DPL::Test::TestFailed
+Unknown exception:
+[fixture] DPL::Test::TestFailed
+Unknown exception:
+
+cl0050_same_process_multiple_fixtures_success
+[dtor] DPL::Test::TestFailed
+Unknown exception:
+[fixture2] DPL::Test::TestFailed
+Unknown exception:
+[fixture] DPL::Test::TestFailed
+Unknown exception:
+
+cl0060_same_process_test_per_fixture_success_fixture1
+[dtor] DPL::Test::TestFailed
+Unknown exception:
+[fixture] DPL::Test::TestFailed
+Unknown exception:
+
+cl0060_same_process_test_per_fixture_success_fixture2
+[dtor] DPL::Test::TestFailed
+Unknown exception:
+[fixture2] DPL::Test::TestFailed
+Unknown exception:
+
+cl0070_same_process_fixture_ignored
+Ignored test
+[fixture] DPL::Test::TestFailed
+Unknown exception:
+
+cl0110_child_no_fixture_success
+[dtor] DPL::Test::TestFailed
+Unknown exception:
+
+cl0120_child_no_fixture_fail
+[test] DPL::Test::TestFailed
+[dtor] DPL::Test::TestFailed
+Unknown exception:
+
+cl0130_child_fixture_success
+[dtor] DPL::Test::TestFailed
+Unknown exception:
+[fixture] DPL::Test::TestFailed
+Unknown exception:
+
+cl0140_child_fixture_fail
+[test] DPL::Test::TestFailed
+[dtor] DPL::Test::TestFailed
+Unknown exception:
+[fixture] DPL::Test::TestFailed
+Unknown exception:
+
+cl0150_child_multiple_fixtures_success
+[dtor] DPL::Test::TestFailed
+Unknown exception:
+[fixture2] DPL::Test::TestFailed
+Unknown exception:
+[fixture] DPL::Test::TestFailed
+Unknown exception:
+
+cl0170_child_fixture_ignored
+Ignored test
+[fixture] DPL::Test::TestFailed
+Unknown exception:
+
diff --git a/tests/cleanup/test_cases_cleanup.cpp b/tests/cleanup/test_cases_cleanup.cpp
new file mode 100644 (file)
index 0000000..f52f749
--- /dev/null
@@ -0,0 +1,264 @@
+/*
+ *  Copyright (c) 2017 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ *  Licensed 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
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License
+ */
+/*
+ * @file       test_cases_cleanup.cpp
+ * @author     Krzysztof Jackiewicz (k.jackiewicz@samsung.com)
+ * @version    1.0
+ */
+
+#include <exception>
+#include <sstream>
+#include <string>
+
+#include <dpl/test/safe_cleanup.h>
+
+#include <dpl/test/test_runner.h>
+#include <dpl/test/test_runner_child.h>
+
+namespace {
+
+const std::string FAIL_MSG = "[test] DPL::Test::TestFailed";
+const std::string DTOR_TAG = "[dtor]";
+
+void runnerFail(const std::string& tag) {
+    std::ostringstream os;
+    os << tag << " DPL::Test::TestFailed";
+    RUNNER_FAIL_MSG(os.str());
+}
+
+void runtimeException() {
+    throw std::runtime_error("");
+}
+
+struct ScopedObject {
+    explicit ScopedObject(const std::string& tag = DTOR_TAG) : m_tag(tag) {}
+    ~ScopedObject() {
+        SafeCleanup::run([this]{
+            runnerFail(m_tag);
+        });
+        SafeCleanup::run([]{
+            runtimeException();
+        });
+    }
+private:
+    std::string m_tag;
+};
+
+struct CleanupFixture {
+    void init(const std::string&)
+    {}
+    void finish()
+    {
+        ScopedObject so("[fixture]");
+    }
+
+    static std::string suffix() { return "_fixture1"; }
+};
+
+struct CleanupFixture2 : public CleanupFixture {
+    static std::string suffix() { return "_fixture2"; }
+
+    void finish()
+    {
+        ScopedObject so("[fixture2]");
+    }
+};
+
+} // anonymous namespace
+
+int main(int argc, char *argv[])
+{
+    int status = DPL::Test::TestRunnerSingleton::Instance().ExecTestRunner(argc, argv);
+    return status;
+}
+
+/*
+ *  These tests are supposed to fail in a specific manner. Please see the
+ *  description or use cleanup_test.sh.
+ */
+RUNNER_TEST_GROUP_INIT(CLEANUP)
+
+/*
+ * Expected result:
+ * - [dtor] DPL::Test::TestFailed
+ * - Unknown exception
+ */
+RUNNER_TEST(cl0010_same_process_no_fixture_success)
+{
+    ScopedObject so;
+}
+
+/*
+ * Expected result:
+ * - [test] DPL::Test::TestFailed
+ * - [dtor] DPL::Test::TestFailed
+ * - Unknown exception
+ */
+RUNNER_TEST(cl0020_same_process_no_fixture_fail)
+{
+    ScopedObject so;
+
+    RUNNER_FAIL_MSG(FAIL_MSG);
+}
+
+/*
+ * Expected result:
+ * - [dtor] DPL::Test::TestFailed
+ * - Unknown exception
+ * - [fixture] DPL::Test::TestFailed
+ * - Unknown exception
+ */
+RUNNER_TEST(cl0030_same_process_fixture_success, CleanupFixture)
+{
+    ScopedObject so;
+}
+
+/*
+ * Expected result:
+ * - [test] DPL::Test::TestFailed
+ * - [dtor] DPL::Test::TestFailed
+ * - Unknown exception
+ * - [fixture] DPL::Test::TestFailed
+ * - Unknown exception
+ */
+RUNNER_TEST(cl0040_same_process_fixture_fail, CleanupFixture)
+{
+    ScopedObject so;
+
+    RUNNER_FAIL_MSG(FAIL_MSG);
+}
+
+/*
+ * Expected result:
+ * - [dtor] DPL::Test::TestFailed
+ * - Unknown exception
+ * - [fixture2] DPL::Test::TestFailed
+ * - Unknown exception
+ * - [fixture] DPL::Test::TestFailed
+ * - Unknown exception
+ */
+RUNNER_TEST(cl0050_same_process_multiple_fixtures_success, CleanupFixture, CleanupFixture2)
+{
+    ScopedObject so;
+}
+
+/*
+ * Expected result (CleanupFixture):
+ * - [dtor] DPL::Test::TestFailed
+ * - Unknown exception
+ * - [fixture] DPL::Test::TestFailed
+ * - Unknown exception
+ *
+ * Expected result (CleanupFixture2):
+ * - [dtor] DPL::Test::TestFailed
+ * - Unknown exception
+ * - [fixture2] DPL::Test::TestFailed
+ * - Unknown exception
+ */
+RUNNER_TEST_MULTIPLE(cl0060_same_process_test_per_fixture_success, CleanupFixture, CleanupFixture2)
+{
+    ScopedObject so;
+}
+
+/*
+ * Expected result:
+ * - Ignored test
+ * - [fixture] DPL::Test::TestFailed
+ * - Unknown exception
+ */
+RUNNER_TEST(cl0070_same_process_fixture_ignored, CleanupFixture)
+{
+    RUNNER_IGNORED_MSG("Ignored test");
+
+    ScopedObject so;
+}
+
+/*
+ * Expected result:
+ * - [dtor] DPL::Test::TestFailed
+ * - Unknown exception
+ */
+RUNNER_CHILD_TEST(cl0110_child_no_fixture_success)
+{
+    ScopedObject so;
+}
+
+/*
+ * Expected result:
+ * - [test] DPL::Test::TestFailed
+ * - [dtor] DPL::Test::TestFailed
+ * - Unknown exception
+ */
+RUNNER_CHILD_TEST(cl0120_child_no_fixture_fail)
+{
+    ScopedObject so;
+
+    RUNNER_FAIL_MSG(FAIL_MSG);
+}
+
+/*
+ * Expected result:
+ * - [dtor] DPL::Test::TestFailed
+ * - Unknown exception
+ * - [fixture] DPL::Test::TestFailed
+ * - Unknown exception
+ */
+RUNNER_CHILD_TEST(cl0130_child_fixture_success, CleanupFixture)
+{
+    ScopedObject so;
+}
+
+/*
+ * Expected result:
+ * - [test] DPL::Test::TestFailed
+ * - [dtor] DPL::Test::TestFailed
+ * - Unknown exception
+ * - [fixture] DPL::Test::TestFailed
+ * - Unknown exception
+ */
+RUNNER_CHILD_TEST(cl0140_child_fixture_fail, CleanupFixture)
+{
+    ScopedObject so;
+
+    RUNNER_FAIL_MSG(FAIL_MSG);
+}
+
+/*
+ * Expected result:
+ * - [dtor] DPL::Test::TestFailed
+ * - Unknown exception
+ * - [fixture2] DPL::Test::TestFailed
+ * - Unknown exception
+ * - [fixture] DPL::Test::TestFailed
+ * - Unknown exception
+ */
+RUNNER_CHILD_TEST(cl0150_child_multiple_fixtures_success, CleanupFixture, CleanupFixture2)
+{
+    ScopedObject so;
+}
+
+/*
+ * Expected result:
+ * - Ignored test
+ * - [fixture] DPL::Test::TestFailed
+ * - Unknown exception
+ */
+RUNNER_CHILD_TEST(cl0170_child_fixture_ignored, CleanupFixture)
+{
+    RUNNER_IGNORED_MSG("Ignored test");
+
+    ScopedObject so;
+}