@@ -24,81 +24,99 @@ import (
24
24
"gotest.tools/v3/assert"
25
25
26
26
"github.com/containerd/nerdctl/v2/pkg/testutil"
27
+ "github.com/containerd/nerdctl/v2/pkg/testutil/nerdtest"
28
+ "github.com/containerd/nerdctl/v2/pkg/testutil/test"
27
29
)
28
30
29
- // skipAttachForDocker should be called by attach-related tests that assert 'read detach keys' in stdout.
30
- func skipAttachForDocker (t * testing.T ) {
31
- t .Helper ()
32
- if testutil .GetTarget () == testutil .Docker {
33
- t .Skip ("When detaching from a container, for a session started with 'docker attach'" +
34
- ", it prints 'read escape sequence', but for one started with 'docker (run|start)', it prints nothing." +
35
- " However, the flag is called '--detach-keys' in all cases" +
36
- ", so nerdctl prints 'read detach keys' for all cases" +
37
- ", and that's why this test is skipped for Docker." )
38
- }
39
- }
40
-
41
- // prepareContainerToAttach spins up a container (entrypoint = shell) with `-it` and detaches from it
42
- // so that it can be re-attached to later.
43
- func prepareContainerToAttach (base * testutil.Base , containerName string ) {
44
- opts := []func (* testutil.Cmd ){
45
- testutil .WithStdin (testutil .NewDelayOnceReader (bytes .NewReader (
31
+ func TestAttachDetachKeys (t * testing.T ) {
32
+ testCase := nerdtest .Setup ()
33
+
34
+ setup := func (data test.Data , helpers test.Helpers ) {
35
+ // unbuffer(1) emulates tty, which is required by `nerdctl run -t`.
36
+ // unbuffer(1) can be installed with `apt-get install expect`.
37
+ //
38
+ // "-p" is needed because we need unbuffer to read from stdin, and from [1]:
39
+ // "Normally, unbuffer does not read from stdin. This simplifies use of unbuffer in some situations.
40
+ // To use unbuffer in a pipeline, use the -p flag."
41
+ //
42
+ // [1] https://linux.die.net/man/1/unbuffer
43
+
44
+ si := testutil .NewDelayOnceReader (bytes .NewReader (
46
45
[]byte {16 , 17 }, // ctrl+p,ctrl+q, see https://www.physics.udel.edu/~watson/scen103/ascii.html
47
- ))),
46
+ ))
47
+
48
+ cmd := helpers .
49
+ Command ("run" , "-it" , "--name" , data .Identifier (), testutil .CommonImage )
50
+ cmd .WithWrapper ("unbuffer" , "-p" )
51
+ cmd .WithStdin (si )
52
+ cmd .Run (& test.Expected {
53
+ Output : test .All (
54
+ // NOTE:
55
+ // When detaching from a container, for a session started with 'docker attach',
56
+ // it prints 'read escape sequence', but for one started with 'docker (run|start)', it prints nothing.
57
+ // However, the flag is called '--detach-keys' in all cases, and nerdctl does print read detach keys
58
+ // in all cases.
59
+ // Disabling the contains test here allow both cli to run the test.
60
+ // test.Contains("read detach keys"),
61
+ func (stdout string , info string , t * testing.T ) {
62
+ container := nerdtest .InspectContainer (helpers , data .Identifier ())
63
+ assert .Equal (t , container .State .Running , true , info )
64
+ }),
65
+ })
48
66
}
49
- // unbuffer(1) emulates tty, which is required by `nerdctl run -t`.
50
- // unbuffer(1) can be installed with `apt-get install expect`.
51
- //
52
- // "-p" is needed because we need unbuffer to read from stdin, and from [1]:
53
- // "Normally, unbuffer does not read from stdin. This simplifies use of unbuffer in some situations.
54
- // To use unbuffer in a pipeline, use the -p flag."
55
- //
56
- // [1] https://linux.die.net/man/1/unbuffer
57
- base .CmdWithHelper ([]string {"unbuffer" , "-p" }, "run" , "-it" , "--name" , containerName , testutil .CommonImage ).
58
- CmdOption (opts ... ).AssertOutContains ("read detach keys" )
59
- container := base .InspectContainer (containerName )
60
- assert .Equal (base .T , container .State .Running , true )
61
- }
62
-
63
- func TestAttach (t * testing.T ) {
64
- t .Parallel ()
65
-
66
- skipAttachForDocker (t )
67
-
68
- base := testutil .NewBase (t )
69
- containerName := testutil .Identifier (t )
70
67
71
- defer base .Cmd ("container" , "rm" , "-f" , containerName ).AssertOK ()
72
- prepareContainerToAttach (base , containerName )
73
-
74
- opts := []func (* testutil.Cmd ){
75
- testutil .WithStdin (testutil .NewDelayOnceReader (strings .NewReader ("expr 1 + 1\n exit\n " ))),
68
+ testCase .SubTests = []* test.Case {
69
+ {
70
+ Description : "TestAttachDefaultKeys" ,
71
+ Require : test .Binary ("unbuffer" ),
72
+ Cleanup : func (data test.Data , helpers test.Helpers ) {
73
+ helpers .Anyhow ("container" , "rm" , "-f" , data .Identifier ())
74
+ },
75
+ Setup : setup ,
76
+ Command : func (data test.Data , helpers test.Helpers ) test.TestableCommand {
77
+ si := testutil .NewDelayOnceReader (strings .NewReader ("expr 1 + 1\n exit\n " ))
78
+ // `unbuffer -p` returns 0 even if the underlying nerdctl process returns a non-zero exit code,
79
+ // so the exit code cannot be easily tested here.
80
+ cmd := helpers .Command ("attach" , data .Identifier ())
81
+ cmd .WithStdin (si )
82
+ cmd .WithWrapper ("unbuffer" , "-p" )
83
+
84
+ return cmd
85
+ },
86
+ Expected : func (data test.Data , helpers test.Helpers ) * test.Expected {
87
+ return & test.Expected {
88
+ Output : func (stdout string , info string , t * testing.T ) {
89
+ container := nerdtest .InspectContainer (helpers , data .Identifier ())
90
+ assert .Equal (t , container .State .Running , false , info )
91
+ },
92
+ }
93
+ },
94
+ },
95
+ {
96
+ Description : "TestAttachCustomKeys" ,
97
+ Require : test .Binary ("unbuffer" ),
98
+ Cleanup : func (data test.Data , helpers test.Helpers ) {
99
+ helpers .Anyhow ("container" , "rm" , "-f" , data .Identifier ())
100
+ },
101
+ Setup : setup ,
102
+ Command : func (data test.Data , helpers test.Helpers ) test.TestableCommand {
103
+ si := testutil .NewDelayOnceReader (bytes .NewReader ([]byte {1 , 2 }))
104
+ cmd := helpers .
105
+ Command ("attach" , "--detach-keys=ctrl-a,ctrl-b" , data .Identifier ())
106
+ cmd .WithStdin (si )
107
+ cmd .WithWrapper ("unbuffer" , "-p" )
108
+ return cmd
109
+ },
110
+ Expected : func (data test.Data , helpers test.Helpers ) * test.Expected {
111
+ return & test.Expected {
112
+ Output : func (stdout string , info string , t * testing.T ) {
113
+ container := nerdtest .InspectContainer (helpers , data .Identifier ())
114
+ assert .Equal (t , container .State .Running , true , info )
115
+ },
116
+ }
117
+ },
118
+ },
76
119
}
77
- // `unbuffer -p` returns 0 even if the underlying nerdctl process returns a non-zero exit code,
78
- // so the exit code cannot be easily tested here.
79
- base .CmdWithHelper ([]string {"unbuffer" , "-p" }, "attach" , containerName ).CmdOption (opts ... ).AssertOutContains ("2" )
80
- container := base .InspectContainer (containerName )
81
- assert .Equal (base .T , container .State .Running , false )
82
- }
83
-
84
- func TestAttachDetachKeys (t * testing.T ) {
85
- t .Parallel ()
86
120
87
- skipAttachForDocker (t )
88
-
89
- base := testutil .NewBase (t )
90
- containerName := testutil .Identifier (t )
91
-
92
- defer base .Cmd ("container" , "rm" , "-f" , containerName ).AssertOK ()
93
- prepareContainerToAttach (base , containerName )
94
-
95
- opts := []func (* testutil.Cmd ){
96
- testutil .WithStdin (testutil .NewDelayOnceReader (bytes .NewReader (
97
- []byte {1 , 2 }, // https://www.physics.udel.edu/~watson/scen103/ascii.html
98
- ))),
99
- }
100
- base .CmdWithHelper ([]string {"unbuffer" , "-p" }, "attach" , "--detach-keys=ctrl-a,ctrl-b" , containerName ).
101
- CmdOption (opts ... ).AssertOutContains ("read detach keys" )
102
- container := base .InspectContainer (containerName )
103
- assert .Equal (base .T , container .State .Running , true )
121
+ testCase .Run (t )
104
122
}
0 commit comments