Shared Catalog
ci / checks (push) Failing after 1h5m14s

This commit is contained in:
khodowany
2026-09-17 01:25:26 -05:00
parent 5941a4cd49
commit fa385205e2
23 changed files with 742 additions and 242 deletions
+80 -5
View File
@@ -18,6 +18,9 @@
#include <boost/asio/use_future.hpp>
#include <boost/json.hpp>
#include <openssl/sha.h>
#include <raylib.h>
#include <unistd.h>
#include <vamp_zero/app.hpp>
#include <vamp_zero/database.hpp>
@@ -118,10 +121,15 @@ auto config_file(std::filesystem::path const &root, vamp_zero::config const &con
return path.string();
}
auto fixture_page() -> std::string {
auto bytes = std::array<std::uchar_t, 24>{137, 80, 78, 71, 13, 10, 26, 10, 0, 0, 0, 13,
73, 72, 68, 82, 0, 0, 3, 208, 0, 0, 1, 228};
return {reinterpret_cast<std::char_t const *>(bytes.data()), bytes.size()};
auto fixture_page(std::int32_t width = 976, std::int32_t height = 484) -> std::string {
auto image = GenImageColor(width, height, WHITE);
auto size = std::int32_t{};
auto bytes = ExportImageToMemory(image, ".png", &size);
UnloadImage(image);
BOOST_REQUIRE(bytes != nullptr);
auto result = std::string{reinterpret_cast<std::char_t const *>(bytes), static_cast<std::size_t>(size)};
MemFree(bytes);
return result;
}
auto checksum(std::string const &bytes) -> std::string {
@@ -354,7 +362,7 @@ BOOST_AUTO_TEST_CASE(readiness_rejects_corrupt_checksums_and_escaping_pages) {
std::filesystem::create_symlink(root.path / "outside.png", page);
} else {
auto bytes = fixture_page();
bytes.back() = 0;
bytes.back() ^= 1;
write_file(page, bytes);
}
auto ready = run_once(root.path, config);
@@ -387,6 +395,73 @@ BOOST_AUTO_TEST_CASE(readiness_rejects_unusable_database_and_runtime_paths) {
BOOST_TEST(read_file(root.path / "blocked") == "regular file");
}
BOOST_AUTO_TEST_CASE(readiness_decodes_pages_even_when_checksums_match) {
for (auto kind : {"truncated", "missing pixels", "wrong dimensions", "oversized"}) {
auto root = temporary_directory{};
auto config = fixture_config(root.path);
make_assets(config);
auto bytes = fixture_page(std::string_view{kind} == "wrong dimensions" ? 10 : 976);
if (std::string_view{kind} == "truncated") {
bytes.resize(24U);
} else if (std::string_view{kind} == "missing pixels") {
bytes.resize(33U);
} else if (std::string_view{kind} == "oversized") {
bytes[16] = 127;
}
auto score_path = std::filesystem::path{config.runtime.assets_path} / "songs" / "first.json";
auto score = boost::json::parse(read_file(score_path));
auto &page = score.at("presentation").at("pages").as_array()[0].as_object();
write_file(score_path.parent_path() / std::string{page.at("path").as_string()}, bytes);
page["sha256"] = checksum(bytes);
write_file(score_path, boost::json::serialize(score));
auto ready = run_once(root.path, config);
BOOST_REQUIRE_MESSAGE(!ready, kind);
BOOST_TEST(ready.error().describe().find("first.pages/1.png") != std::string::npos);
BOOST_TEST(!std::filesystem::exists(config.runtime.heartbeat_path));
}
}
BOOST_AUTO_TEST_CASE(readiness_rejects_actual_heartbeat_directories_and_symlinks) {
for (auto kind : {"directory", "symlink", "dangling symlink"}) {
auto root = temporary_directory{};
auto config = fixture_config(root.path);
make_assets(config);
std::filesystem::create_directories(std::filesystem::path{config.runtime.heartbeat_path}.parent_path());
if (std::string_view{kind} == "directory") {
std::filesystem::create_directory(config.runtime.heartbeat_path);
} else {
if (std::string_view{kind} == "symlink") {
write_file(root.path / "target", "untouched");
}
std::filesystem::create_symlink(root.path / "target", config.runtime.heartbeat_path);
}
auto ready = run_once(root.path, config);
BOOST_REQUIRE(!ready);
BOOST_TEST(ready.error().describe().find(config.runtime.heartbeat_path) != std::string::npos);
require_no_probe(config, true);
if (std::string_view{kind} == "symlink") {
BOOST_TEST(read_file(root.path / "target") == "untouched");
}
}
}
BOOST_AUTO_TEST_CASE(readiness_rejects_unwritable_parent_without_leaving_probes) {
if (::geteuid() == 0) {
BOOST_TEST_MESSAGE("Permission check requires an unprivileged test process");
return;
}
auto root = temporary_directory{};
auto config = fixture_config(root.path);
make_assets(config);
auto parent = std::filesystem::path{config.runtime.heartbeat_path}.parent_path();
std::filesystem::create_directory(parent);
std::filesystem::permissions(parent, std::filesystem::perms::owner_read | std::filesystem::perms::owner_exec);
auto ready = run_once(root.path, config);
std::filesystem::permissions(parent, std::filesystem::perms::owner_all);
BOOST_TEST(!ready);
require_no_probe(config);
}
BOOST_AUTO_TEST_CASE(readiness_rejects_occupied_bind_and_releases_successful_probe) {
auto root = temporary_directory{};
auto config = fixture_config(root.path);