tests: make the offline tests aware of the current terminals row count (#2105)

This fixes the hideous output when your terminal would be too small to
hold all the threads.
This commit is contained in:
Tyler Wilding
2023-01-07 10:35:12 -05:00
committed by GitHub
parent f699675ede
commit 2f4146d469
12 changed files with 149 additions and 27 deletions
+73 -6
View File
@@ -5,8 +5,9 @@
#include "common/log/log.h"
#include "common/util/FileUtil.h"
#include "common/util/StringUtil.h"
#include "common/util/diff.h"
#include "common/util/string_util.h"
#include "common/util/term_util.h"
#include "decompiler/ObjectFile/ObjectFileDB.h"
#include "test/offline/config/config.h"
@@ -201,6 +202,14 @@ void OfflineTestThreadStatus::complete_step() {
g_offline_test_thread_manager.print_current_test_status(config);
}
bool OfflineTestThreadStatus::in_progress() {
return stage == OfflineTestThreadStatus::Stage::IDLE ||
stage == OfflineTestThreadStatus::Stage::COMPARING ||
stage == OfflineTestThreadStatus::Stage::COMPILING ||
stage == OfflineTestThreadStatus::Stage::DECOMPILING ||
stage == OfflineTestThreadStatus::Stage::PREPARING;
}
std::tuple<fmt::color, std::string> thread_stage_to_str(OfflineTestThreadStatus::Stage stage) {
switch (stage) {
case OfflineTestThreadStatus::Stage::IDLE:
@@ -254,23 +263,81 @@ std::string thread_progress_bar(u32 curr_step, u32 total_steps) {
return progress_bar;
}
int OfflineTestThreadManager::num_threads_pending() {
int count = 0;
for (const auto& status : statuses) {
if (status->in_progress()) {
count++;
}
}
return count;
}
int OfflineTestThreadManager::num_threads_succeeded() {
int count = 0;
for (const auto& status : statuses) {
if (status->stage == OfflineTestThreadStatus::Stage::FINISHED) {
count++;
}
}
return count;
}
int OfflineTestThreadManager::num_threads_failed() {
int count = 0;
for (const auto& status : statuses) {
if (status->stage == OfflineTestThreadStatus::Stage::FAILED) {
count++;
}
}
return count;
}
void OfflineTestThreadManager::print_current_test_status(const OfflineTestConfig& config) {
if (!config.pretty_print) {
return;
}
std::lock_guard<std::mutex> guard(print_lock);
// Handle terminal height
auto rows_available = term_util::row_count();
// Truncate any threads we can't display
// - we need to leave 1 row to say how much we are hiding
int threads_to_display = ((rows_available - 2) / 2);
int threads_hidden = statuses.size() - threads_to_display;
int lines_to_clear = (threads_to_display * 2) + (threads_hidden == 0 ? 0 : 1);
// [DECOMP] ▰▰▰▰▰▰▱▱▱▱ (PRI, RUI, FOR, +3 more)
// [1/30] - target-turret-shot // MUTED TEXT
std::lock_guard<std::mutex> guard(print_lock);
fmt::print("\x1b[{}A", g_offline_test_thread_manager.statuses.size() * 2); // move n lines up
for (const auto& status : g_offline_test_thread_manager.statuses) {
fmt::print("\x1b[{}A", lines_to_clear); // move n lines up
fmt::print("\e[?25l"); // hide the cursor
int threads_shown = 0;
for (int i = 0; i < statuses.size() && threads_shown < threads_to_display; i++) {
const auto& status = statuses.at(i);
// Skip completed threads if there are potential in-progress ones to show
if (threads_hidden != 0 && !status->in_progress() &&
(statuses.size() - i) > threads_to_display) {
continue;
}
// first line
const auto [color, stage_text] = thread_stage_to_str(status->stage);
fmt::print(
"\33[2K\r[{:>12}] {} ({})\n", fmt::styled(stage_text, fmt::fg(color)),
"\33[2K\r[{:>12}] {} ({}) [{}]\n", fmt::styled(stage_text, fmt::fg(color)),
fmt::styled(thread_progress_bar(status->curr_step, status->total_steps), fmt::fg(color)),
thread_dgos_to_str(status->dgos));
thread_dgos_to_str(status->dgos), fmt::styled(i, fmt::fg(fmt::color::gray)));
// second line
fmt::print(fmt::fg(fmt::color::gray), "\33[2K\r{:>14} - {}\n",
fmt::format("[{}/{}]", status->curr_step, status->total_steps), status->curr_file);
threads_shown++;
}
if (threads_hidden != 0) {
fmt::print(
fmt::fg(fmt::color::gray), "\33[2K\r+{} other threads. [{} | {} | {}]\n", threads_hidden,
fmt::styled(g_offline_test_thread_manager.num_threads_pending(),
fmt::fg(fmt::color::orange)),
fmt::styled(g_offline_test_thread_manager.num_threads_failed(), fmt::fg(fmt::color::red)),
fmt::styled(g_offline_test_thread_manager.num_threads_succeeded(),
fmt::fg(fmt::color::light_green)));
}
fmt::print("\e[?25h"); // show the cursor
}