testmain_test.go raw
1 package database
2
3 import (
4 "bufio"
5 "bytes"
6 "context"
7 "io"
8 "os"
9 "sort"
10 "sync"
11 "testing"
12
13 "next.orly.dev/pkg/nostr/encoders/event"
14 "next.orly.dev/pkg/nostr/encoders/event/examples"
15 "next.orly.dev/pkg/lol"
16 "next.orly.dev/pkg/lol/log"
17 )
18
19 // Shared test fixtures - initialized once in TestMain
20 var (
21 sharedDB *D
22 sharedDBDir string
23 sharedDBCtx context.Context
24 sharedDBCancel context.CancelFunc
25 sharedDBOnce sync.Once
26 sharedEvents []*event.E // Events that were successfully saved
27 sharedSetupError error
28 )
29
30 // initSharedDB initializes the shared test database with seeded data.
31 // This is called once and shared across all tests that need seeded data.
32 func initSharedDB() {
33 sharedDBOnce.Do(func() {
34 var err error
35
36 // Create a temporary directory for the shared database
37 sharedDBDir, err = os.MkdirTemp("", "shared-test-db-*")
38 if err != nil {
39 sharedSetupError = err
40 return
41 }
42
43 // Create a context for the database
44 sharedDBCtx, sharedDBCancel = context.WithCancel(context.Background())
45
46 // Initialize the database
47 sharedDB, err = New(sharedDBCtx, sharedDBCancel, sharedDBDir, "info")
48 if err != nil {
49 sharedSetupError = err
50 return
51 }
52
53 // Seed the database with events from examples.Cache
54 scanner := bufio.NewScanner(bytes.NewBuffer(examples.Cache))
55 scanner.Buffer(make([]byte, 0, 1_000_000_000), 1_000_000_000)
56
57 var events []*event.E
58 for scanner.Scan() {
59 b := scanner.Bytes()
60 ev := event.New()
61 if _, err = ev.Unmarshal(b); err != nil {
62 continue
63 }
64 events = append(events, ev)
65 }
66
67 // Sort events by CreatedAt for consistent processing
68 sort.Slice(events, func(i, j int) bool {
69 return events[i].CreatedAt < events[j].CreatedAt
70 })
71
72 // Save events to the database
73 for _, ev := range events {
74 if _, err = sharedDB.SaveEvent(sharedDBCtx, ev); err != nil {
75 continue // Skip invalid events
76 }
77 sharedEvents = append(sharedEvents, ev)
78 }
79 })
80 }
81
82 // GetSharedDB returns the shared test database.
83 // Returns nil if testing.Short() is set or if setup failed.
84 func GetSharedDB(t *testing.T) (*D, context.Context) {
85 if testing.Short() {
86 t.Skip("skipping test that requires seeded database in short mode")
87 }
88
89 initSharedDB()
90
91 if sharedSetupError != nil {
92 t.Fatalf("Failed to initialize shared database: %v", sharedSetupError)
93 }
94
95 return sharedDB, sharedDBCtx
96 }
97
98 // GetSharedEvents returns the events that were successfully saved to the shared database.
99 func GetSharedEvents(t *testing.T) []*event.E {
100 if testing.Short() {
101 t.Skip("skipping test that requires seeded events in short mode")
102 }
103
104 initSharedDB()
105
106 if sharedSetupError != nil {
107 t.Fatalf("Failed to initialize shared database: %v", sharedSetupError)
108 }
109
110 return sharedEvents
111 }
112
113 // findEventWithTag finds an event with a single-character tag key and at least 2 elements.
114 // Returns nil if no suitable event is found.
115 func findEventWithTag(events []*event.E) *event.E {
116 for _, ev := range events {
117 if ev.Tags != nil && ev.Tags.Len() > 0 {
118 for _, tg := range *ev.Tags {
119 if tg.Len() >= 2 && len(tg.Key()) == 1 {
120 return ev
121 }
122 }
123 }
124 }
125 return nil
126 }
127
128 func TestMain(m *testing.M) {
129 // Disable all logging during tests unless explicitly enabled
130 if os.Getenv("TEST_LOG") == "" {
131 // Set log level to Off to suppress all logs
132 lol.SetLogLevel("off")
133 // Also redirect output to discard
134 lol.Writer = io.Discard
135 // Disable all log printers
136 log.T = lol.GetNullPrinter()
137 log.D = lol.GetNullPrinter()
138 log.I = lol.GetNullPrinter()
139 log.W = lol.GetNullPrinter()
140 log.E = lol.GetNullPrinter()
141 log.F = lol.GetNullPrinter()
142
143 // Also suppress badger logs
144 os.Setenv("BADGER_LOG_LEVEL", "CRITICAL")
145 }
146
147 // Run tests
148 code := m.Run()
149
150 // Cleanup shared database
151 if sharedDBCancel != nil {
152 sharedDBCancel()
153 }
154 if sharedDB != nil {
155 sharedDB.Close()
156 }
157 if sharedDBDir != "" {
158 os.RemoveAll(sharedDBDir)
159 }
160
161 os.Exit(code)
162 }
163