Supervise quarantined Remote input helpers and block uncertain replacement
This commit is contained in:
1 parent
21d8904ee3
commit
5ab3efdfa7
5 files changed
+771
-4
No files matched your search
@@ -6,6 +6,8 @@ package xorg
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"context"
|
||||
"errors"
|
||||
"io"
|
||||
"os"
|
||||
"os/exec"
|
||||
@@ -16,6 +18,68 @@ import (
|
||||
"git.stormux.org/storm/cthulhu/internal/remoteinput"
|
||||
)
|
||||
|
||||
func TestNativeRemoteKeyHelperSupervisor(t *testing.T) {
|
||||
for _, cancellation := range []string{"explicit", "lease-context"} {
|
||||
t.Run(cancellation, func(t *testing.T) {
|
||||
remoteNativeThread(t)
|
||||
path := os.Getenv("CTHULHU_REMOTE_INPUT_HELPER")
|
||||
supervisor, err := remoteinput.NewSupervisor(path)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
probe := remoteNativeTarget(t)
|
||||
ctx, cancel := context.WithCancel(context.Background())
|
||||
defer cancel()
|
||||
client, err := supervisor.Start(ctx, 71)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
defer func() { client.Cancel(); client.Wait() }()
|
||||
codes := make([]uint16, 0, 2)
|
||||
for _, name := range []string{"Shift_L", "Control_R"} {
|
||||
code, err := probe.backend.Resolve(name)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
codes = append(codes, code)
|
||||
if err := client.Apply(t.Context(), name, true); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
remoteNativeHeld(t, probe, code, true)
|
||||
}
|
||||
if _, err := supervisor.Start(t.Context(), 72); !errors.Is(err, remoteinput.ErrUnavailable) {
|
||||
t.Fatal("active native helper replaced", err)
|
||||
}
|
||||
if cancellation == "explicit" {
|
||||
client.Cancel()
|
||||
} else {
|
||||
cancel()
|
||||
}
|
||||
if err := client.Wait(); err != nil {
|
||||
t.Fatal("native cleanup not confirmed", err)
|
||||
}
|
||||
for _, code := range codes {
|
||||
remoteNativeHeld(t, probe, code, false)
|
||||
}
|
||||
replacement, err := supervisor.Start(t.Context(), 72)
|
||||
if err != nil {
|
||||
t.Fatal("confirmed cleanup blocked fresh owner", err)
|
||||
}
|
||||
defer func() { replacement.Cancel(); replacement.Wait() }()
|
||||
client.Cancel()
|
||||
if err := replacement.Apply(t.Context(), "Shift_L", true); err != nil {
|
||||
t.Fatal("old owner cancellation affected replacement", err)
|
||||
}
|
||||
remoteNativeHeld(t, probe, codes[0], true)
|
||||
replacement.Cancel()
|
||||
if err := replacement.Wait(); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
remoteNativeHeld(t, probe, codes[0], false)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
// The writer owns both write ends exclusively. The supervising test owns the
|
||||
// helper process so it can observe cleanup and reap it after writer SIGKILL.
|
||||
func TestNativeRemoteKeyControlWriter(t *testing.T) {
|
||||
|
||||
Reference in new issue
Block a user