@@ -27,10 +27,20 @@ import (
2727
2828 "github.com/containerd/nerdctl/v2/pkg/tabutil"
2929 "github.com/containerd/nerdctl/v2/pkg/testutil"
30+
31+ "github.com/containerd/nerdctl/mod/tigron/expect"
32+ "github.com/containerd/nerdctl/mod/tigron/test"
33+ "github.com/containerd/nerdctl/mod/tigron/tig"
34+
35+ "github.com/containerd/nerdctl/v2/pkg/testutil/nerdtest"
3036)
3137
3238func TestComposePs (t * testing.T ) {
33- base := testutil .NewBase (t )
39+ testCase := nerdtest .Setup ()
40+
41+ testCase .NoParallel = true
42+ testCase .Require = nerdtest .Private
43+
3444 var dockerComposeYAML = fmt .Sprintf (`
3545services:
3646 wordpress:
@@ -61,52 +71,119 @@ volumes:
6171 wordpress:
6272 db:
6373` , testutil .WordpressImage , testutil .MariaDBImage , testutil .CommonImage )
64- comp := testutil .NewComposeDir (t , dockerComposeYAML )
65- defer comp .CleanUp ()
66- projectName := comp .ProjectName ()
67- t .Logf ("projectName=%q" , projectName )
6874
69- base .ComposeCmd ("-f" , comp .YAMLFullPath (), "up" , "-d" ).AssertOK ()
70- defer base .ComposeCmd ("-f" , comp .YAMLFullPath (), "down" , "-v" ).Run ()
75+ testCase .Setup = func (data test.Data , helpers test.Helpers ) {
76+ composePath := data .Temp ().Save (dockerComposeYAML , "compose.yaml" )
77+ data .Labels ().Set ("composeYaml" , composePath )
78+
79+ helpers .Ensure ("compose" , "-f" , composePath , "up" , "-d" )
80+
81+ time .Sleep (2 * time .Second )
82+ }
83+
84+ testCase .Cleanup = func (data test.Data , helpers test.Helpers ) {
85+ if path := data .Labels ().Get ("composeYaml" ); path != "" {
86+ helpers .Anyhow ("compose" , "-f" , path , "down" , "-v" )
87+ }
88+ }
89+
90+ assertHandler := func (expectedName , expectedImage string ) test.Comparator {
91+ return func (stdout string , t tig.T ) {
7192
72- assertHandler := func (expectedName , expectedImage string ) func (stdout string ) error {
73- return func (stdout string ) error {
7493 lines := strings .Split (strings .TrimSpace (stdout ), "\n " )
75- if len (lines ) < 2 {
76- return fmt .Errorf ("expected at least 2 lines, got %d" , len (lines ))
77- }
94+ assert .Assert (t , len (lines ) >= 2 )
7895
7996 tab := tabutil .NewReader ("NAME\t IMAGE\t COMMAND\t SERVICE\t STATUS\t PORTS" )
80- err := tab .ParseHeader (lines [0 ])
81- if err != nil {
82- return fmt .Errorf ("failed to parse header: %v" , err )
83- }
97+ assert .NilError (t , tab .ParseHeader (lines [0 ]))
8498
8599 container , _ := tab .ReadRow (lines [1 ], "NAME" )
86100 assert .Equal (t , container , expectedName )
87101
88102 image , _ := tab .ReadRow (lines [1 ], "IMAGE" )
89103 assert .Equal (t , image , expectedImage )
90-
91- return nil
92104 }
105+ }
106+
107+ testCase .SubTests = []* test.Case {
108+
109+ {
110+ Description : "compose ps wordpress" ,
111+ Command : func (data test.Data , helpers test.Helpers ) test.TestableCommand {
112+ return helpers .Command ("compose" , "-f" , data .Labels ().Get ("composeYaml" ), "ps" , "wordpress" )
113+ },
114+ Expected : test .Expects (0 , nil ,
115+ assertHandler ("wordpress_container" , testutil .WordpressImage ),
116+ ),
117+ },
93118
119+ {
120+ Description : "compose ps db" ,
121+ Command : func (data test.Data , helpers test.Helpers ) test.TestableCommand {
122+ return helpers .Command ("compose" , "-f" , data .Labels ().Get ("composeYaml" ), "ps" , "db" )
123+ },
124+ Expected : test .Expects (0 , nil ,
125+ assertHandler ("db_container" , testutil .MariaDBImage ),
126+ ),
127+ },
128+
129+ {
130+ Description : "compose ps should not show alpine unless running" ,
131+ Command : func (data test.Data , helpers test.Helpers ) test.TestableCommand {
132+ return helpers .Command ("compose" , "-f" , data .Labels ().Get ("composeYaml" ), "ps" )
133+ },
134+ Expected : test .Expects (0 , nil ,
135+ expect .DoesNotContain (testutil .CommonImage ),
136+ ),
137+ },
138+
139+ {
140+ Description : "compose ps alpine -a" ,
141+ Command : func (data test.Data , helpers test.Helpers ) test.TestableCommand {
142+ return helpers .Command ("compose" , "-f" , data .Labels ().Get ("composeYaml" ), "ps" , "alpine" , "-a" )
143+ },
144+ Expected : test .Expects (0 , nil ,
145+ assertHandler ("alpine_container" , testutil .CommonImage ),
146+ ),
147+ },
148+
149+ {
150+ Description : "compose ps filter exited" ,
151+ Command : func (data test.Data , helpers test.Helpers ) test.TestableCommand {
152+ return helpers .Command ("compose" , "-f" , data .Labels ().Get ("composeYaml" ), "ps" , "-a" , "--filter" , "status=exited" )
153+ },
154+ Expected : test .Expects (0 , nil ,
155+ assertHandler ("alpine_container" , testutil .CommonImage ),
156+ ),
157+ },
158+
159+ {
160+ Description : "compose ps services" ,
161+ Command : func (data test.Data , helpers test.Helpers ) test.TestableCommand {
162+ return helpers .Command ("compose" , "-f" , data .Labels ().Get ("composeYaml" ), "ps" , "--services" , "-a" )
163+ },
164+ Expected : test .Expects (0 , nil ,
165+ expect .All (
166+ expect .Contains ("wordpress\n " ),
167+ expect .Contains ("db\n " ),
168+ expect .Contains ("alpine\n " ),
169+ ),
170+ ),
171+ },
94172 }
95173
96- time .Sleep (3 * time .Second )
97- base .ComposeCmd ("-f" , comp .YAMLFullPath (), "ps" , "wordpress" ).AssertOutWithFunc (assertHandler ("wordpress_container" , testutil .WordpressImage ))
98- base .ComposeCmd ("-f" , comp .YAMLFullPath (), "ps" , "db" ).AssertOutWithFunc (assertHandler ("db_container" , testutil .MariaDBImage ))
99- base .ComposeCmd ("-f" , comp .YAMLFullPath (), "ps" ).AssertOutNotContains (testutil .CommonImage )
100- base .ComposeCmd ("-f" , comp .YAMLFullPath (), "ps" , "alpine" , "-a" ).AssertOutWithFunc (assertHandler ("alpine_container" , testutil .CommonImage ))
101- base .ComposeCmd ("-f" , comp .YAMLFullPath (), "ps" , "-a" , "--filter" , "status=exited" ).AssertOutWithFunc (assertHandler ("alpine_container" , testutil .CommonImage ))
102- base .ComposeCmd ("-f" , comp .YAMLFullPath (), "ps" , "--services" , "-a" ).AssertOutContainsAll ("wordpress\n " , "db\n " , "alpine\n " )
174+ testCase .Run (t )
103175}
104176
105177func TestComposePsJSON (t * testing.T ) {
178+
106179 // docker parses unknown 'format' as a Go template and won't output an error
107180 testutil .DockerIncompatible (t )
108181
109- base := testutil .NewBase (t )
182+ testCase := nerdtest .Setup ()
183+
184+ testCase .NoParallel = true
185+ testCase .Require = nerdtest .Private
186+
110187 var dockerComposeYAML = fmt .Sprintf (`
111188services:
112189 wordpress:
@@ -135,50 +212,131 @@ volumes:
135212 db:
136213` , testutil .WordpressImage , testutil .MariaDBImage )
137214
138- comp := testutil .NewComposeDir (t , dockerComposeYAML )
139- defer comp .CleanUp ()
140- projectName := comp .ProjectName ()
141- t .Logf ("projectName=%q" , projectName )
215+ testCase .Setup = func (data test.Data , helpers test.Helpers ) {
142216
143- base .ComposeCmd ("-f" , comp .YAMLFullPath (), "up" , "-d" ).AssertOK ()
144- defer base .ComposeCmd ("-f" , comp .YAMLFullPath (), "down" , "-v" ).Run ()
217+ composePath := data .Temp ().Save (dockerComposeYAML , "compose.yaml" )
218+ data .Labels ().Set ("composeYaml" , composePath )
219+
220+ helpers .Ensure ("compose" , "-f" , composePath , "up" , "-d" )
221+
222+ time .Sleep (2 * time .Second )
223+ }
224+
225+ testCase .Cleanup = func (data test.Data , helpers test.Helpers ) {
226+ if path := data .Labels ().Get ("composeYaml" ); path != "" {
227+ helpers .Anyhow ("compose" , "-f" , path , "down" , "-v" )
228+ }
229+ }
230+
231+ assertHandler := func (svc string , count int , fields ... string ) test.Comparator {
232+ return func (stdout string , t tig.T ) {
145233
146- assertHandler := func (svc string , count int , fields ... string ) func (stdout string ) error {
147- return func (stdout string ) error {
148- // 1. check json output can be unmarshalled back to printables.
149234 var printables []composeContainerPrintable
150- if err := json .Unmarshal ([]byte (stdout ), & printables ); err != nil {
151- return fmt .Errorf ("[service: %s]failed to unmarshal json output from `compose ps`: %s" , svc , stdout )
152- }
235+ // 1. check json output can be unmarshalled back to printables.
236+ assert .NilError (t , json .Unmarshal ([]byte (stdout ), & printables ))
153237 // 2. check #printables matches expected count.
154- if len (printables ) != count {
155- return fmt .Errorf ("[service: %s]unmarshal generates %d printables, expected %d: %s" , svc , len (printables ), count , stdout )
156- }
238+ assert .Equal (t , len (printables ), count )
157239 // 3. check marshalled json string has all expected substrings.
158240 for _ , field := range fields {
159- if ! strings .Contains (stdout , field ) {
160- return fmt .Errorf ("[service: %s]marshalled json output doesn't have expected string (%s): %s" , svc , field , stdout )
161- }
241+ assert .Assert (t , strings .Contains (stdout , field ),
242+ fmt .Sprintf ("[service: %s] expected %s in %s" , svc , field , stdout ))
162243 }
163- return nil
164244 }
165245 }
166246
167- // check other formats are not supported
168- base .ComposeCmd ("-f" , comp .YAMLFullPath (), "ps" , "--format" , "yaml" ).AssertFail ()
169- // check all services are up (can be marshalled and unmarshalled) and check Image field exists
170- base .ComposeCmd ("-f" , comp .YAMLFullPath (), "ps" , "--format" , "json" ).
171- AssertOutWithFunc (assertHandler ("all" , 2 , `"Service":"wordpress"` , `"Service":"db"` ,
172- fmt .Sprintf (`"Image":"%s"` , testutil .WordpressImage ), fmt .Sprintf (`"Image":"%s"` , testutil .MariaDBImage )))
173- // check wordpress is running
174- base .ComposeCmd ("-f" , comp .YAMLFullPath (), "ps" , "--format" , "json" , "wordpress" ).
175- AssertOutWithFunc (assertHandler ("wordpress" , 1 , `"Service":"wordpress"` , `"State":"running"` , `"TargetPort":80` , `"PublishedPort":8080` ))
176- // check wordpress is stopped
177- base .ComposeCmd ("-f" , comp .YAMLFullPath (), "stop" , "wordpress" ).AssertOK ()
178- base .ComposeCmd ("-f" , comp .YAMLFullPath (), "ps" , "--format" , "json" , "wordpress" , "-a" ).
179- AssertOutWithFunc (assertHandler ("wordpress" , 1 , `"Service":"wordpress"` , `"State":"exited"` ))
180- // check wordpress is removed
181- base .ComposeCmd ("-f" , comp .YAMLFullPath (), "rm" , "-f" , "wordpress" ).AssertOK ()
182- base .ComposeCmd ("-f" , comp .YAMLFullPath (), "ps" , "--format" , "json" , "wordpress" ).
183- AssertOutWithFunc (assertHandler ("wordpress" , 0 ))
247+ testCase .SubTests = []* test.Case {
248+
249+ { // check other formats are not supported
250+ Description : "unsupported format should fail" ,
251+ Command : func (data test.Data , helpers test.Helpers ) test.TestableCommand {
252+ return helpers .Command (
253+ "compose" ,
254+ "-f" , data .Labels ().Get ("composeYaml" ),
255+ "ps" ,
256+ "--format" , "yaml" ,
257+ )
258+ },
259+ Expected : test .Expects (1 , nil , nil ),
260+ },
261+
262+ { // check all services are up (can be marshalled and unmarshalled) and check Image field exists
263+ Description : "ps json all services" ,
264+ NoParallel : true ,
265+ Command : func (data test.Data , helpers test.Helpers ) test.TestableCommand {
266+ return helpers .Command ("compose" , "-f" , data .Labels ().Get ("composeYaml" ), "ps" , "--format" , "json" )
267+ },
268+ Expected : test .Expects (0 , nil ,
269+ assertHandler ("all" , 2 ,
270+ `"Service":"wordpress"` ,
271+ `"Service":"db"` ,
272+ fmt .Sprintf (`"Image":"%s"` , testutil .WordpressImage ),
273+ fmt .Sprintf (`"Image":"%s"` , testutil .MariaDBImage ),
274+ ),
275+ ),
276+ },
277+
278+ { // check wordpress is running
279+ Description : "wordpress running" ,
280+ NoParallel : true ,
281+ Command : func (data test.Data , helpers test.Helpers ) test.TestableCommand {
282+ return helpers .Command ("compose" , "-f" , data .Labels ().Get ("composeYaml" ),
283+ "ps" , "--format" , "json" , "wordpress" )
284+ },
285+ Expected : test .Expects (0 , nil ,
286+ assertHandler ("wordpress" , 1 ,
287+ `"Service":"wordpress"` ,
288+ `"State":"running"` ,
289+ `"TargetPort":80` ,
290+ `"PublishedPort":8080` ,
291+ )),
292+ },
293+
294+ {
295+ Description : "stop wordpress" ,
296+ NoParallel : true ,
297+ Command : func (data test.Data , helpers test.Helpers ) test.TestableCommand {
298+ return helpers .Command ("compose" , "-f" , data .Labels ().Get ("composeYaml" ),
299+ "stop" , "wordpress" )
300+ },
301+ Expected : test .Expects (0 , nil , nil ),
302+ },
303+
304+ { // check wordpress is stopped
305+ Description : "wordpress exited" ,
306+ NoParallel : true ,
307+ Command : func (data test.Data , helpers test.Helpers ) test.TestableCommand {
308+ return helpers .Command ("compose" , "-f" , data .Labels ().Get ("composeYaml" ),
309+ "ps" , "--format" , "json" , "wordpress" , "-a" )
310+ },
311+ Expected : test .Expects (0 , nil ,
312+ assertHandler ("wordpress" , 1 ,
313+ `"Service":"wordpress"` ,
314+ `"State":"exited"` ,
315+ )),
316+ },
317+
318+ {
319+ Description : "remove wordpress" ,
320+ NoParallel : true ,
321+ Command : func (data test.Data , helpers test.Helpers ) test.TestableCommand {
322+ return helpers .Command ("compose" , "-f" , data .Labels ().Get ("composeYaml" ),
323+ "rm" , "-f" , "wordpress" )
324+ },
325+ Expected : test .Expects (0 , nil , nil ),
326+ },
327+
328+ { // check wordpress is removed
329+ Description : "wordpress removed" ,
330+ NoParallel : true ,
331+ Command : func (data test.Data , helpers test.Helpers ) test.TestableCommand {
332+ return helpers .Command ("compose" , "-f" , data .Labels ().Get ("composeYaml" ),
333+ "ps" , "--format" , "json" , "wordpress" )
334+ },
335+ Expected : test .Expects (0 , nil ,
336+ assertHandler ("wordpress" , 0 ),
337+ ),
338+ },
339+ }
340+
341+ testCase .Run (t )
184342}
0 commit comments