You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
244 lines
5.6 KiB
244 lines
5.6 KiB
package spider |
|
|
|
import ( |
|
"context" |
|
"os" |
|
"testing" |
|
"time" |
|
|
|
"next.orly.dev/pkg/database" |
|
) |
|
|
|
func TestSpiderCreation(t *testing.T) { |
|
ctx, cancel := context.WithCancel(context.Background()) |
|
defer cancel() |
|
|
|
// Create a temporary database for testing |
|
tempDir, err := os.MkdirTemp("", "spider-test-*") |
|
if err != nil { |
|
t.Fatalf("Failed to create temp dir: %v", err) |
|
} |
|
defer os.RemoveAll(tempDir) |
|
|
|
db, err := database.New(ctx, cancel, tempDir, "error") |
|
if err != nil { |
|
t.Fatalf("Failed to create test database: %v", err) |
|
} |
|
defer db.Close() |
|
|
|
// Test spider creation |
|
spider, err := New(ctx, db, nil, "follows") |
|
if err != nil { |
|
t.Fatalf("Failed to create spider: %v", err) |
|
} |
|
|
|
if spider == nil { |
|
t.Fatal("Spider is nil") |
|
} |
|
|
|
// Test that spider is not running initially |
|
spider.mu.RLock() |
|
running := spider.running |
|
spider.mu.RUnlock() |
|
|
|
if running { |
|
t.Error("Spider should not be running initially") |
|
} |
|
} |
|
|
|
func TestSpiderCallbacks(t *testing.T) { |
|
ctx, cancel := context.WithCancel(context.Background()) |
|
defer cancel() |
|
|
|
// Create a temporary database for testing |
|
tempDir, err := os.MkdirTemp("", "spider-test-*") |
|
if err != nil { |
|
t.Fatalf("Failed to create temp dir: %v", err) |
|
} |
|
defer os.RemoveAll(tempDir) |
|
|
|
db, err := database.New(ctx, cancel, tempDir, "error") |
|
if err != nil { |
|
t.Fatalf("Failed to create test database: %v", err) |
|
} |
|
defer db.Close() |
|
|
|
spider, err := New(ctx, db, nil, "follows") |
|
if err != nil { |
|
t.Fatalf("Failed to create spider: %v", err) |
|
} |
|
|
|
// Test callback setup |
|
testRelays := []string{"wss://relay1.example.com", "wss://relay2.example.com"} |
|
testPubkeys := [][]byte{{1, 2, 3}, {4, 5, 6}} |
|
|
|
spider.SetCallbacks( |
|
func() []string { return testRelays }, |
|
func() [][]byte { return testPubkeys }, |
|
) |
|
|
|
// Verify callbacks are set |
|
spider.mu.RLock() |
|
hasCallbacks := spider.getAdminRelays != nil && spider.getFollowList != nil |
|
spider.mu.RUnlock() |
|
|
|
if !hasCallbacks { |
|
t.Error("Callbacks should be set") |
|
} |
|
|
|
// Test that start fails without callbacks being set first |
|
spider2, err := New(ctx, db, nil, "follows") |
|
if err != nil { |
|
t.Fatalf("Failed to create second spider: %v", err) |
|
} |
|
|
|
err = spider2.Start() |
|
if err == nil { |
|
t.Error("Start should fail when callbacks are not set") |
|
} |
|
} |
|
|
|
func TestSpiderModeValidation(t *testing.T) { |
|
ctx, cancel := context.WithCancel(context.Background()) |
|
defer cancel() |
|
|
|
// Create a temporary database for testing |
|
tempDir, err := os.MkdirTemp("", "spider-test-*") |
|
if err != nil { |
|
t.Fatalf("Failed to create temp dir: %v", err) |
|
} |
|
defer os.RemoveAll(tempDir) |
|
|
|
db, err := database.New(ctx, cancel, tempDir, "error") |
|
if err != nil { |
|
t.Fatalf("Failed to create test database: %v", err) |
|
} |
|
defer db.Close() |
|
|
|
// Test valid mode |
|
spider, err := New(ctx, db, nil, "follows") |
|
if err != nil { |
|
t.Fatalf("Failed to create spider with valid mode: %v", err) |
|
} |
|
if spider == nil { |
|
t.Fatal("Spider should not be nil for valid mode") |
|
} |
|
|
|
// Test invalid mode |
|
_, err = New(ctx, db, nil, "invalid") |
|
if err == nil { |
|
t.Error("Should fail with invalid mode") |
|
} |
|
|
|
// Test none mode (should succeed but be a no-op) |
|
spider2, err := New(ctx, db, nil, "none") |
|
if err != nil { |
|
t.Errorf("Should succeed with 'none' mode: %v", err) |
|
} |
|
if spider2 == nil { |
|
t.Error("Spider should not be nil for 'none' mode") |
|
} |
|
|
|
// Test that 'none' mode doesn't require callbacks |
|
err = spider2.Start() |
|
if err != nil { |
|
t.Errorf("'none' mode should start without callbacks: %v", err) |
|
} |
|
} |
|
|
|
func TestSpiderBatching(t *testing.T) { |
|
// Test batch creation logic |
|
followList := make([][]byte, 50) // 50 pubkeys |
|
for i := range followList { |
|
followList[i] = make([]byte, 32) |
|
for j := range followList[i] { |
|
followList[i][j] = byte(i) |
|
} |
|
} |
|
|
|
ctx, cancel := context.WithCancel(context.Background()) |
|
defer cancel() |
|
|
|
rc := &RelayConnection{ |
|
url: "wss://test.relay.com", |
|
ctx: ctx, |
|
} |
|
|
|
batches := rc.createBatches(followList) |
|
|
|
// Should create 3 batches: 20, 20, 10 |
|
expectedBatches := 3 |
|
if len(batches) != expectedBatches { |
|
t.Errorf("Expected %d batches, got %d", expectedBatches, len(batches)) |
|
} |
|
|
|
// Check batch sizes |
|
if len(batches[0]) != BatchSize { |
|
t.Errorf("First batch should have %d pubkeys, got %d", BatchSize, len(batches[0])) |
|
} |
|
if len(batches[1]) != BatchSize { |
|
t.Errorf("Second batch should have %d pubkeys, got %d", BatchSize, len(batches[1])) |
|
} |
|
if len(batches[2]) != 10 { |
|
t.Errorf("Third batch should have 10 pubkeys, got %d", len(batches[2])) |
|
} |
|
} |
|
|
|
func TestSpiderStartStop(t *testing.T) { |
|
ctx, cancel := context.WithCancel(context.Background()) |
|
defer cancel() |
|
|
|
// Create a temporary database for testing |
|
tempDir, err := os.MkdirTemp("", "spider-test-*") |
|
if err != nil { |
|
t.Fatalf("Failed to create temp dir: %v", err) |
|
} |
|
defer os.RemoveAll(tempDir) |
|
|
|
db, err := database.New(ctx, cancel, tempDir, "error") |
|
if err != nil { |
|
t.Fatalf("Failed to create test database: %v", err) |
|
} |
|
defer db.Close() |
|
|
|
spider, err := New(ctx, db, nil, "follows") |
|
if err != nil { |
|
t.Fatalf("Failed to create spider: %v", err) |
|
} |
|
|
|
// Set up callbacks |
|
spider.SetCallbacks( |
|
func() []string { return []string{"wss://test.relay.com"} }, |
|
func() [][]byte { return [][]byte{{1, 2, 3}} }, |
|
) |
|
|
|
// Test start |
|
err = spider.Start() |
|
if err != nil { |
|
t.Fatalf("Failed to start spider: %v", err) |
|
} |
|
|
|
// Verify spider is running |
|
spider.mu.RLock() |
|
running := spider.running |
|
spider.mu.RUnlock() |
|
|
|
if !running { |
|
t.Error("Spider should be running after start") |
|
} |
|
|
|
// Test stop |
|
spider.Stop() |
|
|
|
// Give it a moment to stop |
|
time.Sleep(100 * time.Millisecond) |
|
|
|
// Verify spider is stopped |
|
spider.mu.RLock() |
|
running = spider.running |
|
spider.mu.RUnlock() |
|
|
|
if running { |
|
t.Error("Spider should not be running after stop") |
|
} |
|
}
|
|
|