@@ -27,6 +27,7 @@ import (
27
27
"testing"
28
28
"time"
29
29
30
+ "github.com/containerd/containerd/v2/core/leases"
30
31
"github.com/containerd/containerd/v2/core/mount"
31
32
"github.com/containerd/containerd/v2/core/snapshots"
32
33
"github.com/containerd/containerd/v2/core/snapshots/testsuite"
@@ -63,6 +64,32 @@ func newTestSnapshotter(ctx context.Context, root string) (snapshots.Snapshotter
63
64
}, nil
64
65
}
65
66
67
+ func snapshotLease (ctx context.Context , t * testing.T , db * DB , sn string ) (context.Context , func (string ) bool ) {
68
+ lm := NewLeaseManager (db )
69
+ l , err := lm .Create (ctx , leases .WithRandomID ())
70
+ if err != nil {
71
+ t .Fatal (err )
72
+ }
73
+ ltype := fmt .Sprintf ("%s/%s" , bucketKeyObjectSnapshots , sn )
74
+
75
+ t .Cleanup (func () {
76
+ lm .Delete (ctx , l )
77
+
78
+ })
79
+ return leases .WithLease (ctx , l .ID ), func (id string ) bool {
80
+ resources , err := lm .ListResources (ctx , l )
81
+ if err != nil {
82
+ t .Error (err )
83
+ }
84
+ for _ , r := range resources {
85
+ if r .Type == ltype && r .ID == id {
86
+ return true
87
+ }
88
+ }
89
+ return false
90
+ }
91
+ }
92
+
66
93
func TestMetadata (t * testing.T ) {
67
94
if runtime .GOOS == "windows" {
68
95
t .Skip ("snapshotter not implemented on windows" )
@@ -76,121 +103,163 @@ func TestSnapshotterWithRef(t *testing.T) {
76
103
ctx , db := testDB (t , withSnapshotter ("tmp" , func (string ) (snapshots.Snapshotter , error ) {
77
104
return NewTmpSnapshotter (), nil
78
105
}))
79
- sn := db .Snapshotter ("tmp" )
106
+ snapshotter := "tmp"
107
+ ctx1 , leased1 := snapshotLease (ctx , t , db , snapshotter )
108
+ sn := db .Snapshotter (snapshotter )
80
109
110
+ key1 := "test1"
81
111
test1opt := snapshots .WithLabels (
82
112
map [string ]string {
83
- labelSnapshotRef : "test1" ,
113
+ labelSnapshotRef : key1 ,
84
114
},
85
115
)
86
116
87
- _ , err := sn .Prepare (ctx , "test1-tmp" , "" , test1opt )
117
+ key1t := "test1-tmp"
118
+ _ , err := sn .Prepare (ctx1 , key1t , "" , test1opt )
88
119
if err != nil {
89
120
t .Fatal (err )
90
121
}
122
+ if ! leased1 (key1t ) {
123
+ t .Errorf ("no lease for %q" , key1t )
124
+ }
91
125
92
- err = sn .Commit (ctx , "test1" , "test1-tmp" , test1opt )
126
+ err = sn .Commit (ctx1 , key1 , key1t , test1opt )
93
127
if err != nil {
94
128
t .Fatal (err )
95
129
}
130
+ if ! leased1 (key1 ) {
131
+ t .Errorf ("no lease for %q" , key1 )
132
+ }
133
+ if leased1 (key1t ) {
134
+ t .Errorf ("lease should be removed for %q" , key1t )
135
+ }
96
136
97
137
ctx2 := namespaces .WithNamespace (ctx , "testing2" )
98
138
99
- _ , err = sn .Prepare (ctx2 , "test1-tmp" , "" , test1opt )
139
+ _ , err = sn .Prepare (ctx2 , key1t , "" , test1opt )
100
140
if err == nil {
101
141
t .Fatal ("expected already exists error" )
102
142
} else if ! errdefs .IsAlreadyExists (err ) {
103
143
t .Fatal (err )
104
144
}
105
145
106
146
// test1 should now be in the namespace
107
- _ , err = sn .Stat (ctx2 , "test1" )
147
+ _ , err = sn .Stat (ctx2 , key1 )
108
148
if err != nil {
109
149
t .Fatal (err )
110
150
}
111
151
152
+ key2t := "test2-tmp"
153
+ key2 := "test2"
112
154
test2opt := snapshots .WithLabels (
113
155
map [string ]string {
114
- labelSnapshotRef : "test2" ,
156
+ labelSnapshotRef : key2 ,
115
157
},
116
158
)
117
159
118
- _ , err = sn .Prepare (ctx2 , "test2-tmp" , "test1" , test2opt )
160
+ _ , err = sn .Prepare (ctx2 , key2t , key1 , test2opt )
119
161
if err != nil {
120
162
t .Fatal (err )
121
163
}
122
164
123
165
// In original namespace, but not committed
124
- _ , err = sn .Prepare (ctx , "test2-tmp" , "test1" , test2opt )
166
+ _ , err = sn .Prepare (ctx1 , key2t , key1 , test2opt )
125
167
if err != nil {
126
168
t .Fatal (err )
127
169
}
170
+ if ! leased1 (key2t ) {
171
+ t .Errorf ("no lease for %q" , key2t )
172
+ }
173
+ if leased1 (key2 ) {
174
+ t .Errorf ("lease for %q should not exist yet" , key2 )
175
+ }
128
176
129
- err = sn .Commit (ctx2 , "test2" , "test2-tmp" , test2opt )
177
+ err = sn .Commit (ctx2 , key2 , key2t , test2opt )
130
178
if err != nil {
131
179
t .Fatal (err )
132
180
}
133
181
134
182
// See note in Commit function for why
135
183
// this does not return ErrAlreadyExists
136
- err = sn .Commit (ctx , "test2" , "test2-tmp" , test2opt )
184
+ err = sn .Commit (ctx1 , key2 , key2t , test2opt )
137
185
if err != nil {
138
186
t .Fatal (err )
139
187
}
140
188
189
+ ctx2 , leased2 := snapshotLease (ctx2 , t , db , snapshotter )
190
+ if leased2 (key2 ) {
191
+ t .Errorf ("new lease should not have previously created snapshots" )
192
+ }
141
193
// This should error out, already exists in namespace
142
194
// despite mismatched parent
143
- _ , err = sn .Prepare (ctx2 , "test2-tmp-again" , "" , test2opt )
195
+ key2ta := "test2-tmp-again"
196
+ _ , err = sn .Prepare (ctx2 , key2ta , "" , test2opt )
144
197
if err == nil {
145
198
t .Fatal ("expected already exists error" )
146
199
} else if ! errdefs .IsAlreadyExists (err ) {
147
200
t .Fatal (err )
148
201
}
202
+ if ! leased2 (key2 ) {
203
+ t .Errorf ("no lease for %q" , key2 )
204
+ }
149
205
150
206
// In original namespace, but already exists
151
- _ , err = sn .Prepare (ctx , "test2-tmp-again" , "test1" , test2opt )
207
+ _ , err = sn .Prepare (ctx , key2ta , key1 , test2opt )
152
208
if err == nil {
153
209
t .Fatal ("expected already exists error" )
154
210
} else if ! errdefs .IsAlreadyExists (err ) {
155
211
t .Fatal (err )
156
212
}
213
+ if leased1 (key2ta ) {
214
+ t .Errorf ("should not have lease for non-existent snapshot %q" , key2ta )
215
+ }
157
216
158
217
// Now try a third namespace
159
218
160
219
ctx3 := namespaces .WithNamespace (ctx , "testing3" )
220
+ ctx3 , leased3 := snapshotLease (ctx3 , t , db , snapshotter )
161
221
162
222
// This should error out, matching parent not found
163
- _ , err = sn .Prepare (ctx3 , "test2-tmp" , "" , test2opt )
223
+ _ , err = sn .Prepare (ctx3 , key2t , "" , test2opt )
164
224
if err != nil {
165
225
t .Fatal (err )
166
226
}
167
227
168
228
// Remove, not going to use yet
169
- err = sn .Remove (ctx3 , "test2-tmp" )
229
+ err = sn .Remove (ctx3 , key2t )
170
230
if err != nil {
171
231
t .Fatal (err )
172
232
}
173
233
174
- _ , err = sn .Prepare (ctx3 , "test2-tmp" , "test1" , test2opt )
234
+ _ , err = sn .Prepare (ctx3 , key2t , key1 , test2opt )
175
235
if err == nil {
176
236
t .Fatal ("expected not error" )
177
237
} else if ! errdefs .IsNotFound (err ) {
178
238
t .Fatal (err )
179
239
}
240
+ if leased3 (key1 ) {
241
+ t .Errorf ("lease for %q should not have been created" , key1 )
242
+ }
180
243
181
- _ , err = sn .Prepare (ctx3 , "test1-tmp" , "" , test1opt )
244
+ _ , err = sn .Prepare (ctx3 , key1t , "" , test1opt )
182
245
if err == nil {
183
246
t .Fatal ("expected already exists error" )
184
247
} else if ! errdefs .IsAlreadyExists (err ) {
185
248
t .Fatal (err )
186
249
}
250
+ if ! leased3 (key1 ) {
251
+ t .Errorf ("no lease for %q" , key1 )
252
+ }
187
253
188
254
_ , err = sn .Prepare (ctx3 , "test2-tmp" , "test1" , test2opt )
189
255
if err == nil {
190
256
t .Fatal ("expected already exists error" )
191
257
} else if ! errdefs .IsAlreadyExists (err ) {
192
258
t .Fatal (err )
193
259
}
260
+ if ! leased3 (key2 ) {
261
+ t .Errorf ("no lease for %q" , key2 )
262
+ }
194
263
}
195
264
196
265
func TestFilterInheritedLabels (t * testing.T ) {
0 commit comments