@@ -25,12 +25,21 @@ import (
2525
2626 "gotest.tools/v3/assert"
2727
28+ "github.com/containerd/nerdctl/mod/tigron/expect"
29+ "github.com/containerd/nerdctl/mod/tigron/test"
30+ "github.com/containerd/nerdctl/mod/tigron/tig"
31+
2832 "github.com/containerd/nerdctl/v2/pkg/tabutil"
2933 "github.com/containerd/nerdctl/v2/pkg/testutil"
34+ "github.com/containerd/nerdctl/v2/pkg/testutil/nerdtest"
3035)
3136
3237func TestComposePs (t * testing.T ) {
33- base := testutil .NewBase (t )
38+ testCase := nerdtest .Setup ()
39+
40+ testCase .NoParallel = true
41+ testCase .Require = nerdtest .Private
42+
3443 var dockerComposeYAML = fmt .Sprintf (`
3544services:
3645 wordpress:
@@ -61,52 +70,119 @@ volumes:
6170 wordpress:
6271 db:
6372` , 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 )
6873
69- base .ComposeCmd ("-f" , comp .YAMLFullPath (), "up" , "-d" ).AssertOK ()
70- defer base .ComposeCmd ("-f" , comp .YAMLFullPath (), "down" , "-v" ).Run ()
74+ testCase .Setup = func (data test.Data , helpers test.Helpers ) {
75+ composePath := data .Temp ().Save (dockerComposeYAML , "compose.yaml" )
76+ data .Labels ().Set ("composeYaml" , composePath )
77+
78+ helpers .Ensure ("compose" , "-f" , composePath , "up" , "-d" )
79+
80+ time .Sleep (2 * time .Second )
81+ }
82+
83+ testCase .Cleanup = func (data test.Data , helpers test.Helpers ) {
84+ if path := data .Labels ().Get ("composeYaml" ); path != "" {
85+ helpers .Anyhow ("compose" , "-f" , path , "down" , "-v" )
86+ }
87+ }
88+
89+ assertHandler := func (expectedName , expectedImage string ) test.Comparator {
90+ return func (stdout string , t tig.T ) {
7191
72- assertHandler := func (expectedName , expectedImage string ) func (stdout string ) error {
73- return func (stdout string ) error {
7492 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- }
93+ assert .Assert (t , len (lines ) >= 2 )
7894
7995 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- }
96+ assert .NilError (t , tab .ParseHeader (lines [0 ]))
8497
8598 container , _ := tab .ReadRow (lines [1 ], "NAME" )
8699 assert .Equal (t , container , expectedName )
87100
88101 image , _ := tab .ReadRow (lines [1 ], "IMAGE" )
89102 assert .Equal (t , image , expectedImage )
90-
91- return nil
92103 }
104+ }
105+
106+ testCase .SubTests = []* test.Case {
107+
108+ {
109+ Description : "compose ps wordpress" ,
110+ Command : func (data test.Data , helpers test.Helpers ) test.TestableCommand {
111+ return helpers .Command ("compose" , "-f" , data .Labels ().Get ("composeYaml" ), "ps" , "wordpress" )
112+ },
113+ Expected : test .Expects (0 , nil ,
114+ assertHandler ("wordpress_container" , testutil .WordpressImage ),
115+ ),
116+ },
117+
118+ {
119+ Description : "compose ps db" ,
120+ Command : func (data test.Data , helpers test.Helpers ) test.TestableCommand {
121+ return helpers .Command ("compose" , "-f" , data .Labels ().Get ("composeYaml" ), "ps" , "db" )
122+ },
123+ Expected : test .Expects (0 , nil ,
124+ assertHandler ("db_container" , testutil .MariaDBImage ),
125+ ),
126+ },
93127
128+ {
129+ Description : "compose ps should not show alpine unless running" ,
130+ Command : func (data test.Data , helpers test.Helpers ) test.TestableCommand {
131+ return helpers .Command ("compose" , "-f" , data .Labels ().Get ("composeYaml" ), "ps" )
132+ },
133+ Expected : test .Expects (0 , nil ,
134+ expect .DoesNotContain (testutil .CommonImage ),
135+ ),
136+ },
137+
138+ {
139+ Description : "compose ps alpine -a" ,
140+ Command : func (data test.Data , helpers test.Helpers ) test.TestableCommand {
141+ return helpers .Command ("compose" , "-f" , data .Labels ().Get ("composeYaml" ), "ps" , "alpine" , "-a" )
142+ },
143+ Expected : test .Expects (0 , nil ,
144+ assertHandler ("alpine_container" , testutil .CommonImage ),
145+ ),
146+ },
147+
148+ {
149+ Description : "compose ps filter exited" ,
150+ Command : func (data test.Data , helpers test.Helpers ) test.TestableCommand {
151+ return helpers .Command ("compose" , "-f" , data .Labels ().Get ("composeYaml" ), "ps" , "-a" , "--filter" , "status=exited" )
152+ },
153+ Expected : test .Expects (0 , nil ,
154+ assertHandler ("alpine_container" , testutil .CommonImage ),
155+ ),
156+ },
157+
158+ {
159+ Description : "compose ps services" ,
160+ Command : func (data test.Data , helpers test.Helpers ) test.TestableCommand {
161+ return helpers .Command ("compose" , "-f" , data .Labels ().Get ("composeYaml" ), "ps" , "--services" , "-a" )
162+ },
163+ Expected : test .Expects (0 , nil ,
164+ expect .All (
165+ expect .Contains ("wordpress\n " ),
166+ expect .Contains ("db\n " ),
167+ expect .Contains ("alpine\n " ),
168+ ),
169+ ),
170+ },
94171 }
95172
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 " )
173+ testCase .Run (t )
103174}
104175
105176func TestComposePsJSON (t * testing.T ) {
177+
106178 // docker parses unknown 'format' as a Go template and won't output an error
107179 testutil .DockerIncompatible (t )
108180
109- base := testutil .NewBase (t )
181+ testCase := nerdtest .Setup ()
182+
183+ testCase .NoParallel = true
184+ testCase .Require = nerdtest .Private
185+
110186 var dockerComposeYAML = fmt .Sprintf (`
111187services:
112188 wordpress:
@@ -135,50 +211,131 @@ volumes:
135211 db:
136212` , testutil .WordpressImage , testutil .MariaDBImage )
137213
138- comp := testutil .NewComposeDir (t , dockerComposeYAML )
139- defer comp .CleanUp ()
140- projectName := comp .ProjectName ()
141- t .Logf ("projectName=%q" , projectName )
214+ testCase .Setup = func (data test.Data , helpers test.Helpers ) {
142215
143- base .ComposeCmd ("-f" , comp .YAMLFullPath (), "up" , "-d" ).AssertOK ()
144- defer base .ComposeCmd ("-f" , comp .YAMLFullPath (), "down" , "-v" ).Run ()
216+ composePath := data .Temp ().Save (dockerComposeYAML , "compose.yaml" )
217+ data .Labels ().Set ("composeYaml" , composePath )
218+
219+ helpers .Ensure ("compose" , "-f" , composePath , "up" , "-d" )
220+
221+ time .Sleep (2 * time .Second )
222+ }
223+
224+ testCase .Cleanup = func (data test.Data , helpers test.Helpers ) {
225+ if path := data .Labels ().Get ("composeYaml" ); path != "" {
226+ helpers .Anyhow ("compose" , "-f" , path , "down" , "-v" )
227+ }
228+ }
229+
230+ assertHandler := func (svc string , count int , fields ... string ) test.Comparator {
231+ return func (stdout string , t tig.T ) {
145232
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.
149233 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- }
234+ // 1. check json output can be unmarshalled back to printables.
235+ assert .NilError (t , json .Unmarshal ([]byte (stdout ), & printables ))
153236 // 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- }
237+ assert .Equal (t , len (printables ), count )
157238 // 3. check marshalled json string has all expected substrings.
158239 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- }
240+ assert .Assert (t , strings .Contains (stdout , field ),
241+ fmt .Sprintf ("[service: %s] expected %s in %s" , svc , field , stdout ))
162242 }
163- return nil
164243 }
165244 }
166245
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 ))
246+ testCase .SubTests = []* test.Case {
247+
248+ { // check other formats are not supported
249+ Description : "unsupported format should fail" ,
250+ Command : func (data test.Data , helpers test.Helpers ) test.TestableCommand {
251+ return helpers .Command (
252+ "compose" ,
253+ "-f" , data .Labels ().Get ("composeYaml" ),
254+ "ps" ,
255+ "--format" , "yaml" ,
256+ )
257+ },
258+ Expected : test .Expects (1 , nil , nil ),
259+ },
260+
261+ { // check all services are up (can be marshalled and unmarshalled) and check Image field exists
262+ Description : "ps json all services" ,
263+ NoParallel : true ,
264+ Command : func (data test.Data , helpers test.Helpers ) test.TestableCommand {
265+ return helpers .Command ("compose" , "-f" , data .Labels ().Get ("composeYaml" ), "ps" , "--format" , "json" )
266+ },
267+ Expected : test .Expects (0 , nil ,
268+ assertHandler ("all" , 2 ,
269+ `"Service":"wordpress"` ,
270+ `"Service":"db"` ,
271+ fmt .Sprintf (`"Image":"%s"` , testutil .WordpressImage ),
272+ fmt .Sprintf (`"Image":"%s"` , testutil .MariaDBImage ),
273+ ),
274+ ),
275+ },
276+
277+ { // check wordpress is running
278+ Description : "wordpress running" ,
279+ NoParallel : true ,
280+ Command : func (data test.Data , helpers test.Helpers ) test.TestableCommand {
281+ return helpers .Command ("compose" , "-f" , data .Labels ().Get ("composeYaml" ),
282+ "ps" , "--format" , "json" , "wordpress" )
283+ },
284+ Expected : test .Expects (0 , nil ,
285+ assertHandler ("wordpress" , 1 ,
286+ `"Service":"wordpress"` ,
287+ `"State":"running"` ,
288+ `"TargetPort":80` ,
289+ `"PublishedPort":8080` ,
290+ )),
291+ },
292+
293+ {
294+ Description : "stop wordpress" ,
295+ NoParallel : true ,
296+ Command : func (data test.Data , helpers test.Helpers ) test.TestableCommand {
297+ return helpers .Command ("compose" , "-f" , data .Labels ().Get ("composeYaml" ),
298+ "stop" , "wordpress" )
299+ },
300+ Expected : test .Expects (0 , nil , nil ),
301+ },
302+
303+ { // check wordpress is stopped
304+ Description : "wordpress exited" ,
305+ NoParallel : true ,
306+ Command : func (data test.Data , helpers test.Helpers ) test.TestableCommand {
307+ return helpers .Command ("compose" , "-f" , data .Labels ().Get ("composeYaml" ),
308+ "ps" , "--format" , "json" , "wordpress" , "-a" )
309+ },
310+ Expected : test .Expects (0 , nil ,
311+ assertHandler ("wordpress" , 1 ,
312+ `"Service":"wordpress"` ,
313+ `"State":"exited"` ,
314+ )),
315+ },
316+
317+ {
318+ Description : "remove wordpress" ,
319+ NoParallel : true ,
320+ Command : func (data test.Data , helpers test.Helpers ) test.TestableCommand {
321+ return helpers .Command ("compose" , "-f" , data .Labels ().Get ("composeYaml" ),
322+ "rm" , "-f" , "wordpress" )
323+ },
324+ Expected : test .Expects (0 , nil , nil ),
325+ },
326+
327+ { // check wordpress is removed
328+ Description : "wordpress removed" ,
329+ NoParallel : true ,
330+ Command : func (data test.Data , helpers test.Helpers ) test.TestableCommand {
331+ return helpers .Command ("compose" , "-f" , data .Labels ().Get ("composeYaml" ),
332+ "ps" , "--format" , "json" , "wordpress" )
333+ },
334+ Expected : test .Expects (0 , nil ,
335+ assertHandler ("wordpress" , 0 ),
336+ ),
337+ },
338+ }
339+
340+ testCase .Run (t )
184341}
0 commit comments