tests: cover debug build missing mount result IDs

Signed-off-by: CrazyMax <1951866+crazy-max@users.noreply.github.com>
This commit is contained in:
CrazyMax
2026-05-04 15:49:46 +02:00
committed by Mateusz Gozdek
parent 142cd448de
commit 9de08b24ff
2 changed files with 132 additions and 0 deletions
+131
View File
@@ -0,0 +1,131 @@
package tests
import (
"bytes"
"io"
"os/exec"
"strings"
"sync"
"testing"
"time"
"github.com/containerd/continuity/fs/fstest"
"github.com/creack/pty"
"github.com/moby/buildkit/util/testutil/integration"
"github.com/stretchr/testify/require"
)
var debugTests = []func(t *testing.T, sb integration.Sandbox){
testDebugBuildMissingBindMountSource,
}
func testDebugBuildMissingBindMountSource(t *testing.T, sb integration.Sandbox) {
if !isExperimental() {
t.Skip("debug command is experimental")
}
if !isDockerWorker(sb) {
t.Skip("debug monitor test only needs a docker worker")
}
dockerfile := []byte(`
FROM busybox:latest
RUN --mount=type=bind,source=missing,target=/src true
`)
dir := tmpdir(t,
fstest.CreateFile("Dockerfile", dockerfile, 0o600),
)
cmd := buildxCmd(sb, withArgs("debug", "--on=error", "build", "--progress=plain", "--output=type=cacheonly", dir))
f, err := pty.StartWithSize(cmd, &pty.Winsize{
Cols: 120,
Rows: 24,
})
require.NoError(t, err)
defer f.Close()
var output debugOutput
copyDone := make(chan struct{})
go func() {
_, _ = io.Copy(&output, f)
close(copyDone)
}()
waitCh := make(chan error, 1)
go func() {
waitCh <- cmd.Wait()
}()
exited, waitErr := waitForDebugPromptOrExit(t, &output, waitCh)
if !exited {
_, err = f.Write([]byte("exit\r"))
require.NoError(t, err)
waitErr = waitForDebugCommandExit(t, cmd, waitCh, &output)
}
_ = f.Close()
select {
case <-copyDone:
case <-time.After(time.Second):
}
out := output.String()
require.Error(t, waitErr, out)
require.Contains(t, out, "failed to calculate checksum")
require.Contains(t, out, "failed to create container")
require.NotContains(t, out, "panic:")
require.NotContains(t, out, "index out of range")
}
func waitForDebugPromptOrExit(t *testing.T, output *debugOutput, waitCh <-chan error) (bool, error) {
t.Helper()
timeout := time.NewTimer(time.Minute)
defer timeout.Stop()
ticker := time.NewTicker(100 * time.Millisecond)
defer ticker.Stop()
for {
select {
case err := <-waitCh:
return true, err
case <-ticker.C:
if strings.Contains(output.String(), "(buildx) ") {
return false, nil
}
case <-timeout.C:
require.FailNow(t, "timeout waiting for debug monitor", output.String())
}
}
}
func waitForDebugCommandExit(t *testing.T, cmd *exec.Cmd, waitCh <-chan error, output *debugOutput) error {
t.Helper()
select {
case err := <-waitCh:
return err
case <-time.After(30 * time.Second):
if cmd.Process != nil {
_ = cmd.Process.Kill()
}
require.FailNow(t, "timeout waiting for debug command to exit", output.String())
return nil
}
}
type debugOutput struct {
mu sync.Mutex
buf bytes.Buffer
}
func (b *debugOutput) Write(p []byte) (int, error) {
b.mu.Lock()
defer b.mu.Unlock()
return b.buf.Write(p)
}
func (b *debugOutput) String() string {
b.mu.Lock()
defer b.mu.Unlock()
return b.buf.String()
}
+1
View File
@@ -24,6 +24,7 @@ func TestIntegration(t *testing.T) {
var tests []func(t *testing.T, sb integration.Sandbox) var tests []func(t *testing.T, sb integration.Sandbox)
tests = append(tests, commonTests...) tests = append(tests, commonTests...)
tests = append(tests, buildTests...) tests = append(tests, buildTests...)
tests = append(tests, debugTests...)
tests = append(tests, policyBuildTests...) tests = append(tests, policyBuildTests...)
tests = append(tests, policyEvalTests...) tests = append(tests, policyEvalTests...)
tests = append(tests, policyBakeTests...) tests = append(tests, policyBakeTests...)