From 6523107f12e5494266d70e69de6eab9b0a8234fc Mon Sep 17 00:00:00 2001
From: Damiano Amatruda <damiano.amatruda@skywarder.eu>
Date: Sun, 20 Mar 2022 22:45:30 +0100
Subject: [PATCH] Add support for Main Computer unit tests on host

---
 .gitlab-ci.yml                                |  2 +-
 CMakeLists.txt                                |  1 +
 skyward-boardcore                             |  2 +-
 .../MainComputer/Actuators/Actuators.cpp      | 15 ++++
 .../MainComputer/AirBrakes/AirBrakesConfig.h  |  5 ++
 .../Deployment/DeploymentConfig.h             |  4 ++
 .../FlightStatsRecorder/FSRConfig.h           |  2 +
 .../MainComputer/catch/catch-tests-entry.cpp  | 72 +++++++++++--------
 8 files changed, 72 insertions(+), 31 deletions(-)

diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml
index 1f0603576..aa33eb367 100644
--- a/.gitlab-ci.yml
+++ b/.gitlab-ci.yml
@@ -52,7 +52,7 @@ build-debug:
 test:
   stage: test
   script:
-    - ./sbs --jobs 2 --test catch-tests-entry
+    - ./sbs --jobs 2 --test catch-tests-main
 
 # Stage lint
 
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 086757965..2525102b5 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -20,6 +20,7 @@
 # THE SOFTWARE.
 
 cmake_minimum_required(VERSION 3.16)
+enable_testing()
 include(skyward-boardcore/cmake/sbs.cmake)
 
 #-----------------------------------------------------------------------------#
diff --git a/skyward-boardcore b/skyward-boardcore
index a5c11b02f..a10a0ec07 160000
--- a/skyward-boardcore
+++ b/skyward-boardcore
@@ -1 +1 @@
-Subproject commit a5c11b02fab8990b04b2f27f44f2415c79e6e72e
+Subproject commit a10a0ec070e5a7ba2f817f2255811504039c8996
diff --git a/src/boards/MainComputer/Actuators/Actuators.cpp b/src/boards/MainComputer/Actuators/Actuators.cpp
index e4b98ba33..dabf7de85 100644
--- a/src/boards/MainComputer/Actuators/Actuators.cpp
+++ b/src/boards/MainComputer/Actuators/Actuators.cpp
@@ -24,7 +24,10 @@
 
 #include <MainComputer/AirBrakes/AirBrakesConfig.h>
 #include <MainComputer/Deployment/DeploymentConfig.h>
+
+#ifndef COMPILE_FOR_HOST
 #include <interfaces-impl/hwmapping.h>
+#endif
 
 using namespace miosix;
 using namespace MainComputer::DeploymentConfig;
@@ -33,6 +36,8 @@ using namespace MainComputer::AirBrakesConfigs;
 namespace MainComputer
 {
 
+#ifndef COMPILE_FOR_HOST
+
 Actuators::Actuators()
     : servoExpulsion(DPL_SERVO_TIMER, DPL_SERVO_PWM_CH),
       servoAirbrakes(ABK_SERVO_TIMER, ABK_SERVO_PWM_CH),
@@ -42,4 +47,14 @@ Actuators::Actuators()
 {
 }
 
+#else
+
+Actuators::Actuators()
+    : servoExpulsion(), servoAirbrakes(), led1(GpioPin{0, 0}),
+      led2(GpioPin{0, 0}), led3(GpioPin{0, 0}), cutter(GpioPin{0, 0})
+{
+}
+
+#endif
+
 }  // namespace MainComputer
diff --git a/src/boards/MainComputer/AirBrakes/AirBrakesConfig.h b/src/boards/MainComputer/AirBrakes/AirBrakesConfig.h
index 038711aad..829f4dc96 100644
--- a/src/boards/MainComputer/AirBrakes/AirBrakesConfig.h
+++ b/src/boards/MainComputer/AirBrakes/AirBrakesConfig.h
@@ -22,7 +22,10 @@
 
 #pragma once
 
+#ifndef COMPILE_FOR_HOST
 #include <drivers/timer/PWM.h>
+#endif
+
 #include <utils/Constants.h>
 
 namespace MainComputer
