@@ -22,16 +22,18 @@ import (
22
22
"fmt"
23
23
"os"
24
24
"path/filepath"
25
+ "strconv"
25
26
"strings"
26
27
"testing"
27
28
28
- "github.com/moby/sys/userns"
29
29
"gotest.tools/v3/assert"
30
30
31
31
"github.com/containerd/cgroups/v3"
32
32
containerd "github.com/containerd/containerd/v2/client"
33
33
"github.com/containerd/continuity/testutil/loopback"
34
+ "github.com/containerd/nerdctl/mod/tigron/expect"
34
35
"github.com/containerd/nerdctl/mod/tigron/require"
36
+ "github.com/containerd/nerdctl/mod/tigron/test"
35
37
36
38
"github.com/containerd/nerdctl/v2/pkg/cmd/container"
37
39
"github.com/containerd/nerdctl/v2/pkg/idutil/containerwalker"
@@ -224,9 +226,9 @@ func TestIssue3781(t *testing.T) {
224
226
}
225
227
226
228
func TestRunDevice (t * testing.T ) {
227
- if os . Geteuid () != 0 || userns . RunningInUserNS () {
228
- t . Skip ( "test requires the root in the initial user namespace" )
229
- }
229
+ testCase := nerdtest . Setup ()
230
+
231
+ testCase . Require = nerdtest . Rootful
230
232
231
233
if unameR := infoutil .UnameR (); strings .Contains (unameR , ".el8" ) {
232
234
t .Logf ("Assuming to be running on EL8 (kernel release %q)" , unameR )
@@ -238,39 +240,93 @@ func TestRunDevice(t *testing.T) {
238
240
239
241
const n = 3
240
242
lo := make ([]* loopback.Loopback , n )
241
- loContent := make ([]string , n )
242
243
243
- for i := 0 ; i < n ; i ++ {
244
- var err error
245
- lo [i ], err = loopback .New (4096 )
246
- assert .NilError (t , err )
247
- t .Logf ("lo[%d] = %+v" , i , lo [i ])
248
- defer lo [i ].Close ()
249
- loContent [i ] = fmt .Sprintf ("lo%d-content" , i )
250
- assert .NilError (t , os .WriteFile (lo [i ].Device , []byte (loContent [i ]), 0700 ))
244
+ testCase .Setup = func (data test.Data , helpers test.Helpers ) {
245
+
246
+ for i := 0 ; i < n ; i ++ {
247
+ var err error
248
+ lo [i ], err = loopback .New (4096 )
249
+ assert .NilError (t , err )
250
+ t .Logf ("lo[%d] = %+v" , i , lo [i ])
251
+ loContent := fmt .Sprintf ("lo%d-content" , i )
252
+ assert .NilError (t , os .WriteFile (lo [i ].Device , []byte (loContent ), 0o700 ))
253
+ data .Set ("loContent" + strconv .Itoa (i ), loContent )
254
+ }
255
+
256
+ // lo0 is readable but not writable.
257
+ // lo1 is readable and writable
258
+ // lo2 is not accessible.
259
+ helpers .Ensure ("run" ,
260
+ "-d" ,
261
+ "--name" , data .Identifier (),
262
+ "--device" , lo [0 ].Device + ":r" ,
263
+ "--device" , lo [1 ].Device ,
264
+ testutil .AlpineImage , "sleep" , nerdtest .Infinity )
265
+ data .Set ("id" , data .Identifier ())
266
+ }
267
+
268
+ testCase .Cleanup = func (data test.Data , helpers test.Helpers ) {
269
+ for i := 0 ; i < n ; i ++ {
270
+ if lo [i ] != nil {
271
+ _ = lo [i ].Close ()
272
+ }
273
+ }
274
+ helpers .Anyhow ("rm" , "-f" , data .Identifier ())
251
275
}
252
276
253
- base := testutil .NewBase (t )
254
- containerName := testutil .Identifier (t )
255
- defer base .Cmd ("rm" , "-f" , containerName ).AssertOK ()
256
- // lo0 is readable but not writable.
257
- // lo1 is readable and writable
258
- // lo2 is not accessible.
259
- base .Cmd ("run" ,
260
- "-d" ,
261
- "--name" , containerName ,
262
- "--device" , lo [0 ].Device + ":r" ,
263
- "--device" , lo [1 ].Device ,
264
- testutil .AlpineImage , "sleep" , nerdtest .Infinity ).Run ()
265
-
266
- base .Cmd ("exec" , containerName , "cat" , lo [0 ].Device ).AssertOutContains (loContent [0 ])
267
- base .Cmd ("exec" , containerName , "cat" , lo [1 ].Device ).AssertOutContains (loContent [1 ])
268
- base .Cmd ("exec" , containerName , "cat" , lo [2 ].Device ).AssertFail ()
269
- base .Cmd ("exec" , containerName , "sh" , "-ec" , "echo -n \" overwritten-lo0-content\" >" + lo [0 ].Device ).AssertFail ()
270
- base .Cmd ("exec" , containerName , "sh" , "-ec" , "echo -n \" overwritten-lo1-content\" >" + lo [1 ].Device ).AssertOK ()
271
- lo1Read , err := os .ReadFile (lo [1 ].Device )
272
- assert .NilError (t , err )
273
- assert .Equal (t , string (bytes .Trim (lo1Read , "\x00 " )), "overwritten-lo1-content" )
277
+ testCase .SubTests = []* test.Case {
278
+ {
279
+ Description : "can read lo0" ,
280
+ Command : func (data test.Data , helpers test.Helpers ) test.TestableCommand {
281
+ return helpers .Command ("exec" , data .Get ("id" ), "cat" , lo [0 ].Device )
282
+ },
283
+ Expected : func (data test.Data , helpers test.Helpers ) * test.Expected {
284
+ return & test.Expected {
285
+ Output : expect .Contains (data .Get ("locontent0" )),
286
+ }
287
+ },
288
+ },
289
+ {
290
+ Description : "cannot write lo0" ,
291
+ Command : func (data test.Data , helpers test.Helpers ) test.TestableCommand {
292
+ return helpers .Command ("exec" , data .Get ("id" ), "sh" , "-ec" , "echo -n \" overwritten-lo1-content\" >" + lo [0 ].Device )
293
+ },
294
+ Expected : test .Expects (expect .ExitCodeGenericFail , nil , nil ),
295
+ },
296
+ {
297
+ Description : "cannot read lo2" ,
298
+ Command : func (data test.Data , helpers test.Helpers ) test.TestableCommand {
299
+ return helpers .Command ("exec" , data .Get ("id" ), "cat" , lo [2 ].Device )
300
+ },
301
+ Expected : test .Expects (expect .ExitCodeGenericFail , nil , nil ),
302
+ },
303
+ {
304
+ Description : "can read lo1" ,
305
+ NoParallel : true ,
306
+ Command : func (data test.Data , helpers test.Helpers ) test.TestableCommand {
307
+ return helpers .Command ("exec" , data .Get ("id" ), "cat" , lo [1 ].Device )
308
+ },
309
+ Expected : func (data test.Data , helpers test.Helpers ) * test.Expected {
310
+ return & test.Expected {
311
+ Output : expect .Contains (data .Get ("locontent1" )),
312
+ }
313
+ },
314
+ },
315
+ {
316
+ Description : "can write lo1 and read back updated value" ,
317
+ NoParallel : true ,
318
+ Command : func (data test.Data , helpers test.Helpers ) test.TestableCommand {
319
+ return helpers .Command ("exec" , data .Get ("id" ), "sh" , "-ec" , "echo -n \" overwritten-lo1-content\" >" + lo [1 ].Device )
320
+ },
321
+ Expected : test .Expects (expect .ExitCodeSuccess , nil , func (stdout string , info string , t * testing.T ) {
322
+ lo1Read , err := os .ReadFile (lo [1 ].Device )
323
+ assert .NilError (t , err )
324
+ assert .Equal (t , string (bytes .Trim (lo1Read , "\x00 " )), "overwritten-lo1-content" )
325
+ }),
326
+ },
327
+ }
328
+
329
+ testCase .Run (t )
274
330
}
275
331
276
332
func TestParseDevice (t * testing.T ) {
0 commit comments