Files
keep/src/tests/common/test_helpers.rs
Andrew Phillips 49793a0f94 feat: add streaming tar export/import and rename "none" to "raw"
- Add streaming tar-based export (--export produces .keep.tar)
- Add streaming tar import (--import reads .keep.tar archives)
- Add server endpoints GET /api/export and POST /api/import
- Rename CompressionType::None to CompressionType::Raw with "none" as alias
- Add DB migration to update existing "none" compression values to "raw"
- Fix export endpoint to propagate errors to client instead of swallowing
- Fix import endpoint to return 413 on max_body_size instead of truncating

Export streams items as tar archives without loading entire files into memory.
Import extracts items with new IDs, preserving original order. Both work
locally and via client/server mode.

Co-Authored-By: opencode <noreply@opencode.ai>
2026-03-17 21:24:39 -03:00

108 lines
3.4 KiB
Rust

//! Common test utilities and helper functions to reduce duplication in tests
use crate::db;
use rusqlite::Connection;
use std::fs::File;
use std::io::Write;
use std::path::PathBuf;
use tempfile::TempDir;
/// Create a temporary directory for testing
pub fn create_temp_dir() -> TempDir {
TempDir::new().expect("Failed to create temporary directory")
}
/// Create a temporary file with the given content
pub fn create_temp_file_with_content(dir: &TempDir, filename: &str, content: &str) -> PathBuf {
let file_path = dir.path().join(filename);
let mut file = File::create(&file_path).expect("Failed to create test file");
write!(file, "{content}").expect("Failed to write to test file");
file_path
}
/// Create an empty temporary file
pub fn create_empty_temp_file(dir: &TempDir, filename: &str) -> PathBuf {
let file_path = dir.path().join(filename);
File::create(&file_path).expect("Failed to create empty test file");
file_path
}
/// Helper to test basic temporary directory setup
pub fn test_temp_dir_setup() {
let temp_dir = create_temp_dir();
assert!(temp_dir.path().exists());
}
/// Helper to test file creation and verification
pub fn test_file_creation(dir: &TempDir, filename: &str, content: &str) -> PathBuf {
let file_path = create_temp_file_with_content(dir, filename, content);
assert!(file_path.exists());
let metadata = std::fs::metadata(&file_path).expect("Failed to get file metadata");
assert!(metadata.len() > 0);
file_path
}
/// Create a temporary database for testing
pub fn create_temp_db() -> (TempDir, Connection, PathBuf) {
let temp_dir = create_temp_dir();
let db_path = temp_dir.path().join("test.db");
let conn = db::open(db_path.clone()).expect("Failed to open database");
(temp_dir, conn, db_path)
}
/// Create a test item in the database
pub fn create_test_item(conn: &Connection) -> i64 {
let item = crate::db::Item {
id: None,
ts: chrono::Utc::now(),
size: Some(100),
compression: crate::compression_engine::CompressionType::Raw.to_string(),
};
db::insert_item(conn, item).expect("Failed to insert item")
}
/// Test compression and decompression with an engine
pub fn test_compression_engine(
engine: &dyn crate::compression_engine::CompressionEngine,
test_data: &[u8],
) {
let dir = create_temp_dir();
let file_path = dir.path().join("test_compression.dat");
// Test compression
{
let mut writer = engine
.create(file_path.clone())
.expect("Failed to create writer");
writer.write_all(test_data).expect("Failed to write data");
}
// Test decompression
let mut reader = engine.open(file_path).expect("Failed to open reader");
let mut decompressed = Vec::new();
std::io::copy(&mut reader, &mut decompressed).expect("Failed to read data");
assert_eq!(test_data, decompressed.as_slice());
}
/// Get the size of a file
pub fn get_file_size(file_path: &PathBuf) -> u64 {
let metadata = std::fs::metadata(file_path).expect("Failed to get file metadata");
metadata.len()
}
/// Assert that a file exists
pub fn assert_file_exists(file_path: &PathBuf) {
assert!(file_path.exists(), "File {file_path:?} does not exist");
}
/// Assert that a file does not exist
pub fn assert_file_not_exists(file_path: &PathBuf) {
assert!(
!file_path.exists(),
"File {file_path:?} should not exist but it does"
);
}