proxy_test.go 4.6 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
M
Medya Gh 已提交
75
	p := t.Name()
M
Medya Gh 已提交
76 77
	mk := NewMinikubeRunner(t, p)

M
Medya Gh 已提交
78 79
	ctx, cancel := context.WithTimeout(context.Background(), 10*time.Minute)
	defer cancel()
80
	_, _, err = mk.RunWithContext(ctx, "delete")
M
Medya Gh 已提交
81 82 83 84 85 86
	if err != nil {
		t.Logf("Error deleting minikube before test setup %s : ", err)
	}

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

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

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

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

}

// testProxyWarning checks user is warned correctly about the proxy related env vars
func testProxyWarning(t *testing.T) {
M
Medya Gh 已提交
114
	p := "TestProxy"
M
Medya Gh 已提交
115
	mk := NewMinikubeRunner(t, p, "--wait=false")
116
	ctx, cancel := context.WithTimeout(context.Background(), 10*time.Minute)
M
Medya Gh 已提交
117
	defer cancel()
118 119
	startCmd := fmt.Sprintf("start %s %s", mk.StartArgs, mk.GlobalArgs)
	stdout, stderr, err := mk.RunWithContext(ctx, startCmd)
M
Medya Gh 已提交
120 121 122 123 124 125 126 127 128 129 130 131 132 133
	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)
	}
}
134 135 136

// testProxyDashboard checks if dashboard URL is accessible if proxy is set
func testProxyDashboard(t *testing.T) {
M
Medya Gh 已提交
137
	p := "TestProxy" // profile name
M
Medya Gh 已提交
138
	mk := NewMinikubeRunner(t, p, "--wait=false")
139
	cmd, out := mk.RunDaemon("dashboard --url")
140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155
	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)
	}
156 157

	resp, err := retryablehttp.Get(u.String())
158 159 160 161 162 163 164 165 166 167 168
	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)
	}
}