proxy_test.go 4.5 KB
Newer Older
M
Medya Gh 已提交
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
// +build integration

/*
Copyright 2019 The Kubernetes Authors All rights reserved.

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

    http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

package integration

import (
	"context"
	"fmt"
24
	"io/ioutil"
M
Medya Gh 已提交
25 26 27 28 29
	"os"
	"strings"
	"testing"
	"time"

M
Medya Gh 已提交
30
	"net/http"
31
	"net/url"
M
Medya Gh 已提交
32

M
Medya Gh 已提交
33
	"github.com/elazarl/goproxy"
34
	retryablehttp "github.com/hashicorp/go-retryablehttp"
M
Medya Gh 已提交
35 36 37 38 39
	"github.com/phayes/freeport"
	"github.com/pkg/errors"
)

// setUpProxy runs a local http proxy and sets the env vars for it.
M
Medya Gh 已提交
40
func setUpProxy(t *testing.T) (*http.Server, error) {
M
Medya Gh 已提交
41 42
	port, err := freeport.GetFreePort()
	if err != nil {
M
Medya Gh 已提交
43
		return nil, errors.Wrap(err, "Failed to get an open port")
M
Medya Gh 已提交
44 45
	}

M
Medya Gh 已提交
46
	addr := fmt.Sprintf("localhost:%d", port)
M
Medya Gh 已提交
47 48
	err = os.Setenv("NO_PROXY", "")
	if err != nil {
M
Medya Gh 已提交
49
		return nil, errors.Wrap(err, "Failed to set no proxy env")
M
Medya Gh 已提交
50 51 52
	}
	err = os.Setenv("HTTP_PROXY", addr)
	if err != nil {
M
Medya Gh 已提交
53
		return nil, errors.Wrap(err, "Failed to set http proxy env")
M
Medya Gh 已提交
54 55 56
	}

	proxy := goproxy.NewProxyHttpServer()
M
Medya Gh 已提交
57 58 59 60 61 62 63
	srv := &http.Server{Addr: addr, Handler: proxy}
	go func(s *http.Server, t *testing.T) {
		if err := s.ListenAndServe(); err != http.ErrServerClosed {
			t.Errorf("Failed to start http server for proxy mock")
		}
	}(srv, t)
	return srv, nil
M
Medya Gh 已提交
64 65 66
}

func TestProxy(t *testing.T) {
67 68
	origHP := os.Getenv("HTTP_PROXY")
	origNP := os.Getenv("NO_PROXY")
M
Medya Gh 已提交
69
	srv, err := setUpProxy(t)
70 71 72 73
	if err != nil {
		t.Fatalf("Failed to set up the test proxy: %s", err)
	}

74
	// making sure there is no running minikube to avoid https://github.com/kubernetes/minikube/issues/4132
75
	mk := NewMinikubeRunner(t)
M
Medya Gh 已提交
76 77
	ctx, cancel := context.WithTimeout(context.Background(), 10*time.Minute)
	defer cancel()
78
	_, _, err = mk.RunWithContext(ctx, "delete")
M
Medya Gh 已提交
79 80 81 82 83 84
	if err != nil {
		t.Logf("Error deleting minikube before test setup %s : ", err)
	}

	// Clean up after setting up proxy
	defer func(t *testing.T) {
85
		err = os.Setenv("HTTP_PROXY", origHP)
M
Medya Gh 已提交
86
		if err != nil {
87
			t.Errorf("Error reverting the HTTP_PROXY env")
M
Medya Gh 已提交
88
		}
M
Medya Gh 已提交
89
		err = os.Setenv("NO_PROXY", origNP)
M
Medya Gh 已提交
90
		if err != nil {
M
Medya Gh 已提交
91
			t.Errorf("Error reverting the NO_PROXY env")
M
Medya Gh 已提交
92
		}
93 94

		err := srv.Shutdown(context.TODO()) // shutting down the http proxy after tests
M
Medya Gh 已提交
95
		if err != nil {
96
			t.Errorf("Error shutting down the http proxy")
M
Medya Gh 已提交
97
		}
M
Medya Gh 已提交
98

99
		_, _, err = mk.RunWithContext(ctx, "delete")
M
Medya Gh 已提交
100 101 102
		if err != nil {
			t.Logf("Error deleting minikube when cleaning up proxy setup: %s", err)
		}
M
Medya Gh 已提交
103 104
	}(t)

M
Medya Gh 已提交
105 106
	t.Run("Proxy Console Warnning", testProxyWarning)
	t.Run("Proxy Dashboard", testProxyDashboard)
M
Medya Gh 已提交
107 108 109 110 111

}

// testProxyWarning checks user is warned correctly about the proxy related env vars
func testProxyWarning(t *testing.T) {
112
	mk := NewMinikubeRunner(t, "--wait=false")
113
	ctx, cancel := context.WithTimeout(context.Background(), 10*time.Minute)
M
Medya Gh 已提交
114
	defer cancel()
115 116
	startCmd := fmt.Sprintf("start %s %s", mk.StartArgs, mk.GlobalArgs)
	stdout, stderr, err := mk.RunWithContext(ctx, startCmd)
M
Medya Gh 已提交
117 118 119 120 121 122 123 124 125 126 127 128 129 130
	if err != nil {
		t.Fatalf("start: %v\nstdout: %s\nstderr: %s", err, stdout, stderr)
	}

	msg := "Found network options:"
	if !strings.Contains(stdout, msg) {
		t.Errorf("Proxy wranning (%s) is missing from the output: %s", msg, stderr)
	}

	msg = "You appear to be using a proxy"
	if !strings.Contains(stderr, msg) {
		t.Errorf("Proxy wranning (%s) is missing from the output: %s", msg, stderr)
	}
}
131 132 133

// testProxyDashboard checks if dashboard URL is accessible if proxy is set
func testProxyDashboard(t *testing.T) {
134
	mk := NewMinikubeRunner(t, "--wait=false")
135
	cmd, out := mk.RunDaemon("dashboard --url")
136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151
	defer func() {
		err := cmd.Process.Kill()
		if err != nil {
			t.Logf("Failed to kill dashboard command: %v", err)
		}
	}()

	s, err := readLineWithTimeout(out, 180*time.Second)
	if err != nil {
		t.Fatalf("failed to read url: %v", err)
	}

	u, err := url.Parse(strings.TrimSpace(s))
	if err != nil {
		t.Fatalf("failed to parse %q: %v", s, err)
	}
152 153

	resp, err := retryablehttp.Get(u.String())
154 155 156 157 158 159 160 161 162 163 164
	if err != nil {
		t.Fatalf("failed get: %v", err)
	}
	if resp.StatusCode != http.StatusOK {
		body, err := ioutil.ReadAll(resp.Body)
		if err != nil {
			t.Fatalf("Unable to read http response body: %v", err)
		}
		t.Errorf("%s returned status code %d, expected %d.\nbody:\n%s", u, resp.StatusCode, http.StatusOK, body)
	}
}