feat: simple valgrind integration in vctest & AppImage workflow: change build-type to RelWithDebInfo
This commit is contained in:
parent
727d578e33
commit
4c23dc6adf
7
.github/workflows/appimage.yml
vendored
7
.github/workflows/appimage.yml
vendored
@ -24,18 +24,19 @@ jobs:
|
||||
run: |
|
||||
sudo apt-get update
|
||||
sudo apt-get install -y build-essential libglfw3-dev libglfw3 libglew-dev \
|
||||
libglm-dev libpng-dev libopenal-dev libluajit-5.1-dev libvorbis-dev libcurl4-openssl-dev libgtest-dev cmake squashfs-tools
|
||||
libglm-dev libpng-dev libopenal-dev libluajit-5.1-dev libvorbis-dev \
|
||||
libcurl4-openssl-dev libgtest-dev cmake squashfs-tools valgrind
|
||||
# fix luajit paths
|
||||
sudo ln -s /usr/lib/x86_64-linux-gnu/libluajit-5.1.a /usr/lib/x86_64-linux-gnu/liblua5.1.a
|
||||
sudo ln -s /usr/include/luajit-2.1 /usr/include/lua
|
||||
# install EnTT
|
||||
git clone https://github.com/skypjack/entt.git
|
||||
cd entt/build
|
||||
cmake -DCMAKE_BUILD_TYPE=Release ..
|
||||
cmake -DCMAKE_BUILD_TYPE=RelWithDebInfo ..
|
||||
sudo make install
|
||||
cd ../..
|
||||
- name: Configure
|
||||
run: cmake -S . -B build -DCMAKE_BUILD_TYPE=Release -DVOXELENGINE_BUILD_APPDIR=1 -DVOXELENGINE_BUILD_TESTS=ON
|
||||
run: cmake -S . -B build -DCMAKE_BUILD_TYPE=RelWithDebInfo -DVOXELENGINE_BUILD_APPDIR=1 -DVOXELENGINE_BUILD_TESTS=ON
|
||||
- name: Build
|
||||
run: cmake --build build -t install
|
||||
- name: Run tests
|
||||
|
||||
@ -16,6 +16,7 @@ struct Config {
|
||||
fs::path directory;
|
||||
fs::path resDir {"res"};
|
||||
fs::path workingDir {"."};
|
||||
std::string memchecker = "valgrind";
|
||||
bool outputAlways = false;
|
||||
};
|
||||
|
||||
@ -29,6 +30,7 @@ static bool perform_keyword(
|
||||
std::cout << " --tests <path>, -d <path> = tests directory path\n";
|
||||
std::cout << " --res <path>, -r <path> = 'res' directory path\n";
|
||||
std::cout << " --user <path>, -u <path> = user directory path\n";
|
||||
std::cout << " --memchecker <path> = path to valgrind\n";
|
||||
std::cout << " --output-always = always show tests output\n";
|
||||
std::cout << std::endl;
|
||||
return false;
|
||||
@ -127,6 +129,37 @@ static void display_test_output(
|
||||
}
|
||||
}
|
||||
|
||||
static void display_segfault_valgrind(
|
||||
const fs::path& path, const fs::path& name, std::ostream& stream
|
||||
) {
|
||||
stream << "[MEMCHECK] " << name << std::endl;
|
||||
if (fs::exists(path)) {
|
||||
std::ifstream t(path);
|
||||
while (!t.eof()) {
|
||||
std::string line;
|
||||
std::getline(t, line);
|
||||
// skip until the terminating signal
|
||||
if (line.find("Process terminating with default action of signal ") != std::string::npos) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
std::stringstream ss;
|
||||
while (!t.eof()) {
|
||||
std::string line;
|
||||
std::getline(t, line);
|
||||
size_t pos = line.find("== ");
|
||||
if (pos == std::string::npos) {
|
||||
continue;
|
||||
}
|
||||
if (line.find("If you") != std::string::npos) {
|
||||
break;
|
||||
}
|
||||
ss << line.substr(pos + 3) << "\n";
|
||||
}
|
||||
stream << ss.str() << std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
static std::string fix_path(std::string s) {
|
||||
for (char& c : s) {
|
||||
if (c == '\\') {
|
||||
@ -136,7 +169,7 @@ static std::string fix_path(std::string s) {
|
||||
return s;
|
||||
}
|
||||
|
||||
static bool run_test(const Config& config, const fs::path& path) {
|
||||
static bool run_test(const Config& config, const fs::path& path, bool memcheck = false) {
|
||||
using std::chrono::duration_cast;
|
||||
using std::chrono::high_resolution_clock;
|
||||
using std::chrono::milliseconds;
|
||||
@ -145,6 +178,9 @@ static bool run_test(const Config& config, const fs::path& path) {
|
||||
|
||||
auto name = path.stem();
|
||||
std::stringstream ss;
|
||||
if (memcheck) {
|
||||
ss << config.memchecker << " ";
|
||||
}
|
||||
ss << fs::canonical(config.executable) << " --headless";
|
||||
ss << " --test " << fix_path(path.string());
|
||||
ss << " --res " << fix_path(config.resDir.string());
|
||||
@ -162,9 +198,17 @@ static bool run_test(const Config& config, const fs::path& path) {
|
||||
.count();
|
||||
|
||||
if (code) {
|
||||
display_test_output(outputFile, name, std::cerr);
|
||||
std::cerr << "[FAILED] " << name << " in " << testTime << " ms" << std::endl;
|
||||
fs::remove(outputFile);
|
||||
if (memcheck) {
|
||||
// valgrind-specific output
|
||||
display_segfault_valgrind(outputFile, name, std::cerr);
|
||||
fs::remove(outputFile);
|
||||
} else {
|
||||
display_test_output(outputFile, name, std::cerr);
|
||||
std::cerr << "[FAILED] " << name << " in " << testTime
|
||||
<< " ms (code=" << code << ")" << std::endl;
|
||||
fs::remove(outputFile);
|
||||
run_test(config, path, true);
|
||||
}
|
||||
return false;
|
||||
} else {
|
||||
if (config.outputAlways) {
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user