-
Notifications
You must be signed in to change notification settings - Fork 11
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add a test-runner that can be used by CI to execute all test suites and gather results. Signed-off-by: Pedro Falcato <pedro.falcato@gmail.com>
- Loading branch information
Showing
9 changed files
with
697 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
import("//build/app.gni") | ||
|
||
app_executable("test-runner") { | ||
include_dirs = [ "include" ] | ||
package_name = "test-runner" | ||
|
||
output_name = "test-runner" | ||
|
||
sources = [ "main.cpp", "gtest.cpp", "fsx.cpp", "process.cpp", "kunit.cpp"] | ||
|
||
deps = [ "//lib/onyx" ] | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,58 @@ | ||
/* | ||
* Copyright (c) 2023 Pedro Falcato | ||
* This file is part of Onyx, and is released under the terms of the MIT License | ||
* check LICENSE at the root directory for more information | ||
* | ||
* SPDX-License-Identifier: MIT | ||
*/ | ||
|
||
#include <err.h> | ||
#include <unistd.h> | ||
|
||
#include <filesystem> | ||
|
||
#include "include/process.h" | ||
#include "include/test.h" | ||
|
||
struct fsx_test : public test | ||
{ | ||
std::filesystem::path exec_path_; | ||
|
||
fsx_test(std::filesystem::path &&exec, std::string &&name, int timeout_seconds = -1) | ||
: test{std::move(name), timeout_seconds}, exec_path_{std::move(exec)} | ||
{ | ||
} | ||
|
||
test_result run_test() const override; | ||
}; | ||
|
||
#define FSX_TEST_DURATION 60 | ||
|
||
test_result fsx_test::run_test() const | ||
{ | ||
if (access(exec_path_.c_str(), X_OK) < 0) | ||
return test_result::skip; | ||
|
||
// Make sure fsx-testfile doesn't exist before we start rerunning | ||
unlink("fsx-testfile"); | ||
|
||
pid_t pid = run_process(exec_path_, {"fsx", "-d", "1m", "fsx-testfile"}, environ); | ||
|
||
if (pid < 0) | ||
{ | ||
warn("run_process"); | ||
return test_result::exec_error; | ||
} | ||
|
||
return wait_for_process(pid, "fsx", timeout_seconds_); | ||
} | ||
|
||
const fsx_test fsx_t{"/usr/bin/fsx", "fsx", FSX_TEST_DURATION * 2}; | ||
|
||
const static auto _do = []() { | ||
register_test(&fsx_t); | ||
return 0; | ||
}(); | ||
|
||
// TODO: Do we want some generic "execute-test-and-look-at-result" logic? | ||
// I tried to be very generic for extensibility's sake |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,50 @@ | ||
/* | ||
* Copyright (c) 2023 Pedro Falcato | ||
* This file is part of Onyx, and is released under the terms of the MIT License | ||
* check LICENSE at the root directory for more information | ||
* | ||
* SPDX-License-Identifier: MIT | ||
*/ | ||
|
||
#include <err.h> | ||
#include <unistd.h> | ||
|
||
#include <filesystem> | ||
|
||
#include "include/process.h" | ||
#include "include/test.h" | ||
|
||
struct gtest_test : public test | ||
{ | ||
std::filesystem::path exec_path_; | ||
gtest_test(std::filesystem::path &&exec, std::string &&name, int timeout_seconds = -1) | ||
: test{std::move(name), timeout_seconds}, exec_path_{std::move(exec)} | ||
{ | ||
} | ||
test_result run_test() const override; | ||
}; | ||
|
||
const gtest_test gtests[] = { | ||
gtest_test(std::filesystem::path("/usr/bin/kernel_api_tests"), "kernel_api_tests", 30), | ||
gtest_test(std::filesystem::path("/usr/bin/net_tests"), "net_tests", 20)}; | ||
|
||
test_result gtest_test::run_test() const | ||
{ | ||
if (access(exec_path_.c_str(), X_OK) < 0) | ||
return test_result::skip; | ||
|
||
pid_t pid = run_process(exec_path_, {name_}, environ); | ||
|
||
if (pid < 0) | ||
{ | ||
warn("run_process"); | ||
return test_result::exec_error; | ||
} | ||
|
||
return wait_for_process(pid, name_, timeout_seconds_); | ||
} | ||
|
||
const static auto _do = []() { | ||
register_tests(gtests); | ||
return 0; | ||
}(); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,55 @@ | ||
/* | ||
* Copyright (c) 2023 Pedro Falcato | ||
* This file is part of Onyx, and is released under the terms of the MIT License | ||
* check LICENSE at the root directory for more information | ||
* | ||
* SPDX-License-Identifier: MIT | ||
*/ | ||
#pragma once | ||
|
||
#include <err.h> | ||
#include <unistd.h> | ||
|
||
#include <cassert> | ||
#include <filesystem> | ||
#include <string> | ||
#include <vector> | ||
|
||
#include "test.h" | ||
|
||
/** | ||
* @brief Run a process and return its pid | ||
* | ||
* @param exec_path_ Path to the executable | ||
* @param argv Vector of arguments (NOT NULL TERMINATED) | ||
* @param envp envp (NULL-terminated) | ||
* @return -1 on error, pids > 0 | ||
*/ | ||
pid_t run_process(const std::filesystem::path &exec_path_, const std::vector<std::string> &argv, | ||
char **envp); | ||
|
||
/** | ||
* @brief Interpret a wait status into a test result | ||
* | ||
* @param wstatus Wait status | ||
* @param test_name Name of the test (for logging purposes) | ||
* @return A valid test_result value | ||
*/ | ||
test_result interpret_wstatus(int wstatus, const std::string &test_name); | ||
|
||
/** | ||
* @brief Wait for a process | ||
* Note: May SIGTERM and SIGKILL a process if it times out. | ||
* | ||
* @param pid PID to wait for | ||
* @param test_name Name of the test (for logging purposes) | ||
* @param timeout Timeout in seconds, if set for the test, else -1 (sleeps forever) | ||
* @return A valid test_result value | ||
*/ | ||
test_result wait_for_process(pid_t pid, const std::string &test_name, int timeout); | ||
|
||
/** | ||
* @brief Set up SIGCHLD handling | ||
* | ||
*/ | ||
void setup_sigchld(); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,65 @@ | ||
/* | ||
* Copyright (c) 2023 Pedro Falcato | ||
* This file is part of Onyx, and is released under the terms of the MIT License | ||
* check LICENSE at the root directory for more information | ||
* | ||
* SPDX-License-Identifier: MIT | ||
*/ | ||
|
||
#pragma once | ||
#include <string> | ||
|
||
enum class test_result | ||
{ | ||
ok = 0, | ||
error = 1, | ||
skip = 2, | ||
exec_error | ||
}; | ||
|
||
/** | ||
* @brief Represents a generic test skeleton | ||
* Various test backends then implement this. | ||
* | ||
*/ | ||
struct test | ||
{ | ||
std::string name_; | ||
int timeout_seconds_ = -1; | ||
|
||
bool dont_re_run = false; | ||
|
||
test(std::string &&name, int timeout_seconds) | ||
: name_{std::move(name)}, timeout_seconds_{timeout_seconds} | ||
{ | ||
} | ||
|
||
void no_rerun() | ||
{ | ||
dont_re_run = true; | ||
} | ||
|
||
virtual test_result run_test() const = 0; | ||
}; | ||
|
||
/** | ||
* @brief Register a test | ||
* | ||
* @param t Test to register | ||
*/ | ||
void register_test(const test *t); | ||
|
||
/** | ||
* @brief Register tests | ||
* | ||
* @tparam Container Container type | ||
* @param c Container to look at and register tests from | ||
*/ | ||
template <typename Container> | ||
void register_tests(const Container &c) | ||
{ | ||
for (auto &t : c) | ||
{ | ||
register_test(&t); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,65 @@ | ||
/* | ||
* Copyright (c) 2023 Pedro Falcato | ||
* This file is part of Onyx, and is released under the terms of the MIT License | ||
* check LICENSE at the root directory for more information | ||
* | ||
* SPDX-License-Identifier: MIT | ||
*/ | ||
#include <err.h> | ||
#include <sys/syscall.h> | ||
#include <sys/types.h> | ||
#include <unistd.h> | ||
|
||
#include "include/test.h" | ||
|
||
struct kunit_test : public test | ||
{ | ||
kunit_test() : test{"kunit", 0} | ||
{ | ||
dont_re_run = true; | ||
} | ||
|
||
test_result run_test() const override; | ||
}; | ||
|
||
test_result kunit_test::run_test() const | ||
{ | ||
// Get the dmesg | ||
int size = (int) syscall(SYS_syslog, 10, nullptr, -1); | ||
if (size < 0) | ||
err(1, "syslog"); | ||
|
||
std::string log; | ||
log.resize(size); | ||
|
||
if (syscall(SYS_syslog, 2, log.data(), size) < 0) | ||
err(1, "syslog"); | ||
|
||
// Now look for "kunit: tests done --" and get that line | ||
auto pos = log.find("kunit: tests done --"); | ||
|
||
if (pos == std::string::npos) | ||
return test_result::skip; | ||
|
||
const char *s = log.data() + pos; | ||
|
||
unsigned int total = 0; | ||
unsigned int failed = 0; | ||
|
||
if (sscanf(s, "kunit: tests done -- %u tests executed, %u", &total, &failed) != 2) | ||
{ | ||
warnx("kunit_test: Kernel broke kunit result log format...\n"); | ||
return test_result::error; | ||
} | ||
|
||
printf("kunit: tests done -- %u tests executed, %u failed\n", total, failed); | ||
|
||
return failed != 0 ? test_result::error : test_result::ok; | ||
} | ||
|
||
static kunit_test ku; | ||
|
||
const static auto _do = []() { | ||
register_test(&ku); | ||
return 0; | ||
}(); |
Oops, something went wrong.