Skip to content

Commit 72f2f27

Browse files
committed
Updated unit tests to be clearer, relying on asserting linkCache
1 parent 04e31de commit 72f2f27

File tree

2 files changed

+79
-124
lines changed

2 files changed

+79
-124
lines changed

pkg/linkcache/cache.go

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,15 @@ func NewListingCache(period time.Duration, dir string) *ListingCache {
5454
}
5555
}
5656

57+
func NewMockListingCache(period time.Duration, dir string) *ListingCache {
58+
return &ListingCache{
59+
period: period,
60+
dir: dir,
61+
links: newLinkCache(),
62+
fs: &mockFS{},
63+
}
64+
}
65+
5766
// Run starts the cache's background loop. The filesystem is listed and the cache
5867
// updated according to the frequency specified by the period. It will run until
5968
// the context is cancelled.

pkg/linkcache/cache_test.go

Lines changed: 70 additions & 124 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,12 @@ import (
44
"os"
55
"testing"
66
"testing/fstest"
7+
8+
"github.com/google/go-cmp/cmp"
79
)
810

11+
var allowUnexportedLinkCache = cmp.AllowUnexported(linkCache{}, linkCacheEntry{})
12+
913
const (
1014
// Test disk names in /dev/disk/by-id format
1115
gcpPersistentDiskID = "google-persistent-disk-0"
@@ -49,7 +53,7 @@ func TestListAndUpdate(t *testing.T) {
4953
tests := []struct {
5054
name string
5155
setupFS func(*mockFS)
52-
expectedLinks map[string]string
56+
expectedCache *linkCache
5357
expectError bool
5458
}{
5559
{
@@ -62,9 +66,11 @@ func TestListAndUpdate(t *testing.T) {
6266
m.symlinks[gcpPersistentDiskID] = devicePathSDA
6367
m.symlinks[gcpPVCID] = devicePathSDB
6468
},
65-
expectedLinks: map[string]string{
66-
gcpPersistentDiskID: devicePathSDA,
67-
gcpPVCID: devicePathSDB,
69+
expectedCache: &linkCache{
70+
devices: map[string]linkCacheEntry{
71+
gcpPersistentDiskID: {path: devicePathSDA, brokenSymlink: false},
72+
gcpPVCID: {path: devicePathSDB, brokenSymlink: false},
73+
},
6874
},
6975
expectError: false,
7076
},
@@ -74,8 +80,10 @@ func TestListAndUpdate(t *testing.T) {
7480
m.MapFS[gcpPersistentDiskID] = &fstest.MapFile{}
7581
// No symlink target for gcpPersistentDiskID
7682
},
77-
expectedLinks: map[string]string{},
78-
expectError: true,
83+
expectedCache: &linkCache{
84+
devices: map[string]linkCacheEntry{},
85+
},
86+
expectError: true,
7987
},
8088
{
8189
name: "partition files ignored",
@@ -85,8 +93,10 @@ func TestListAndUpdate(t *testing.T) {
8593
m.symlinks[gcpPersistentDiskID] = devicePathSDA
8694
m.symlinks[gcpPersistentDiskPartitionID] = devicePathSDA + "1"
8795
},
88-
expectedLinks: map[string]string{
89-
gcpPersistentDiskID: devicePathSDA,
96+
expectedCache: &linkCache{
97+
devices: map[string]linkCacheEntry{
98+
gcpPersistentDiskID: {path: devicePathSDA, brokenSymlink: false},
99+
},
90100
},
91101
expectError: false,
92102
},
@@ -111,129 +121,65 @@ func TestListAndUpdate(t *testing.T) {
111121
}
112122
}
113123

114-
// Verify the cache contents
115-
for symlink, expectedTarget := range tt.expectedLinks {
116-
entry, exists := cache.links.devices[symlink]
117-
if !exists {
118-
t.Errorf("symlink %s should exist in cache", symlink)
119-
continue
120-
}
121-
if entry.path != expectedTarget {
122-
t.Errorf("symlink %s should point to %s, got %s", symlink, expectedTarget, entry.path)
123-
}
124-
if entry.brokenSymlink {
125-
t.Errorf("symlink %s should not be marked as broken", symlink)
126-
}
124+
// Compare the entire cache state
125+
if diff := cmp.Diff(tt.expectedCache, cache.links, allowUnexportedLinkCache); diff != "" {
126+
t.Errorf("linkCache mismatch (-expected +got):\n%s", diff)
127127
}
128128
})
129129
}
130130
}
131131

