Files
gitks/tests/snapshot_test.rs
T

159 lines
4.9 KiB
Rust

//! Copyright (c) 2022-2026 GitDataAi All rights reserved.
//! Tests for snapshot operations.
use std::path::PathBuf;
use gitks::snapshot::ops::{create_snapshot, restore_snapshot};
use gitks::snapshot::storage::{LocalSnapshotStorage, SnapshotStorageBackend};
fn temp_bare_repo() -> PathBuf {
let dir = tempfile::tempdir().unwrap().path().to_path_buf();
let result = std::process::Command::new("git")
.args(["init", "--bare"])
.arg(&dir)
.output()
.expect("git init --bare should work");
assert!(result.status.success());
// Create an initial commit so HEAD exists
// We need a working tree to create a commit, so we create one temporarily
let work_dir = tempfile::tempdir().unwrap().path().to_path_buf();
let result2 = std::process::Command::new("git")
.args(["init"])
.arg(&work_dir)
.output()
.expect("git init should work");
assert!(result2.status.success());
// Create a file and commit
std::fs::write(work_dir.join("test.txt"), "hello world").unwrap();
let result3 = std::process::Command::new("git")
.args(["add", "test.txt"])
.current_dir(&work_dir)
.output();
let _ = result3;
let result4 = std::process::Command::new("git")
.args(["commit", "-m", "initial commit"])
.env("GIT_AUTHOR_NAME", "test")
.env("GIT_AUTHOR_EMAIL", "test@test.com")
.env("GIT_COMMITTER_NAME", "test")
.env("GIT_COMMITTER_EMAIL", "test@test.com")
.current_dir(&work_dir)
.output();
let _ = result4;
// Push to bare repo
let result5 = std::process::Command::new("git")
.args(["push", &dir.to_string_lossy(), "master:refs/heads/master"])
.current_dir(&work_dir)
.output();
let _ = result5;
dir
}
#[test]
fn test_snapshot_create_and_restore() {
let repo = temp_bare_repo();
let gb = gitks::bare::GitBare::new(repo.clone());
// Create snapshot
let result = create_snapshot(&gb);
if let Ok(data) = result {
assert!(!data.is_empty());
// Restore to a different location
let target = tempfile::tempdir().unwrap().path().to_path_buf();
// Initialize target as bare repo first
let init_result = std::process::Command::new("git")
.args(["init", "--bare"])
.arg(&target)
.output();
if let Ok(init_output) = init_result
&& init_output.status.success()
{
let restore_result = restore_snapshot(&target, &data);
// May succeed or fail depending on git bundle compatibility
let _ = restore_result;
}
}
}
#[test]
fn test_local_snapshot_storage_write_and_read() {
let dir = tempfile::tempdir().unwrap().path().to_path_buf();
let storage = LocalSnapshotStorage::new(dir);
// Write snapshot
let result = storage.write_snapshot("snap001", "test.git", "abc123", b"bundle_data");
assert!(result.is_ok());
// Read snapshot
let result = storage.read_snapshot("snap001");
assert!(result.is_ok());
assert_eq!(result.unwrap(), b"bundle_data".to_vec());
// Read non-existent
let result = storage.read_snapshot("nonexistent");
assert!(result.is_err());
}
#[test]
fn test_local_snapshot_storage_list() {
let dir = tempfile::tempdir().unwrap().path().to_path_buf();
let storage = LocalSnapshotStorage::new(dir);
// Write two snapshots
storage
.write_snapshot("snap001", "repo1.git", "abc123", b"data1")
.unwrap();
storage
.write_snapshot("snap002", "repo2.git", "def456", b"data2")
.unwrap();
// List all
let result = storage.list_snapshots("");
assert!(result.is_ok());
assert_eq!(result.unwrap().len(), 2);
// List filtered
let result = storage.list_snapshots("repo1.git");
assert!(result.is_ok());
let snapshots = result.unwrap();
assert_eq!(snapshots.len(), 1);
assert_eq!(snapshots[0].relative_path, "repo1.git");
}
#[test]
fn test_local_snapshot_storage_delete() {
let dir = tempfile::tempdir().unwrap().path().to_path_buf();
let storage = LocalSnapshotStorage::new(dir);
storage
.write_snapshot("snap001", "test.git", "abc123", b"data")
.unwrap();
assert!(storage.read_snapshot("snap001").is_ok());
storage.delete_snapshot("snap001").unwrap();
assert!(storage.read_snapshot("snap001").is_err());
// Delete non-existent
assert!(storage.delete_snapshot("nonexistent").is_err());
}
#[test]
fn test_local_snapshot_storage_rejects_traversal_id() {
let dir = tempfile::tempdir().unwrap().path().to_path_buf();
let storage = LocalSnapshotStorage::new(dir);
assert!(storage.read_snapshot("../escape").is_err());
assert!(storage.delete_snapshot("../escape").is_err());
assert!(
storage
.write_snapshot("../escape", "repo.git", "abc123", b"data")
.is_err()
);
}