Files

116 lines
2.9 KiB
Go

package agent
import (
"io"
"os"
"path/filepath"
"strings"
"testing"
"time"
"github.com/x-grk/longpolling-remote-access/internal/proto"
)
// A terminal opened with a folder starts its shell there; a folder that is
// not there leaves it at home.
func TestStartPTYDir(t *testing.T) {
dir, err := filepath.EvalSymlinks(t.TempDir())
if err != nil {
t.Fatal(err)
}
sub := filepath.Join(dir, "sub dir")
if err := os.Mkdir(sub, 0o755); err != nil {
t.Fatal(err)
}
if got := ptyPwd(t, sub); got != sub {
t.Fatalf("pwd = %q, want %q", got, sub)
}
home, _ := filepath.EvalSymlinks(homeDir(""))
if got := ptyPwd(t, filepath.Join(dir, "missing")); got != home {
t.Fatalf("pwd for a missing folder = %q, want home %q", got, home)
}
}
// ptyPwd opens a terminal at dir and returns where its shell is.
func ptyPwd(t *testing.T, dir string) string {
t.Helper()
t.Setenv("SHELL", "/bin/sh")
p, err := StartPTY("", dir)
if err != nil {
t.Fatal(err)
}
defer p.Close()
if _, err := p.Write([]byte("echo \"@@$(pwd -P)@@\"\n")); err != nil {
t.Fatal(err)
}
var out strings.Builder
buf := make([]byte, 4096)
deadline := time.Now().Add(5 * time.Second)
for time.Now().Before(deadline) {
n, err := p.Read(buf)
out.Write(buf[:n])
s := out.String()
// The echoed command line has "@@$(pwd" in it; the answer does not.
for _, part := range strings.Split(s, "@@") {
if strings.HasPrefix(part, "/") && strings.Contains(s, part+"@@") {
return part
}
}
if err != nil {
break
}
}
t.Fatalf("no pwd in %q", out.String())
return ""
}
// A terminal tells the folder its shell is in now, after a cd.
func TestPTYCwd(t *testing.T) {
dir, err := filepath.EvalSymlinks(t.TempDir())
if err != nil {
t.Fatal(err)
}
sub := filepath.Join(dir, "next one")
if err := os.Mkdir(sub, 0o755); err != nil {
t.Fatal(err)
}
t.Setenv("SHELL", "/bin/sh")
p, err := StartPTY("", dir)
if err != nil {
t.Fatal(err)
}
defer p.Close()
go func() { _, _ = io.Copy(io.Discard, p) }()
if _, err := p.Write([]byte("cd 'next one'\n")); err != nil {
t.Fatal(err)
}
var got string
for i := 0; i < 50; i++ {
if got, err = p.Cwd(); err == nil && got == sub {
return
}
time.Sleep(100 * time.Millisecond)
}
t.Fatalf("Cwd = %q, %v; want %q", got, err, sub)
}
// The panel asks for a terminal's folder by its session.
func TestTermCwdTask(t *testing.T) {
dir, _ := filepath.EvalSymlinks(t.TempDir())
t.Setenv("SHELL", "/bin/sh")
p, err := StartPTY("", dir)
if err != nil {
t.Fatal(err)
}
defer p.Close()
termsBySID.Store("s1", p)
defer termsBySID.Delete("s1")
res, err := dispatchTask(proto.TaskEnvelope{Type: proto.TaskTermCwd, Args: []byte(`{"session":"s1"}`)})
if err != nil || res.(map[string]string)["path"] != dir {
t.Fatalf("term.cwd = %v, %v; want %q", res, err, dir)
}
if _, err := dispatchTask(proto.TaskEnvelope{Type: proto.TaskTermCwd, Args: []byte(`{"session":"nope"}`)}); err == nil {
t.Fatal("an unknown session has a folder")
}
}