2025-06-07 17:56:45 +08:00
|
|
|
|
package document
|
|
|
|
|
|
|
|
|
|
import (
|
2025-06-07 18:13:29 +08:00
|
|
|
|
"fmt"
|
2025-06-07 17:56:45 +08:00
|
|
|
|
"os"
|
2025-06-08 10:31:34 +08:00
|
|
|
|
"path/filepath"
|
2025-06-07 18:13:29 +08:00
|
|
|
|
"sync"
|
2025-06-07 17:56:45 +08:00
|
|
|
|
"testing"
|
2025-06-08 10:31:34 +08:00
|
|
|
|
|
|
|
|
|
"git.pyer.club/kingecg/godocdb/storage"
|
|
|
|
|
"git.pyer.club/kingecg/godocdb/utils"
|
2025-06-07 17:56:45 +08:00
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
// 测试用结构体
|
|
|
|
|
type TestDoc struct {
|
|
|
|
|
ID string `bson:"_id"`
|
|
|
|
|
Name string `bson:"name"`
|
|
|
|
|
Age int `bson:"age"`
|
|
|
|
|
}
|
|
|
|
|
|
2025-06-08 10:31:34 +08:00
|
|
|
|
func TestMain(m *testing.M) {
|
|
|
|
|
projectRoot := utils.GetProjectRootDir()
|
|
|
|
|
dir := filepath.Join(projectRoot, "test_data")
|
|
|
|
|
defer os.RemoveAll(dir)
|
|
|
|
|
storage.NewStorageManager(dir, 0)
|
|
|
|
|
m.Run()
|
|
|
|
|
storage.GetInstance().Close()
|
|
|
|
|
}
|
|
|
|
|
|
2025-06-07 17:56:45 +08:00
|
|
|
|
func TestDocumentStore(t *testing.T) {
|
|
|
|
|
// 测试目录
|
|
|
|
|
|
|
|
|
|
// 初始化文档存储
|
2025-06-08 10:31:34 +08:00
|
|
|
|
ds, err := NewDocumentStore("test")
|
2025-06-07 17:56:45 +08:00
|
|
|
|
if err != nil {
|
|
|
|
|
t.Fatalf("Failed to create document store: %v", err)
|
|
|
|
|
}
|
|
|
|
|
defer ds.storage.Close()
|
|
|
|
|
|
2025-06-07 22:28:29 +08:00
|
|
|
|
// 测试文档ID和数据
|
|
|
|
|
docID := "doc123"
|
|
|
|
|
doc := map[string]interface{}{
|
|
|
|
|
"_id": docID,
|
|
|
|
|
"name": "Test Document",
|
2025-06-07 17:56:45 +08:00
|
|
|
|
}
|
|
|
|
|
|
2025-06-07 22:28:29 +08:00
|
|
|
|
// 测试基本操作(使用默认collection)
|
|
|
|
|
collection := "test_collection"
|
|
|
|
|
if err := ds.StoreDocument(collection, docID, doc); err != nil {
|
2025-06-07 17:56:45 +08:00
|
|
|
|
t.Errorf("StoreDocument failed: %v", err)
|
|
|
|
|
}
|
|
|
|
|
|
2025-06-07 22:28:29 +08:00
|
|
|
|
// 验证存储结果
|
|
|
|
|
var result map[string]interface{}
|
|
|
|
|
if err := ds.GetDocument(collection, docID, &result); err != nil {
|
2025-06-07 17:56:45 +08:00
|
|
|
|
t.Errorf("GetDocument failed: %v", err)
|
|
|
|
|
}
|
|
|
|
|
|
2025-06-07 22:28:29 +08:00
|
|
|
|
// 验证删除功能
|
|
|
|
|
if err := ds.DeleteDocument(collection, docID); err != nil {
|
2025-06-07 17:56:45 +08:00
|
|
|
|
t.Errorf("DeleteDocument failed: %v", err)
|
|
|
|
|
}
|
|
|
|
|
|
2025-06-07 22:28:29 +08:00
|
|
|
|
// 删除后验证
|
|
|
|
|
if err := ds.GetDocument(collection, docID, &result); err == nil {
|
|
|
|
|
t.Error("Expected error after DeleteDocument")
|
2025-06-07 17:56:45 +08:00
|
|
|
|
}
|
2025-06-07 18:13:29 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func TestErrorHandling(t *testing.T) {
|
|
|
|
|
|
2025-06-08 10:31:34 +08:00
|
|
|
|
ds, _ := NewDocumentStore("test_error")
|
2025-06-07 22:28:29 +08:00
|
|
|
|
|
|
|
|
|
// 测试存储非map文档
|
2025-06-07 18:13:29 +08:00
|
|
|
|
invalidDoc := struct {
|
|
|
|
|
F func()
|
|
|
|
|
}{}
|
|
|
|
|
|
2025-06-07 22:28:29 +08:00
|
|
|
|
if err := ds.StoreDocument("invalid", "doc1", invalidDoc); err == nil {
|
2025-06-07 18:13:29 +08:00
|
|
|
|
t.Error("Expected error for invalid document")
|
|
|
|
|
}
|
2025-06-07 22:28:29 +08:00
|
|
|
|
|
|
|
|
|
// 测试存储nil文档
|
|
|
|
|
if err := ds.StoreDocument("invalid", "doc2", nil); err == nil {
|
|
|
|
|
t.Error("Expected error for nil document")
|
|
|
|
|
}
|
2025-06-07 18:13:29 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func TestConcurrentAccess(t *testing.T) {
|
|
|
|
|
// 测试并发写入同一ID
|
2025-06-08 10:31:34 +08:00
|
|
|
|
dir := "testdb_concurrent"
|
2025-06-07 18:13:29 +08:00
|
|
|
|
|
|
|
|
|
numGoroutines := 10
|
|
|
|
|
var wg sync.WaitGroup
|
|
|
|
|
key := "concurrent_test"
|
|
|
|
|
|
2025-06-07 22:28:29 +08:00
|
|
|
|
ds, err := NewDocumentStore(dir)
|
|
|
|
|
if err != nil {
|
|
|
|
|
t.Fatalf("Failed to create document store: %v", err)
|
|
|
|
|
}
|
2025-06-08 10:31:34 +08:00
|
|
|
|
// defer ds.storage.Close()
|
2025-06-07 22:28:29 +08:00
|
|
|
|
|
2025-06-07 18:13:29 +08:00
|
|
|
|
wg.Add(numGoroutines)
|
|
|
|
|
|
|
|
|
|
for i := 0; i < numGoroutines; i++ {
|
|
|
|
|
go func(i int) {
|
|
|
|
|
defer wg.Done()
|
2025-06-07 22:28:29 +08:00
|
|
|
|
testDoc := map[string]interface{}{
|
|
|
|
|
"_id": key,
|
|
|
|
|
"name": fmt.Sprintf("Test%d", i),
|
2025-06-07 18:13:29 +08:00
|
|
|
|
}
|
2025-06-07 22:28:29 +08:00
|
|
|
|
err := ds.StoreDocument(key, fmt.Sprintf("doc%d", i), testDoc)
|
2025-06-07 18:13:29 +08:00
|
|
|
|
if err != nil {
|
|
|
|
|
t.Errorf("StoreDocument failed: %v", err)
|
|
|
|
|
}
|
|
|
|
|
}(i)
|
|
|
|
|
}
|
|
|
|
|
wg.Wait()
|
|
|
|
|
|
|
|
|
|
// 验证最终值是否为最后一个写入
|
2025-06-07 22:28:29 +08:00
|
|
|
|
var result map[string]interface{}
|
|
|
|
|
if err := ds.GetDocument(key, "doc9", &result); err != nil {
|
2025-06-07 18:13:29 +08:00
|
|
|
|
t.Errorf("GetDocument failed: %v", err)
|
|
|
|
|
}
|
|
|
|
|
}
|