Skip to content

Commit ffb7505

Browse files
committed
test: add unit tests for flush manager and recovery packages
- Extend flush_manager_test.go with tests for getDeltaSafe, stopTimer, replaceTimer, and flushContext behavior - Add recovery_test.go with tests for checkFilesValid, readDirectory, and removeBufferFiles functions - Achieves 27.4% coverage for v2 internal package - Achieves 44.7% coverage for v1 recovery package
1 parent 5598323 commit ffb7505

File tree

2 files changed

+539
-0
lines changed

2 files changed

+539
-0
lines changed
Lines changed: 283 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,283 @@
1+
package recovery
2+
3+
import (
4+
"io/fs"
5+
"os"
6+
"path/filepath"
7+
"testing"
8+
"time"
9+
)
10+
11+
// mockFileInfo implements fs.FileInfo for testing
12+
type mockFileInfo struct {
13+
name string
14+
size int64
15+
mode fs.FileMode
16+
modTime time.Time
17+
isDir bool
18+
}
19+
20+
func (m mockFileInfo) Name() string { return m.name }
21+
func (m mockFileInfo) Size() int64 { return m.size }
22+
func (m mockFileInfo) Mode() fs.FileMode { return m.mode }
23+
func (m mockFileInfo) ModTime() time.Time { return m.modTime }
24+
func (m mockFileInfo) IsDir() bool { return m.isDir }
25+
func (m mockFileInfo) Sys() any { return nil }
26+
27+
func TestCheckFilesValid_MatchingFiles(t *testing.T) {
28+
irFiles := map[string]fs.FileInfo{
29+
"tag1": mockFileInfo{name: "tag1.ir"},
30+
"tag2": mockFileInfo{name: "tag2.ir"},
31+
}
32+
zstdFiles := map[string]fs.FileInfo{
33+
"tag1": mockFileInfo{name: "tag1.zst"},
34+
"tag2": mockFileInfo{name: "tag2.zst"},
35+
}
36+
37+
err := checkFilesValid(irFiles, zstdFiles)
38+
if err != nil {
39+
t.Errorf("checkFilesValid() error = %v, want nil", err)
40+
}
41+
}
42+
43+
func TestCheckFilesValid_EmptyMaps(t *testing.T) {
44+
irFiles := map[string]fs.FileInfo{}
45+
zstdFiles := map[string]fs.FileInfo{}
46+
47+
err := checkFilesValid(irFiles, zstdFiles)
48+
if err != nil {
49+
t.Errorf("checkFilesValid() with empty maps error = %v, want nil", err)
50+
}
51+
}
52+
53+
func TestCheckFilesValid_DifferentLengths(t *testing.T) {
54+
irFiles := map[string]fs.FileInfo{
55+
"tag1": mockFileInfo{name: "tag1.ir"},
56+
"tag2": mockFileInfo{name: "tag2.ir"},
57+
}
58+
zstdFiles := map[string]fs.FileInfo{
59+
"tag1": mockFileInfo{name: "tag1.zst"},
60+
}
61+
62+
err := checkFilesValid(irFiles, zstdFiles)
63+
if err == nil {
64+
t.Error("checkFilesValid() expected error for different lengths, got nil")
65+
}
66+
}
67+
68+
func TestCheckFilesValid_MissingZstdFile(t *testing.T) {
69+
irFiles := map[string]fs.FileInfo{
70+
"tag1": mockFileInfo{name: "tag1.ir"},
71+
"tag2": mockFileInfo{name: "tag2.ir"},
72+
}
73+
zstdFiles := map[string]fs.FileInfo{
74+
"tag1": mockFileInfo{name: "tag1.zst"},
75+
"different": mockFileInfo{name: "different.zst"},
76+
}
77+
78+
err := checkFilesValid(irFiles, zstdFiles)
79+
if err == nil {
80+
t.Error("checkFilesValid() expected error for mismatched keys, got nil")
81+
}
82+
}
83+
84+
func TestReadDirectory_NonExistentDirectory(t *testing.T) {
85+
files, err := readDirectory("/nonexistent/path/that/does/not/exist")
86+
if err != nil {
87+
t.Errorf("readDirectory() error = %v, want nil for non-existent", err)
88+
}
89+
if len(files) != 0 {
90+
t.Errorf("readDirectory() returned %d files, want 0", len(files))
91+
}
92+
}
93+
94+
func TestReadDirectory_EmptyDirectory(t *testing.T) {
95+
// Create a temporary directory
96+
tmpDir, err := os.MkdirTemp("", "recovery_test_*")
97+
if err != nil {
98+
t.Fatalf("Failed to create temp dir: %v", err)
99+
}
100+
defer os.RemoveAll(tmpDir)
101+
102+
files, err := readDirectory(tmpDir)
103+
if err != nil {
104+
t.Errorf("readDirectory() error = %v, want nil", err)
105+
}
106+
if len(files) != 0 {
107+
t.Errorf("readDirectory() returned %d files, want 0", len(files))
108+
}
109+
}
110+
111+
func TestReadDirectory_WithFiles(t *testing.T) {
112+
// Create a temporary directory
113+
tmpDir, err := os.MkdirTemp("", "recovery_test_*")
114+
if err != nil {
115+
t.Fatalf("Failed to create temp dir: %v", err)
116+
}
117+
defer os.RemoveAll(tmpDir)
118+
119+
// Create test files
120+
testFiles := []string{"tag1.ir", "tag2.ir", "another.ir"}
121+
for _, name := range testFiles {
122+
f, err := os.Create(filepath.Join(tmpDir, name))
123+
if err != nil {
124+
t.Fatalf("Failed to create test file: %v", err)
125+
}
126+
f.Close()
127+
}
128+
129+
files, err := readDirectory(tmpDir)
130+
if err != nil {
131+
t.Errorf("readDirectory() error = %v, want nil", err)
132+
}
133+
if len(files) != len(testFiles) {
134+
t.Errorf("readDirectory() returned %d files, want %d", len(files), len(testFiles))
135+
}
136+
137+
// Verify tags (filenames without extension)
138+
expectedTags := map[string]bool{"tag1": true, "tag2": true, "another": true}
139+
for tag := range files {
140+
if !expectedTags[tag] {
141+
t.Errorf("readDirectory() unexpected tag %q", tag)
142+
}
143+
}
144+
}
145+
146+
func TestReadDirectory_DuplicateTags(t *testing.T) {
147+
// Create a temporary directory
148+
tmpDir, err := os.MkdirTemp("", "recovery_test_*")
149+
if err != nil {
150+
t.Fatalf("Failed to create temp dir: %v", err)
151+
}
152+
defer os.RemoveAll(tmpDir)
153+
154+
// Create files with same base name but different extensions
155+
// This simulates a bug scenario where both tag1.ir and tag1.other exist
156+
testFiles := []string{"tag1.ir", "tag1.other"}
157+
for _, name := range testFiles {
158+
f, err := os.Create(filepath.Join(tmpDir, name))
159+
if err != nil {
160+
t.Fatalf("Failed to create test file: %v", err)
161+
}
162+
f.Close()
163+
}
164+
165+
_, err = readDirectory(tmpDir)
166+
if err == nil {
167+
t.Error("readDirectory() expected error for duplicate tags, got nil")
168+
}
169+
}
170+
171+
func TestReadDirectory_IgnoresSubdirectories(t *testing.T) {
172+
// Create a temporary directory
173+
tmpDir, err := os.MkdirTemp("", "recovery_test_*")
174+
if err != nil {
175+
t.Fatalf("Failed to create temp dir: %v", err)
176+
}
177+
defer os.RemoveAll(tmpDir)
178+
179+
// Create a regular file
180+
f, err := os.Create(filepath.Join(tmpDir, "tag1.ir"))
181+
if err != nil {
182+
t.Fatalf("Failed to create test file: %v", err)
183+
}
184+
f.Close()
185+
186+
// Create a subdirectory
187+
subDir := filepath.Join(tmpDir, "subdir.ir")
188+
if err := os.Mkdir(subDir, 0755); err != nil {
189+
t.Fatalf("Failed to create subdir: %v", err)
190+
}
191+
192+
_, err = readDirectory(tmpDir)
193+
// Should error because subdirectory is not a regular file
194+
if err == nil {
195+
t.Error("readDirectory() expected error for subdirectory, got nil")
196+
}
197+
}
198+
199+
func TestRemoveBufferFiles(t *testing.T) {
200+
// Create a temporary directory
201+
tmpDir, err := os.MkdirTemp("", "recovery_test_*")
202+
if err != nil {
203+
t.Fatalf("Failed to create temp dir: %v", err)
204+
}
205+
defer os.RemoveAll(tmpDir)
206+
207+
irPath := filepath.Join(tmpDir, "test.ir")
208+
zstdPath := filepath.Join(tmpDir, "test.zst")
209+
210+
// Create files
211+
if f, err := os.Create(irPath); err != nil {
212+
t.Fatalf("Failed to create IR file: %v", err)
213+
} else {
214+
f.Close()
215+
}
216+
if f, err := os.Create(zstdPath); err != nil {
217+
t.Fatalf("Failed to create Zstd file: %v", err)
218+
} else {
219+
f.Close()
220+
}
221+
222+
// Remove files
223+
err = removeBufferFiles(irPath, zstdPath)
224+
if err != nil {
225+
t.Errorf("removeBufferFiles() error = %v, want nil", err)
226+
}
227+
228+
// Verify files are removed
229+
if _, err := os.Stat(irPath); !os.IsNotExist(err) {
230+
t.Error("IR file should have been removed")
231+
}
232+
if _, err := os.Stat(zstdPath); !os.IsNotExist(err) {
233+
t.Error("Zstd file should have been removed")
234+
}
235+
}
236+
237+
func TestRemoveBufferFiles_MissingIRFile(t *testing.T) {
238+
// Create a temporary directory
239+
tmpDir, err := os.MkdirTemp("", "recovery_test_*")
240+
if err != nil {
241+
t.Fatalf("Failed to create temp dir: %v", err)
242+
}
243+
defer os.RemoveAll(tmpDir)
244+
245+
irPath := filepath.Join(tmpDir, "nonexistent.ir")
246+
zstdPath := filepath.Join(tmpDir, "test.zst")
247+
248+
// Create only zstd file
249+
if f, err := os.Create(zstdPath); err != nil {
250+
t.Fatalf("Failed to create Zstd file: %v", err)
251+
} else {
252+
f.Close()
253+
}
254+
255+
err = removeBufferFiles(irPath, zstdPath)
256+
if err == nil {
257+
t.Error("removeBufferFiles() expected error for missing IR file, got nil")
258+
}
259+
}
260+
261+
func TestRemoveBufferFiles_MissingZstdFile(t *testing.T) {
262+
// Create a temporary directory
263+
tmpDir, err := os.MkdirTemp("", "recovery_test_*")
264+
if err != nil {
265+
t.Fatalf("Failed to create temp dir: %v", err)
266+
}
267+
defer os.RemoveAll(tmpDir)
268+
269+
irPath := filepath.Join(tmpDir, "test.ir")
270+
zstdPath := filepath.Join(tmpDir, "nonexistent.zst")
271+
272+
// Create only IR file
273+
if f, err := os.Create(irPath); err != nil {
274+
t.Fatalf("Failed to create IR file: %v", err)
275+
} else {
276+
f.Close()
277+
}
278+
279+
err = removeBufferFiles(irPath, zstdPath)
280+
if err == nil {
281+
t.Error("removeBufferFiles() expected error for missing Zstd file, got nil")
282+
}
283+
}

0 commit comments

Comments
 (0)