8000 change TestNewAPIClientFromFlagsWithHttpProxyEnv to an e2e test · docker/cli@6288e8b · GitHub
[go: up one dir, main page]

Skip to content

Commit 6288e8b

Browse files
committed
change TestNewAPIClientFromFlagsWithHttpProxyEnv to an e2e test
Golang uses a `sync.Once` when determining the proxy to use. This means that it's not possible to test the proxy configuration in unit tests, because the proxy configuration will be "fixated" the first time Golang detects the proxy configuration. This patch changes TestNewAPIClientFromFlagsWithHttpProxyEnv to an e2e test so that we can verify the CLI picks up the proxy configuration. Signed-off-by: Sebastiaan van Stijn <github@gone.nl> (cherry picked from commit 40c6b11) Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
1 parent 1e9575e commit 6288e8b

File tree

2 files changed

+43
-19
lines changed

2 files changed

+43
-19
lines changed

cli/command/cli_test.go

Lines changed: 0 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@ import (
66
"crypto/x509"
77
"fmt"
88
"io/ioutil"
9-
"net/http"
109
"os"
1110
"runtime"
1211
"testing"
@@ -80,24 +79,6 @@ func TestNewAPIClientFromFlagsWithAPIVersionFromEnv(t *testing.T) {
8079
assert.Check(t, is.Equal(customVersion, apiclient.ClientVersion()))
8180
}
8281

83-
func TestNewAPIClientFromFlagsWithHttpProxyEnv(t *testing.T) {
84-
defer env.Patch(t, "HTTP_PROXY", "http://proxy.acme.example.com:1234")()
85-
defer env.Patch(t, "DOCKER_HOST", "tcp://docker.acme.example.com:2376")()
86-
87-
opts := &flags.CommonOptions{}
88-
configFile := &configfile.ConfigFile{}
89-
apiclient, err := NewAPIClientFromFlags(opts, configFile)
90-
assert.NilError(t, err)
91-
transport, ok := apiclient.HTTPClient().Transport.(*http.Transport)
92-
assert.Assert(t, ok)
93-
assert.Assert(t, transport.Proxy != nil)
94-
request, err := http.NewRequest(http.MethodGet, "tcp://docker.acme.example.com:2376", nil)
95-
assert.NilError(t, err)
96-
url, err := transport.Proxy(request)
97-
assert.NilError(t, err)
98-
assert.Check(t, is.Equal("http://proxy.acme.example.com:1234", url.String()))
99-
}
100-
10182
type fakeClient struct {
10283
client.Client
10384
pingFunc func() (types.Ping, error)

e2e/global/cli_test.go

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,13 @@
11
package global
22

33
import (
4+
"net/http"
5+
"net/http/httptest"
6+
"strings"
47
"testing"
58

69
"github.com/docker/cli/internal/test/environment"
10+
"gotest.tools/v3/assert"
711
"gotest.tools/v3/icmd"
812
"gotest.tools/v3/skip"
913
)
@@ -22,3 +26,42 @@ func TestTLSVerify(t *testing.T) {
2226
result = icmd.RunCmd(icmd.Command("docker", "--tlsverify=true", "ps"))
2327
result.Assert(t, icmd.Expected{ExitCode: 1, Err: "ca.pem"})
2428
}
29+
30+
// TestTCPSchemeUsesHTTPProxyEnv verifies that the cli uses HTTP_PROXY if
31+
// DOCKER_HOST is set to use the 'tcp://' scheme.
32+
//
33+
// Prior to go1.16, https:// schemes would use HTTPS_PROXY, and any other
34+
// scheme would use HTTP_PROXY. However, golang/net@7b1cca2 (per a request in
35+
// golang/go#40909) changed this behavior to only use HTTP_PROXY for http://
36+
// schemes, no longer using a proxy for any other scheme.
37+
//
38+
// Docker uses the tcp:// scheme as a default for API connections, to indicate
39+
// that the API is not "purely" HTTP. Various parts in the code also *require*
40+
// this scheme to be used. While we could change the default and allow http(s)
41+
// schemes to be used, doing so will take time, taking into account that there
42+
// are many installs in existence that have tcp:// configured as DOCKER_HOST.
43+
//
44+
// Note that due to Golang's use of sync.Once for proxy-detection, this test
45+
// cannot be done as a unit-test, hence it being an e2e test.
46+
func TestTCPSchemeUsesHTTPProxyEnv(t *testing.T) {
47+
const responseJSON = `{"Version": "99.99.9", "ApiVersion": "1.41", "MinAPIVersion": "1.12"}`
48+
var received string
49+
proxyServer := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
50+
received = r.Host
51+
w.Header().Set("Content-Type", "application/json")
52+
_, _ = w.Write([]byte(responseJSON))
53+
}))
54+
defer proxyServer.Close()
55+
56+
// Configure the CLI to use our proxyServer. DOCKER_HOST can point to any
57+
// address (as it won't be connected to), but must use tcp:// for this test,
58+
// to verify it's using HTTP_PROXY.
59+
result := icmd.RunCmd(
60+
icmd.Command("docker", "version", "--format", "{{ .Server.Version }}"),
61+
icmd.WithEnv("HTTP_PROXY="+proxyServer.URL, "DOCKER_HOST=tcp://docker.acme.example.com:2376"),
62+
)
63+
// Verify the command ran successfully, and that it connected to the proxyServer
64+
result.Assert(t, icmd.Success)
65+
assert.Equal(t, strings.TrimSpace(result.Stdout()), "99.99.9")
66+
assert.Equal(t, received, "docker.acme.example.com:2376")
67+
}

0 commit comments

Comments
 (0)
0