Skip to content

Commit 02560e3

Browse files
committed
test: revert TestComposeRunWithServicePorts and TestComposeRunWithPublish to legacy framework
These two tests run a long-lived nginx container that the test needs to poll over HTTP. The nerdtest cmd.Background() + EnsureContainerStarted pattern was failing in rootless mode: the backgrounded compose run's stderr is captured into a pty buffer that nothing reads, so when the inner `nerdctl run -d` fails (likely due to host port 8080 conflict), the error is invisible and EnsureContainerStarted just times out with a misleading "Command should succeed" assertion. Restoring the pre-refactor testutil.NewBase + goroutine + HTTP probe pattern for these two tests only. The other tests in the file run quick, exiting commands and keep using nerdtest. Signed-off-by: sathiraumesh <sathiraumesh@gmail.com>
1 parent 32c8d8d commit 02560e3

1 file changed

Lines changed: 91 additions & 68 deletions

File tree

cmd/nerdctl/compose/compose_run_linux_test.go

Lines changed: 91 additions & 68 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ import (
2121
"io"
2222
"strings"
2323
"testing"
24+
"time"
2425

2526
"gotest.tools/v3/assert"
2627

@@ -118,101 +119,123 @@ services:
118119
}
119120

120121
func TestComposeRunWithServicePorts(t *testing.T) {
121-
testCase := nerdtest.Setup()
122+
base := testutil.NewBase(t)
123+
// specify the name of container in order to remove
124+
// TODO: when `compose rm` is implemented, replace it.
125+
containerName := testutil.Identifier(t)
122126

123-
testCase.Setup = func(data test.Data, helpers test.Helpers) {
124-
dockerComposeYAML := fmt.Sprintf(`
127+
dockerComposeYAML := fmt.Sprintf(`
125128
services:
126129
web:
127130
image: %s
128131
ports:
129132
- 8080:80
130133
`, testutil.NginxAlpineImage)
131134

132-
data.Temp().Save(dockerComposeYAML, "compose.yaml")
133-
data.Labels().Set("composeYAML", data.Temp().Path("compose.yaml"))
134-
cmd := helpers.Command(
135-
"compose",
136-
"-f",
137-
data.Temp().Path("compose.yaml"),
138-
"run",
139-
"--service-ports",
140-
"--name",
141-
data.Identifier(),
142-
"web",
143-
)
144-
cmd.WithPseudoTTY()
145-
cmd.Background()
146-
nerdtest.EnsureContainerStarted(helpers, data.Identifier())
147-
}
135+
comp := testutil.NewComposeDir(t, dockerComposeYAML)
136+
defer comp.CleanUp()
137+
projectName := comp.ProjectName()
138+
t.Logf("projectName=%q", projectName)
139+
defer base.ComposeCmd("-f", comp.YAMLFullPath(), "down", "-v").Run()
148140

149-
testCase.Cleanup = func(data test.Data, helpers test.Helpers) {
150-
if yaml := data.Labels().Get("composeYAML"); yaml != "" {
151-
helpers.Anyhow("compose", "-f", yaml, "down", "-v")
141+
defer base.Cmd("rm", "-f", "-v", containerName).Run()
142+
go func() {
143+
// unbuffer(1) emulates tty, which is required by `nerdctl run -t`.
144+
// unbuffer(1) can be installed with `apt-get install expect`.
145+
unbuffer := []string{"unbuffer"}
146+
base.ComposeCmdWithHelper(unbuffer, "-f", comp.YAMLFullPath(),
147+
"run", "--service-ports", "--name", containerName, "web").Run()
148+
}()
149+
150+
checkNginx := func() error {
151+
resp, err := nettestutil.HTTPGet("http://127.0.0.1:8080", 5, false)
152+
if err != nil {
153+
return err
154+
}
155+
respBody, err := io.ReadAll(resp.Body)
156+
if err != nil {
157+
return err
158+
}
159+
if !strings.Contains(string(respBody), testutil.NginxAlpineIndexHTMLSnippet) {
160+
t.Logf("respBody=%q", respBody)
161+
return fmt.Errorf("respBody does not contain %q", testutil.NginxAlpineIndexHTMLSnippet)
152162
}
163+
return nil
153164
}
154-
155-
testCase.Expected = func(data test.Data, helpers test.Helpers) *test.Expected {
156-
return &test.Expected{
157-
Output: func(stdout string, t tig.T) {
158-
resp, err := nettestutil.HTTPGet("http://127.0.0.1:8080", 30, false)
159-
assert.NilError(t, err)
160-
respBody, err := io.ReadAll(resp.Body)
161-
assert.NilError(t, err)
162-
assert.Assert(t, strings.Contains(string(respBody), testutil.NginxAlpineIndexHTMLSnippet))
163-
},
165+
var nginxWorking bool
166+
for i := 0; i < 30; i++ {
167+
t.Logf("(retry %d)", i)
168+
err := checkNginx()
169+
if err == nil {
170+
nginxWorking = true
171+
break
164172
}
173+
t.Log(err)
174+
time.Sleep(3 * time.Second)
165175
}
166-
167-
testCase.Run(t)
176+
if !nginxWorking {
177+
t.Fatal("nginx is not working")
178+
}
179+
t.Log("nginx seems functional")
168180
}
169181

170182
func TestComposeRunWithPublish(t *testing.T) {
171-
testCase := nerdtest.Setup()
183+
base := testutil.NewBase(t)
184+
// specify the name of container in order to remove
185+
// TODO: when `compose rm` is implemented, replace it.
186+
containerName := testutil.Identifier(t)
172187

173-
testCase.Setup = func(data test.Data, helpers test.Helpers) {
174-
dockerComposeYAML := fmt.Sprintf(`
188+
dockerComposeYAML := fmt.Sprintf(`
175189
services:
176190
web:
177191
image: %s
178192
`, testutil.NginxAlpineImage)
179193

180-
data.Temp().Save(dockerComposeYAML, "compose.yaml")
181-
data.Labels().Set("composeYAML", data.Temp().Path("compose.yaml"))
182-
cmd := helpers.Command(
183-
"compose",
184-
"-f",
185-
data.Temp().Path("compose.yaml"),
186-
"run",
187-
"--publish", "8080:80",
188-
"--name",
189-
data.Identifier(),
190-
"web",
191-
)
192-
cmd.WithPseudoTTY()
193-
cmd.Background()
194-
nerdtest.EnsureContainerStarted(helpers, data.Identifier())
195-
}
194+
comp := testutil.NewComposeDir(t, dockerComposeYAML)
195+
defer comp.CleanUp()
196+
projectName := comp.ProjectName()
197+
t.Logf("projectName=%q", projectName)
198+
defer base.ComposeCmd("-f", comp.YAMLFullPath(), "down", "-v").Run()
196199

197-
testCase.Cleanup = func(data test.Data, helpers test.Helpers) {
198-
if yaml := data.Labels().Get("composeYAML"); yaml != "" {
199-
helpers.Anyhow("compose", "-f", yaml, "down", "-v")
200+
defer base.Cmd("rm", "-f", "-v", containerName).Run()
201+
go func() {
202+
// unbuffer(1) emulates tty, which is required by `nerdctl run -t`.
203+
// unbuffer(1) can be installed with `apt-get install expect`.
204+
unbuffer := []string{"unbuffer"}
205+
base.ComposeCmdWithHelper(unbuffer, "-f", comp.YAMLFullPath(),
206+
"run", "--publish", "8080:80", "--name", containerName, "web").Run()
207+
}()
208+
209+
checkNginx := func() error {
210+
resp, err := nettestutil.HTTPGet("http://127.0.0.1:8080", 5, false)
211+
if err != nil {
212+
return err
213+
}
214+
respBody, err := io.ReadAll(resp.Body)
215+
if err != nil {
216+
return err
217+
}
218+
if !strings.Contains(string(respBody), testutil.NginxAlpineIndexHTMLSnippet) {
219+
t.Logf("respBody=%q", respBody)
220+
return fmt.Errorf("respBody does not contain %q", testutil.NginxAlpineIndexHTMLSnippet)
200221
}
222+
return nil
201223
}
202-
203-
testCase.Expected = func(data test.Data, helpers test.Helpers) *test.Expected {
204-
return &test.Expected{
205-
Output: func(stdout string, t tig.T) {
206-
resp, err := nettestutil.HTTPGet("http://127.0.0.1:8080", 30, false)
207-
assert.NilError(t, err)
208-
respBody, err := io.ReadAll(resp.Body)
209-
assert.NilError(t, err)
210-
assert.Assert(t, strings.Contains(string(respBody), testutil.NginxAlpineIndexHTMLSnippet))
211-
},
224+
var nginxWorking bool
225+
for i := 0; i < 30; i++ {
226+
t.Logf("(retry %d)", i)
227+
err := checkNginx()
228+
if err == nil {
229+
nginxWorking = true
230+
break
212231
}
232+
t.Log(err)
233+
time.Sleep(3 * time.Second)
213234
}
214-
215-
testCase.Run(t)
235+
if !nginxWorking {
236+
t.Fatal("nginx is not working")
237+
}
238+
t.Log("nginx seems functional")
216239
}
217240

218241
func TestComposeRunWithEnv(t *testing.T) {

0 commit comments

Comments
 (0)