diff options
| author | Christine Dodrill <xe@tailscale.com> | 2021-07-09 13:58:01 -0400 |
|---|---|---|
| committer | Christine Dodrill <xe@tailscale.com> | 2021-07-12 10:38:36 -0400 |
| commit | 77c856c0f5566223061904f0ce90435bee383d34 (patch) | |
| tree | c7c8e22191e297d459c86a7bf2556e18901dee90 /tstest/integration/vms/vms_steps_test.go | |
| parent | afbd35482d23e9df28ae2f036df43c6bf8f2aeea (diff) | |
| download | tailscale-Xe/testcontrol-v6.tar.xz tailscale-Xe/testcontrol-v6.zip | |
tstest/integration/testcontrol: ipv6 supportXe/testcontrol-v6
And a bunch of IPv6 tests!
Signed-off-by: Christine Dodrill <xe@tailscale.com>
Diffstat (limited to 'tstest/integration/vms/vms_steps_test.go')
| -rw-r--r-- | tstest/integration/vms/vms_steps_test.go | 134 |
1 files changed, 134 insertions, 0 deletions
diff --git a/tstest/integration/vms/vms_steps_test.go b/tstest/integration/vms/vms_steps_test.go new file mode 100644 index 000000000..45ba95e12 --- /dev/null +++ b/tstest/integration/vms/vms_steps_test.go @@ -0,0 +1,134 @@ +// Copyright (c) 2021 Tailscale Inc & AUTHORS All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// +build linux + +package vms + +import ( + "bytes" + "context" + "fmt" + "net" + "net/http" + "strings" + "testing" + "time" + + "golang.org/x/crypto/ssh" + "inet.af/netaddr" +) + +const timeout = 15 * time.Second + +func retry(t *testing.T, fn func() error) { + t.Helper() + const tries = 3 + var err error + for i := 0; i < tries; i++ { + err = fn() + if err != nil { + t.Logf("%dth invocation failed, trying again: %v", i, err) + time.Sleep(50 * time.Millisecond) + } + if err == nil { + return + } + } + t.Fatalf("tried %d times, got: %v", tries, err) +} + +func (h Harness) testPing(t *testing.T, ipAddr netaddr.IP, cli *ssh.Client) { + var outp []byte + var err error + retry(t, func() error { + sess := getSession(t, cli) + + outp, err = sess.CombinedOutput(fmt.Sprintf("tailscale ping -c 1 %s", ipAddr)) + return err + }) + + if !bytes.Contains(outp, []byte("pong")) { + t.Log(string(outp)) + t.Fatal("no pong") + } + + retry(t, func() error { + sess := getSession(t, cli) + + // NOTE(Xe): the ping command is inconsistent across distros. Joy. + pingCmd := fmt.Sprintf("sh -c 'ping -c 1 %[1]s || ping -6 -c 1 %[1]s || ping6 -c 1 %[1]s\n'", ipAddr) + t.Logf("running %q", pingCmd) + outp, err = sess.CombinedOutput(pingCmd) + return err + }) + + if !bytes.Contains(outp, []byte("bytes")) { + t.Log(string(outp)) + t.Fatalf("wanted output to contain %q, it did not", "bytes") + } +} + +func getSession(t *testing.T, cli *ssh.Client) *ssh.Session { + sess, err := cli.NewSession() + if err != nil { + t.Fatal(err) + } + + t.Cleanup(func() { + sess.Close() + }) + + return sess +} + +func (h Harness) testOutgoingTCP(t *testing.T, ipAddr netaddr.IP, cli *ssh.Client) { + const sendmsg = "this is a message that curl won't print" + ctx, cancel := context.WithCancel(context.Background()) + s := &http.Server{ + Handler: http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + t.Logf("http connection from %s", r.RemoteAddr) + cancel() + fmt.Fprintln(w, sendmsg) + }), + } + ln, err := net.Listen("tcp", net.JoinHostPort("::", "0")) + if err != nil { + t.Fatalf("can't make HTTP server: %v", err) + } + _, port, _ := net.SplitHostPort(ln.Addr().String()) + go s.Serve(ln) + + // sess := getSession(t, cli) + // sess.Stderr = logger.FuncWriter(t.Logf) + // sess.Stdout = logger.FuncWriter(t.Logf) + // sess.Run("ip route show table all") + + // sess = getSession(t, cli) + // sess.Stderr = logger.FuncWriter(t.Logf) + // sess.Stdout = logger.FuncWriter(t.Logf) + // sess.Run("sysctl -a") + + var outp []byte + retry(t, func() error { + var err error + sess := getSession(t, cli) + v6Arg := "" + if ipAddr.Is6() { + v6Arg = "-6 -g" + } + cmd := fmt.Sprintf("curl -v %s -s -f http://%s\n", v6Arg, net.JoinHostPort(ipAddr.String(), port)) + t.Logf("running: %s", cmd) + outp, err = sess.CombinedOutput(cmd) + if err != nil { + t.Log(string(outp)) + } + return err + }) + + if msg := string(bytes.TrimSpace(outp)); !strings.Contains(msg, sendmsg) { + t.Fatalf("wanted %q, got: %q", sendmsg, msg) + } + <-ctx.Done() +} |
