1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105
|
//go:build integration
// +build integration
package docker_test
import (
"net/http"
"net/http/httptest"
"net/url"
"os"
"strings"
"testing"
"time"
"github.com/gorilla/websocket"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
"gitlab.com/gitlab-org/gitlab-runner/common"
"gitlab.com/gitlab-org/gitlab-runner/helpers"
"gitlab.com/gitlab-org/gitlab-runner/helpers/test"
"gitlab.com/gitlab-org/gitlab-runner/session"
)
func TestInteractiveTerminal(t *testing.T) {
test.SkipIfGitLabCIOn(t, test.OSWindows)
helpers.SkipIntegrationTests(t, "docker", "info")
successfulBuild, err := common.GetRemoteLongRunningBuild()
assert.NoError(t, err)
sess, err := session.NewSession(nil)
require.NoError(t, err)
build := &common.Build{
JobResponse: successfulBuild,
Runner: &common.RunnerConfig{
RunnerSettings: common.RunnerSettings{
Executor: "docker",
Docker: &common.DockerConfig{
Image: common.TestAlpineImage,
PullPolicy: common.StringOrArray{common.PullPolicyIfNotPresent},
},
},
},
Session: sess,
}
// Start build
go func() {
_ = build.Run(&common.Config{}, &common.Trace{Writer: os.Stdout})
}()
srv := httptest.NewServer(build.Session.Handler())
defer srv.Close()
u := url.URL{
Scheme: "ws",
Host: srv.Listener.Addr().String(),
Path: build.Session.Endpoint + "/exec",
}
headers := http.Header{
"Authorization": []string{build.Session.Token},
}
var webSocket *websocket.Conn
var resp *http.Response
started := time.Now()
for time.Since(started) < 25*time.Second {
webSocket, resp, err = websocket.DefaultDialer.Dial(u.String(), headers)
if err == nil {
break
}
time.Sleep(50 * time.Millisecond)
}
require.NotNil(t, webSocket)
require.Equal(t, http.StatusSwitchingProtocols, resp.StatusCode)
defer webSocket.Close()
err = webSocket.WriteMessage(websocket.BinaryMessage, []byte("uname\n"))
require.NoError(t, err)
readStarted := time.Now()
var tty []byte
for time.Since(readStarted) < 5*time.Second {
typ, b, err := webSocket.ReadMessage()
require.NoError(t, err)
require.Equal(t, websocket.BinaryMessage, typ)
tty = append(tty, b...)
if strings.Contains(string(b), "Linux") {
break
}
time.Sleep(50 * time.Microsecond)
}
t.Log(string(tty))
assert.Contains(t, string(tty), "Linux")
}
|