json-archive/tests/compressed_archive_tests.rs
nobody 2ab1c31993
feat: transparently append to compressed archives
When appending to a compressed archive (gzip, brotli, zstd), the tool
now handles compression automatically. Since some compression formats don't
support appending to compressed files in place, we write a new
compressed file with all the data and atomically rename it to replace
the original (assuming there is enough space on that filesystem).

This means you can work with compressed archives the same way as
uncompressed ones. Point the tool at your .json.gz file and append
values. No manual decompression/recompression needed.
2025-11-30 17:09:49 -08:00

64 lines
2.1 KiB
Rust

// Integration tests for compressed archive functionality
use json_archive::{append_to_archive, ArchiveWriter, Header};
use json_archive::{ArchiveReader, ReadMode};
use serde_json::json;
use std::io::Write;
use tempfile::NamedTempFile;
#[test]
#[cfg(feature = "compression")]
fn test_append_to_compressed_archive_basic() -> Result<(), Box<dyn std::error::Error>> {
use flate2::write::GzEncoder;
use flate2::Compression;
// Create initial archive
let archive_file = NamedTempFile::with_suffix(".json.archive")?;
let header = Header::new(json!({"count": 0}), Some("test".to_string()));
{
let mut writer = ArchiveWriter::new(archive_file.path(), None)
.map_err(|e| format!("Failed to create writer: {:?}", e))?;
writer.write_header(&header)
.map_err(|e| format!("Failed to write header: {:?}", e))?;
writer.finish()
.map_err(|e| format!("Failed to finish: {:?}", e))?;
}
// Compress it
let compressed_file = NamedTempFile::with_suffix(".json.archive.gz")?;
{
let input = std::fs::read(archive_file.path())?;
let mut encoder = GzEncoder::new(
compressed_file.as_file().try_clone()?,
Compression::default()
);
encoder.write_all(&input)?;
encoder.finish()?;
}
// Create a new state file to append
let mut state_file = NamedTempFile::new()?;
writeln!(state_file, r#"{{"count": 1}}"#)?;
state_file.flush()?;
// Append to compressed archive
let diagnostics = append_to_archive(
compressed_file.path(),
&[state_file.path()],
compressed_file.path(),
None,
None,
);
// Should succeed with no diagnostics
assert!(diagnostics.is_empty(), "Got diagnostics: {:?}", diagnostics);
// Verify the archive was updated (decompressed)
let reader = ArchiveReader::new(compressed_file.path(), ReadMode::FullValidation)?;
let result = reader.read(compressed_file.path())?;
assert_eq!(result.final_state, json!({"count": 1}));
assert_eq!(result.observation_count, 1);
Ok(())
}