e2e/term_test.go

bd5cf5d7d1f34fa780660fd7562b9ffd9746ee27
gitbay/e2e/term_test.go history · blame · raw

87 lines · 2907 bytes

 1package e2e
 2
 3import (
 4	"os"
 5	"os/exec"
 6	"path/filepath"
 7	"strings"
 8	"testing"
 9)
10
11// GITBAY_TERM selects terminal output per session. Stock ssh without it
12// gets the plain rows scripts read.
13func TestTermEnvSelectsTerminalOutput(t *testing.T) {
14	t.Parallel()
15	inst := startInstance(t)
16	key := inst.newKey(t, "alice")
17	inst.admin(t, "admin", "user", "create", "alice", "--key", key+".pub",
18		"--email", "alice@example.test", "--verified")
19	if _, errOut, code := inst.ssh(t, key, "", "repo", "create", "alice/app"); code != 0 {
20		t.Fatalf("repo create: %d %s", code, errOut)
21	}
22
23	plain, _, _ := inst.sshTerm(t, key, "", "repo", "list")
24	if strings.Contains(plain, "PATH") || !strings.Contains(plain, "alice/app\t") {
25		t.Errorf("plain repo list: %q", plain)
26	}
27	term, _, _ := inst.sshTerm(t, key, "80,color", "repo", "list")
28	if !strings.HasPrefix(term, "\x1b[2mPATH") {
29		t.Errorf("terminal repo list: %q", term)
30	}
31}
32
33// The CLI shares one connection per instance. Each session's terminal
34// selection must reach the server on its own, not the one the master
35// session was opened with — which is why it travels as a leading
36// --term=<v> argument rather than SetEnv: OpenSSH's mux client does not
37// forward a new session's SetEnv onto an existing ControlMaster.
38func TestTermEnvOverMultiplexedSession(t *testing.T) {
39	t.Parallel()
40	inst := startInstance(t)
41	key := inst.newKey(t, "alice")
42	inst.admin(t, "admin", "user", "create", "alice", "--key", key+".pub",
43		"--email", "alice@example.test", "--verified")
44	inst.ssh(t, key, "", "repo", "create", "alice/app")
45
46	dir, err := os.MkdirTemp("", "gbmux")
47	if err != nil {
48		t.Fatal(err)
49	}
50	t.Cleanup(func() { os.RemoveAll(dir) })
51	sock := filepath.Join(dir, "cm")
52	mux := func(term string) string {
53		t.Helper()
54		cmdArgs := []string{"repo", "list"}
55		if term != "" {
56			// "--" stops the local ssh client from parsing --term=... as one
57			// of its own options; it is not part of the remote command line.
58			cmdArgs = append([]string{"--", "--term=" + term}, cmdArgs...)
59		}
60		cmd := inst.sshCmd(key, cmdArgs...)
61		opts := []string{"-o", "ControlMaster=auto", "-o", "ControlPath=" + sock, "-o", "ControlPersist=30"}
62		for j, a := range cmd.Args {
63			if a == "git@127.0.0.1" {
64				cmd.Args = append(cmd.Args[:j:j], append(opts, cmd.Args[j:]...)...)
65				break
66			}
67		}
68		out, err := cmd.Output()
69		if err != nil {
70			t.Fatalf("ssh %s: %v", term, err)
71		}
72		return string(out)
73	}
74	t.Cleanup(func() {
75		exec.Command("ssh", "-o", "ControlPath="+sock, "-O", "exit", "git@127.0.0.1").Run()
76	})
77
78	if out := mux("80"); !strings.HasPrefix(out, "PATH") {
79		t.Fatalf("master session: %q", out)
80	}
81	if out := mux("80,color"); !strings.HasPrefix(out, "\x1b[2mPATH") {
82		t.Errorf("second session kept the master's GITBAY_TERM: %q", out)
83	}
84	if out := mux(""); strings.Contains(out, "PATH") {
85		t.Errorf("session without GITBAY_TERM got terminal output: %q", out)
86	}
87}