205 lines
6.4 KiB
Go
205 lines
6.4 KiB
Go
package agate
|
|
|
|
import (
|
|
"context"
|
|
"os"
|
|
"path/filepath"
|
|
"testing"
|
|
"time"
|
|
|
|
"gitea.unprism.ru/KRBL/Agate/remote"
|
|
"gitea.unprism.ru/KRBL/Agate/store"
|
|
)
|
|
|
|
// TestGRPCServerClient tests the interaction between a gRPC server and client.
|
|
// It creates multiple snapshots with different content on the server,
|
|
// connects a client to the server, downloads the latest snapshot,
|
|
// and verifies the contents of the files.
|
|
func TestGRPCServerClient(t *testing.T) {
|
|
// Skip this test in short mode
|
|
if testing.Short() {
|
|
t.Skip("Skipping gRPC server-client test in short mode")
|
|
}
|
|
|
|
// Create a temporary directory for the server
|
|
serverDir, err := os.MkdirTemp("", "agate-server-*")
|
|
if err != nil {
|
|
t.Fatalf("Failed to create server temp directory: %v", err)
|
|
}
|
|
defer os.RemoveAll(serverDir)
|
|
|
|
// Create a temporary directory for the client
|
|
clientDir, err := os.MkdirTemp("", "agate-client-*")
|
|
if err != nil {
|
|
t.Fatalf("Failed to create client temp directory: %v", err)
|
|
}
|
|
defer os.RemoveAll(clientDir)
|
|
|
|
// Create Agate options for the server
|
|
serverOptions := AgateOptions{
|
|
WorkDir: serverDir,
|
|
}
|
|
|
|
// Create Agate instance for the server
|
|
serverAgate, err := New(serverOptions)
|
|
if err != nil {
|
|
t.Fatalf("Failed to create server Agate instance: %v", err)
|
|
}
|
|
defer serverAgate.Close()
|
|
|
|
// Create a data directory
|
|
dataDir := serverAgate.options.BlobStore.GetActiveDir()
|
|
if err := os.MkdirAll(dataDir, 0755); err != nil {
|
|
t.Fatalf("Failed to create data directory: %v", err)
|
|
}
|
|
|
|
// Create initial test files for the first snapshot
|
|
initialFiles := map[string]string{
|
|
filepath.Join(dataDir, "file1.txt"): "Initial content of file 1",
|
|
filepath.Join(dataDir, "file2.txt"): "Initial content of file 2",
|
|
filepath.Join(dataDir, "subdir", "file3.txt"): "Initial content of file 3",
|
|
}
|
|
|
|
// Create subdirectory
|
|
if err := os.MkdirAll(filepath.Join(dataDir, "subdir"), 0755); err != nil {
|
|
t.Fatalf("Failed to create subdirectory: %v", err)
|
|
}
|
|
|
|
// Create the files
|
|
for path, content := range initialFiles {
|
|
if err := os.WriteFile(path, []byte(content), 0644); err != nil {
|
|
t.Fatalf("Failed to create test file %s: %v", path, err)
|
|
}
|
|
}
|
|
|
|
// Create the first snapshot
|
|
ctx := context.Background()
|
|
snapshot1ID, err := serverAgate.SaveSnapshot(ctx, "Snapshot 1", "")
|
|
if err != nil {
|
|
t.Fatalf("Failed to create first snapshot: %v", err)
|
|
}
|
|
t.Logf("Created first snapshot with ID: %s", snapshot1ID)
|
|
|
|
// Modify some files and add a new file for the second snapshot
|
|
modifiedFiles := map[string]string{
|
|
filepath.Join(dataDir, "file1.txt"): "Modified content of file 1",
|
|
filepath.Join(dataDir, "file4.txt"): "Content of new file 4",
|
|
}
|
|
|
|
for path, content := range modifiedFiles {
|
|
if err := os.WriteFile(path, []byte(content), 0644); err != nil {
|
|
t.Fatalf("Failed to modify/create test file %s: %v", path, err)
|
|
}
|
|
}
|
|
|
|
// Create the second snapshot
|
|
snapshot2ID, err := serverAgate.SaveSnapshot(ctx, "Snapshot 2", snapshot1ID)
|
|
if err != nil {
|
|
t.Fatalf("Failed to create second snapshot: %v", err)
|
|
}
|
|
t.Logf("Created second snapshot with ID: %s", snapshot2ID)
|
|
|
|
// Delete a file and modify another for the third snapshot
|
|
if err := os.Remove(filepath.Join(dataDir, "file2.txt")); err != nil {
|
|
t.Fatalf("Failed to delete test file: %v", err)
|
|
}
|
|
|
|
if err := os.WriteFile(filepath.Join(dataDir, "subdir/file3.txt"), []byte("Modified content of file 3"), 0644); err != nil {
|
|
t.Fatalf("Failed to modify test file: %v", err)
|
|
}
|
|
|
|
// Create the third snapshot
|
|
snapshot3ID, err := serverAgate.SaveSnapshot(ctx, "Snapshot 3", snapshot2ID)
|
|
if err != nil {
|
|
t.Fatalf("Failed to create third snapshot: %v", err)
|
|
}
|
|
t.Logf("Created third snapshot with ID: %s", snapshot3ID)
|
|
|
|
// Start the gRPC server
|
|
serverAddress := "localhost:50051"
|
|
server, err := remote.RunServer(ctx, serverAgate.manager, serverAddress)
|
|
if err != nil {
|
|
t.Fatalf("Failed to start gRPC server: %v", err)
|
|
}
|
|
defer server.Stop(ctx)
|
|
|
|
// Give the server a moment to start
|
|
time.Sleep(100 * time.Millisecond)
|
|
|
|
// Connect a client to the server
|
|
client, err := remote.NewClient(serverAddress)
|
|
if err != nil {
|
|
t.Fatalf("Failed to connect client to server: %v", err)
|
|
}
|
|
defer client.Close()
|
|
|
|
// List snapshots from the client
|
|
snapshots, err := client.ListSnapshots(ctx)
|
|
if err != nil {
|
|
t.Fatalf("Failed to list snapshots from client: %v", err)
|
|
}
|
|
|
|
// Verify we have 3 snapshots
|
|
if len(snapshots) != 3 {
|
|
t.Errorf("Expected 3 snapshots, got %d", len(snapshots))
|
|
}
|
|
|
|
// Find the latest snapshot (should be snapshot3)
|
|
var latestSnapshot store.SnapshotInfo
|
|
for _, snapshot := range snapshots {
|
|
if latestSnapshot.CreationTime.Before(snapshot.CreationTime) {
|
|
latestSnapshot = snapshot
|
|
}
|
|
}
|
|
|
|
// Verify the latest snapshot is snapshot3
|
|
if latestSnapshot.ID != snapshot3ID {
|
|
t.Errorf("Latest snapshot ID is %s, expected %s", latestSnapshot.ID, snapshot3ID)
|
|
}
|
|
|
|
// Get detailed information about the latest snapshot
|
|
snapshotDetails, err := client.FetchSnapshotDetails(ctx, latestSnapshot.ID)
|
|
if err != nil {
|
|
t.Fatalf("Failed to fetch snapshot details: %v", err)
|
|
}
|
|
|
|
// Verify the snapshot details
|
|
if snapshotDetails.ID != snapshot3ID {
|
|
t.Errorf("Snapshot details ID is %s, expected %s", snapshotDetails.ID, snapshot3ID)
|
|
}
|
|
|
|
// Create a directory to download the snapshot to
|
|
downloadDir := filepath.Join(clientDir, "download")
|
|
if err := os.MkdirAll(downloadDir, 0755); err != nil {
|
|
t.Fatalf("Failed to create download directory: %v", err)
|
|
}
|
|
|
|
// Download the snapshot
|
|
err = client.DownloadSnapshot(ctx, latestSnapshot.ID, downloadDir, "")
|
|
if err != nil {
|
|
t.Fatalf("Failed to download snapshot: %v", err)
|
|
}
|
|
|
|
// Verify the downloaded files match the expected content
|
|
expectedFiles := map[string]string{
|
|
filepath.Join(downloadDir, "file1.txt"): "Modified content of file 1",
|
|
filepath.Join(downloadDir, "file4.txt"): "Content of new file 4",
|
|
filepath.Join(downloadDir, "subdir/file3.txt"): "Modified content of file 3",
|
|
}
|
|
|
|
for path, expectedContent := range expectedFiles {
|
|
content, err := os.ReadFile(path)
|
|
if err != nil {
|
|
t.Fatalf("Failed to read downloaded file %s: %v", path, err)
|
|
}
|
|
if string(content) != expectedContent {
|
|
t.Errorf("Downloaded file %s has wrong content: got %s, want %s", path, string(content), expectedContent)
|
|
}
|
|
}
|
|
|
|
// Verify that file2.txt doesn't exist in the downloaded snapshot
|
|
if _, err := os.Stat(filepath.Join(downloadDir, "file2.txt")); !os.IsNotExist(err) {
|
|
t.Errorf("file2.txt should not exist in the downloaded snapshot")
|
|
}
|
|
}
|