internal/storage/disk_test.go (view raw)
1package storage
2
3import (
4 "bytes"
5 "os"
6 "path/filepath"
7 "strings"
8 "testing"
9)
10
11func TestNew(t *testing.T) {
12 dir := t.TempDir()
13 s, err := New(dir)
14 if err != nil {
15 t.Fatalf("New: %v", err)
16 }
17 if s.basePath != dir {
18 t.Fatalf("basePath = %q, want %q", s.basePath, dir)
19 }
20 // Verify directory was created.
21 if _, err := os.Stat(dir); os.IsNotExist(err) {
22 t.Fatal("storage directory was not created")
23 }
24}
25
26func TestStoreAndOpen(t *testing.T) {
27 dir := t.TempDir()
28 s, _ := New(dir)
29
30 data := []byte("hello world")
31 hash, rel, err := s.Store(data, "txt")
32 if err != nil {
33 t.Fatalf("Store: %v", err)
34 }
35 if hash == "" {
36 t.Fatal("expected non-empty hash")
37 }
38 if !strings.HasSuffix(rel, ".txt") {
39 t.Fatalf("expected .txt extension, got %q", rel)
40 }
41 if !strings.HasPrefix(rel, hash[:2]+"/"+hash[2:4]+"/"+hash[4:6]+"/") {
42 t.Fatalf("rel path %q does not match hash prefix", rel)
43 }
44
45 f, err := s.Open(rel)
46 if err != nil {
47 t.Fatalf("Open: %v", err)
48 }
49 defer f.Close()
50
51 var buf bytes.Buffer
52 buf.ReadFrom(f)
53 if buf.String() != "hello world" {
54 t.Fatalf("content = %q, want %q", buf.String(), "hello world")
55 }
56
57 // Check absolute path.
58 abs := s.AbsPath(rel)
59 if _, err := os.Stat(abs); os.IsNotExist(err) {
60 t.Fatal("absolute path does not exist")
61 }
62}
63
64func TestStoreAt(t *testing.T) {
65 dir := t.TempDir()
66 s, _ := New(dir)
67
68 if err := s.StoreAt("custom/dir/file.txt", []byte("custom")); err != nil {
69 t.Fatalf("StoreAt: %v", err)
70 }
71
72 data, err := os.ReadFile(filepath.Join(dir, "custom/dir/file.txt"))
73 if err != nil {
74 t.Fatalf("reading stored file: %v", err)
75 }
76 if string(data) != "custom" {
77 t.Fatalf("content = %q", string(data))
78 }
79}
80
81func TestDelete(t *testing.T) {
82 dir := t.TempDir()
83 s, _ := New(dir)
84
85 _, rel, _ := s.Store([]byte("delete me"), "txt")
86
87 if err := s.Delete(rel); err != nil {
88 t.Fatalf("Delete: %v", err)
89 }
90
91 // File should be gone.
92 abs := filepath.Join(dir, rel)
93 if _, err := os.Stat(abs); !os.IsNotExist(err) {
94 t.Fatal("file should be deleted")
95 }
96}
97
98func TestDelete_NotFound(t *testing.T) {
99 dir := t.TempDir()
100 s, _ := New(dir)
101
102 err := s.Delete("nonexistent/file.txt")
103 if err == nil {
104 t.Fatal("expected error deleting non-existent file")
105 }
106}
107
108func TestStore_Duplicate(t *testing.T) {
109 // Storing the same data twice should succeed (overwrites).
110 dir := t.TempDir()
111 s, _ := New(dir)
112
113 hash1, _, _ := s.Store([]byte("same data"), "txt")
114 hash2, rel2, _ := s.Store([]byte("same data"), "txt")
115
116 if hash1 != hash2 {
117 t.Fatal("same data should produce same hash")
118 }
119
120 // File should still be readable.
121 f, _ := s.Open(rel2)
122 defer f.Close()
123 var buf bytes.Buffer
124 buf.ReadFrom(f)
125 if buf.String() != "same data" {
126 t.Fatalf("content = %q", buf.String())
127 }
128}
129
130func TestConsistentPartitioning(t *testing.T) {
131 dir := t.TempDir()
132 s, _ := New(dir)
133
134 data := []byte("partition test")
135 hash, rel, _ := s.Store(data, "dat")
136
137 expected := hash[:2] + "/" + hash[2:4] + "/" + hash[4:6] + "/" + hash[:12] + ".dat"
138 if rel != expected {
139 t.Fatalf("rel = %q, want %q", rel, expected)
140 }
141}