From bfc0ee923d6bdcea2565beeeec762f15cb37f366 Mon Sep 17 00:00:00 2001 From: rick-five <165170199+rick-five@users.noreply.github.com> Date: Wed, 30 Jul 2025 18:54:53 +0800 Subject: [PATCH 1/7] Update fetch_test.rs Signed-off-by: rick-five <165170199+rick-five@users.noreply.github.com> --- libra/tests/command/fetch_test.rs | 106 ++++++++++++++++++++++++++++++ 1 file changed, 106 insertions(+) diff --git a/libra/tests/command/fetch_test.rs b/libra/tests/command/fetch_test.rs index 8b1378917..91eb41fb8 100644 --- a/libra/tests/command/fetch_test.rs +++ b/libra/tests/command/fetch_test.rs @@ -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 { + 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); + } + // Failed to start the command + Ok(Err(e)) => { + panic!("Failed to run 'libra fetch' command: {}", e); + } + } + + eprintln!("test_fetch_invalid_remote passed"); +} From 1bb845f188806fbe6eb13cbe38cbbf85d4ebbda6 Mon Sep 17 00:00:00 2001 From: rick-five <165170199+rick-five@users.noreply.github.com> Date: Wed, 30 Jul 2025 18:55:49 +0800 Subject: [PATCH 2/7] Update lfs_test.rs Signed-off-by: rick-five <165170199+rick-five@users.noreply.github.com> --- libra/tests/command/lfs_test.rs | 106 ++++++++++++++++++++++++++++++++ 1 file changed, 106 insertions(+) diff --git a/libra/tests/command/lfs_test.rs b/libra/tests/command/lfs_test.rs index 8b1378917..2e61d1bc1 100644 --- a/libra/tests/command/lfs_test.rs +++ b/libra/tests/command/lfs_test.rs @@ -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 + ); +} From 958a5222643e8e2d4ed99b692ba7a40d11c90356 Mon Sep 17 00:00:00 2001 From: rick-five <165170199+rick-five@users.noreply.github.com> Date: Wed, 30 Jul 2025 18:56:17 +0800 Subject: [PATCH 3/7] Update merge_test.rs Signed-off-by: rick-five <165170199+rick-five@users.noreply.github.com> --- libra/tests/command/merge_test.rs | 189 ++++++++++++++++++++++++++++++ 1 file changed, 189 insertions(+) diff --git a/libra/tests/command/merge_test.rs b/libra/tests/command/merge_test.rs index 8b1378917..a18a6297c 100644 --- a/libra/tests/command/merge_test.rs +++ b/libra/tests/command/merge_test.rs @@ -1 +1,190 @@ +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(); + + // 变量可以直接在 `format!` 字符串中使用 + // FIX: 更新 println! 格式 + println!("Temporary directory created at: {temp_path:?}"); + assert!(temp_path.is_dir(), "Temporary path is not a valid directory"); + + // 修改这一行:使用 env!("CARGO_BIN_EXE_libra") 来获取 libra 可执行文件的路径 + 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 fast-forward merge of local branches +async fn test_merge_fast_forward() { + let temp_repo = init_temp_repo(); + let temp_path = temp_repo.path(); + + // Create and switch to the feature branch + // FIX: 移除 & + Command::new(env!("CARGO_BIN_EXE_libra")) + .current_dir(temp_path) + .args(["branch", "feature"]) + .output() + .expect("Failed to create branch"); + // FIX: 移除 & + Command::new(env!("CARGO_BIN_EXE_libra")) + .current_dir(temp_path) + .args(["checkout", "feature"]) + .output() + .expect("Failed to checkout branch"); + + // Commit changes on the feature branch + let file_path = temp_path.join("file.txt"); + std::fs::write(&file_path, "Feature content").expect("Failed to write file"); + // FIX: 移除 & + Command::new(env!("CARGO_BIN_EXE_libra")) + .current_dir(temp_path) + .args(["add", "."]) + .output() + .expect("Failed to add file"); + // FIX: 移除 & + Command::new(env!("CARGO_BIN_EXE_libra")) + .current_dir(temp_path) + .args(["commit", "-m", "Add feature content"]) + .output() + .expect("Failed to commit"); + + // Switch back to the main branch and perform fast-forward merge + // FIX: 移除 & + Command::new(env!("CARGO_BIN_EXE_libra")) + .current_dir(temp_path) + .args(["checkout", "main"]) + .output() + .expect("Failed to checkout main branch"); + // FIX: 移除 & + let merge_output = Command::new(env!("CARGO_BIN_EXE_libra")) + .current_dir(temp_path) + .args(["merge", "feature"]) + .output() + .expect("Failed to merge branch"); + assert!( + merge_output.status.success(), + "Fast-forward merge failed: {}", + String::from_utf8_lossy(&merge_output.stderr) + ); +} + + +#[tokio::test] +/// Test merging a remote branch +async fn test_merge_remote_branch() { + let temp_repo = init_temp_repo(); + let temp_path = temp_repo.path(); + + // Simulate adding a remote branch + // FIX: 移除 & + Command::new(env!("CARGO_BIN_EXE_libra")) + .current_dir(temp_path) + .args(["remote", "add", "origin", "https://example.com/repo.git"]) + .output() + .expect("Failed to add remote"); + + // Merge the remote branch + // FIX: 移除 & + let merge_output = Command::new(env!("CARGO_BIN_EXE_libra")) + .current_dir(temp_path) + .args(["merge", "origin/feature"]) + .output() + .expect("Failed to merge remote branch"); + assert!( + merge_output.status.success(), + "Merge remote branch failed: {}", + String::from_utf8_lossy(&merge_output.stderr) + ); +} + + +#[tokio::test] +/// Test merging branches with no common ancestor +async fn test_merge_no_common_ancestor() { + let temp_repo = init_temp_repo(); + let temp_path = temp_repo.path(); + + // Create and switch to branch1 + // FIX: 移除 & + Command::new(env!("CARGO_BIN_EXE_libra")) + .current_dir(temp_path) + .args(["branch", "branch1"]) + .output() + .expect("Failed to create branch"); + // FIX: 移除 & + Command::new(env!("CARGO_BIN_EXE_libra")) + .current_dir(temp_path) + .args(["checkout", "branch1"]) + .output() + .expect("Failed to checkout branch"); + + // Commit changes on branch1 + let branch1_file = temp_path.join("branch1.txt"); + std::fs::write(&branch1_file, "Branch1 content").expect("Failed to write file"); + // FIX: 移除 & + Command::new(env!("CARGO_BIN_EXE_libra")) + .current_dir(temp_path) + .args(["add", "."]) + .output() + .expect("Failed to add file"); + // FIX: 移除 & + Command::new(env!("CARGO_BIN_EXE_libra")) + .current_dir(temp_path) + .args(["commit", "-m", "Add branch1 content"]) + .output() + .expect("Failed to commit"); + + // Create and switch to branch2 + // FIX: 移除 & + Command::new(env!("CARGO_BIN_EXE_libra")) + .current_dir(temp_path) + .args(["checkout", "-b", "branch2", "HEAD~1"]) + .output() + .expect("Failed to create branch"); + + // Commit changes on branch2 + let branch2_file = temp_path.join("branch2.txt"); + std::fs::write(&branch2_file, "Branch2 content").expect("Failed to write file"); + // FIX: 移除 & + Command::new(env!("CARGO_BIN_EXE_libra")) + .current_dir(temp_path) + .args(["add", "."]) + .output() + .expect("Failed to add file"); + // FIX: 移除 & + Command::new(env!("CARGO_BIN_EXE_libra")) + .current_dir(temp_path) + .args(["commit", "-m", "Add branch2 content"]) + .output() + .expect("Failed to commit"); + + // Attempt to merge branches with no common ancestor + // FIX: 移除 & + let merge_output = Command::new(env!("CARGO_BIN_EXE_libra")) + .current_dir(temp_path) + .args(["merge", "branch2"]) + .output() + .expect("Failed to merge branch"); + assert!( + merge_output.status.success(), + "Merge no common ancestor branch failed: {}", + String::from_utf8_lossy(&merge_output.stderr) + ); +} From 42454d72aa477752015086ce12922f3b47880a9a Mon Sep 17 00:00:00 2001 From: rick-five <165170199+rick-five@users.noreply.github.com> Date: Wed, 30 Jul 2025 21:47:54 +0800 Subject: [PATCH 4/7] Update merge_test.rs Signed-off-by: rick-five <165170199+rick-five@users.noreply.github.com> --- libra/tests/command/merge_test.rs | 35 ++++++++++++++----------------- 1 file changed, 16 insertions(+), 19 deletions(-) diff --git a/libra/tests/command/merge_test.rs b/libra/tests/command/merge_test.rs index a18a6297c..2187c72b6 100644 --- a/libra/tests/command/merge_test.rs +++ b/libra/tests/command/merge_test.rs @@ -6,17 +6,14 @@ fn init_temp_repo() -> TempDir { let temp_dir = tempfile::tempdir().expect("Failed to create temporary directory"); let temp_path = temp_dir.path(); - // 变量可以直接在 `format!` 字符串中使用 - // FIX: 更新 println! 格式 println!("Temporary directory created at: {temp_path:?}"); assert!(temp_path.is_dir(), "Temporary path is not a valid directory"); - // 修改这一行:使用 env!("CARGO_BIN_EXE_libra") 来获取 libra 可执行文件的路径 let output = Command::new(env!("CARGO_BIN_EXE_libra")) .current_dir(temp_path) .arg("init") .output() - .expect("Failed to execute libra binary"); // 错误信息保持不变,但现在应该能找到文件了 + .expect("Failed to execute libra binary"); if !output.status.success() { panic!( @@ -35,13 +32,13 @@ async fn test_merge_fast_forward() { let temp_path = temp_repo.path(); // Create and switch to the feature branch - // FIX: 移除 & + Command::new(env!("CARGO_BIN_EXE_libra")) .current_dir(temp_path) .args(["branch", "feature"]) .output() .expect("Failed to create branch"); - // FIX: 移除 & + Command::new(env!("CARGO_BIN_EXE_libra")) .current_dir(temp_path) .args(["checkout", "feature"]) @@ -51,13 +48,13 @@ async fn test_merge_fast_forward() { // Commit changes on the feature branch let file_path = temp_path.join("file.txt"); std::fs::write(&file_path, "Feature content").expect("Failed to write file"); - // FIX: 移除 & + Command::new(env!("CARGO_BIN_EXE_libra")) .current_dir(temp_path) .args(["add", "."]) .output() .expect("Failed to add file"); - // FIX: 移除 & + Command::new(env!("CARGO_BIN_EXE_libra")) .current_dir(temp_path) .args(["commit", "-m", "Add feature content"]) @@ -65,13 +62,13 @@ async fn test_merge_fast_forward() { .expect("Failed to commit"); // Switch back to the main branch and perform fast-forward merge - // FIX: 移除 & + Command::new(env!("CARGO_BIN_EXE_libra")) .current_dir(temp_path) .args(["checkout", "main"]) .output() .expect("Failed to checkout main branch"); - // FIX: 移除 & + let merge_output = Command::new(env!("CARGO_BIN_EXE_libra")) .current_dir(temp_path) .args(["merge", "feature"]) @@ -100,7 +97,7 @@ async fn test_merge_remote_branch() { .expect("Failed to add remote"); // Merge the remote branch - // FIX: 移除 & + let merge_output = Command::new(env!("CARGO_BIN_EXE_libra")) .current_dir(temp_path) .args(["merge", "origin/feature"]) @@ -121,13 +118,13 @@ async fn test_merge_no_common_ancestor() { let temp_path = temp_repo.path(); // Create and switch to branch1 - // FIX: 移除 & + Command::new(env!("CARGO_BIN_EXE_libra")) .current_dir(temp_path) .args(["branch", "branch1"]) .output() .expect("Failed to create branch"); - // FIX: 移除 & + Command::new(env!("CARGO_BIN_EXE_libra")) .current_dir(temp_path) .args(["checkout", "branch1"]) @@ -137,13 +134,13 @@ async fn test_merge_no_common_ancestor() { // Commit changes on branch1 let branch1_file = temp_path.join("branch1.txt"); std::fs::write(&branch1_file, "Branch1 content").expect("Failed to write file"); - // FIX: 移除 & + Command::new(env!("CARGO_BIN_EXE_libra")) .current_dir(temp_path) .args(["add", "."]) .output() .expect("Failed to add file"); - // FIX: 移除 & + Command::new(env!("CARGO_BIN_EXE_libra")) .current_dir(temp_path) .args(["commit", "-m", "Add branch1 content"]) @@ -151,7 +148,7 @@ async fn test_merge_no_common_ancestor() { .expect("Failed to commit"); // Create and switch to branch2 - // FIX: 移除 & + Command::new(env!("CARGO_BIN_EXE_libra")) .current_dir(temp_path) .args(["checkout", "-b", "branch2", "HEAD~1"]) @@ -161,13 +158,13 @@ async fn test_merge_no_common_ancestor() { // Commit changes on branch2 let branch2_file = temp_path.join("branch2.txt"); std::fs::write(&branch2_file, "Branch2 content").expect("Failed to write file"); - // FIX: 移除 & + Command::new(env!("CARGO_BIN_EXE_libra")) .current_dir(temp_path) .args(["add", "."]) .output() .expect("Failed to add file"); - // FIX: 移除 & + Command::new(env!("CARGO_BIN_EXE_libra")) .current_dir(temp_path) .args(["commit", "-m", "Add branch2 content"]) @@ -175,7 +172,7 @@ async fn test_merge_no_common_ancestor() { .expect("Failed to commit"); // Attempt to merge branches with no common ancestor - // FIX: 移除 & + let merge_output = Command::new(env!("CARGO_BIN_EXE_libra")) .current_dir(temp_path) .args(["merge", "branch2"]) From e2be0c2e2f1fb449639fa5a635755711ccb8e0d9 Mon Sep 17 00:00:00 2001 From: rick-five <165170199+rick-five@users.noreply.github.com> Date: Wed, 30 Jul 2025 21:56:21 +0800 Subject: [PATCH 5/7] Update fetch_test.rs Signed-off-by: rick-five <165170199+rick-five@users.noreply.github.com> --- libra/tests/command/fetch_test.rs | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/libra/tests/command/fetch_test.rs b/libra/tests/command/fetch_test.rs index 91eb41fb8..5cb255bef 100644 --- a/libra/tests/command/fetch_test.rs +++ b/libra/tests/command/fetch_test.rs @@ -85,7 +85,8 @@ async fn test_fetch_invalid_remote() { } // Command completed within timeout Ok(Ok(output)) => { - eprintln!("Fetch completed (status: {})", output.status); + + eprintln!("Fetch completed (status: {:?})", output.status); assert!( !output.status.success(), "Fetch should fail when remote is unreachable" @@ -95,11 +96,13 @@ async fn test_fetch_invalid_remote() { !stderr.trim().is_empty(), "Expected error message in stderr, but was empty" ); - eprintln!("Fetch failed as expected: {}", stderr); + + eprintln!("Fetch failed as expected: {stderr}"); } // Failed to start the command Ok(Err(e)) => { - panic!("Failed to run 'libra fetch' command: {}", e); + + panic!("Failed to run 'libra fetch' command: {e}"); } } From ed362590154ca3108d3ed998587b2de48fc01cb6 Mon Sep 17 00:00:00 2001 From: rick-five <165170199+rick-five@users.noreply.github.com> Date: Wed, 30 Jul 2025 21:56:37 +0800 Subject: [PATCH 6/7] Update lfs_test.rs Signed-off-by: rick-five <165170199+rick-five@users.noreply.github.com> From f5476a8d6b4dbe0fd39cc652489a4063e47ba2a6 Mon Sep 17 00:00:00 2001 From: rick-five <165170199+rick-five@users.noreply.github.com> Date: Thu, 31 Jul 2025 09:44:37 +0800 Subject: [PATCH 7/7] Update libra/tests/command/merge_test.rs Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> Signed-off-by: rick-five <165170199+rick-five@users.noreply.github.com> --- libra/tests/command/merge_test.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libra/tests/command/merge_test.rs b/libra/tests/command/merge_test.rs index 2187c72b6..22564decb 100644 --- a/libra/tests/command/merge_test.rs +++ b/libra/tests/command/merge_test.rs @@ -89,7 +89,7 @@ async fn test_merge_remote_branch() { let temp_path = temp_repo.path(); // Simulate adding a remote branch - // FIX: 移除 & + // FIX: Remove & Command::new(env!("CARGO_BIN_EXE_libra")) .current_dir(temp_path) .args(["remote", "add", "origin", "https://example.com/repo.git"])