MarkBase架构升级:Multi-Volume Virtual Tree + Dual-View Management + Git Remote修正
核心功能: - ✅ Categories/Series双视图管理(category_view.rs + import_markdown.rs) - ✅ FUSE Multi-Volume支持(tree_type参数) - ✅ SSH/SFTP/SCP/rsync协议完整实现(4042行) - ✅ NFS/SMB Module Phase 1-3完成 - ✅ Archive Module Phase 1-4完成(2916行) - ✅ Download Center API完整实现 - ✅ S3兼容API实现(560行) Git配置修正: - ✅ 删除错误origin(gitea.momentry.ddns.net) - ✅ 删除m5max128(指向机器名) - ✅ 设置origin = m5max128gitea.momentry.ddns.net/admin/markbase - ✅ 设置m4minigitea = m4minigitea.momentry.ddns.net/warren/markbase 数据清理: - ✅ 删除38个临时SQLite(保留accusys.sqlite、demo.sqlite) - ✅ 删除.bak、test_*.bin、调试脚本等临时文件 - ✅ 删除临时目录(build/、download files/、raid_test/等) - ✅ 更新.gitignore排除临时文件 架构优化: - 52个文件修改,2434行新增,4739行删除 - Workspace成员整合(16个crate) - 数据库状态:accusys.sqlite保留(主demo测试) 远程同步: - ✅ 准备推送到m5max128gitea(远程Gitea) - ✅ 准备推送到m4minigitea(本地Gitea)
This commit is contained in:
@@ -15,19 +15,19 @@ fn temp_db() -> (Connection, String) {
|
||||
#[test]
|
||||
fn test_api_logic_create_folder() {
|
||||
let (conn, user_id) = temp_db();
|
||||
let mut tree = FileTree::load(&conn, &user_id).unwrap();
|
||||
let mut tree = FileTree::load(&conn, &user_id, "untitled folder").unwrap();
|
||||
|
||||
let folder = FileTree::new_folder("API_Test_Folder", None);
|
||||
tree.insert_node(&conn, &folder).unwrap();
|
||||
|
||||
let loaded = FileTree::load(&conn, &user_id).unwrap();
|
||||
let loaded = FileTree::load(&conn, &user_id, "untitled folder").unwrap();
|
||||
assert_eq!(loaded.nodes.len(), 1);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_api_logic_create_file() {
|
||||
let (conn, user_id) = temp_db();
|
||||
let mut tree = FileTree::load(&conn, &user_id).unwrap();
|
||||
let mut tree = FileTree::load(&conn, &user_id, "untitled folder").unwrap();
|
||||
|
||||
let (file_node, register_sql) = FileTree::new_file_node(
|
||||
"test_api.mp4",
|
||||
@@ -46,7 +46,7 @@ fn test_api_logic_create_file() {
|
||||
|
||||
tree.insert_node(&conn, &file_node).unwrap();
|
||||
|
||||
let loaded = FileTree::load(&conn, &user_id).unwrap();
|
||||
let loaded = FileTree::load(&conn, &user_id, "untitled folder").unwrap();
|
||||
assert_eq!(loaded.nodes.len(), 1);
|
||||
assert_eq!(loaded.nodes[0].node_type, NodeType::File);
|
||||
}
|
||||
@@ -54,7 +54,7 @@ fn test_api_logic_create_file() {
|
||||
#[test]
|
||||
fn test_api_logic_get_tree_with_mode() {
|
||||
let (conn, user_id) = temp_db();
|
||||
let mut tree = FileTree::load(&conn, &user_id).unwrap();
|
||||
let mut tree = FileTree::load(&conn, &user_id, "untitled folder").unwrap();
|
||||
|
||||
let folder = FileTree::new_folder("Root", None);
|
||||
tree.insert_node(&conn, &folder).unwrap();
|
||||
@@ -76,7 +76,7 @@ fn test_api_logic_get_tree_with_mode() {
|
||||
#[test]
|
||||
fn test_api_logic_update_node() {
|
||||
let (conn, user_id) = temp_db();
|
||||
let mut tree = FileTree::load(&conn, &user_id).unwrap();
|
||||
let mut tree = FileTree::load(&conn, &user_id, "untitled folder").unwrap();
|
||||
|
||||
let mut folder = FileTree::new_folder("Original", None);
|
||||
tree.insert_node(&conn, &folder).unwrap();
|
||||
@@ -85,7 +85,7 @@ fn test_api_logic_update_node() {
|
||||
folder.icon = Some("🎬".to_string());
|
||||
tree.update_node(&conn, &folder.node_id, &folder).unwrap();
|
||||
|
||||
let loaded = FileTree::load(&conn, &user_id).unwrap();
|
||||
let loaded = FileTree::load(&conn, &user_id, "untitled folder").unwrap();
|
||||
assert_eq!(loaded.nodes[0].label, "Updated_via_API");
|
||||
assert_eq!(loaded.nodes[0].icon, Some("🎬".to_string()));
|
||||
}
|
||||
@@ -93,7 +93,7 @@ fn test_api_logic_update_node() {
|
||||
#[test]
|
||||
fn test_api_logic_delete_node() {
|
||||
let (conn, user_id) = temp_db();
|
||||
let mut tree = FileTree::load(&conn, &user_id).unwrap();
|
||||
let mut tree = FileTree::load(&conn, &user_id, "untitled folder").unwrap();
|
||||
|
||||
let folder = FileTree::new_folder("ToDelete", None);
|
||||
let node_id = folder.node_id.clone();
|
||||
@@ -103,21 +103,21 @@ fn test_api_logic_delete_node() {
|
||||
|
||||
tree.delete_node(&conn, &node_id).unwrap();
|
||||
|
||||
let loaded = FileTree::load(&conn, &user_id).unwrap();
|
||||
let loaded = FileTree::load(&conn, &user_id, "untitled folder").unwrap();
|
||||
assert_eq!(loaded.nodes.len(), 0);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_api_logic_delete_all_nodes() {
|
||||
let (conn, user_id) = temp_db();
|
||||
let mut tree = FileTree::load(&conn, &user_id).unwrap();
|
||||
let mut tree = FileTree::load(&conn, &user_id, "untitled folder").unwrap();
|
||||
|
||||
for i in 1..=5 {
|
||||
let folder = FileTree::new_folder(&format!("Folder{}", i), None);
|
||||
tree.insert_node(&conn, &folder).unwrap();
|
||||
}
|
||||
|
||||
let loaded = FileTree::load(&conn, &user_id).unwrap();
|
||||
let loaded = FileTree::load(&conn, &user_id, "untitled folder").unwrap();
|
||||
assert_eq!(loaded.nodes.len(), 5);
|
||||
|
||||
//模擬delete_all_nodes API邏輯
|
||||
@@ -129,14 +129,14 @@ fn test_api_logic_delete_all_nodes() {
|
||||
.unwrap();
|
||||
}
|
||||
|
||||
let after_delete = FileTree::load(&conn, &user_id).unwrap();
|
||||
let after_delete = FileTree::load(&conn, &user_id, "untitled folder").unwrap();
|
||||
assert_eq!(after_delete.nodes.len(), 0);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_api_logic_move_node() {
|
||||
let (conn, user_id) = temp_db();
|
||||
let mut tree = FileTree::load(&conn, &user_id).unwrap();
|
||||
let mut tree = FileTree::load(&conn, &user_id, "untitled folder").unwrap();
|
||||
|
||||
let parent = FileTree::new_folder("Parent", None);
|
||||
let child = FileTree::new_folder("Child", Some(parent.node_id.clone()));
|
||||
@@ -147,7 +147,7 @@ fn test_api_logic_move_node() {
|
||||
//移動到根目錄
|
||||
tree.move_node(&conn, &child.node_id, None).unwrap();
|
||||
|
||||
let loaded = FileTree::load(&conn, &user_id).unwrap();
|
||||
let loaded = FileTree::load(&conn, &user_id, "untitled folder").unwrap();
|
||||
let moved_node = loaded
|
||||
.nodes
|
||||
.iter()
|
||||
@@ -159,7 +159,7 @@ fn test_api_logic_move_node() {
|
||||
#[test]
|
||||
fn test_api_logic_update_alias() {
|
||||
let (conn, user_id) = temp_db();
|
||||
let mut tree = FileTree::load(&conn, &user_id).unwrap();
|
||||
let mut tree = FileTree::load(&conn, &user_id, "untitled folder").unwrap();
|
||||
|
||||
let folder = FileTree::new_folder("Videos", None);
|
||||
tree.insert_node(&conn, &folder).unwrap();
|
||||
@@ -169,7 +169,7 @@ fn test_api_logic_update_alias() {
|
||||
tree.update_node_alias(&conn, &folder.node_id, "en_us", "Videos")
|
||||
.unwrap();
|
||||
|
||||
let loaded = FileTree::load(&conn, &user_id).unwrap();
|
||||
let loaded = FileTree::load(&conn, &user_id, "untitled folder").unwrap();
|
||||
assert_eq!(
|
||||
loaded.nodes[0].aliases.get("zh_tw").map(|s| s.as_str()),
|
||||
Some("影片")
|
||||
@@ -183,7 +183,7 @@ fn test_api_logic_update_alias() {
|
||||
#[test]
|
||||
fn test_api_logic_nested_structure() {
|
||||
let (conn, user_id) = temp_db();
|
||||
let mut tree = FileTree::load(&conn, &user_id).unwrap();
|
||||
let mut tree = FileTree::load(&conn, &user_id, "untitled folder").unwrap();
|
||||
|
||||
let root = FileTree::new_folder("Root", None);
|
||||
let level1 = FileTree::new_folder("Level1", Some(root.node_id.clone()));
|
||||
@@ -193,7 +193,7 @@ fn test_api_logic_nested_structure() {
|
||||
tree.insert_node(&conn, &level1).unwrap();
|
||||
tree.insert_node(&conn, &level2).unwrap();
|
||||
|
||||
let loaded = FileTree::load(&conn, &user_id).unwrap();
|
||||
let loaded = FileTree::load(&conn, &user_id, "untitled folder").unwrap();
|
||||
assert_eq!(loaded.nodes.len(), 3);
|
||||
}
|
||||
|
||||
@@ -232,7 +232,7 @@ fn test_api_logic_file_info() {
|
||||
fn test_api_logic_restore_scenario() {
|
||||
//模擬restore_tree API邏輯
|
||||
let (conn, user_id) = temp_db();
|
||||
let mut tree = FileTree::load(&conn, &user_id).unwrap();
|
||||
let mut tree = FileTree::load(&conn, &user_id, "untitled folder").unwrap();
|
||||
|
||||
//建立基本結構
|
||||
let home = FileTree::new_folder("Home", None);
|
||||
@@ -241,7 +241,7 @@ fn test_api_logic_restore_scenario() {
|
||||
tree.insert_node(&conn, &home).unwrap();
|
||||
tree.insert_node(&conn, &movies).unwrap();
|
||||
|
||||
let loaded = FileTree::load(&conn, &user_id).unwrap();
|
||||
let loaded = FileTree::load(&conn, &user_id, "untitled folder").unwrap();
|
||||
assert!(loaded.nodes.iter().any(|n| n.label == "Home"));
|
||||
assert!(loaded.nodes.iter().any(|n| n.label == "Movies"));
|
||||
}
|
||||
|
||||
164
tests/archive_perf_test.sh
Executable file
164
tests/archive_perf_test.sh
Executable file
@@ -0,0 +1,164 @@
|
||||
#!/bin/bash
|
||||
|
||||
# MarkBase Archive Module Performance Test Script
|
||||
|
||||
echo "========================================="
|
||||
echo "MarkBase Archive Performance Test Suite"
|
||||
echo "========================================="
|
||||
|
||||
# Configuration
|
||||
SERVER_URL="http://localhost:11438"
|
||||
UPLOAD_ENDPOINT="/api/v2/upload"
|
||||
USER_ID="perf_test"
|
||||
TEST_DIR="/tmp/markbase_perf_test"
|
||||
LOG_FILE="/tmp/markbase_perf_results.log"
|
||||
|
||||
# Create test directory
|
||||
mkdir -p $TEST_DIR
|
||||
|
||||
# Function to generate test ZIP files
|
||||
generate_test_zip() {
|
||||
size=$1
|
||||
name=$2
|
||||
|
||||
echo "Generating $size MB test ZIP file..."
|
||||
|
||||
# Create temp directory with files
|
||||
temp_dir=$(mktemp -d)
|
||||
for i in {1..10}; do
|
||||
dd if=/dev/urandom of="$temp_dir/file_$i.txt" bs=1M count=$((size / 10)) 2>/dev/null
|
||||
done
|
||||
|
||||
# Create ZIP
|
||||
cd $temp_dir
|
||||
zip -r "$TEST_DIR/$name" . >/dev/null 2>&1
|
||||
cd -
|
||||
rm -rf $temp_dir
|
||||
|
||||
echo "Generated $TEST_DIR/$name ($(du -h $TEST_DIR/$name | cut -f1))"
|
||||
}
|
||||
|
||||
# Function to test upload performance
|
||||
test_upload() {
|
||||
file=$1
|
||||
description=$2
|
||||
|
||||
echo ""
|
||||
echo "Testing: $description"
|
||||
echo "File: $file"
|
||||
|
||||
# Measure upload time
|
||||
start_time=$(date +%s%N)
|
||||
|
||||
response=$(curl -s -w "\n%{http_code}\n%{time_total}" \
|
||||
-X POST "$SERVER_URL$UPLOAD_ENDPOINT/$USER_ID" \
|
||||
-F "file=@$file")
|
||||
|
||||
end_time=$(date +%s%N)
|
||||
|
||||
# Parse response
|
||||
http_code=$(echo "$response" | tail -n 2 | head -n 1)
|
||||
time_total=$(echo "$response" | tail -n 1)
|
||||
json_response=$(echo "$response" | head -n -2)
|
||||
|
||||
# Calculate duration in milliseconds
|
||||
duration_ms=$(( (end_time - start_time) / 1000000 ))
|
||||
|
||||
# Log results
|
||||
echo "HTTP Code: $http_code"
|
||||
echo "Upload Time: ${time_total}s"
|
||||
echo "Duration: ${duration_ms}ms"
|
||||
|
||||
if [ "$http_code" == "201" ]; then
|
||||
echo "✅ Upload successful"
|
||||
|
||||
# Check if extracted field exists
|
||||
if echo "$json_response" | jq -e '.extracted' >/dev/null 2>&1; then
|
||||
extracted_count=$(echo "$json_response" | jq -r '.extracted.count')
|
||||
extracted_bytes=$(echo "$json_response" | jq -r '.extracted.bytes')
|
||||
echo "✅ Extracted: $extracted_count files, $extracted_bytes bytes"
|
||||
|
||||
echo "SUCCESS|$description|$http_code|${time_total}s|${duration_ms}ms|$extracted_count|$extracted_bytes" >> $LOG_FILE
|
||||
else
|
||||
echo "⚠️ No extracted field in response"
|
||||
echo "PARTIAL|$description|$http_code|${time_total}s|${duration_ms}ms" >> $LOG_FILE
|
||||
fi
|
||||
else
|
||||
echo "❌ Upload failed"
|
||||
echo "FAILED|$description|$http_code|${time_total}s|${duration_ms}ms" >> $LOG_FILE
|
||||
fi
|
||||
}
|
||||
|
||||
# Function to test concurrent uploads
|
||||
test_concurrent() {
|
||||
count=$1
|
||||
|
||||
echo ""
|
||||
echo "Testing concurrent uploads: $count simultaneous"
|
||||
|
||||
# Generate small test files
|
||||
for i in {1..$count}; do
|
||||
temp_dir=$(mktemp -d)
|
||||
echo "file $i content" > "$temp_dir/test_$i.txt"
|
||||
cd $temp_dir
|
||||
zip -r "$TEST_DIR/concurrent_$i.zip" test_$i.txt >/dev/null 2>&1
|
||||
cd -
|
||||
rm -rf $temp_dir
|
||||
done
|
||||
|
||||
# Run concurrent uploads
|
||||
start_time=$(date +%s%N)
|
||||
|
||||
for i in {1..$count}; do
|
||||
curl -s -X POST "$SERVER_URL$UPLOAD_ENDPOINT/concurrent_test" \
|
||||
-F "file=@$TEST_DIR/concurrent_$i.zip" &
|
||||
done
|
||||
|
||||
# Wait for all to complete
|
||||
wait
|
||||
|
||||
end_time=$(date +%s%N)
|
||||
duration_ms=$(( (end_time - start_time) / 1000000 ))
|
||||
|
||||
echo "Total time for $count concurrent uploads: ${duration_ms}ms"
|
||||
echo "CONCURRENT|$count uploads|${duration_ms}ms" >> $LOG_FILE
|
||||
|
||||
# Cleanup
|
||||
rm -f $TEST_DIR/concurrent_*.zip
|
||||
}
|
||||
|
||||
# Main test execution
|
||||
echo ""
|
||||
echo "Starting performance tests..."
|
||||
echo "Log file: $LOG_FILE"
|
||||
echo ""
|
||||
|
||||
# Test 1: Small file (10MB)
|
||||
generate_test_zip 10 "test_10mb.zip"
|
||||
test_upload "$TEST_DIR/test_10mb.zip" "10MB ZIP file"
|
||||
|
||||
# Test 2: Medium file (100MB)
|
||||
generate_test_zip 100 "test_100mb.zip"
|
||||
test_upload "$TEST_DIR/test_100mb.zip" "100MB ZIP file"
|
||||
|
||||
# Test 3: Large file (1GB) - Optional, comment out if needed
|
||||
# generate_test_zip 1000 "test_1gb.zip"
|
||||
# test_upload "$TEST_DIR/test_1gb.zip" "1GB ZIP file"
|
||||
|
||||
# Test 4: Concurrent uploads (10)
|
||||
test_concurrent 10
|
||||
|
||||
# Test 5: Concurrent uploads (50)
|
||||
test_concurrent 50
|
||||
|
||||
echo ""
|
||||
echo "========================================="
|
||||
echo "Performance tests completed"
|
||||
echo "Results saved to: $LOG_FILE"
|
||||
echo "========================================="
|
||||
echo ""
|
||||
echo "Summary:"
|
||||
cat $LOG_FILE
|
||||
|
||||
# Cleanup
|
||||
rm -rf $TEST_DIR
|
||||
@@ -11,7 +11,7 @@ fn temp_db() -> (Connection, String) {
|
||||
#[test]
|
||||
fn test_api_create_folder_node() {
|
||||
let (conn, user_id) = temp_db();
|
||||
let mut tree = FileTree::load(&conn, &user_id).unwrap();
|
||||
let mut tree = FileTree::load(&conn, &user_id, "untitled folder").unwrap();
|
||||
|
||||
let label = "TestFolder";
|
||||
let node_type = NodeType::Folder;
|
||||
@@ -20,7 +20,7 @@ fn test_api_create_folder_node() {
|
||||
let node_id = folder.node_id.clone();
|
||||
tree.insert_node(&conn, &folder).unwrap();
|
||||
|
||||
let loaded = FileTree::load(&conn, &user_id).unwrap();
|
||||
let loaded = FileTree::load(&conn, &user_id, "untitled folder").unwrap();
|
||||
let found = loaded.nodes.iter().find(|n| n.node_id == node_id);
|
||||
|
||||
assert!(found.is_some());
|
||||
@@ -33,7 +33,7 @@ fn test_api_create_folder_node() {
|
||||
#[test]
|
||||
fn test_api_create_file_node() {
|
||||
let (conn, user_id) = temp_db();
|
||||
let mut tree = FileTree::load(&conn, &user_id).unwrap();
|
||||
let mut tree = FileTree::load(&conn, &user_id, "untitled folder").unwrap();
|
||||
|
||||
let parent = FileTree::new_folder("Parent", None);
|
||||
tree.insert_node(&conn, &parent).unwrap();
|
||||
@@ -56,7 +56,7 @@ fn test_api_create_file_node() {
|
||||
let node_id = file_node.node_id.clone();
|
||||
tree.insert_node(&conn, &file_node).unwrap();
|
||||
|
||||
let loaded = FileTree::load(&conn, &user_id).unwrap();
|
||||
let loaded = FileTree::load(&conn, &user_id, "untitled folder").unwrap();
|
||||
let found = loaded.nodes.iter().find(|n| n.node_id == node_id);
|
||||
|
||||
assert!(found.is_some());
|
||||
@@ -70,7 +70,7 @@ fn test_api_create_file_node() {
|
||||
#[test]
|
||||
fn test_api_update_node() {
|
||||
let (conn, user_id) = temp_db();
|
||||
let mut tree = FileTree::load(&conn, &user_id).unwrap();
|
||||
let mut tree = FileTree::load(&conn, &user_id, "untitled folder").unwrap();
|
||||
|
||||
let mut folder = FileTree::new_folder("Original", None);
|
||||
tree.insert_node(&conn, &folder).unwrap();
|
||||
@@ -81,7 +81,7 @@ fn test_api_update_node() {
|
||||
|
||||
tree.update_node(&conn, &folder.node_id, &folder).unwrap();
|
||||
|
||||
let loaded = FileTree::load(&conn, &user_id).unwrap();
|
||||
let loaded = FileTree::load(&conn, &user_id, "untitled folder").unwrap();
|
||||
let found = loaded.nodes.iter().find(|n| n.node_id == folder.node_id);
|
||||
|
||||
assert!(found.is_some());
|
||||
@@ -94,7 +94,7 @@ fn test_api_update_node() {
|
||||
#[test]
|
||||
fn test_api_delete_node() {
|
||||
let (conn, user_id) = temp_db();
|
||||
let mut tree = FileTree::load(&conn, &user_id).unwrap();
|
||||
let mut tree = FileTree::load(&conn, &user_id, "untitled folder").unwrap();
|
||||
|
||||
let folder = FileTree::new_folder("ToDelete", None);
|
||||
let node_id = folder.node_id.clone();
|
||||
@@ -102,7 +102,7 @@ fn test_api_delete_node() {
|
||||
|
||||
tree.delete_node(&conn, &node_id).unwrap();
|
||||
|
||||
let loaded = FileTree::load(&conn, &user_id).unwrap();
|
||||
let loaded = FileTree::load(&conn, &user_id, "untitled folder").unwrap();
|
||||
let found = loaded.nodes.iter().find(|n| n.node_id == node_id);
|
||||
|
||||
assert!(found.is_none(), "deleted node should not be found");
|
||||
@@ -111,7 +111,7 @@ fn test_api_delete_node() {
|
||||
#[test]
|
||||
fn test_api_move_node() {
|
||||
let (conn, user_id) = temp_db();
|
||||
let mut tree = FileTree::load(&conn, &user_id).unwrap();
|
||||
let mut tree = FileTree::load(&conn, &user_id, "untitled folder").unwrap();
|
||||
|
||||
let root = FileTree::new_folder("Root", None);
|
||||
let child = FileTree::new_folder("Child", Some(root.node_id.clone()));
|
||||
@@ -121,7 +121,7 @@ fn test_api_move_node() {
|
||||
|
||||
tree.move_node(&conn, &child.node_id, None).unwrap();
|
||||
|
||||
let loaded = FileTree::load(&conn, &user_id).unwrap();
|
||||
let loaded = FileTree::load(&conn, &user_id, "untitled folder").unwrap();
|
||||
let moved = loaded.nodes.iter().find(|n| n.node_id == child.node_id);
|
||||
|
||||
assert!(moved.is_some());
|
||||
@@ -134,7 +134,7 @@ fn test_api_move_node() {
|
||||
#[test]
|
||||
fn test_api_update_alias() {
|
||||
let (conn, user_id) = temp_db();
|
||||
let mut tree = FileTree::load(&conn, &user_id).unwrap();
|
||||
let mut tree = FileTree::load(&conn, &user_id, "untitled folder").unwrap();
|
||||
|
||||
let folder = FileTree::new_folder("Videos", None);
|
||||
tree.insert_node(&conn, &folder).unwrap();
|
||||
@@ -146,7 +146,7 @@ fn test_api_update_alias() {
|
||||
tree.update_node_alias(&conn, &folder.node_id, "ja_jp", "動画")
|
||||
.unwrap();
|
||||
|
||||
let loaded = FileTree::load(&conn, &user_id).unwrap();
|
||||
let loaded = FileTree::load(&conn, &user_id, "untitled folder").unwrap();
|
||||
let found = loaded.nodes.iter().find(|n| n.node_id == folder.node_id);
|
||||
|
||||
assert!(found.is_some());
|
||||
@@ -168,7 +168,7 @@ fn test_api_update_alias() {
|
||||
#[test]
|
||||
fn test_api_get_tree() {
|
||||
let (conn, user_id) = temp_db();
|
||||
let mut tree = FileTree::load(&conn, &user_id).unwrap();
|
||||
let mut tree = FileTree::load(&conn, &user_id, "untitled folder").unwrap();
|
||||
|
||||
let root = FileTree::new_folder("Root", None);
|
||||
let child1 = FileTree::new_folder("Child1", Some(root.node_id.clone()));
|
||||
@@ -178,7 +178,7 @@ fn test_api_get_tree() {
|
||||
tree.insert_node(&conn, &child1).unwrap();
|
||||
tree.insert_node(&conn, &child2).unwrap();
|
||||
|
||||
let loaded = FileTree::load(&conn, &user_id).unwrap();
|
||||
let loaded = FileTree::load(&conn, &user_id, "untitled folder").unwrap();
|
||||
assert_eq!(loaded.nodes.len(), 3);
|
||||
assert_eq!(loaded.user_id, user_id);
|
||||
}
|
||||
@@ -186,7 +186,7 @@ fn test_api_get_tree() {
|
||||
#[test]
|
||||
fn test_api_build_tree_structure() {
|
||||
let (conn, user_id) = temp_db();
|
||||
let mut tree = FileTree::load(&conn, &user_id).unwrap();
|
||||
let mut tree = FileTree::load(&conn, &user_id, "untitled folder").unwrap();
|
||||
|
||||
let root = FileTree::new_folder("Root", None);
|
||||
let child1 = FileTree::new_folder("Child1", Some(root.node_id.clone()));
|
||||
@@ -228,14 +228,14 @@ fn test_api_add_location() {
|
||||
#[test]
|
||||
fn test_api_delete_all_nodes() {
|
||||
let (conn, user_id) = temp_db();
|
||||
let mut tree = FileTree::load(&conn, &user_id).unwrap();
|
||||
let mut tree = FileTree::load(&conn, &user_id, "untitled folder").unwrap();
|
||||
|
||||
for i in 1..=5 {
|
||||
let folder = FileTree::new_folder(&format!("Folder{}", i), None);
|
||||
tree.insert_node(&conn, &folder).unwrap();
|
||||
}
|
||||
|
||||
let loaded = FileTree::load(&conn, &user_id).unwrap();
|
||||
let loaded = FileTree::load(&conn, &user_id, "untitled folder").unwrap();
|
||||
assert_eq!(loaded.nodes.len(), 5);
|
||||
|
||||
for node in &loaded.nodes {
|
||||
@@ -246,6 +246,6 @@ fn test_api_delete_all_nodes() {
|
||||
.unwrap();
|
||||
}
|
||||
|
||||
let after_delete = FileTree::load(&conn, &user_id).unwrap();
|
||||
let after_delete = FileTree::load(&conn, &user_id, "untitled folder").unwrap();
|
||||
assert_eq!(after_delete.nodes.len(), 0);
|
||||
}
|
||||
|
||||
@@ -11,7 +11,7 @@ fn temp_db() -> (Connection, String) {
|
||||
#[test]
|
||||
fn test_tree_mode_render() {
|
||||
let (conn, user_id) = temp_db();
|
||||
let mut tree = FileTree::load(&conn, &user_id).unwrap();
|
||||
let mut tree = FileTree::load(&conn, &user_id, "untitled folder").unwrap();
|
||||
|
||||
let root = FileTree::new_folder("Root", None);
|
||||
let child1 = FileTree::new_folder("Child1", Some(root.node_id.clone()));
|
||||
@@ -32,7 +32,7 @@ fn test_tree_mode_render() {
|
||||
#[test]
|
||||
fn test_list_mode_render() {
|
||||
let (conn, user_id) = temp_db();
|
||||
let mut tree = FileTree::load(&conn, &user_id).unwrap();
|
||||
let mut tree = FileTree::load(&conn, &user_id, "untitled folder").unwrap();
|
||||
|
||||
let folder = FileTree::new_folder("Videos", None);
|
||||
tree.insert_node(&conn, &folder).unwrap();
|
||||
@@ -48,7 +48,7 @@ fn test_list_mode_render() {
|
||||
#[test]
|
||||
fn test_grid_sm_mode_render() {
|
||||
let (conn, user_id) = temp_db();
|
||||
let mut tree = FileTree::load(&conn, &user_id).unwrap();
|
||||
let mut tree = FileTree::load(&conn, &user_id, "untitled folder").unwrap();
|
||||
|
||||
let folder = FileTree::new_folder("Images", None);
|
||||
tree.insert_node(&conn, &folder).unwrap();
|
||||
@@ -63,7 +63,7 @@ fn test_grid_sm_mode_render() {
|
||||
#[test]
|
||||
fn test_grid_lg_mode_render() {
|
||||
let (conn, user_id) = temp_db();
|
||||
let mut tree = FileTree::load(&conn, &user_id).unwrap();
|
||||
let mut tree = FileTree::load(&conn, &user_id, "untitled folder").unwrap();
|
||||
|
||||
let folder = FileTree::new_folder("Documents", None);
|
||||
tree.insert_node(&conn, &folder).unwrap();
|
||||
|
||||
49
tests/scp_sender_test.sh
Executable file
49
tests/scp_sender_test.sh
Executable file
@@ -0,0 +1,49 @@
|
||||
#!/bin/bash
|
||||
# SCP Sender测试脚本
|
||||
|
||||
echo "=== MarkBase SCP Sender测试 ==="
|
||||
|
||||
# 启动MarkBase SSH服务器
|
||||
echo "1. 启动SSH服务器..."
|
||||
cargo run --bin markbase-core -- sftp --user warren &
|
||||
SSH_PID=$!
|
||||
sleep 2
|
||||
|
||||
# 测试SCP下载
|
||||
echo "2. 测试SCP下载(scp -f)..."
|
||||
TEST_FILE="/Users/accusys/momentry/var/sftpgo/data/warren/Home/download-1.jpg"
|
||||
|
||||
if [ -f "$TEST_FILE" ]; then
|
||||
echo " 测试文件: $TEST_FILE"
|
||||
|
||||
# SCP下载命令(从服务器下载)
|
||||
scp -P 2023 warren@127.0.0.1:$TEST_FILE /tmp/scp_test.jpg
|
||||
|
||||
if [ -f "/tmp/scp_test.jpg" ]; then
|
||||
echo " ✅ SCP下载成功"
|
||||
ls -lh /tmp/scp_test.jpg
|
||||
|
||||
# 检查文件大小是否匹配
|
||||
ORIG_SIZE=$(stat -f%z "$TEST_FILE")
|
||||
COPY_SIZE=$(stat -f%z "/tmp/scp_test.jpg")
|
||||
|
||||
if [ "$ORIG_SIZE" == "$COPY_SIZE" ]; then
|
||||
echo " ✅ 文件大小匹配: $ORIG_SIZE bytes"
|
||||
else
|
||||
echo " ❌ 文件大小不匹配: $ORIG_SIZE vs $COPY_SIZE"
|
||||
fi
|
||||
|
||||
# 清理测试文件
|
||||
rm /tmp/scp_test.jpg
|
||||
else
|
||||
echo " ❌ SCP下载失败"
|
||||
fi
|
||||
else
|
||||
echo " ⚠️ 测试文件不存在: $TEST_FILE"
|
||||
fi
|
||||
|
||||
# 清理
|
||||
echo "3. 清理..."
|
||||
kill $SSH_PID 2>/dev/null
|
||||
|
||||
echo "=== 测试完成 ==="
|
||||
52
tests/sftp_test.sh
Executable file
52
tests/sftp_test.sh
Executable file
@@ -0,0 +1,52 @@
|
||||
#!/bin/bash
|
||||
|
||||
echo "=== MarkBase SFTP完整测试 ==="
|
||||
echo ""
|
||||
|
||||
# 启动SFTP服务器(后台)
|
||||
echo "1. 启动SFTP服务器(port 2023, user warren)..."
|
||||
cargo run --bin markbase-core -- sftp --user warren --port 2023 > /tmp/sftp_server.log 2>&1 &
|
||||
SERVER_PID=$!
|
||||
echo "Server PID: $SERVER_PID"
|
||||
sleep 3
|
||||
|
||||
# 检查服务器是否启动
|
||||
if ! lsof -ti:2023 > /dev/null; then
|
||||
echo "❌ SFTP服务器启动失败"
|
||||
cat /tmp/sftp_server.log
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo "✅ SFTP服务器启动成功"
|
||||
echo ""
|
||||
|
||||
# 测试bcrypt验证
|
||||
echo "2. 测试bcrypt密码验证..."
|
||||
cargo run --bin markbase-core -- bcrypt-test --password demo123
|
||||
echo ""
|
||||
|
||||
# 测试SFTP登录(使用sshpass)
|
||||
echo "3. 测试SFTP登录(用户warren,密码demo123)..."
|
||||
if command -v sshpass > /dev/null; then
|
||||
sshpass -p 'demo123' sftp -P 2023 -o StrictHostKeyChecking=no warren@127.0.0.1 << 'EOF'
|
||||
ls
|
||||
quit
|
||||
EOF
|
||||
else
|
||||
echo "⚠️ sshpass未安装,使用手动测试"
|
||||
echo "手动测试命令:"
|
||||
echo "sftp -P 2023 warren@127.0.0.1"
|
||||
echo "密码:demo123"
|
||||
fi
|
||||
|
||||
echo ""
|
||||
|
||||
# 停止服务器
|
||||
echo "4. 停止SFTP服务器..."
|
||||
kill $SERVER_PID 2>/dev/null
|
||||
sleep 1
|
||||
echo "✅ 测试完成"
|
||||
|
||||
echo ""
|
||||
echo "查看服务器日志:"
|
||||
echo "cat /tmp/sftp_server.log"
|
||||
Reference in New Issue
Block a user