132-
func TestListAndUpdateWithChanges(t *testing.T) {
133-
mock := newMockFS()
134-
cache := NewListingCache(0, ".")
135-
cache.fs = mock
136-
137-
// Initial state: one disk with a valid symlink
138-
mock.MapFS[gcpPersistentDiskID] = &fstest.MapFile{}
139-
mock.symlinks[gcpPersistentDiskID] = devicePathSDA
140-
141-
// First listAndUpdate should add the disk to cache
142-
err := cache.listAndUpdate()
143-
if err != nil {
144-
t.Fatalf("unexpected error in first listAndUpdate: %v", err)
145-
}
146-
147-
// Verify initial state
148-
entry, exists := cache.links.devices[gcpPersistentDiskID]
149-
if !exists {
150-
t.Fatal("gcpPersistentDiskID should exist in cache after first listAndUpdate")
151-
}
152-
if entry.path != devicePathSDA {
153-
t.Errorf("gcpPersistentDiskID should point to %s, got %s", devicePathSDA, entry.path)
154-
}
155-
156-
// Add a new disk and update the symlink target
157-
mock.MapFS[gcpPVCID] = &fstest.MapFile{}
158-
mock.symlinks[gcpPVCID] = devicePathSDB
159-
mock.symlinks[gcpPersistentDiskID] = devicePathSDB // Update existing disk's target
160-
161-
// Second listAndUpdate should update the cache
162-
err = cache.listAndUpdate()
163-
if err != nil {
164-
t.Fatalf("unexpected error in second listAndUpdate: %v", err)
165-
}
166-
167-
// Verify both disks are in cache with correct paths
168-
entry, exists = cache.links.devices[gcpPersistentDiskID]
169-
if !exists {
170-
t.Fatal("gcpPersistentDiskID should still exist in cache")
171-
}
172-
if entry.path != devicePathSDB {
173-
t.Errorf("gcpPersistentDiskID should now point to %s, got %s", devicePathSDB, entry.path)
174-
}
175-
176-
entry, exists = cache.links.devices[gcpPVCID]
177-
if !exists {
178-
t.Fatal("gcpPVCID should exist in cache after second listAndUpdate")
179-
}
180-
if entry.path != devicePathSDB {
181-
t.Errorf("gcpPVCID should point to %s, got %s", devicePathSDB, entry.path)
182-
}
183-
184-
// Break the symlink for gcpPersistentDiskID but keep the file
185-
delete(mock.symlinks, gcpPersistentDiskID)
186-
187-
// Third listAndUpdate should mark the disk as broken but keep its last known value
188-
err = cache.listAndUpdate()
189-
if err == nil {
190-
t.Error("expected error for broken symlink")
191-
}
192-
193-
// Verify gcpPersistentDiskID is marked as broken but maintains its last known value
194-
entry, exists = cache.links.devices[gcpPersistentDiskID]
195-
if !exists {
196-
t.Fatal("gcpPersistentDiskID should still exist in cache")
197-
}
198-
if entry.path != devicePathSDB {
199-
t.Errorf("gcpPersistentDiskID should maintain its last known value %s, got %s", devicePathSDB, entry.path)
200-
}
201-
if !entry.brokenSymlink {
202-
t.Error("gcpPersistentDiskID should be marked as broken")
203-
}
204-
205-
// Verify gcpPVCID is still valid
206-
entry, exists = cache.links.devices[gcpPVCID]
207-
if !exists {
208-
t.Fatal("gcpPVCID should still exist in cache")
209-
}
210-
if entry.path != devicePathSDB {
211-
t.Errorf("gcpPVCID should still point to %s, got %s", devicePathSDB, entry.path)
212-
}
213-
if entry.brokenSymlink {
214-
t.Error("gcpPVCID should not be marked as broken")
215-
}
216-
217-
// Remove one disk
218-
delete(mock.MapFS, gcpPersistentDiskID)
219-
delete(mock.symlinks, gcpPersistentDiskID)
220-
221-
// Fourth listAndUpdate should remove the deleted disk
222-
err = cache.listAndUpdate()
223-
if err != nil {
224-
t.Fatalf("unexpected error in fourth listAndUpdate: %v", err)
132+
func TestLinkCache(t *testing.T) {
133+
tests := []struct {
134+
name string
135+
setupCache func(*linkCache)
136+
expected *linkCache
137+
}{
138+
{
139+
name: "AddOrUpdateDevice",
140+
setupCache: func(lc *linkCache) {
141+
lc.AddOrUpdateDevice("symlink1", "/dev/sda")
142+
lc.AddOrUpdateDevice("symlink2", "/dev/sdb")
143+
},
144+
expected: &linkCache{
145+
devices: map[string]linkCacheEntry{
146+
"symlink1": {path: "/dev/sda", brokenSymlink: false},
147+
"symlink2": {path: "/dev/sdb", brokenSymlink: false},
148+
},
149+
},
150+
},
151+
{
152+
name: "BrokenSymlink",
153+
setupCache: func(lc *linkCache) {
154+
lc.AddOrUpdateDevice("symlink1", "/dev/sda")
155+
lc.BrokenSymlink("symlink1")
156+
},
157+
expected: &linkCache{
158+
devices: map[string]linkCacheEntry{
159+
"symlink1": {path: "/dev/sda", brokenSymlink: true},
160+
},
161+
},
162+
},
163+
{
164+
name: "RemoveDevice",
165+
setupCache: func(lc *linkCache) {
166+
lc.AddOrUpdateDevice("symlink1", "/dev/sda")
167+
lc.RemoveDevice("symlink1")
168+
},
169+
expected: &linkCache{
170+
devices: map[string]linkCacheEntry{},
171+
},
172+
},
225173
}
226174

227-
// Verify only gcpPVCID remains
228-
if _, exists := cache.links.devices[gcpPersistentDiskID]; exists {
229-
t.Error("gcpPersistentDiskID should be removed from cache")
230-
}
175+
for _, tt := range tests {
176+
t.Run(tt.name, func(t *testing.T) {
177+
cache := newLinkCache()
178+
tt.setupCache(cache)
231179

232-
entry, exists = cache.links.devices[gcpPVCID]
233-
if !exists {
234-
t.Fatal("gcpPVCID should still exist in cache")
235-
}
236-
if entry.path != devicePathSDB {
237-
t.Errorf("gcpPVCID should still point to %s, got %s", devicePathSDB, entry.path)
180+
if diff := cmp.Diff(tt.expected, cache, allowUnexportedLinkCache); diff != "" {
181+
t.Errorf("linkCache mismatch (-expected +got):\n%s", diff)
182+
}
183+
})
238184
}
239185
}

0 commit comments

Comments
 (0)