From e74d29caeef5a8870a38570cb79fcdd1fb702dd7 Mon Sep 17 00:00:00 2001
From: Florian Schmaus <flow@cs.fau.de>
Date: Wed, 9 Dec 2020 19:28:03 +0100
Subject: [PATCH] [test] Add EMPER test runner

---
 .gitlab-ci.yml                                |  7 ++++
 ...SignalPrivateSemaphoreFromAnywhereTest.cpp | 19 +----------
 tests/TellActorFromAnywhereTest.cpp           | 19 +----------
 tests/meson.build                             |  8 +++++
 tests/test-runner/emper-test-runner.cpp       | 33 +++++++++++++++++++
 tests/test-runner/meson.build                 |  8 +++++
 6 files changed, 58 insertions(+), 36 deletions(-)
 create mode 100644 tests/test-runner/emper-test-runner.cpp
 create mode 100644 tests/test-runner/meson.build

diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml
index 675725ee..87b24637 100644
--- a/.gitlab-ci.yml
+++ b/.gitlab-ci.yml
@@ -78,6 +78,13 @@ variables:
   extends:
     - .clang
     - .default-library-static
+  variables:
+    # Clang's sanitizers require undefined symbols to be allowed when
+    # linking. See also:
+    # - https://github.com/mesonbuild/meson/issues/764
+    # - https://mesonbuild.com/Builtin-options.html
+    EMPER_B_LUNDEF: 'false'
+
 
 .clang-sanitizer-undefined:
   extends:
diff --git a/tests/SignalPrivateSemaphoreFromAnywhereTest.cpp b/tests/SignalPrivateSemaphoreFromAnywhereTest.cpp
index d4fd5858..e5f87139 100644
--- a/tests/SignalPrivateSemaphoreFromAnywhereTest.cpp
+++ b/tests/SignalPrivateSemaphoreFromAnywhereTest.cpp
@@ -1,15 +1,12 @@
 // SPDX-License-Identifier: LGPL-3.0-or-later
 // Copyright © 2020 Florian Schmaus
-#include <cstdlib>	// for exit, EXIT_FAILURE, EXIT_SUCCESS
 #include <thread>
 
 #include "BinaryPrivateSemaphore.hpp"
 #include "Fiber.hpp"
-#include "Runtime.hpp"	// for Runtime
-#include "emper-common.h"
 #include "emper.hpp"
 
