1
0
mirror of https://github.com/moby/moby.git synced 2025-10-31 17:50:33 +03:00
Files
moby/integration-cli/docker_api_exec_resize_test.go
Sebastiaan van Stijn d3e45f8743 testutil: move back to internal
This package was originally internal, but was moved out when BuildKit
used it for its integration tests. That's no longer the case, so we
can make it internal again.

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2025-09-08 10:08:30 +02:00

112 lines
3.0 KiB
Go

package main
import (
"bytes"
"encoding/json"
"fmt"
"io"
"net/http"
"strings"
"sync"
"testing"
"github.com/moby/moby/v2/integration-cli/cli"
"github.com/moby/moby/v2/internal/testutil"
"github.com/moby/moby/v2/internal/testutil/request"
"github.com/pkg/errors"
"gotest.tools/v3/assert"
)
func (s *DockerAPISuite) TestExecResizeAPIHeightWidthNoInt(c *testing.T) {
testRequires(c, DaemonIsLinux)
out := cli.DockerCmd(c, "run", "-d", "busybox", "top").Stdout()
cleanedContainerID := strings.TrimSpace(out)
endpoint := "/exec/" + cleanedContainerID + "/resize?h=foo&w=bar"
res, _, err := request.Post(testutil.GetContext(c), endpoint)
assert.NilError(c, err)
assert.Equal(c, res.StatusCode, http.StatusBadRequest)
}
// Part of #14845
func (s *DockerAPISuite) TestExecResizeImmediatelyAfterExecStart(c *testing.T) {
name := "exec_resize_test"
cli.DockerCmd(c, "run", "-d", "-i", "-t", "--name", name, "--restart", "always", "busybox", "/bin/sh")
testExecResize := func() error {
data := map[string]any{
"AttachStdin": true,
"Cmd": []string{"/bin/sh"},
}
uri := fmt.Sprintf("/containers/%s/exec", name)
res, body, err := request.Post(testutil.GetContext(c), uri, request.JSONBody(data))
if err != nil {
return err
}
if res.StatusCode != http.StatusCreated {
return errors.Errorf("POST %s is expected to return %d, got %d", uri, http.StatusCreated, res.StatusCode)
}
buf, err := request.ReadBody(body)
assert.NilError(c, err)
out := map[string]string{}
err = json.Unmarshal(buf, &out)
if err != nil {
return errors.Wrap(err, "ExecCreate returned invalid json")
}
execID := out["Id"]
if len(execID) < 1 {
return errors.New("ExecCreate got invalid execID")
}
payload := bytes.NewBufferString(`{"Tty":true}`)
wc, _, err := requestHijack(http.MethodPost, fmt.Sprintf("/exec/%s/start", execID), payload, "application/json", request.DaemonHost())
if err != nil {
return errors.Wrap(err, "failed to start the exec")
}
defer wc.Close()
_, rc, err := request.Post(testutil.GetContext(c), fmt.Sprintf("/exec/%s/resize?h=24&w=80", execID), request.ContentType("text/plain"))
if err != nil {
// It's probably a panic of the daemon if io.ErrUnexpectedEOF is returned.
if errors.Is(err, io.ErrUnexpectedEOF) {
return errors.New("the daemon might have crashed")
}
// Other error happened, should be reported.
return errors.Wrap(err, "failed to exec resize immediately after start")
}
rc.Close()
return nil
}
// The panic happens when daemon.ContainerExecStart is called but the
// container.Exec is not called.
// Because the panic is not 100% reproducible, we send the requests concurrently
// to increase the probability that the problem is triggered.
var (
n = 10
ch = make(chan error, n)
wg sync.WaitGroup
)
for i := 0; i < n; i++ {
wg.Add(1)
go func() {
defer wg.Done()
if err := testExecResize(); err != nil {
ch <- err
}
}()
}
wg.Wait()
select {
case err := <-ch:
c.Fatal(err.Error())
default:
}
}