Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
106 changes: 106 additions & 0 deletions libra/tests/command/fetch_test.rs
Original file line number Diff line number Diff line change
@@ -1 +1,107 @@
use std::process::Command;
use std::time::Duration;
use tempfile::TempDir;
use tokio::process::Command as TokioCommand;
use tokio::time::timeout;

/// Helper function: Initialize a temporary Libra repository
fn init_temp_repo() -> TempDir {
let temp_dir = tempfile::tempdir().expect("Failed to create temporary directory");
let temp_path = temp_dir.path();

eprintln!("Temporary directory created at: {temp_path:?}");
assert!(temp_path.is_dir(), "Temporary path is not a valid directory");

let output = Command::new(env!("CARGO_BIN_EXE_libra"))
.current_dir(temp_path)
.arg("init")
.output()
.expect("Failed to execute libra binary");

if !output.status.success() {
panic!(
"Failed to initialize libra repository: {}",
String::from_utf8_lossy(&output.stderr)
);
}

eprintln!("Initialized libra repo at: {temp_path:?}");
temp_dir
}

#[tokio::test]
/// Test fetching from an invalid remote repository with timeout
async fn test_fetch_invalid_remote() {
let temp_repo = init_temp_repo();
let temp_path = temp_repo.path();

eprintln!("Starting test: fetch from invalid remote");

// Configure an invalid remote repository
eprintln!("Adding invalid remote: https://invalid-url.example/repo.git");
let remote_output = TokioCommand::new(env!("CARGO_BIN_EXE_libra"))
.current_dir(temp_path)
.args(["remote", "add", "origin", "https://invalid-url.example/repo.git"])
.output()
.await
.expect("Failed to add remote");

assert!(
remote_output.status.success(),
"Failed to add remote: {}",
String::from_utf8_lossy(&remote_output.stderr)
);

// Set upstream branch
eprintln!("Setting upstream to origin/main");
let branch_output = TokioCommand::new(env!("CARGO_BIN_EXE_libra"))
.current_dir(temp_path)
.args(["branch", "--set-upstream-to", "origin/main"])
.output()
.await
.expect("Failed to set upstream branch");

assert!(
branch_output.status.success(),
"Failed to set upstream: {}",
String::from_utf8_lossy(&branch_output.stderr)
);

// Attempt to fetch with 15-second timeout to avoid hanging CI
eprintln!("Attempting 'libra fetch' with 15s timeout...");
let fetch_result = timeout(Duration::from_secs(15), async {
Comment on lines +70 to +72

Copilot AI Jul 30, 2025

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[nitpick] A 15-second timeout may be too long for CI environments and could slow down test execution. Consider reducing to 5-10 seconds or making it configurable via environment variable.

Suggested change
// Attempt to fetch with 15-second timeout to avoid hanging CI
eprintln!("Attempting 'libra fetch' with 15s timeout...");
let fetch_result = timeout(Duration::from_secs(15), async {
// Attempt to fetch with a configurable timeout to avoid hanging CI
let timeout_seconds = std::env::var("LIBRA_FETCH_TIMEOUT")
.ok()
.and_then(|val| val.parse::<u64>().ok())
.unwrap_or(10); // Default to 10 seconds if not set or invalid
eprintln!("Attempting 'libra fetch' with {timeout_seconds}s timeout...");
let fetch_result = timeout(Duration::from_secs(timeout_seconds), async {

Copilot uses AI. Check for mistakes.
TokioCommand::new(env!("CARGO_BIN_EXE_libra"))
.current_dir(temp_path)
.arg("fetch")
.output()
.await
})
.await;

match fetch_result {
// Timeout occurred — this is expected for unreachable remotes
Err(_) => {
eprintln!("Fetch timed out after 15 seconds — expected for invalid remote");
}
// Command completed within timeout
Ok(Ok(output)) => {
eprintln!("Fetch completed (status: {})", output.status);
assert!(
!output.status.success(),
"Fetch should fail when remote is unreachable"
);
let stderr = String::from_utf8_lossy(&output.stderr);
assert!(
!stderr.trim().is_empty(),
"Expected error message in stderr, but was empty"
);
eprintln!("Fetch failed as expected: {}", stderr);

Check failure on line 98 in libra/tests/command/fetch_test.rs

View workflow job for this annotation

GitHub Actions / Clippy Check

variables can be used directly in the `format!` string
}
// Failed to start the command
Ok(Err(e)) => {
panic!("Failed to run 'libra fetch' command: {}", e);

Check failure on line 102 in libra/tests/command/fetch_test.rs

View workflow job for this annotation

GitHub Actions / Clippy Check

variables can be used directly in the `format!` string
}
}

eprintln!("test_fetch_invalid_remote passed");
}
106 changes: 106 additions & 0 deletions libra/tests/command/lfs_test.rs
Original file line number Diff line number Diff line change
@@ -1 +1,107 @@
use std::process::Command;
use tempfile::TempDir;

/// Helper function: Initialize a temporary Libra repository
fn init_temp_repo() -> TempDir {
let temp_dir = tempfile::tempdir().expect("Failed to create temporary directory");
let temp_path = temp_dir.path();

// Variables can be used directly in the `format!` string
// FIX: Removed {:?} and added variable directly with formatting
println!("Temporary directory created at: {temp_path:?}");
assert!(temp_path.is_dir(), "Temporary path is not a valid directory");

// Using env!("CARGO_BIN_EXE_libra") to get the path to the libra executable
let output = Command::new(env!("CARGO_BIN_EXE_libra"))
.current_dir(temp_path)
.arg("init")
.output()
.expect("Failed to execute libra binary");

if !output.status.success() {
panic!(
"Failed to initialize libra repository: {}",
String::from_utf8_lossy(&output.stderr)
);
}

temp_dir
}

#[tokio::test]
/// Test track/untrack path rule management
async fn test_lfs_track_untrack() {
let temp_repo = init_temp_repo();
let temp_path = temp_repo.path();

// Add a path rule
// FIX: Removed & from args
let track_output = Command::new(env!("CARGO_BIN_EXE_libra"))
.current_dir(temp_path)
.args(["lfs", "track", "*.txt"]) // Changed &[...] to [...]
.output()
.expect("Failed to track path");
assert!(
track_output.status.success(),
"Failed to track path: {}",
String::from_utf8_lossy(&track_output.stderr)
);

// Remove a path rule
// FIX: Removed & from args
let untrack_output = Command::new(env!("CARGO_BIN_EXE_libra"))
.current_dir(temp_path)
.args(["lfs", "untrack", "*.txt"]) // Changed &[...] to [...]
.output()
.expect("Failed to untrack path");
assert!(
untrack_output.status.success(),
"Failed to untrack path: {}",
String::from_utf8_lossy(&untrack_output.stderr)
);
}

#[tokio::test]
/// Test file status viewing
async fn test_lfs_ls_files() {
let temp_repo = init_temp_repo();
let temp_path = temp_repo.path();

// Create a test file and add it to LFS
let file_path = temp_path.join("tracked_file.txt");
std::fs::write(&file_path, "Tracked content").expect("Failed to create tracked file");

// FIX: Removed & from args
Command::new(env!("CARGO_BIN_EXE_libra"))
.current_dir(temp_path)
.args(["lfs", "track", "*.txt"]) // Changed &[...] to [...]
.output()
.expect("Failed to track file");

// FIX: Removed & from args
Command::new(env!("CARGO_BIN_EXE_libra"))
.current_dir(temp_path)
.args(["add", "tracked_file.txt"]) // Changed &[...] to [...]
.output()
.expect("Failed to add file to LFS");

// View file status
// FIX: Removed & from args
let ls_files_output = Command::new(env!("CARGO_BIN_EXE_libra"))
.current_dir(temp_path)
.args(["lfs", "ls-files"]) // Changed &[...] to [...]
.output()
.expect("Failed to list LFS files");
assert!(
ls_files_output.status.success(),
"Failed to list LFS files: {}",
String::from_utf8_lossy(&ls_files_output.stderr)
);

let stdout = String::from_utf8_lossy(&ls_files_output.stdout);
// FIX: Variables can be used directly in the `format!` string
assert!(
stdout.contains("tracked_file.txt"),
"LFS file list does not contain expected file: {stdout}", // Changed {} to direct variable embed
);
}
Loading
Loading