diff --git a/dehydrate/test/build_dehydrate_test.sh b/dehydrate/test/build_dehydrate_test.sh index aad0e66..8ac2efa 100755 --- a/dehydrate/test/build_dehydrate_test.sh +++ b/dehydrate/test/build_dehydrate_test.sh @@ -6,23 +6,59 @@ PROJECT_DIR="$( cd "$SCRIPT_DIR/.." && pwd )" cd "$SCRIPT_DIR" -# Clean up old test data -rm -rf dehydrate_test_data +# Clean up old test data and any existing binaries +# Force removal with chmod to handle permission issues +if [ -d dehydrate_test_data ]; then + chmod -R u+w dehydrate_test_data 2>/dev/null || true + rm -rf dehydrate_test_data +fi +rm -f dehydrate_test -# Build the test program - mount the entire project directory to access ../output/dehydrate -docker run --rm -v "$PROJECT_DIR":/workdir -w /workdir/test gitea.jde.nz/public/dropshell-build-base:latest \ +# Build the test program using Docker +# The Docker container supports both amd64 and arm64 architectures +docker run --rm \ + -v "$PROJECT_DIR":/workdir \ + -w /workdir/test \ + gitea.jde.nz/public/dropshell-build-base:latest \ bash -c " - if [ -f dehydrate_test.cpp ]; then - g++ -std=c++23 -static dehydrate_test.cpp -o dehydrate_test - else + # Verify we can find the source file + if [ ! -f dehydrate_test.cpp ]; then echo 'ERROR: dehydrate_test.cpp not found in current directory' + echo 'Working directory:' && pwd + echo 'Available files:' && ls -la exit 1 fi + + # Clean any existing binary and compile + rm -f dehydrate_test + if ! g++ -std=c++23 -static dehydrate_test.cpp -o dehydrate_test; then + echo 'ERROR: Compilation failed' + exit 1 + fi + + # Verify binary was created and is executable + if [ ! -f dehydrate_test ]; then + echo 'ERROR: Binary was not created' + exit 1 + fi + + # Quick architecture check - the binary should at least start + if ! timeout 5 ./dehydrate_test 2>/dev/null; then + # If it fails to run, check if it's an architecture mismatch + if file dehydrate_test | grep -q 'cannot execute'; then + echo 'ERROR: Binary architecture mismatch' + echo 'Host arch:' && uname -m + echo 'Binary info:' && file dehydrate_test + exit 1 + fi + fi " # Check if compilation succeeded if [ ! -f "./dehydrate_test" ]; then - echo "Error: Failed to compile dehydrate_test" + echo "Error: Failed to compile dehydrate_test - binary not found" + echo "Files in current directory:" + ls -la exit 1 fi diff --git a/dehydrate/test/dehydrate_test_data/generated/_original.cpp b/dehydrate/test/dehydrate_test_data/generated/_original.cpp deleted file mode 100644 index 522d161..0000000 --- a/dehydrate/test/dehydrate_test_data/generated/_original.cpp +++ /dev/null @@ -1,188 +0,0 @@ -#include -#include -#include -#include -#include - -/* - - THIS FILE IS AUTO-GENERATED BY DEHYDRATE. - DO NOT EDIT THIS FILE. - -*/ - - -#include "_original.hpp" -namespace recreate_original { - - -// Tiny dependency-free FNV-1a 64-bit hash -static uint64_t fnv1a_64(const void* data, size_t len) { - const uint8_t* p = static_cast(data); - uint64_t h = 0xcbf29ce484222325ULL; - for (size_t i = 0; i < len; ++i) - h = (h ^ p[i]) * 0x100000001b3ULL; - return h; -} - - -// Base64 decoding function - no dependencies -static void base64_decode(const char* encoded_data, size_t encoded_len, unsigned char* output, size_t* output_len) { - const char* base64_chars = - "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; - size_t out_pos = 0; - int val = 0, valb = -8; - - for (size_t i = 0; i < encoded_len; i++) { - char c = encoded_data[i]; - if (c == '=') break; - - // Find position in base64_chars - const char* pos = strchr(base64_chars, c); - if (pos == nullptr) continue; // Skip invalid characters - - val = (val << 6) + static_cast(pos - base64_chars); - valb += 6; - if (valb >= 0) { - output[out_pos++] = static_cast((val >> valb) & 0xFF); - valb -= 8; - } - } - - *output_len = out_pos; -} - -// Utility function to recreate a file with proper permissions -static bool _recreate_file_(const std::filesystem::path& outpath, uint64_t file_hash, std::filesystem::perms file_perms, const unsigned char* filedata, size_t filedata_len) { - namespace fs = std::filesystem; - bool needs_write = false; - - // Check if file exists and has correct hash - if (fs::exists(outpath)) { - // Check content hash - std::ifstream in(outpath, std::ios::binary); - std::ostringstream oss; - oss << in.rdbuf(); - std::string data = oss.str(); - uint64_t existing_hash = fnv1a_64(data.data(), data.size()); - needs_write = existing_hash != file_hash; - } else { - needs_write = true; // File doesn't exist, need to create it - } - - bool needs_permission_update = true; - if (!needs_write) { // we always update permissions if the file is written or changed. Othewise we check. - fs::perms current_perms = fs::status(outpath).permissions(); - needs_permission_update = current_perms != file_perms; - } - - if (needs_write) { - bool existed = fs::exists(outpath); - - fs::create_directories(outpath.parent_path()); - std::ofstream out(outpath, std::ios::binary); - out.write(reinterpret_cast(filedata), filedata_len); - out.close(); - // Set the file permissions - fs::permissions(outpath, file_perms); - - if (!existed) { - std::cout << "[dehydrate] " << outpath.filename() << ": created\n"; - } else { - std::cout << "[dehydrate] " << outpath.filename() << ": updated (hash changed)\n"; - } - return true; - } - - if (needs_permission_update) { - // Update only permissions - fs::permissions(outpath, file_perms); - std::cout << "[dehydrate] " << outpath.filename() << ": updated (permissions changed)\n"; - return true; - } - - return false; -} - -bool recreate_tree(std::string destination_folder) { - namespace fs = std::filesystem; - bool any_written = false; - { - // File: small.txt - fs::path outpath = fs::path(destination_folder) / "small.txt"; - static const char filedata_base64[] = "eA=="; - - // Decode Base64 data - size_t decoded_size = (strlen(filedata_base64) * 3) / 4; - unsigned char* decoded_data = new unsigned char[decoded_size]; - size_t actual_size; - base64_decode(filedata_base64, strlen(filedata_base64), decoded_data, &actual_size); - - bool file_written = _recreate_file_(outpath, 12638214688346347271ULL, std::filesystem::perms(384), decoded_data, actual_size); - delete[] decoded_data; - any_written = any_written || file_written; - } - { - // File: test2.bin - fs::path outpath = fs::path(destination_folder) / "test2.bin"; - static const char filedata_base64[] = "AP9CEzferb7v"; - - // Decode Base64 data - size_t decoded_size = (strlen(filedata_base64) * 3) / 4; - unsigned char* decoded_data = new unsigned char[decoded_size]; - size_t actual_size; - base64_decode(filedata_base64, strlen(filedata_base64), decoded_data, &actual_size); - - bool file_written = _recreate_file_(outpath, 10042072622899139650ULL, std::filesystem::perms(448), decoded_data, actual_size); - delete[] decoded_data; - any_written = any_written || file_written; - } - { - // File: test3.sh - fs::path outpath = fs::path(destination_folder) / "test3.sh"; - static const char filedata_base64[] = "IyEvYmluL2Jhc2gKZWNobyAnSGVsbG8gZnJvbSB0ZXN0IHNjcmlwdCcKZXhpdCAw"; - - // Decode Base64 data - size_t decoded_size = (strlen(filedata_base64) * 3) / 4; - unsigned char* decoded_data = new unsigned char[decoded_size]; - size_t actual_size; - base64_decode(filedata_base64, strlen(filedata_base64), decoded_data, &actual_size); - - bool file_written = _recreate_file_(outpath, 14335927320996074478ULL, std::filesystem::perms(488), decoded_data, actual_size); - delete[] decoded_data; - any_written = any_written || file_written; - } - { - // File: test1.txt - fs::path outpath = fs::path(destination_folder) / "test1.txt"; - static const char filedata_base64[] = "VGhpcyBpcyBhIHNpbXBsZSB0ZXh0IGZpbGUuCkl0IGhhcyBtdWx0aXBsZSBsaW5lcy4KTGluZSAz"\ - "Lg=="; - - // Decode Base64 data - size_t decoded_size = (strlen(filedata_base64) * 3) / 4; - unsigned char* decoded_data = new unsigned char[decoded_size]; - size_t actual_size; - base64_decode(filedata_base64, strlen(filedata_base64), decoded_data, &actual_size); - - bool file_written = _recreate_file_(outpath, 11900461415522640014ULL, std::filesystem::perms(384), decoded_data, actual_size); - delete[] decoded_data; - any_written = any_written || file_written; - } - { - // File: subdir/nested.txt - fs::path outpath = fs::path(destination_folder) / "subdir/nested.txt"; - static const char filedata_base64[] = "VGhpcyBmaWxlIGlzIGluIGEgc3ViZGlyZWN0b3J5Lg=="; - - // Decode Base64 data - size_t decoded_size = (strlen(filedata_base64) * 3) / 4; - unsigned char* decoded_data = new unsigned char[decoded_size]; - size_t actual_size; - base64_decode(filedata_base64, strlen(filedata_base64), decoded_data, &actual_size); - - bool file_written = _recreate_file_(outpath, 14153000318456068100ULL, std::filesystem::perms(256), decoded_data, actual_size); - delete[] decoded_data; - any_written = any_written || file_written; - } - return any_written; -} -} diff --git a/dehydrate/test/dehydrate_test_data/generated/_original.hpp b/dehydrate/test/dehydrate_test_data/generated/_original.hpp deleted file mode 100644 index e5a5a33..0000000 --- a/dehydrate/test/dehydrate_test_data/generated/_original.hpp +++ /dev/null @@ -1,15 +0,0 @@ - -#pragma once - -/* - - THIS FILE IS AUTO-GENERATED BY DEHYDRATE. - DO NOT EDIT THIS FILE. - -*/ - - -#include -namespace recreate_original { - bool recreate_tree(std::string destination_folder); -} diff --git a/dehydrate/test/dehydrate_test_data/generated/_test1.cpp b/dehydrate/test/dehydrate_test_data/generated/_test1.cpp deleted file mode 100644 index d928603..0000000 --- a/dehydrate/test/dehydrate_test_data/generated/_test1.cpp +++ /dev/null @@ -1,114 +0,0 @@ -#include -#include -#include -#include -#include - -// Tiny dependency-free FNV-1a 64-bit hash -static uint64_t fnv1a_64(const void* data, size_t len) { - const uint8_t* p = static_cast(data); - uint64_t h = 0xcbf29ce484222325ULL; - for (size_t i = 0; i < len; ++i) - h = (h ^ p[i]) * 0x100000001b3ULL; - return h; -} -#include "_test1.hpp" -namespace recreate_test1 { - -// Base64 decoding function - no dependencies -static void base64_decode(const char* encoded_data, size_t encoded_len, unsigned char* output, size_t* output_len) { - const char* base64_chars = - "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; - size_t out_pos = 0; - int val = 0, valb = -8; - - for (size_t i = 0; i < encoded_len; i++) { - char c = encoded_data[i]; - if (c == '=') break; - - // Find position in base64_chars - const char* pos = strchr(base64_chars, c); - if (pos == nullptr) continue; // Skip invalid characters - - val = (val << 6) + static_cast(pos - base64_chars); - valb += 6; - if (valb >= 0) { - output[out_pos++] = static_cast((val >> valb) & 0xFF); - valb -= 8; - } - } - - *output_len = out_pos; -} - -// Utility function to recreate a file with proper permissions -static bool _recreate_file_(const std::filesystem::path& outpath, uint64_t file_hash, std::filesystem::perms file_perms, const unsigned char* filedata, size_t filedata_len) { - namespace fs = std::filesystem; - bool needs_write = false; - - // Check if file exists and has correct hash - if (fs::exists(outpath)) { - // Check content hash - std::ifstream in(outpath, std::ios::binary); - std::ostringstream oss; - oss << in.rdbuf(); - std::string data = oss.str(); - uint64_t existing_hash = fnv1a_64(data.data(), data.size()); - needs_write = existing_hash != file_hash; - } else { - needs_write = true; // File doesn't exist, need to create it - } - - bool needs_permission_update = true; - if (!needs_write) { // we always update permissions if the file is written or changed. Othewise we check. - fs::perms current_perms = fs::status(outpath).permissions(); - needs_permission_update = current_perms != file_perms; - } - - if (needs_write) { - bool existed = fs::exists(outpath); - - fs::create_directories(outpath.parent_path()); - std::ofstream out(outpath, std::ios::binary); - out.write(reinterpret_cast(filedata), filedata_len); - out.close(); - // Set the file permissions - fs::permissions(outpath, file_perms); - - if (!existed) { - std::cout << "[dehydrate] " << outpath.filename() << ": created\n"; - } else { - std::cout << "[dehydrate] " << outpath.filename() << ": updated (hash changed)\n"; - } - return true; - } - - if (needs_permission_update) { - // Update only permissions - fs::permissions(outpath, file_perms); - std::cout << "[dehydrate] " << outpath.filename() << ": updated (permissions changed)\n"; - return true; - } - - return false; -} - -bool recreate_file(std::string destination_folder) { - namespace fs = std::filesystem; - fs::path outpath = fs::path(destination_folder) / "test1.txt"; - - // File data embedded as Base64 - static const char filedata_base64[] = "VGhpcyBpcyBhIHNpbXBsZSB0ZXh0IGZpbGUuCkl0IGhhcyBtdWx0aXBsZSBsaW5lcy4KTGluZSAz"\ - "Lg=="; - - // Decode Base64 data - size_t decoded_size = (strlen(filedata_base64) * 3) / 4; - unsigned char* decoded_data = new unsigned char[decoded_size]; - size_t actual_size; - base64_decode(filedata_base64, strlen(filedata_base64), decoded_data, &actual_size); - - bool result = _recreate_file_(outpath, 11900461415522640014ULL, std::filesystem::perms(384), decoded_data, actual_size); - delete[] decoded_data; - return result; -} -} diff --git a/dehydrate/test/dehydrate_test_data/generated/_test1.hpp b/dehydrate/test/dehydrate_test_data/generated/_test1.hpp deleted file mode 100644 index 31cde3f..0000000 --- a/dehydrate/test/dehydrate_test_data/generated/_test1.hpp +++ /dev/null @@ -1,5 +0,0 @@ -#pragma once -#include -namespace recreate_test1 { -bool recreate_file(std::string destination_folder); -} diff --git a/dehydrate/test/dehydrate_test_data/original/small.txt b/dehydrate/test/dehydrate_test_data/original/small.txt deleted file mode 100644 index c1b0730..0000000 --- a/dehydrate/test/dehydrate_test_data/original/small.txt +++ /dev/null @@ -1 +0,0 @@ -x \ No newline at end of file diff --git a/dehydrate/test/dehydrate_test_data/original/subdir/nested.txt b/dehydrate/test/dehydrate_test_data/original/subdir/nested.txt deleted file mode 100644 index 6087a8f..0000000 --- a/dehydrate/test/dehydrate_test_data/original/subdir/nested.txt +++ /dev/null @@ -1 +0,0 @@ -This file is in a subdirectory. \ No newline at end of file diff --git a/dehydrate/test/dehydrate_test_data/original/test1.txt b/dehydrate/test/dehydrate_test_data/original/test1.txt deleted file mode 100644 index 0c8f83e..0000000 --- a/dehydrate/test/dehydrate_test_data/original/test1.txt +++ /dev/null @@ -1,3 +0,0 @@ -This is a simple text file. -It has multiple lines. -Line 3. \ No newline at end of file diff --git a/dehydrate/test/dehydrate_test_data/original/test2.bin b/dehydrate/test/dehydrate_test_data/original/test2.bin deleted file mode 100755 index 112ff51..0000000 Binary files a/dehydrate/test/dehydrate_test_data/original/test2.bin and /dev/null differ diff --git a/dehydrate/test/dehydrate_test_data/original/test3.sh b/dehydrate/test/dehydrate_test_data/original/test3.sh deleted file mode 100755 index 7fbe9cd..0000000 --- a/dehydrate/test/dehydrate_test_data/original/test3.sh +++ /dev/null @@ -1,3 +0,0 @@ -#!/bin/bash -echo 'Hello from test script' -exit 0 \ No newline at end of file diff --git a/dehydrate/test/dehydrate_test_data/recreated/test1.txt b/dehydrate/test/dehydrate_test_data/recreated/test1.txt deleted file mode 100644 index 0c8f83e..0000000 --- a/dehydrate/test/dehydrate_test_data/recreated/test1.txt +++ /dev/null @@ -1,3 +0,0 @@ -This is a simple text file. -It has multiple lines. -Line 3. \ No newline at end of file diff --git a/dehydrate/test/dehydrate_test_data/recreated/tree/small.txt b/dehydrate/test/dehydrate_test_data/recreated/tree/small.txt deleted file mode 100644 index c1b0730..0000000 --- a/dehydrate/test/dehydrate_test_data/recreated/tree/small.txt +++ /dev/null @@ -1 +0,0 @@ -x \ No newline at end of file diff --git a/dehydrate/test/dehydrate_test_data/recreated/tree/subdir/nested.txt b/dehydrate/test/dehydrate_test_data/recreated/tree/subdir/nested.txt deleted file mode 100644 index 6087a8f..0000000 --- a/dehydrate/test/dehydrate_test_data/recreated/tree/subdir/nested.txt +++ /dev/null @@ -1 +0,0 @@ -This file is in a subdirectory. \ No newline at end of file diff --git a/dehydrate/test/dehydrate_test_data/recreated/tree/test1.txt b/dehydrate/test/dehydrate_test_data/recreated/tree/test1.txt deleted file mode 100644 index 0c8f83e..0000000 --- a/dehydrate/test/dehydrate_test_data/recreated/tree/test1.txt +++ /dev/null @@ -1,3 +0,0 @@ -This is a simple text file. -It has multiple lines. -Line 3. \ No newline at end of file diff --git a/dehydrate/test/dehydrate_test_data/recreated/tree/test2.bin b/dehydrate/test/dehydrate_test_data/recreated/tree/test2.bin deleted file mode 100755 index 112ff51..0000000 Binary files a/dehydrate/test/dehydrate_test_data/recreated/tree/test2.bin and /dev/null differ diff --git a/dehydrate/test/dehydrate_test_data/recreated/tree/test3.sh b/dehydrate/test/dehydrate_test_data/recreated/tree/test3.sh deleted file mode 100755 index 7fbe9cd..0000000 --- a/dehydrate/test/dehydrate_test_data/recreated/tree/test3.sh +++ /dev/null @@ -1,3 +0,0 @@ -#!/bin/bash -echo 'Hello from test script' -exit 0 \ No newline at end of file diff --git a/dehydrate/test/dehydrate_test_data/test_recreate b/dehydrate/test/dehydrate_test_data/test_recreate deleted file mode 100755 index 2d9b2a1..0000000 Binary files a/dehydrate/test/dehydrate_test_data/test_recreate and /dev/null differ diff --git a/dehydrate/test/dehydrate_test_data/test_recreate.cpp b/dehydrate/test/dehydrate_test_data/test_recreate.cpp deleted file mode 100644 index 04f41e3..0000000 --- a/dehydrate/test/dehydrate_test_data/test_recreate.cpp +++ /dev/null @@ -1,22 +0,0 @@ - -#include -#include "generated/_test1.hpp" -#include "generated/_original.hpp" - -int main() { - std::cout << "Testing file recreation..." << std::endl; - - // Test single file recreation - std::cout << "Recreating single file..." << std::endl; - if (recreate_test1::recreate_file("recreated")) { - std::cout << "Single file recreation returned true" << std::endl; - } - - // Test directory recreation - std::cout << "Recreating directory tree..." << std::endl; - if (recreate_original::recreate_tree("recreated/tree")) { - std::cout << "Directory recreation returned true" << std::endl; - } - - return 0; -}