@@ -29,6 +29,7 @@ import (
2929
3030 "github.com/containerd/containerd/errdefs"
3131 "github.com/containerd/containerd/filters"
32+ "github.com/containerd/containerd/leases"
3233 "github.com/containerd/containerd/mount"
3334 "github.com/containerd/containerd/namespaces"
3435 "github.com/containerd/containerd/pkg/testutil"
@@ -63,6 +64,32 @@ func newTestSnapshotter(ctx context.Context, root string) (snapshots.Snapshotter
6364 }, nil
6465}
6566
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+
6693func TestMetadata (t * testing.T ) {
6794 if runtime .GOOS == "windows" {
6895 t .Skip ("snapshotter not implemented on windows" )
@@ -76,121 +103,163 @@ func TestSnapshotterWithRef(t *testing.T) {
76103 ctx , db := testDB (t , withSnapshotter ("tmp" , func (string ) (snapshots.Snapshotter , error ) {
77104 return NewTmpSnapshotter (), nil
78105 }))
79- sn := db .Snapshotter ("tmp" )
106+ snapshotter := "tmp"
107+ ctx1 , leased1 := snapshotLease (ctx , t , db , snapshotter )
108+ sn := db .Snapshotter (snapshotter )
80109
110+ key1 := "test1"
81111 test1opt := snapshots .WithLabels (
82112 map [string ]string {
83- labelSnapshotRef : "test1" ,
113+ labelSnapshotRef : key1 ,
84114 },
85115 )
86116
87- _ , err := sn .Prepare (ctx , "test1-tmp" , "" , test1opt )
117+ key1t := "test1-tmp"
118+ _ , err := sn .Prepare (ctx1 , key1t , "" , test1opt )
88119 if err != nil {
89120 t .Fatal (err )
90121 }
122+ if ! leased1 (key1t ) {
123+ t .Errorf ("no lease for %q" , key1t )
124+ }
91125
92- err = sn .Commit (ctx , "test1" , "test1-tmp" , test1opt )
126+ err = sn .Commit (ctx1 , key1 , key1t , test1opt )
93127 if err != nil {
94128 t .Fatal (err )
95129 }
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+ }
96136
97137 ctx2 := namespaces .WithNamespace (ctx , "testing2" )
98138
99- _ , err = sn .Prepare (ctx2 , "test1-tmp" , "" , test1opt )
139+ _ , err = sn .Prepare (ctx2 , key1t , "" , test1opt )
100140 if err == nil {
101141 t .Fatal ("expected already exists error" )
102142 } else if ! errdefs .IsAlreadyExists (err ) {
103143 t .Fatal (err )
104144 }
105145
106146 // test1 should now be in the namespace
107- _ , err = sn .Stat (ctx2 , "test1" )
147+ _ , err = sn .Stat (ctx2 , key1 )
108148 if err != nil {
109149 t .Fatal (err )
110150 }
111151
152+ key2t := "test2-tmp"
153+ key2 := "test2"
112154 test2opt := snapshots .WithLabels (
113155 map [string ]string {
114- labelSnapshotRef : "test2" ,
156+ labelSnapshotRef : key2 ,
115157 },
116158 )
117159
118- _ , err = sn .Prepare (ctx2 , "test2-tmp" , "test1" , test2opt )
160+ _ , err = sn .Prepare (ctx2 , key2t , key1 , test2opt )
119161 if err != nil {
120162 t .Fatal (err )
121163 }
122164
123165 // In original namespace, but not committed
124- _ , err = sn .Prepare (ctx , "test2-tmp" , "test1" , test2opt )
166+ _ , err = sn .Prepare (ctx1 , key2t , key1 , test2opt )
125167 if err != nil {
126168 t .Fatal (err )
127169 }
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+ }
128176
129- err = sn .Commit (ctx2 , "test2" , "test2-tmp" , test2opt )
177+ err = sn .Commit (ctx2 , key2 , key2t , test2opt )
130178 if err != nil {
131179 t .Fatal (err )
132180 }
133181
134182 // See note in Commit function for why
135183 // this does not return ErrAlreadyExists
136- err = sn .Commit (ctx , "test2" , "test2-tmp" , test2opt )
184+ err = sn .Commit (ctx1 , key2 , key2t , test2opt )
137185 if err != nil {
138186 t .Fatal (err )
139187 }
140188
189+ ctx2 , leased2 := snapshotLease (ctx2 , t , db , snapshotter )
190+ if leased2 (key2 ) {
191+ t .Errorf ("new lease should not have previously created snapshots" )
192+ }
141193 // This should error out, already exists in namespace
142194 // despite mismatched parent
143- _ , err = sn .Prepare (ctx2 , "test2-tmp-again" , "" , test2opt )
195+ key2ta := "test2-tmp-again"
196+ _ , err = sn .Prepare (ctx2 , key2ta , "" , test2opt )
144197 if err == nil {
145198 t .Fatal ("expected already exists error" )
146199 } else if ! errdefs .IsAlreadyExists (err ) {
147200 t .Fatal (err )
148201 }
202+ if ! leased2 (key2 ) {
203+ t .Errorf ("no lease for %q" , key2 )
204+ }
149205
150206 // In original namespace, but already exists
151- _ , err = sn .Prepare (ctx , "test2-tmp-again" , "test1" , test2opt )
207+ _ , err = sn .Prepare (ctx , key2ta , key1 , test2opt )
152208 if err == nil {
153209 t .Fatal ("expected already exists error" )
154210 } else if ! errdefs .IsAlreadyExists (err ) {
155211 t .Fatal (err )
156212 }
213+ if leased1 (key2ta ) {
214+ t .Errorf ("should not have lease for non-existent snapshot %q" , key2ta )
215+ }
157216
158217 // Now try a third namespace
159218
160219 ctx3 := namespaces .WithNamespace (ctx , "testing3" )
220+ ctx3 , leased3 := snapshotLease (ctx3 , t , db , snapshotter )
161221
162222 // This should error out, matching parent not found
163- _ , err = sn .Prepare (ctx3 , "test2-tmp" , "" , test2opt )
223+ _ , err = sn .Prepare (ctx3 , key2t , "" , test2opt )
164224 if err != nil {
165225 t .Fatal (err )
166226 }
167227
168228 // Remove, not going to use yet
169- err = sn .Remove (ctx3 , "test2-tmp" )
229+ err = sn .Remove (ctx3 , key2t )
170230 if err != nil {
171231 t .Fatal (err )
172232 }
173233
174- _ , err = sn .Prepare (ctx3 , "test2-tmp" , "test1" , test2opt )
234+ _ , err = sn .Prepare (ctx3 , key2t , key1 , test2opt )
175235 if err == nil {
176236 t .Fatal ("expected not error" )
177237 } else if ! errdefs .IsNotFound (err ) {
178238 t .Fatal (err )
179239 }
240+ if leased3 (key1 ) {
241+ t .Errorf ("lease for %q should not have been created" , key1 )
242+ }
180243
181- _ , err = sn .Prepare (ctx3 , "test1-tmp" , "" , test1opt )
244+ _ , err = sn .Prepare (ctx3 , key1t , "" , test1opt )
182245 if err == nil {
183246 t .Fatal ("expected already exists error" )
184247 } else if ! errdefs .IsAlreadyExists (err ) {
185248 t .Fatal (err )
186249 }
250+ if ! leased3 (key1 ) {
251+ t .Errorf ("no lease for %q" , key1 )
252+ }
187253
188254 _ , err = sn .Prepare (ctx3 , "test2-tmp" , "test1" , test2opt )
189255 if err == nil {
190256 t .Fatal ("expected already exists error" )
191257 } else if ! errdefs .IsAlreadyExists (err ) {
192258 t .Fatal (err )
193259 }
260+ if ! leased3 (key2 ) {
261+ t .Errorf ("no lease for %q" , key2 )
262+ }
194263}
195264
196265func TestFilterInheritedLabels (t * testing.T ) {
0 commit comments