[sim] Translate unit tests to catch2 (#9004)

This commit is contained in:
Peter Johnson
2026-06-21 19:13:33 -07:00
committed by GitHub
parent 678176cd3c
commit edbf2db5a7
12 changed files with 150 additions and 89 deletions

View File

@@ -78,7 +78,7 @@ cc_test(
srcs = glob(["src/test/native/**/*.cpp"]),
deps = [
"//simulation/halsim_ds_socket",
"//thirdparty/googletest",
"//thirdparty/catch2",
],
)

View File

@@ -11,18 +11,13 @@ ext {
apply plugin: 'google-test-test-suite'
ext {
staticGtestConfigs = [:]
}
staticGtestConfigs["${pluginName}Test"] = []
apply from: "${rootDir}/shared/googletest.gradle"
apply from: "${rootDir}/shared/catch2.gradle"
apply from: "${rootDir}/shared/plugins/setupBuild.gradle"
model {
testSuites {
"${pluginName}Test"(GoogleTestTestSuiteSpec) {
"${pluginName}Catch2Test"(GoogleTestTestSuiteSpec) {
for(NativeComponentSpec c : $.components) {
if (c.name == pluginName) {
testing c
@@ -38,6 +33,9 @@ model {
srcDirs 'src/test/native/include', 'src/main/native/cpp'
}
}
binaries.all {
lib project: ':thirdparty:catch2', library: 'catch2', linkage: 'static'
}
}
}
binaries {

View File

@@ -2,13 +2,35 @@
// Open Source Software; you can modify and/or share it under the terms of
// the WPILib BSD license file in the root directory of this project.
#include <gtest/gtest.h>
#include <string_view>
#include <catch2/catch_session.hpp>
#include <catch2/catch_test_macros.hpp>
#include "wpi/hal/HAL.h"
int main(int argc, char** argv) {
HAL_Initialize(500, 0);
::testing::InitGoogleTest(&argc, argv);
int ret = RUN_ALL_TESTS();
return ret;
namespace {
bool IsCatchListCommand(int argc, char** argv) {
for (int i = 1; i < argc; ++i) {
std::string_view arg{argv[i]};
if (arg == "--list-tests" || arg == "--list-tags" ||
arg == "--list-reporters" || arg == "--list-listeners") {
return true;
}
}
return false;
}
} // namespace
TEST_CASE("HALSimDSSocket RuntimeType", "[simulation][halsim_ds_socket]") {
CHECK(HAL_RuntimeType::HAL_RUNTIME_SIMULATION == HAL_GetRuntimeType());
}
int main(int argc, char** argv) {
if (!IsCatchListCommand(argc, argv)) {
HAL_Initialize(500, 0);
}
return Catch::Session().run(argc, argv);
}

View File

@@ -130,7 +130,7 @@ cc_test(
],
deps = [
":halsim_gui",
"//thirdparty/googletest",
"//thirdparty/catch2",
],
)

View File

@@ -10,15 +10,34 @@ ext {
apply plugin: 'google-test-test-suite'
ext {
staticGtestConfigs = [:]
}
staticGtestConfigs["${pluginName}Test"] = []
apply from: "${rootDir}/shared/googletest.gradle"
apply from: "${rootDir}/shared/catch2.gradle"
apply from: "${rootDir}/shared/plugins/setupBuild.gradle"
model {
testSuites {
"${pluginName}Catch2Test"(GoogleTestTestSuiteSpec) {
for(NativeComponentSpec c : $.components) {
if (c.name == pluginName) {
testing c
break
}
}
sources.cpp {
source {
srcDirs 'src/test/native/cpp'
include '**/*.cpp'
}
exportedHeaders {
srcDirs 'src/test/native/include', 'src/main/native/cpp'
}
}
binaries.all {
lib project: ':thirdparty:catch2', library: 'catch2', linkage: 'static'
}
}
}
}
model {
binaries {
@@ -48,5 +67,12 @@ model {
}
}
}
withType(GoogleTestTestSuiteBinarySpec) {
project(':hal').addHalDependency(it, 'shared')
project(':ntcore').addNtcoreDependency(it, 'shared')
lib project: ':wpinet', library: 'wpinet', linkage: 'shared'
lib project: ':wpiutil', library: 'wpiutil', linkage: 'shared'
lib library: pluginName, linkage: 'shared'
}
}
}

View File

@@ -2,13 +2,35 @@
// Open Source Software; you can modify and/or share it under the terms of
// the WPILib BSD license file in the root directory of this project.
#include <gtest/gtest.h>
#include <string_view>
#include <catch2/catch_session.hpp>
#include <catch2/catch_test_macros.hpp>
#include "wpi/hal/HAL.h"
int main(int argc, char** argv) {
HAL_Initialize(500, 0);
::testing::InitGoogleTest(&argc, argv);
int ret = RUN_ALL_TESTS();
return ret;
namespace {
bool IsCatchListCommand(int argc, char** argv) {
for (int i = 1; i < argc; ++i) {
std::string_view arg{argv[i]};
if (arg == "--list-tests" || arg == "--list-tags" ||
arg == "--list-reporters" || arg == "--list-listeners") {
return true;
}
}
return false;
}
} // namespace
TEST_CASE("HALSimGui RuntimeType", "[simulation][halsim_gui]") {
CHECK(HAL_RuntimeType::HAL_RUNTIME_SIMULATION == HAL_GetRuntimeType());
}
int main(int argc, char** argv) {
if (!IsCatchListCommand(argc, argv)) {
HAL_Initialize(500, 0);
}
return Catch::Session().run(argc, argv);
}

View File

@@ -9,15 +9,6 @@ ext {
pluginName = 'halsim_ws_client'
}
apply plugin: 'google-test-test-suite'
ext {
staticGtestConfigs = [:]
}
staticGtestConfigs["${pluginName}Test"] = []
apply from: "${rootDir}/shared/googletest.gradle"
apply from: "${rootDir}/shared/plugins/setupBuild.gradle"
model {

View File

@@ -14,16 +14,6 @@ ext {
pluginName = 'halsim_ws_core'
}
apply plugin: 'google-test-test-suite'
ext {
staticGtestConfigs = [:]
}
staticGtestConfigs["${pluginName}Test"] = []
apply from: "${rootDir}/shared/googletest.gradle"
apply from: "${rootDir}/shared/config.gradle"
apply from: "${rootDir}/shared/plugins/publish.gradle"

View File

@@ -89,7 +89,7 @@ cc_test(
deps = [
":halsim_ws_server",
":test_headers",
"//thirdparty/googletest",
"//thirdparty/catch2",
],
)

View File

@@ -11,19 +11,13 @@ ext {
apply plugin: 'google-test-test-suite'
ext {
staticGtestConfigs = [:]
}
staticGtestConfigs["${pluginName}Test"] = []
apply from: "${rootDir}/shared/googletest.gradle"
apply from: "${rootDir}/shared/catch2.gradle"
apply from: "${rootDir}/shared/plugins/setupBuild.gradle"
model {
testSuites {
"${pluginName}Test"(GoogleTestTestSuiteSpec) {
"${pluginName}Catch2Test"(GoogleTestTestSuiteSpec) {
for(NativeComponentSpec c : $.components) {
if (c.name == pluginName) {
testing c
@@ -39,6 +33,9 @@ model {
srcDirs 'src/test/native/include', 'src/main/native/cpp'
}
}
binaries.all {
lib project: ':thirdparty:catch2', library: 'catch2', linkage: 'static'
}
}
}

View File

@@ -6,10 +6,12 @@
#include <memory>
#include <string>
#include <string_view>
#include <thread>
#include <utility>
#include <gtest/gtest.h>
#include <catch2/catch_session.hpp>
#include <catch2/catch_test_macros.hpp>
#include "WebServerClientTest.hpp"
#include "wpi/hal/DriverStation.h"
@@ -25,8 +27,7 @@ using namespace wpilibws;
static const int POLLING_SPEED = 10; // 10 ms polling
class WebServerIntegrationTest : public ::testing::Test {
public:
struct WebServerIntegrationTest {
WebServerIntegrationTest() {
// Initialize server
m_server.Initialize();
@@ -40,25 +41,42 @@ class WebServerIntegrationTest : public ::testing::Test {
bool IsConnectedClientWS() { return m_webserverClient->IsConnectedWS(); }
protected:
std::shared_ptr<WebServerClientTest> m_webserverClient;
HALSimWSServer m_server;
};
TEST_F(WebServerIntegrationTest, DISABLED_DigitalOutput) {
namespace {
bool IsCatchListCommand(int argc, char** argv) {
for (int i = 1; i < argc; ++i) {
std::string_view arg{argv[i]};
if (arg == "--list-tests" || arg == "--list-tags" ||
arg == "--list-reporters" || arg == "--list-listeners") {
return true;
}
}
return false;
}
} // namespace
TEST_CASE("WebServerIntegrationTest DigitalOutput",
"[simulation][halsim_ws_server][.]") {
WebServerIntegrationTest test;
// Create expected results
const bool EXPECTED_VALUE = false;
const int PIN = 0;
bool done = false;
// Attach timer to loop for test function
m_server.runner.ExecSync([&](auto& loop) {
test.m_server.runner.ExecSync([&](auto& loop) {
auto timer = wpi::net::uv::Timer::Create(loop);
timer->timeout.connect([&] {
if (done) {
return;
}
if (IsConnectedClientWS()) {
if (test.IsConnectedClientWS()) {
wpi::util::print("***** Setting DIO value for pin {} to {}\n", PIN,
(EXPECTED_VALUE ? "true" : "false"));
HALSIM_SetDIOValue(PIN, EXPECTED_VALUE);
@@ -78,7 +96,7 @@ TEST_F(WebServerIntegrationTest, DISABLED_DigitalOutput) {
std::string test_device;
bool test_value = true; // Default value from HAL initialization
try {
auto& msg = m_webserverClient->GetLastMessage();
auto& msg = test.m_webserverClient->GetLastMessage();
test_type = msg.at("type").get_string();
test_device = msg.at("device").get_string();
auto& data = msg.at("data");
@@ -90,31 +108,34 @@ TEST_F(WebServerIntegrationTest, DISABLED_DigitalOutput) {
}
// Compare results
EXPECT_EQ("DIO", test_type);
EXPECT_EQ(std::to_string(PIN), test_device);
EXPECT_EQ(EXPECTED_VALUE, test_value);
CHECK("DIO" == test_type);
CHECK(std::to_string(PIN) == test_device);
CHECK(EXPECTED_VALUE == test_value);
}
TEST_F(WebServerIntegrationTest, DISABLED_DigitalInput) {
TEST_CASE("WebServerIntegrationTest DigitalInput",
"[simulation][halsim_ws_server][.]") {
WebServerIntegrationTest test;
// Create expected results
const bool EXPECTED_VALUE = false;
const int PIN = 0;
bool done = false;
// Attach timer to loop for test function
m_server.runner.ExecSync([&](auto& loop) {
test.m_server.runner.ExecSync([&](auto& loop) {
auto timer = wpi::net::uv::Timer::Create(loop);
timer->timeout.connect([&] {
if (done) {
return;
}
if (IsConnectedClientWS()) {
if (test.IsConnectedClientWS()) {
wpi::util::json msg = wpi::util::json::object();
msg["type"] = "DIO";
msg["device"] = std::to_string(PIN);
msg["data"] = wpi::util::json::object("<>value", EXPECTED_VALUE);
wpi::util::print("***** Input JSON: {}\n", msg.to_string());
m_webserverClient->SendMessage(msg);
test.m_webserverClient->SendMessage(msg);
done = true;
}
});
@@ -128,22 +149,25 @@ TEST_F(WebServerIntegrationTest, DISABLED_DigitalInput) {
// Compare results
bool test_value = HALSIM_GetDIOValue(PIN);
EXPECT_EQ(EXPECTED_VALUE, test_value);
CHECK(EXPECTED_VALUE == test_value);
}
TEST_F(WebServerIntegrationTest, DriverStation) {
TEST_CASE("WebServerIntegrationTest DriverStation",
"[simulation][halsim_ws_server]") {
WebServerIntegrationTest test;
// Create expected results
const bool EXPECTED_VALUE = true;
bool done = false;
// Attach timer to loop for test function
m_server.runner.ExecSync([&](auto& loop) {
test.m_server.runner.ExecSync([&](auto& loop) {
auto timer = wpi::net::uv::Timer::Create(loop);
timer->timeout.connect([&] {
if (done) {
return;
}
if (IsConnectedClientWS()) {
if (test.IsConnectedClientWS()) {
auto data = wpi::util::json::object();
data[">enabled"] = EXPECTED_VALUE;
data[">new_data"] = true;
@@ -152,7 +176,7 @@ TEST_F(WebServerIntegrationTest, DriverStation) {
msg["device"] = "";
msg["data"] = std::move(data);
wpi::util::print("***** Input JSON: {}\n", msg.to_string());
m_webserverClient->SendMessage(msg);
test.m_webserverClient->SendMessage(msg);
done = true;
}
});
@@ -170,12 +194,12 @@ TEST_F(WebServerIntegrationTest, DriverStation) {
HAL_ControlWord cw;
HAL_GetControlWord(&cw);
bool test_value = HAL_ControlWord_IsEnabled(cw);
EXPECT_EQ(EXPECTED_VALUE, test_value);
CHECK(EXPECTED_VALUE == test_value);
}
int main(int argc, char* argv[]) {
::testing::InitGoogleTest(&argc, argv);
HAL_Initialize(500, 0);
int ret = RUN_ALL_TESTS();
return ret;
if (!IsCatchListCommand(argc, argv)) {
HAL_Initialize(500, 0);
}
return Catch::Session().run(argc, argv);
}

View File

@@ -9,15 +9,6 @@ ext {
pluginName = 'halsim_xrp'
}
apply plugin: 'google-test-test-suite'
ext {
staticGtestConfigs = [:]
}
staticGtestConfigs["${pluginName}Test"] = []
apply from: "${rootDir}/shared/googletest.gradle"
apply from: "${rootDir}/shared/plugins/setupBuild.gradle"
model {