-static void testSignalPrivateSemaphoreFromAnywhere() {
+void emperTest() {
 	BinaryPrivateSemaphore bpsTest;
 	BinaryPrivateSemaphore bpsSignalledFromAnywhere;
 
@@ -28,18 +25,4 @@ static void testSignalPrivateSemaphoreFromAnywhere() {
 
 	// TODO: Remove this once we use std::jthread when EMPER uses C++20.
 	signallingThread.join();
-
-	exit(EXIT_SUCCESS);
-}
-
-auto main(UNUSED_ARG int argc, UNUSED_ARG char* argv[]) -> int {
-	Runtime runtime;
-
-	Fiber* alphaFiber = Fiber::from(&testSignalPrivateSemaphoreFromAnywhere);
-
-	runtime.scheduleFromAnywhere(*alphaFiber);
-
-	runtime.waitUntilFinished();
-
-	return EXIT_FAILURE;
 }
diff --git a/tests/TellActorFromAnywhereTest.cpp b/tests/TellActorFromAnywhereTest.cpp
index 4f535657..bedfbd6d 100644
--- a/tests/TellActorFromAnywhereTest.cpp
+++ b/tests/TellActorFromAnywhereTest.cpp
@@ -1,13 +1,10 @@
 // SPDX-License-Identifier: LGPL-3.0-or-later
 // Copyright © 2020 Florian Schmaus
-#include <cstdlib>		 // for exit, EXIT_FAILURE, EXIT_SUCCESS
 #include <functional>	 // for bind
 #include <thread>
 
 #include "Actor.hpp"
 #include "BinaryPrivateSemaphore.hpp"
-#include "Fiber.hpp"
-#include "Runtime.hpp"	// for Runtime
 #include "emper-common.h"
 
 class SignallingActor : public Actor<unsigned int> {
@@ -21,7 +18,7 @@ class SignallingActor : public Actor<unsigned int> {
 	SignallingActor(BinaryPrivateSemaphore& bps) : bps(bps){};
 };
 
-static void testTellActorFromAnywhere() {
+void emperTest() {
 	BinaryPrivateSemaphore bps;
 	SignallingActor signallingActor(bps);
 	signallingActor.start();
@@ -33,18 +30,4 @@ static void testTellActorFromAnywhere() {
 
 	// TODO: Remove this once we use std::jthread when EMPER uses C++20.
 	signallingThread.join();
-
-	exit(EXIT_SUCCESS);
-}
-
-auto main(UNUSED_ARG int argc, UNUSED_ARG char* argv[]) -> int {
-	Runtime runtime;
-
-	Fiber* alphaFiber = Fiber::from(&testTellActorFromAnywhere);
-
-	runtime.scheduleFromAnywhere(*alphaFiber);
-
-	runtime.waitUntilFinished();
-
-	return EXIT_FAILURE;
 }
diff --git a/tests/meson.build b/tests/meson.build
index 32e83633..a4ba8ce8 100644
--- a/tests/meson.build
+++ b/tests/meson.build
@@ -54,12 +54,14 @@ tests = {
 			'description': 'Simple test for PrivateSemaphore:signalFromAnywhere()',
 			'test_suite': 'smoke',
 			'is_parallel': true,
+			'emper_test_runner': true,
 		  },
 		  'TellActorFromAnywhereTest.cpp':
 		  {
 			'description': 'Simple test for Actor:tellFromAnywhere()',
 			'test_suite': 'smoke',
 			'is_parallel': true,
+			'emper_test_runner': true,
 		  },
 		}
 
@@ -74,6 +76,8 @@ test_env = environment(
   }
 )
 
+subdir('test-runner')
+
 foreach source, test_dict : tests
   # TODO: Use meson fs (filesystem) module once meson >= 0.53 is in
   # buster-backports, instead of split('.')[0]
@@ -86,6 +90,10 @@ foreach source, test_dict : tests
   	test_deps += test_dict['dependencies']
   endif
 
+  if test_dict.get('emper_test_runner', false)
+	test_deps += emper_test_runner_dep
+  endif
+
   test_exe = executable(test_name,
 						source,
 						include_directories: emper_all_include,
diff --git a/tests/test-runner/emper-test-runner.cpp b/tests/test-runner/emper-test-runner.cpp
new file mode 100644
index 00000000..711e757f
--- /dev/null
+++ b/tests/test-runner/emper-test-runner.cpp
@@ -0,0 +1,33 @@
+// SPDX-License-Identifier: LGPL-3.0-or-later
+// Copyright © 2020 Florian Schmaus
+#include <cstdlib>
+#include <iostream>
+
+#include "Fiber.hpp"
+#include "Runtime.hpp"
+#include "emper-common.h"
+
+void emperTest() __attribute__((weak));
+
+static void invokeTest() {
+	emperTest();
+
+	exit(EXIT_SUCCESS);
+}
+
+auto main(UNUSED_ARG int argc, UNUSED_ARG char* argv[]) -> int {
+	if (!&emperTest) {
+		std::cerr << "ERROR: The emperTest() method is not defined.";
+		return EXIT_FAILURE;
+	}
+
+	Runtime runtime;
+
+	Fiber* alphaFiber = Fiber::from(&invokeTest);
+
+	runtime.scheduleFromAnywhere(*alphaFiber);
+
+	runtime.waitUntilFinished();
+
+	return EXIT_FAILURE;
+}
diff --git a/tests/test-runner/meson.build b/tests/test-runner/meson.build
new file mode 100644
index 00000000..151b2cab
--- /dev/null
+++ b/tests/test-runner/meson.build
@@ -0,0 +1,8 @@
+emper_test_runner_lib = library('emper-test-runner',
+								'emper-test-runner.cpp',
+								dependencies: emper_dep
+							   )
+
+emper_test_runner_dep = declare_dependency(
+  link_with : emper_test_runner_lib
+)
-- 
GitLab