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: |
|
run: |
|
||||||
sudo apt-get update
|
sudo apt-get update
|
||||||
sudo apt-get install -y build-essential libglfw3-dev libglfw3 libglew-dev \
|
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
|
# 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/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
|
sudo ln -s /usr/include/luajit-2.1 /usr/include/lua
|
||||||
# install EnTT
|
# install EnTT
|
||||||
git clone https://github.com/skypjack/entt.git
|
git clone https://github.com/skypjack/entt.git
|
||||||
cd entt/build
|
cd entt/build
|
||||||
cmake -DCMAKE_BUILD_TYPE=Release ..
|
cmake -DCMAKE_BUILD_TYPE=RelWithDebInfo ..
|
||||||
sudo make install
|
sudo make install
|
||||||
cd ../..
|
cd ../..
|
||||||
- name: Configure
|
- 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
|
- name: Build
|
||||||
run: cmake --build build -t install
|
run: cmake --build build -t install
|
||||||
- name: Run tests
|
- name: Run tests
|
||||||
|
|||||||
@ -16,6 +16,7 @@ struct Config {
|
|||||||
fs::path directory;
|
fs::path directory;
|
||||||
fs::path resDir {"res"};
|
fs::path resDir {"res"};
|
||||||
fs::path workingDir {"."};
|
fs::path workingDir {"."};
|
||||||
|
std::string memchecker = "valgrind";
|
||||||
bool outputAlways = false;
|
bool outputAlways = false;
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -29,6 +30,7 @@ static bool perform_keyword(
|
|||||||
std::cout << " --tests <path>, -d <path> = tests directory path\n";
|
std::cout << " --tests <path>, -d <path> = tests directory path\n";
|
||||||
std::cout << " --res <path>, -r <path> = 'res' 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 << " --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 << " --output-always = always show tests output\n";
|
||||||
std::cout << std::endl;
|
std::cout << std::endl;
|
||||||
return false;
|
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) {
|
static std::string fix_path(std::string s) {
|
||||||
for (char& c : s) {
|
for (char& c : s) {
|
||||||
if (c == '\\') {
|
if (c == '\\') {
|
||||||
@ -136,7 +169,7 @@ static std::string fix_path(std::string s) {
|
|||||||
return 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::duration_cast;
|
||||||
using std::chrono::high_resolution_clock;
|
using std::chrono::high_resolution_clock;
|
||||||
using std::chrono::milliseconds;
|
using std::chrono::milliseconds;
|
||||||
@ -145,6 +178,9 @@ static bool run_test(const Config& config, const fs::path& path) {
|
|||||||
|
|
||||||
auto name = path.stem();
|
auto name = path.stem();
|
||||||
std::stringstream ss;
|
std::stringstream ss;
|
||||||
|
if (memcheck) {
|
||||||
|
ss << config.memchecker << " ";
|
||||||
|
}
|
||||||
ss << fs::canonical(config.executable) << " --headless";
|
ss << fs::canonical(config.executable) << " --headless";
|
||||||
ss << " --test " << fix_path(path.string());
|
ss << " --test " << fix_path(path.string());
|
||||||
ss << " --res " << fix_path(config.resDir.string());
|
ss << " --res " << fix_path(config.resDir.string());
|
||||||
@ -162,9 +198,17 @@ static bool run_test(const Config& config, const fs::path& path) {
|
|||||||
.count();
|
.count();
|
||||||
|
|
||||||
if (code) {
|
if (code) {
|
||||||
display_test_output(outputFile, name, std::cerr);
|
if (memcheck) {
|
||||||
std::cerr << "[FAILED] " << name << " in " << testTime << " ms" << std::endl;
|
// valgrind-specific output
|
||||||
fs::remove(outputFile);
|
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;
|
return false;
|
||||||
} else {
|
} else {
|
||||||
if (config.outputAlways) {
|
if (config.outputAlways) {
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user