mirror of
https://github.com/steredbits/pelagia.git
synced 2026-10-17 19:01:27 +02:00
94 lines
3.0 KiB
C++
94 lines
3.0 KiB
C++
// SPDX-License-Identifier: GPL-3.0-or-later
|
|
// Copyright (C) 2026 steredbits and Pelagia contributors
|
|
// Tests of util/log_file: log file per run (rotation), lines
|
|
// flushed immediately, secrets masked as on the console.
|
|
|
|
#include <stdlib.h>
|
|
#include <unistd.h>
|
|
|
|
#include <cstdio>
|
|
#include <fstream>
|
|
#include <sstream>
|
|
#include <string>
|
|
|
|
#include "test_framework.h"
|
|
#include "util/log.h"
|
|
#include "util/log_file.h"
|
|
|
|
static std::string read_file(const std::string& path) {
|
|
std::ifstream in(path);
|
|
std::stringstream ss;
|
|
ss << in.rdbuf();
|
|
return ss.str();
|
|
}
|
|
|
|
static bool exists(const std::string& path) { return access(path.c_str(), F_OK) == 0; }
|
|
|
|
static bool contains(const std::string& text, const std::string& part) {
|
|
return text.find(part) != std::string::npos;
|
|
}
|
|
|
|
// A "run": opens the file, writes a marked line, closes.
|
|
static void run_once(const std::string& dir, const std::string& marker) {
|
|
util::LogFile f;
|
|
CHECK(f.open(dir, "app", 3));
|
|
util::log_install_console_and_file(nullptr, &f);
|
|
LOG_INFO("%s", marker.c_str());
|
|
// Readable right away, before closing (crash: nothing lost).
|
|
CHECK(contains(read_file(dir + "/app.log"), marker));
|
|
util::log_set_sink(nullptr, nullptr);
|
|
}
|
|
|
|
int main() {
|
|
char tmpl[] = "/tmp/pelagia-logfile-XXXXXX";
|
|
const char* base = mkdtemp(tmpl);
|
|
CHECK(base != nullptr);
|
|
const std::string dir = base;
|
|
|
|
// Format: relative timestamp, level, message; startup header.
|
|
run_once(dir, "premiere");
|
|
const std::string first = read_file(dir + "/app.log");
|
|
CHECK(contains(first, "=== Pelagia, start "));
|
|
CHECK(contains(first, "INFO premiere"));
|
|
|
|
// Rotation: 3 files at most (current + 2 previous), from the most recent to the
|
|
// oldest.
|
|
run_once(dir, "deuxieme");
|
|
run_once(dir, "troisieme");
|
|
run_once(dir, "quatrieme");
|
|
CHECK(contains(read_file(dir + "/app.log"), "quatrieme"));
|
|
CHECK(contains(read_file(dir + "/app.1.log"), "troisieme"));
|
|
CHECK(contains(read_file(dir + "/app.2.log"), "deuxieme"));
|
|
CHECK(!exists(dir + "/app.3.log"));
|
|
CHECK(!contains(read_file(dir + "/app.log"), "troisieme"));
|
|
|
|
// Secrets masked in the file as on the console.
|
|
{
|
|
util::LogFile f;
|
|
CHECK(f.open(dir, "secret", 1));
|
|
util::log_install_console_and_file(nullptr, &f);
|
|
util::log_add_secret("JetonTresSecret12345");
|
|
LOG_INFO("token=JetonTresSecret12345 Token=\"JetonTresSecret12345\"");
|
|
util::log_set_sink(nullptr, nullptr);
|
|
util::log_clear_secrets();
|
|
const std::string text = read_file(dir + "/secret.log");
|
|
CHECK(!contains(text, "JetonTresSecret12345"));
|
|
CHECK(contains(text, "********"));
|
|
}
|
|
|
|
// Folder missing: clean failure, no write attempted.
|
|
{
|
|
util::LogFile f;
|
|
CHECK(!f.open(dir + "/absent", "app", 2));
|
|
CHECK(!f.is_open());
|
|
f.write(util::LogLevel::Info, "ignored");
|
|
}
|
|
|
|
std::remove((dir + "/app.log").c_str());
|
|
std::remove((dir + "/app.1.log").c_str());
|
|
std::remove((dir + "/app.2.log").c_str());
|
|
std::remove((dir + "/secret.log").c_str());
|
|
rmdir(dir.c_str());
|
|
return testfw::test_failures();
|
|
}
|