Isolate routing fixtures from host Screen sessions
This commit is contained in:
1 parent
0b3ba7fbe7
commit
e6da76e14a
3 files changed
+60
-3
No files matched your search
@@ -14,6 +14,7 @@ import (
|
||||
"os/exec"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
"syscall"
|
||||
"testing"
|
||||
"time"
|
||||
)
|
||||
@@ -66,13 +67,54 @@ func TestControlProcess(t *testing.T) {
|
||||
func child_command(mode string) *exec.Cmd {
|
||||
command := exec.Command(os.Args[0], "-test.run=^TestControlProcess$")
|
||||
command.Env = append(os.Environ(), "FENRIR_CONTROL_PROCESS="+mode)
|
||||
// A fixture must not inherit the developer's real VT as its controlling TTY.
|
||||
command.SysProcAttr = &syscall.SysProcAttr{Setsid: true}
|
||||
return command
|
||||
}
|
||||
|
||||
// Screen daemons launched by a fixture may be reparented to PID 1 and never
|
||||
// reach the coordinator; their full ancestry still belongs to that fixture.
|
||||
func fixture_ancestors(ancestors []int, coordinator int) []int {
|
||||
for i, pid := range ancestors {
|
||||
if pid == coordinator {
|
||||
return ancestors[:i]
|
||||
}
|
||||
}
|
||||
return ancestors
|
||||
}
|
||||
|
||||
func TestFixtureScreenInspectionExcludesHostAndKeepsPrivateSessions(t *testing.T) {
|
||||
for _, trial := range []struct {
|
||||
name string
|
||||
ancestors []int
|
||||
handled bool
|
||||
}{
|
||||
{"host Screen above coordinator", []int{120, 300, 100}, false},
|
||||
{"private Screen below coordinator", []int{120, 100, 300}, true},
|
||||
{"private Screen reparented to init", []int{120, 100}, true},
|
||||
{"coordinator caller", []int{300, 100}, false},
|
||||
} {
|
||||
t.Run(trial.name, func(t *testing.T) {
|
||||
f := new_screen_fixture(t)
|
||||
f.attach(200, 300, "/dev/null", true)
|
||||
reader, handled, err := attached_screen_reader(f.root, fixture_ancestors(trial.ancestors, 300), os.Geteuid(), []instance{{PID: 300}})
|
||||
if err != nil || handled != trial.handled || handled && reader.PID != 300 {
|
||||
t.Fatalf("reader=%+v handled=%v err=%v; want handled=%v", reader, handled, err, trial.handled)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func run_reader_process(mode string) {
|
||||
encoder := json.NewEncoder(os.Stdout)
|
||||
directory := os.Getenv("FENRIR_CONTROL_DIRECTORY")
|
||||
server, err := Open(context.Background(), Options{Directory: directory, RegistryDirectory: filepath.Join(directory, "registry"), TerminalMode: mode == "terminal", WindowID: os.Getenv("WINDOWID")})
|
||||
// Processes above the test coordinator belong to the host, not this fixture.
|
||||
// Screen sessions created by the native test remain inside the inspected tree.
|
||||
coordinator := os.Getppid()
|
||||
lookup := func(ancestors []int, uid int, readers []instance) (instance, bool, error) {
|
||||
return attached_screen_reader("/proc", fixture_ancestors(ancestors, coordinator), uid, readers)
|
||||
}
|
||||
server, err := open_server(context.Background(), Options{Directory: directory, RegistryDirectory: filepath.Join(directory, "registry"), TerminalMode: mode == "terminal", WindowID: os.Getenv("WINDOWID")}, lookup)
|
||||
if err != nil {
|
||||
_ = encoder.Encode(processReply{Error: err.Error()})
|
||||
return
|
||||
|
||||
Reference in new issue
Block a user