@@ -22,16 +22,18 @@ import (
2222 "fmt"
2323 "os"
2424 "path/filepath"
25+ "strconv"
2526 "strings"
2627 "testing"
2728
28- "github.com/moby/sys/userns"
2929 "gotest.tools/v3/assert"
3030
3131 "github.com/containerd/cgroups/v3"
3232 containerd "github.com/containerd/containerd/v2/client"
3333 "github.com/containerd/continuity/testutil/loopback"
34+ "github.com/containerd/nerdctl/mod/tigron/expect"
3435 "github.com/containerd/nerdctl/mod/tigron/require"
36+ "github.com/containerd/nerdctl/mod/tigron/test"
3537
3638 "github.com/containerd/nerdctl/v2/pkg/cmd/container"
3739 "github.com/containerd/nerdctl/v2/pkg/idutil/containerwalker"
@@ -224,9 +226,9 @@ func TestIssue3781(t *testing.T) {
224226}
225227
226228func 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
230232
231233 if unameR := infoutil .UnameR (); strings .Contains (unameR , ".el8" ) {
232234 t .Logf ("Assuming to be running on EL8 (kernel release %q)" , unameR )
@@ -238,39 +240,93 @@ func TestRunDevice(t *testing.T) {
238240
239241 const n = 3
240242 lo := make ([]* loopback.Loopback , n )
241- loContent := make ([]string , n )
242243
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 ())
251275 }
252276
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 )
274330}
275331
276332func TestParseDevice (t * testing.T ) {
0 commit comments