@@ -31,9 +34,11 @@ namespace MainComputer
 namespace AirBrakesConfigs
 {
 
+#ifndef COMPILE_FOR_HOST
 TIM_TypeDef* const ABK_SERVO_TIMER = TIM8;
 constexpr Boardcore::TimerUtils::Channel ABK_SERVO_PWM_CH =
     Boardcore::TimerUtils::Channel::CHANNEL_2;
+#endif
 
 static constexpr int SHADOW_MODE_TIMEOUT = 3.5 * 1000;
 
diff --git a/src/boards/MainComputer/Deployment/DeploymentConfig.h b/src/boards/MainComputer/Deployment/DeploymentConfig.h
index f9a64688d..12b41953c 100644
--- a/src/boards/MainComputer/Deployment/DeploymentConfig.h
+++ b/src/boards/MainComputer/Deployment/DeploymentConfig.h
@@ -20,8 +20,10 @@
  * THE SOFTWARE.
  */
 
+#ifndef COMPILE_FOR_HOST
 #include <drivers/timer/PWM.h>
 #include <drivers/timer/TimerUtils.h>
+#endif
 
 namespace MainComputer
 {
@@ -29,9 +31,11 @@ namespace MainComputer
 namespace DeploymentConfig
 {
 
+#ifndef COMPILE_FOR_HOST
 static TIM_TypeDef* const DPL_SERVO_TIMER = TIM4;
 static constexpr Boardcore::TimerUtils::Channel DPL_SERVO_PWM_CH =
     Boardcore::TimerUtils::Channel::CHANNEL_1;
+#endif
 
 static constexpr int OPEN_NC_TIMEOUT = 5 * 1000;  // [ms]
 static constexpr int CUT_DURATION    = 50;        // [ms]
diff --git a/src/boards/MainComputer/FlightStatsRecorder/FSRConfig.h b/src/boards/MainComputer/FlightStatsRecorder/FSRConfig.h
index 3d376a748..2b68bfd95 100644
--- a/src/boards/MainComputer/FlightStatsRecorder/FSRConfig.h
+++ b/src/boards/MainComputer/FlightStatsRecorder/FSRConfig.h
@@ -20,8 +20,10 @@
  * THE SOFTWARE.
  */
 
+#ifndef COMPILE_FOR_HOST
 #include <drivers/timer/PWM.h>
 #include <drivers/timer/TimerUtils.h>
+#endif
 
 namespace MainComputer
 {
diff --git a/src/tests/MainComputer/catch/catch-tests-entry.cpp b/src/tests/MainComputer/catch/catch-tests-entry.cpp
index 1b970e126..1acb03098 100644
--- a/src/tests/MainComputer/catch/catch-tests-entry.cpp
+++ b/src/tests/MainComputer/catch/catch-tests-entry.cpp
@@ -1,5 +1,5 @@
-/* Copyright (c) 2019 Skyward Experimental Rocketry
- * Author: Luca Erbetta
+/* Copyright (c) 2019-2021 Skyward Experimental Rocketry
+ * Authors: Luca Erbetta, Damiano Amatruda
  *
  * Permission is hereby granted, free of charge, to any person obtaining a copy
  * of this software and associated documentation files (the "Software"), to deal
@@ -21,14 +21,14 @@
  */
 
 /*
- * Entrypoint for all Catch1-based tests. You should not need to modify this
+ * Entrypoint for all Catch2-based tests. You should not need to modify this
  * file.
  *
  * To add a test, just create a new source file and include <catch.hpp>, then
  * add test cases as you wish. Do not add a main() function in your test
  * sources.
  * Once the test is written, compile the test source file(s) + this entrypoint
- * in sbs.conf. Run it and all your test will be automatically executed.
+ * in CMakeLists.txt. Run it and all your test will be automatically executed.
  *
  * You can also include this file in your test source if you want to run it as a
  * standalone test, and not togheter with all the others. See the
@@ -41,21 +41,33 @@
  * https://github.com/catchorg/Catch2/blob/Catch1.x/docs/command-line.md
  *
  * To specify the command line options, add, in the definition of the entrypoint
- * in sbs.conf, add the CATCH1_CL_OPTIONS define.
- * Example: -DCATCH1_CL_OPTIONS="\"[tag1][tag2] -s\""
+ * in CMakeLists.txt, add the CATCH_CL_OPTIONS define.
+ * Example: -DCATCH_CL_OPTIONS="\"[tag1][tag2] -s\""
  * Remember to correctly escape the quotation marks, as shown
  * above.
  *
  * Further information at:
- * https://git.skywarder.eu/r2a/skyward-boardcore/wikis/Testing
+ * https://git.skywarder.eu/scs/skyward-boardcore/wikis/Testing
  */
 
 #define CATCH_CONFIG_RUNNER
 #define CATCH_CONFIG_NO_POSIX_SIGNALS
 
+#include <catch2/catch.hpp>
+
+// No tags or command line options as default.
+#ifndef CATCH_CL_OPTIONS
+#define CATCH_CL_OPTIONS ""
+#endif
+
+#ifdef COMPILE_FOR_HOST
+
+int main(int argc, char* argv[]) { return Catch::Session().run(argc, argv); }
+
+#else
+
 #include <miosix.h>
 
-#include <catch2/catch.hpp>
 #include <cstring>
 #include <string>
 #include <vector>
@@ -64,11 +76,6 @@ using miosix::Thread;
 using std::string;
 using std::vector;
 
-// No tags or command line options as default.
-#ifndef CATCH1_CL_OPTIONS
-#define CATCH1_CL_OPTIONS ""
-#endif
-
 /**
  * @brief Splits a string around spaces
  * Eg: "This is a string" -> {"This", "is", "a", "string"}
@@ -76,15 +83,18 @@ using std::vector;
  * @param str String to split
  * @return vector<string>
  */
-vector<string> splitSpaces(string str)
+static vector<string> splitSpaces(const string& str)
 {
-    unsigned int p = 0;
-    bool end       = false;
+    size_t p = 0;
+    bool end = false;
     vector<string> out;
 
+    if (str.length() == 0)
+        return out;
+
     do
     {
-        unsigned int p2 = str.find(" ", p);
+        size_t p2 = str.find(" ", p);
 
         if (p2 == string::npos)  // No match
         {
@@ -98,6 +108,7 @@ vector<string> splitSpaces(string str)
         {
             out.push_back(str.substr(p, len));
         }
+
         p = p2 + 1;
     } while (!end);
 
@@ -106,18 +117,18 @@ vector<string> splitSpaces(string str)
 
 /**
  * @brief Entrypoint for the tests. Parses the options and tags
- * provided in sbs.conf and runs a Catch1 session.
+ * provided in CMakeLists.txt and runs a Catch2 session.
  */
 int main()
 {
-    // Parse command line arguments from #defines in sbs.conf
+    // Parse command line arguments from #defines in CMakeLists.txt
 
     string skw{"Skyward-tests"};
 
-    // CATCH1_CL_OPTIONS defined in sbs.conf
-    string options_str{CATCH1_CL_OPTIONS};
+    // CATCH_CL_OPTIONS defined in CMakeLists.txt
+    string optionsStr{CATCH_CL_OPTIONS};
 
-    vector<string> options = splitSpaces(options_str);
+    vector<string> options = splitSpaces(optionsStr);
     vector<string> args{skw};
 
     if (options.size() > 0)
@@ -126,14 +137,14 @@ int main()
     // Convert vector of strings to array of c-strings
     size_t argc = args.size();
 
-    char** argv =
-        new char*[argc];  // Array of c strings, aka array of char pointers
+    // Array of c strings, aka array of char pointers
+    char** argv = new char*[argc];
     for (size_t i = 0; i < argc; i++)
     {
-        string s    = args.at(i);
-        char* c_arg = new char[s.length() + 1];
-        strcpy(c_arg, s.c_str());
-        argv[i] = c_arg;
+        string s   = args.at(i);
+        char* cArg = new char[s.length() + 1];
+        strcpy(cArg, s.c_str());
+        argv[i] = cArg;
     }
 
     // Run tests with the provided arguments
@@ -147,9 +158,12 @@ int main()
     delete[] argv;
 
     printf("End.\n");
+
     // Infinite loop to avoid board reset each time we return
-    for (;;)
+    while (true)
     {
         Thread::sleep(10000);
     }
 }
+
+#endif  // COMPILE_FOR_HOST
-- 
GitLab