Skip to content

Commit

Permalink
Introduce auto inject integration tests
Browse files Browse the repository at this point in the history
The integration tests were not exercising proxy auto inject.

Introduce a `--proxy-auto-inject` flag to `install_test.go`, which
now exercises install, check, and smoke test deploy for both manual and
auto injected use cases.

Part of #2569

Signed-off-by: Andrew Seigner <[email protected]>
  • Loading branch information
siggy committed Mar 29, 2019
1 parent 48ddde2 commit 807e73d
Show file tree
Hide file tree
Showing 4 changed files with 85 additions and 28 deletions.
1 change: 1 addition & 0 deletions bin/test-run
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@ printf "Testing Linkerd version [%s] namespace [%s] k8s-context [%s]\\n" "$linke
exit_code=0

run_test "$test_directory/install_test.go" || exit_code=$?
run_test "$test_directory/install_test.go" "--proxy-auto-inject" || exit_code=$?
for test in $(find "$test_directory" -mindepth 2 -name '*_test.go'); do
run_test "$test" || exit_code=$?
done
Expand Down
46 changes: 33 additions & 13 deletions test/install_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -56,11 +56,11 @@ var (
knownErrorsRegex = regexp.MustCompile(strings.Join([]string{

// k8s hitting readiness endpoints before components are ready
`.* linkerd-(controller|identity|grafana|prometheus|web)-.*-.* linkerd-proxy ERR! \[ *\d+.\d+s\] proxy={server=in listen=0\.0\.0\.0:4143 remote=.*} linkerd2_proxy::proxy::http::router service error: an error occurred trying to connect: Connection refused \(os error 111\) \(address: 127\.0\.0\.1:.*\)`,
`.* linkerd-(controller|identity|grafana|prometheus|web)-.*-.* linkerd-proxy ERR! \[ *\d+.\d+s\] proxy={server=out listen=127\.0\.0\.1:4140 remote=.*} linkerd2_proxy::proxy::http::router service error: an error occurred trying to connect: Connection refused \(os error 111\) \(address: .*:4191\)`,
`.* linkerd-(controller|identity|grafana|prometheus|web)-.*-.* linkerd-proxy WARN \[ *\d+.\d+s\] .* linkerd2_proxy::proxy::reconnect connect error to ControlAddr .*`,
`.* linkerd-(controller|identity|grafana|prometheus|proxy-injector|web)-.*-.* linkerd-proxy ERR! \[ *\d+.\d+s\] proxy={server=in listen=0\.0\.0\.0:4143 remote=.*} linkerd2_proxy::proxy::http::router service error: an error occurred trying to connect: Connection refused \(os error 111\) \(address: 127\.0\.0\.1:.*\)`,
`.* linkerd-(controller|identity|grafana|prometheus|proxy-injector|web)-.*-.* linkerd-proxy ERR! \[ *\d+.\d+s\] proxy={server=out listen=127\.0\.0\.1:4140 remote=.*} linkerd2_proxy::proxy::http::router service error: an error occurred trying to connect: Connection refused \(os error 111\) \(address: .*:4191\)`,
`.* linkerd-(controller|identity|grafana|prometheus|proxy-injector|web)-.*-.* linkerd-proxy WARN \[ *\d+.\d+s\] .* linkerd2_proxy::proxy::reconnect connect error to ControlAddr .*`,

`.* linkerd-(controller|identity|grafana|prometheus|web)-.*-.* linkerd-proxy ERR! \[ *\d+.\d+s\] admin={server=metrics listen=0\.0\.0\.0:4191 remote=.*} linkerd2_proxy::control::serve_http error serving metrics: Error { kind: Shutdown, .* }`,
`.* linkerd-(controller|identity|grafana|prometheus|proxy-injector|web)-.*-.* linkerd-proxy ERR! \[ *\d+.\d+s\] admin={server=metrics listen=0\.0\.0\.0:4191 remote=.*} linkerd2_proxy::control::serve_http error serving metrics: Error { kind: Shutdown, .* }`,

`.* linkerd-controller-.*-.* tap time=".*" level=error msg="\[.*\] encountered an error: rpc error: code = Canceled desc = context canceled"`,
`.* linkerd-web-.*-.* linkerd-proxy WARN trust_dns_proto::xfer::dns_exchange failed to associate send_message response to the sender`,
Expand Down Expand Up @@ -106,6 +106,10 @@ func TestInstall(t *testing.T) {
"--proxy-log-level", "warn,linkerd2_proxy=debug",
"--linkerd-version", TestHelper.GetVersion(),
}
if TestHelper.AutoInject() {
cmd = append(cmd, []string{"--proxy-auto-inject"}...)
linkerdDeployReplicas["linkerd-proxy-injector"] = deploySpec{1, []string{"proxy-injector"}}
}

out, _, err := TestHelper.LinkerdRun(cmd...)
if err != nil {
Expand Down Expand Up @@ -218,19 +222,35 @@ func TestDashboard(t *testing.T) {
}

func TestInject(t *testing.T) {
cmd := []string{"inject", "testdata/smoke_test.yaml"}
var out string
var err error

out, injectReport, err := TestHelper.LinkerdRun(cmd...)
if err != nil {
t.Fatalf("linkerd inject command failed: %s\n%s", err, out)
}
prefixedNs := TestHelper.GetTestNamespace("smoke-test")

err = TestHelper.ValidateOutput(injectReport, "inject.report.golden")
if err != nil {
t.Fatalf("Received unexpected output\n%s", err.Error())
if TestHelper.AutoInject() {
out, err = testutil.ReadFile("testdata/smoke_test.yaml")
if err != nil {
t.Fatalf("failed to read smoke test file: %s", err)
}
err = TestHelper.CreateNamespaceIfNotExists(prefixedNs, true)
if err != nil {
t.Fatalf("failed to create %s namespace with auto inject enabled: %s", prefixedNs, err)
}
} else {
cmd := []string{"inject", "testdata/smoke_test.yaml"}

var injectReport string
out, injectReport, err = TestHelper.LinkerdRun(cmd...)
if err != nil {
t.Fatalf("linkerd inject command failed: %s\n%s", err, out)
}

err = TestHelper.ValidateOutput(injectReport, "inject.report.golden")
if err != nil {
t.Fatalf("Received unexpected output\n%s", err.Error())
}
}

prefixedNs := TestHelper.GetTestNamespace("smoke-test")
out, err = TestHelper.KubectlApply(out, prefixedNs)
if err != nil {
t.Fatalf("kubectl apply command failed\n%s", out)
Expand Down
17 changes: 14 additions & 3 deletions testutil/kubernetes_helper.go
Original file line number Diff line number Diff line change
Expand Up @@ -55,11 +55,22 @@ func (h *KubernetesHelper) CheckIfNamespaceExists(namespace string) error {
}

// CreateNamespaceIfNotExists creates a namespace if it does not already exist.
func (h *KubernetesHelper) CreateNamespaceIfNotExists(namespace string) error {
func (h *KubernetesHelper) CreateNamespaceIfNotExists(namespace string, autoInject bool) error {
err := h.CheckIfNamespaceExists(namespace)

if err != nil {
ns := &corev1.Namespace{ObjectMeta: metav1.ObjectMeta{Name: namespace}}
ns := &corev1.Namespace{
ObjectMeta: metav1.ObjectMeta{
Name: namespace,
},
}
if autoInject {
ns.GetObjectMeta().SetAnnotations(
map[string]string{
k8s.ProxyInjectAnnotation: k8s.ProxyInjectEnabled,
},
)
}
_, err = h.clientset.CoreV1().Namespaces().Create(ns)

if err != nil {
Expand All @@ -78,7 +89,7 @@ func (h *KubernetesHelper) KubectlApply(stdin string, namespace string) (string,
namespace = "default"
}

err := h.CreateNamespaceIfNotExists(namespace)
err := h.CreateNamespaceIfNotExists(namespace, false)
if err != nil {
return "", err
}
Expand Down
49 changes: 37 additions & 12 deletions testutil/test_helper.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ type TestHelper struct {
linkerd string
version string
namespace string
autoInject bool
httpClient http.Client
KubernetesHelper
}
Expand All @@ -36,6 +37,7 @@ func NewTestHelper() *TestHelper {
k8sContext := flag.String("k8s-context", "", "kubernetes context associated with the test cluster")
linkerd := flag.String("linkerd", "", "path to the linkerd binary to test")
namespace := flag.String("linkerd-namespace", "l5d-integration", "the namespace where linkerd is installed")
autoInject := flag.Bool("proxy-auto-inject", false, "enable proxy sidecar auto-injection in tests")
runTests := flag.Bool("integration-tests", false, "must be provided to run the integration tests")
verbose := flag.Bool("verbose", false, "turn on debug logging")
flag.Parse()
Expand Down Expand Up @@ -64,11 +66,20 @@ func NewTestHelper() *TestHelper {
}

ns := *namespace
if *autoInject {
ns += "-auto-inject"
}

testHelper := &TestHelper{
<<<<<<< HEAD
k8sContext: *k8sContext,
linkerd: *linkerd,
namespace: ns,
=======
linkerd: *linkerd,
namespace: ns,
autoInject: *autoInject,
>>>>>>> a66735ec... Introduce auto inject integration tests
}

version, _, err := testHelper.LinkerdRun("version", "--client", "--short")
Expand Down Expand Up @@ -109,15 +120,10 @@ func (h *TestHelper) GetTestNamespace(testName string) string {
return h.namespace + "-" + testName
}

// combinedOutput executes a shell command and returns the output.
func (h *TestHelper) combinedOutput(stdin string, name string, arg ...string) (string, string, error) {
command := exec.Command(name, arg...)
command.Stdin = strings.NewReader(stdin)
var stderr bytes.Buffer
command.Stderr = &stderr

stdout, err := command.Output()
return string(stdout), stderr.String(), err
// AutoInject returns whether or not Proxy Auto Inject is enabled for the given
// test.
func (h *TestHelper) AutoInject() bool {
return h.autoInject
}

// LinkerdRun executes a linkerd command appended with the --linkerd-namespace
Expand All @@ -130,7 +136,7 @@ func (h *TestHelper) LinkerdRun(arg ...string) (string, string, error) {
// --linkerd-namespace flag, and provides a string at Stdin.
func (h *TestHelper) PipeToLinkerdRun(stdin string, arg ...string) (string, string, error) {
withParams := append(arg, "--linkerd-namespace", h.namespace, "--context="+h.k8sContext)
return h.combinedOutput(stdin, h.linkerd, withParams...)
return combinedOutput(stdin, h.linkerd, withParams...)
}

// LinkerdRunStream initiates a linkerd command appended with the
Expand Down Expand Up @@ -162,11 +168,10 @@ func (h *TestHelper) LinkerdRunStream(arg ...string) (*Stream, error) {
// ValidateOutput validates a string against the contents of a file in the
// test's testdata directory.
func (h *TestHelper) ValidateOutput(out, fixtureFile string) error {
b, err := ioutil.ReadFile("testdata/" + fixtureFile)
expected, err := ReadFile("testdata/" + fixtureFile)
if err != nil {
return err
}
expected := string(b)

if out != expected {
return fmt.Errorf(
Expand Down Expand Up @@ -244,3 +249,23 @@ func (h *TestHelper) HTTPGetURL(url string) (string, error) {

return body, err
}

// ReadFile reads a file from disk and returns the contents as a string.
func ReadFile(file string) (string, error) {
b, err := ioutil.ReadFile(file)
if err != nil {
return "", err
}
return string(b), nil
}

// combinedOutput executes a shell command and returns the output.
func combinedOutput(stdin string, name string, arg ...string) (string, string, error) {
command := exec.Command(name, arg...)
command.Stdin = strings.NewReader(stdin)
var stderr bytes.Buffer
command.Stderr = &stderr

stdout, err := command.Output()
return string(stdout), stderr.String(), err
}

0 comments on commit 807e73d

Please sign in to comment.