mirror of
https://github.com/tailscale/tailscale.git
synced 2025-04-19 05:02:34 +00:00
tstest/integration/vms: make first end to end test (#2332)
This makes sure `tailscale status` and `tailscale ping` works. It also switches goexpect to use a batch instead of manually banging out each line, which makes the tests so much easier to read. Signed-off-by: Christine Dodrill <xe@tailscale.com>
This commit is contained in:
parent
805d5d3cde
commit
a8360050e7
@ -627,6 +627,8 @@ func TestVMIntegrationEndToEnd(t *testing.T) {
|
|||||||
ramsem := semaphore.NewWeighted(int64(*vmRamLimit))
|
ramsem := semaphore.NewWeighted(int64(*vmRamLimit))
|
||||||
bins := integration.BuildTestBinaries(t)
|
bins := integration.BuildTestBinaries(t)
|
||||||
|
|
||||||
|
makeTestNode(t, bins, loginServer)
|
||||||
|
|
||||||
t.Run("do", func(t *testing.T) {
|
t.Run("do", func(t *testing.T) {
|
||||||
for n, distro := range distros {
|
for n, distro := range distros {
|
||||||
n, distro := n, distro
|
n, distro := n, distro
|
||||||
@ -718,9 +720,9 @@ func testDistro(t *testing.T, loginServer string, d Distro, signer ssh.Signer, i
|
|||||||
expect.Verbose(true),
|
expect.Verbose(true),
|
||||||
expect.VerboseWriter(logger.FuncWriter(t.Logf)),
|
expect.VerboseWriter(logger.FuncWriter(t.Logf)),
|
||||||
|
|
||||||
// // NOTE(Xe): if you get a timeout, uncomment this line to have the raw
|
// // NOTE(Xe): if you get a timeout, uncomment this region to have the raw
|
||||||
// output be sent to the test log quicker.
|
// // output be sent to the test log quicker.
|
||||||
//expect.Tee(nopWriteCloser{logger.FuncWriter(t.Logf)}),
|
// expect.Tee(nopWriteCloser{logger.FuncWriter(t.Logf)}),
|
||||||
)
|
)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("%d: can't register a shell session: %v", port, err)
|
t.Fatalf("%d: can't register a shell session: %v", port, err)
|
||||||
@ -729,11 +731,11 @@ func testDistro(t *testing.T, loginServer string, d Distro, signer ssh.Signer, i
|
|||||||
|
|
||||||
t.Log("opened session")
|
t.Log("opened session")
|
||||||
|
|
||||||
_, _, err = e.Expect(regexp.MustCompile(`(\#)`), timeout)
|
var batch = []expect.Batcher{
|
||||||
if err != nil {
|
&expect.BSnd{S: "PS1='# '\n"},
|
||||||
t.Fatalf("%d: can't get a shell: %v", port, err)
|
&expect.BExp{R: `(\#)`},
|
||||||
}
|
}
|
||||||
t.Logf("got shell for %d", port)
|
|
||||||
switch d.initSystem {
|
switch d.initSystem {
|
||||||
case "openrc":
|
case "openrc":
|
||||||
// NOTE(Xe): this is a sin, however openrc doesn't really have the concept
|
// NOTE(Xe): this is a sin, however openrc doesn't really have the concept
|
||||||
@ -741,23 +743,36 @@ func testDistro(t *testing.T, loginServer string, d Distro, signer ssh.Signer, i
|
|||||||
// ready once the `tailscale up` command is sent. This is not ideal, but I
|
// ready once the `tailscale up` command is sent. This is not ideal, but I
|
||||||
// am not really sure there is a good way around this without a delay of
|
// am not really sure there is a good way around this without a delay of
|
||||||
// some kind.
|
// some kind.
|
||||||
err = e.Send("rc-service tailscaled start && sleep 2\n")
|
batch = append(batch, &expect.BSnd{S: "rc-service tailscaled start && sleep 2\n"})
|
||||||
case "systemd":
|
case "systemd":
|
||||||
err = e.Send("systemctl start tailscaled.service\n")
|
batch = append(batch, &expect.BSnd{S: "systemctl start tailscaled.service\n"})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
batch = append(batch,
|
||||||
|
&expect.BExp{R: `(\#)`},
|
||||||
|
&expect.BSnd{S: fmt.Sprintf("tailscale up --login-server=%s\n", loginServer)},
|
||||||
|
&expect.BExp{R: `Success.`},
|
||||||
|
&expect.BSnd{S: "sleep 5 && tailscale status\n"},
|
||||||
|
&expect.BExp{R: `100.64.0.1`},
|
||||||
|
&expect.BExp{R: `(\#)`},
|
||||||
|
&expect.BSnd{S: "tailscale ping -c 1 100.64.0.1\n"},
|
||||||
|
&expect.BExp{R: `pong from.*\(100.64.0.1\)`},
|
||||||
|
&expect.BSnd{S: "ping -c 1 100.64.0.1\n"},
|
||||||
|
&expect.BExp{R: `bytes`},
|
||||||
|
)
|
||||||
|
|
||||||
|
_, err = e.ExpectBatch(batch, timeout)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("can't send command to start tailscaled: %v", err)
|
sess, terr := cli.NewSession()
|
||||||
|
if terr != nil {
|
||||||
|
t.Fatalf("can't dump tailscaled logs on failed test: %v", err)
|
||||||
}
|
}
|
||||||
_, _, err = e.Expect(regexp.MustCompile(`(\#)`), timeout)
|
sess.Stdout = logger.FuncWriter(t.Logf)
|
||||||
if err != nil {
|
sess.Stderr = logger.FuncWriter(t.Logf)
|
||||||
t.Fatalf("%d: can't get a shell: %v", port, err)
|
terr = sess.Run("journalctl -u tailscaled")
|
||||||
|
if terr != nil {
|
||||||
|
t.Fatalf("can't dump tailscaled logs on failed test: %v", err)
|
||||||
}
|
}
|
||||||
err = e.Send(fmt.Sprintf("tailscale up --login-server %s\n", loginServer))
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("%d: can't send tailscale up command: %v", port, err)
|
|
||||||
}
|
|
||||||
_, _, err = e.Expect(regexp.MustCompile(`Success.`), timeout)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("not successful: %v", err)
|
t.Fatalf("not successful: %v", err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -874,6 +889,56 @@ func TestDeriveBindhost(t *testing.T) {
|
|||||||
t.Log(deriveBindhost(t))
|
t.Log(deriveBindhost(t))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func makeTestNode(t *testing.T, bins *integration.Binaries, controlURL string) {
|
||||||
|
dir := t.TempDir()
|
||||||
|
cmd := exec.Command(
|
||||||
|
bins.Daemon,
|
||||||
|
"--tun=userspace-networking",
|
||||||
|
"--state="+filepath.Join(dir, "state.json"),
|
||||||
|
"--socket="+filepath.Join(dir, "sock"),
|
||||||
|
"--socks5-server=localhost:0",
|
||||||
|
)
|
||||||
|
|
||||||
|
cmd.Env = append(os.Environ(), "NOTIFY_SOCKET="+filepath.Join(dir, "notify_socket"))
|
||||||
|
|
||||||
|
err := cmd.Start()
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("can't start tailscaled: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
t.Cleanup(func() {
|
||||||
|
cmd.Process.Kill()
|
||||||
|
})
|
||||||
|
|
||||||
|
ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
|
||||||
|
defer cancel()
|
||||||
|
ticker := time.NewTicker(100 * time.Millisecond)
|
||||||
|
|
||||||
|
outer:
|
||||||
|
for {
|
||||||
|
select {
|
||||||
|
case <-ctx.Done():
|
||||||
|
t.Fatal("timed out waiting for tailscaled to come up")
|
||||||
|
return
|
||||||
|
case <-ticker.C:
|
||||||
|
conn, err := net.Dial("unix", filepath.Join(dir, "sock"))
|
||||||
|
if err != nil {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
conn.Close()
|
||||||
|
break outer
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
run(t, dir, bins.CLI,
|
||||||
|
"--socket="+filepath.Join(dir, "sock"),
|
||||||
|
"up",
|
||||||
|
"--login-server="+controlURL,
|
||||||
|
"--hostname=tester",
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
type nopWriteCloser struct {
|
type nopWriteCloser struct {
|
||||||
io.Writer
|
io.Writer
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user