@@ -4,8 +4,12 @@ import (
4
4
"os"
5
5
"testing"
6
6
"testing/fstest"
7
+
8
+ "github.com/google/go-cmp/cmp"
7
9
)
8
10
11
+ var allowUnexportedLinkCache = cmp .AllowUnexported (linkCache {}, linkCacheEntry {})
12
+
9
13
const (
10
14
// Test disk names in /dev/disk/by-id format
11
15
gcpPersistentDiskID = "google-persistent-disk-0"
@@ -49,7 +53,7 @@ func TestListAndUpdate(t *testing.T) {
49
53
tests := []struct {
50
54
name string
51
55
setupFS func (* mockFS )
52
- expectedLinks map [ string ] string
56
+ expectedCache * linkCache
53
57
expectError bool
54
58
}{
55
59
{
@@ -62,9 +66,11 @@ func TestListAndUpdate(t *testing.T) {
62
66
m .symlinks [gcpPersistentDiskID ] = devicePathSDA
63
67
m .symlinks [gcpPVCID ] = devicePathSDB
64
68
},
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
+ },
68
74
},
69
75
expectError : false ,
70
76
},
@@ -74,8 +80,10 @@ func TestListAndUpdate(t *testing.T) {
74
80
m .MapFS [gcpPersistentDiskID ] = & fstest.MapFile {}
75
81
// No symlink target for gcpPersistentDiskID
76
82
},
77
- expectedLinks : map [string ]string {},
78
- expectError : true ,
83
+ expectedCache : & linkCache {
84
+ devices : map [string ]linkCacheEntry {},
85
+ },
86
+ expectError : true ,
79
87
},
80
88
{
81
89
name : "partition files ignored" ,
@@ -85,8 +93,10 @@ func TestListAndUpdate(t *testing.T) {
85
93
m .symlinks [gcpPersistentDiskID ] = devicePathSDA
86
94
m .symlinks [gcpPersistentDiskPartitionID ] = devicePathSDA + "1"
87
95
},
88
- expectedLinks : map [string ]string {
89
- gcpPersistentDiskID : devicePathSDA ,
96
+ expectedCache : & linkCache {
97
+ devices : map [string ]linkCacheEntry {
98
+ gcpPersistentDiskID : {path : devicePathSDA , brokenSymlink : false },
99
+ },
90
100
},
91
101
expectError : false ,
92
102
},
@@ -111,129 +121,65 @@ func TestListAndUpdate(t *testing.T) {
111
121
}
112
122
}
113
123
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 )
127
127
}
128
128
})
129
129
}
130
130
}
131
131
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
+ },
225
173
}
226
174
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 )
231
179
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
+ })
238
184
}
239
185
}
0 commit comments