mirror of
https://tangled.org/evan.jarrett.net/at-container-registry
synced 2026-08-31 13:17:09 +00:00
148 lines
3.8 KiB
Go
148 lines
3.8 KiB
Go
package atproto
|
|
|
|
import (
|
|
"sync"
|
|
"testing"
|
|
)
|
|
|
|
func TestGetDirectorySingleton(t *testing.T) {
|
|
t.Run("returns non-nil directory", func(t *testing.T) {
|
|
dir := GetDirectory()
|
|
if dir == nil {
|
|
t.Fatal("GetDirectory() returned nil")
|
|
}
|
|
})
|
|
|
|
t.Run("singleton behavior - same instance", func(t *testing.T) {
|
|
// Get directory twice
|
|
dir1 := GetDirectory()
|
|
dir2 := GetDirectory()
|
|
|
|
// They should be the exact same instance (same pointer)
|
|
if dir1 != dir2 {
|
|
t.Error("GetDirectory() returned different instances, expected singleton")
|
|
}
|
|
})
|
|
}
|
|
|
|
func TestGetDirectoryConcurrency(t *testing.T) {
|
|
t.Run("concurrent access is thread-safe", func(t *testing.T) {
|
|
const numGoroutines = 100
|
|
var wg sync.WaitGroup
|
|
|
|
// Channel to collect all directory instances
|
|
instances := make(chan any, numGoroutines)
|
|
|
|
// Launch many goroutines concurrently accessing GetDirectory
|
|
for range numGoroutines {
|
|
wg.Go(func() {
|
|
dir := GetDirectory()
|
|
instances <- dir
|
|
})
|
|
}
|
|
|
|
// Wait for all goroutines to complete
|
|
wg.Wait()
|
|
close(instances)
|
|
|
|
// Collect all instances
|
|
var dirs []any
|
|
for dir := range instances {
|
|
dirs = append(dirs, dir)
|
|
}
|
|
|
|
// Verify we got the expected number of results
|
|
if len(dirs) != numGoroutines {
|
|
t.Fatalf("Expected %d directory instances, got %d", numGoroutines, len(dirs))
|
|
}
|
|
|
|
// All instances should be identical (singleton)
|
|
firstDir := dirs[0]
|
|
for i, dir := range dirs {
|
|
if dir != firstDir {
|
|
t.Errorf("Directory instance %d differs from first instance", i)
|
|
}
|
|
}
|
|
})
|
|
|
|
}
|
|
|
|
func TestGetDirectorySequential(t *testing.T) {
|
|
t.Run("multiple calls in sequence", func(t *testing.T) {
|
|
// Get directory multiple times in sequence
|
|
dirs := make([]any, 10)
|
|
for i := range 10 {
|
|
dirs[i] = GetDirectory()
|
|
}
|
|
|
|
// All should be the same instance
|
|
for i := 1; i < len(dirs); i++ {
|
|
if dirs[i] != dirs[0] {
|
|
t.Errorf("Call %d returned different instance than first call", i)
|
|
}
|
|
}
|
|
})
|
|
}
|
|
|
|
// TestGetDirectoryInterface verifies the directory is properly initialized
|
|
func TestGetDirectoryInterface(t *testing.T) {
|
|
// Verify the directory instance works as expected
|
|
dir := GetDirectory()
|
|
|
|
// Verify directory is not nil
|
|
if dir == nil {
|
|
t.Fatal("Directory should not be nil")
|
|
}
|
|
|
|
// Verify it's the indigo Directory interface type
|
|
// We can't easily introspect the methods without importing indigo's types,
|
|
// but we can verify the instance is usable by checking it's not nil
|
|
// and that it's the same as subsequent calls (already tested above)
|
|
|
|
// Additional verification: the directory should be the same across calls
|
|
dir2 := GetDirectory()
|
|
if dir != dir2 {
|
|
t.Error("Directory instances differ, singleton pattern broken")
|
|
}
|
|
}
|
|
|
|
// TestGetDirectoryRaceConditions specifically tests race conditions during initialization
|
|
func TestGetDirectoryRaceConditions(t *testing.T) {
|
|
// This test would ideally reset the singleton, but since we can't do that
|
|
// safely, we instead verify that even if GetDirectory is called concurrently
|
|
// before initialization completes, it still works correctly.
|
|
//
|
|
// The sync.Once ensures this is safe, so calling GetDirectory from multiple
|
|
// goroutines simultaneously should still result in exactly one initialization
|
|
// and all goroutines getting the same instance.
|
|
|
|
const numGoroutines = 50
|
|
var wg sync.WaitGroup
|
|
|
|
instances := make([]any, numGoroutines)
|
|
var mu sync.Mutex
|
|
|
|
// Simulate many goroutines trying to get the directory simultaneously
|
|
for i := 0; i < numGoroutines; i++ {
|
|
wg.Go(func() {
|
|
dir := GetDirectory()
|
|
mu.Lock()
|
|
instances[i] = dir
|
|
mu.Unlock()
|
|
})
|
|
}
|
|
|
|
wg.Wait()
|
|
|
|
// Verify all instances are identical
|
|
firstDir := instances[0]
|
|
for i, dir := range instances {
|
|
if dir == nil {
|
|
t.Errorf("Instance %d is nil", i)
|
|
}
|
|
if dir != firstDir {
|
|
t.Errorf("Instance %d differs from first instance", i)
|
|
}
|
|
}
|
|
}
|