mirror of
https://github.com/Awuqing/BackupX.git
synced 2026-06-13 13:49:38 +08:00
通过 mongodump/mongorestore --archive 流式管线接入 MongoDB 数据源,与现有数据库运行器架构一致;注册到 Master 与 Agent,含任务校验、默认端口与前端表单/恢复确认。5 个单测覆盖参数构造、全库、空产物与缺工具分支。
103 lines
3.8 KiB
Go
103 lines
3.8 KiB
Go
package backup
|
|
|
|
import (
|
|
"context"
|
|
"errors"
|
|
"io"
|
|
"os"
|
|
"strings"
|
|
"testing"
|
|
)
|
|
|
|
func argIndex(args []string, target string) int {
|
|
for i, a := range args {
|
|
if a == target {
|
|
return i
|
|
}
|
|
}
|
|
return -1
|
|
}
|
|
|
|
func TestMongoDBRunnerRunUsesMongodump(t *testing.T) {
|
|
executor := &fakeCommandExecutor{runFunc: func(name string, args []string, options CommandOptions) error {
|
|
if options.Stdout != nil {
|
|
_, _ = io.WriteString(options.Stdout, "mongo archive bytes")
|
|
}
|
|
return nil
|
|
}}
|
|
runner := NewMongoDBRunner(executor)
|
|
result, err := runner.Run(context.Background(), TaskSpec{Name: "mongo", Type: "mongodb", Database: DatabaseSpec{Host: "127.0.0.1", Port: 27017, User: "admin", Password: "secret", Names: []string{"app"}}}, NopLogWriter{})
|
|
if err != nil {
|
|
t.Fatalf("Run returned error: %v", err)
|
|
}
|
|
if executor.lastName != "mongodump" {
|
|
t.Fatalf("expected mongodump, got %s", executor.lastName)
|
|
}
|
|
args := executor.lastArgs
|
|
if argIndex(args, "--archive") < 0 {
|
|
t.Fatalf("expected --archive flag, got %#v", args)
|
|
}
|
|
if i := argIndex(args, "--db"); i < 0 || i+1 >= len(args) || args[i+1] != "app" {
|
|
t.Fatalf("expected --db app, got %#v", args)
|
|
}
|
|
if i := argIndex(args, "--username"); i < 0 || args[i+1] != "admin" {
|
|
t.Fatalf("expected --username admin, got %#v", args)
|
|
}
|
|
if argIndex(args, "--authenticationDatabase") < 0 || argIndex(args, "--password") < 0 {
|
|
t.Fatalf("expected auth args, got %#v", args)
|
|
}
|
|
if _, err := os.Stat(result.ArtifactPath); err != nil {
|
|
t.Fatalf("artifact file missing: %v", err)
|
|
}
|
|
if result.StorageKey == "" || !strings.HasSuffix(result.FileName, ".archive") {
|
|
t.Fatalf("unexpected result metadata: %#v", result)
|
|
}
|
|
}
|
|
|
|
func TestMongoDBRunnerRunBackupsAllWhenNoDatabase(t *testing.T) {
|
|
executor := &fakeCommandExecutor{runFunc: func(name string, args []string, options CommandOptions) error {
|
|
_, _ = io.WriteString(options.Stdout, "all dbs")
|
|
return nil
|
|
}}
|
|
runner := NewMongoDBRunner(executor)
|
|
_, err := runner.Run(context.Background(), TaskSpec{Name: "mongo", Type: "mongodb", Database: DatabaseSpec{Host: "127.0.0.1", Port: 27017}}, NopLogWriter{})
|
|
if err != nil {
|
|
t.Fatalf("Run returned error: %v", err)
|
|
}
|
|
if argIndex(executor.lastArgs, "--db") >= 0 {
|
|
t.Fatalf("expected no --db when backing up all databases, got %#v", executor.lastArgs)
|
|
}
|
|
}
|
|
|
|
func TestMongoDBRunnerRunRejectsEmptyOutput(t *testing.T) {
|
|
executor := &fakeCommandExecutor{} // runFunc nil → writes nothing
|
|
runner := NewMongoDBRunner(executor)
|
|
_, err := runner.Run(context.Background(), TaskSpec{Name: "mongo", Type: "mongodb", Database: DatabaseSpec{Host: "127.0.0.1", Port: 27017, Names: []string{"app"}}}, NopLogWriter{})
|
|
if err == nil {
|
|
t.Fatal("expected error for empty mongodump output")
|
|
}
|
|
}
|
|
|
|
func TestMongoDBRunnerRestoreUsesMongorestore(t *testing.T) {
|
|
executor := &fakeCommandExecutor{}
|
|
runner := NewMongoDBRunner(executor)
|
|
artifact := filepathJoinTempFile(t, "dump.archive", "mongo archive bytes")
|
|
if err := runner.Restore(context.Background(), TaskSpec{Name: "mongo", Type: "mongodb", Database: DatabaseSpec{Host: "127.0.0.1", Port: 27017, User: "admin", Password: "secret"}}, artifact, NopLogWriter{}); err != nil {
|
|
t.Fatalf("Restore returned error: %v", err)
|
|
}
|
|
if executor.lastName != "mongorestore" {
|
|
t.Fatalf("expected mongorestore, got %s", executor.lastName)
|
|
}
|
|
if argIndex(executor.lastArgs, "--drop") < 0 || argIndex(executor.lastArgs, "--archive") < 0 {
|
|
t.Fatalf("expected --drop --archive, got %#v", executor.lastArgs)
|
|
}
|
|
}
|
|
|
|
func TestMongoDBRunnerRunReturnsLookupError(t *testing.T) {
|
|
runner := NewMongoDBRunner(&fakeCommandExecutor{lookupErr: errors.New("missing")})
|
|
_, err := runner.Run(context.Background(), TaskSpec{Name: "mongo", Type: "mongodb", Database: DatabaseSpec{Host: "127.0.0.1", Port: 27017, Names: []string{"app"}}}, NopLogWriter{})
|
|
if err == nil {
|
|
t.Fatal("expected error when mongodump is missing")
|
|
}
|
|
}
|