1package docker
2
3import (
4 "archive/tar"
5 "bytes"
6 "context"
7 "encoding/binary"
8 "io"
9 "strings"
10 "testing"
11
12 "github.com/stretchr/testify/assert"
13 "github.com/stretchr/testify/require"
14)
15
16func TestParseExecOutput_SplitsStdoutAndStderr(t *testing.T) {
17 stream := append(frameDockerStream(1, []byte("hello\n")), frameDockerStream(2, []byte("warn\n"))...)
18
19 stdout, stderr, err := parseExecOutput(bytes.NewReader(stream))
20
21 require.NoError(t, err)
22 assert.Equal(t, []byte("hello\n"), stdout)
23 assert.Equal(t, []byte("warn\n"), stderr)
24}
25
26func TestRuntime_ExecInContainer_RejectsEmptyCommand(t *testing.T) {
27 r := &Runtime{}
28
29 tests := []struct {
30 name string
31 cmd []string
32 }{
33 {name: "nil", cmd: nil},
34 {name: "empty slice", cmd: []string{}},
35 }
36
37 for _, tt := range tests {
38 t.Run(tt.name, func(t *testing.T) {
39 result, err := r.ExecInContainer(context.Background(), "abc123", tt.cmd)
40 require.Error(t, err)
41 assert.Nil(t, result)
42 })
43 }
44}
45
46func frameDockerStream(streamID byte, payload []byte) []byte {
47 frame := make([]byte, 8+len(payload))
48 frame[0] = streamID
49 binary.BigEndian.PutUint32(frame[4:8], uint32(len(payload)))
50 copy(frame[8:], payload)
51 return frame
52}
53
54func TestExtractFileFromTarMatchesFullCleanPath(t *testing.T) {
55 var buf bytes.Buffer
56 tw := tar.NewWriter(&buf)
57 require.NoError(t, tw.WriteHeader(&tar.Header{Name: "other/.env", Typeflag: tar.TypeReg, Size: int64(len("wrong"))}))
58 _, err := tw.Write([]byte("wrong"))
59 require.NoError(t, err)
60 require.NoError(t, tw.WriteHeader(&tar.Header{Name: "app/.env", Typeflag: tar.TypeReg, Size: int64(len("right"))}))
61 _, err = tw.Write([]byte("right"))
62 require.NoError(t, err)
63 require.NoError(t, tw.Close())
64
65 rc, err := extractFileFromTar(io.NopCloser(bytes.NewReader(buf.Bytes())), "/app/.env")
66 require.NoError(t, err)
67 defer rc.Close()
68
69 data, err := io.ReadAll(rc)
70 require.NoError(t, err)
71 assert.Equal(t, "right", string(data))
72}
73
74func TestReadExtractedEnvFileRejectsOversizedContent(t *testing.T) {
75 data, err := readExtractedEnvFile(io.NopCloser(strings.NewReader(strings.Repeat("a", maxExtractedEnvFileSize+1))))
76 require.Error(t, err)
77 assert.Nil(t, data)
78 assert.Contains(t, err.Error(), "exceeds")
79}