1package launcher
2
3import (
4 "context"
5 "net"
6 "os"
7 "path/filepath"
8 "strings"
9 "testing"
10 "time"
11
12 "github.com/bnema/neferwl/internal/adapters/logging"
13)
14
15// The session commands run with the child environment and the right
16// arguments; the scripts on PATH record them.
17func TestExportSession(t *testing.T) {
18 dir := t.TempDir()
19 out := filepath.Join(dir, "calls")
20 script := "#!/bin/sh\necho \"${0##*/} $* $WAYLAND_DISPLAY\" >> " + out + "\n"
21 for _, name := range []string{"dbus-update-activation-environment", "systemctl"} {
22 if err := os.WriteFile(filepath.Join(dir, name), []byte(script), 0o755); err != nil {
23 t.Fatal(err)
24 }
25 }
26 env := []string{"PATH=" + dir, "WAYLAND_DISPLAY=wayland-9"}
27 ctx := context.Background()
28 ExportSession(ctx, env, logging.For(ctx, "launcher"))
29 UnexportSession(env, logging.For(ctx, "launcher"))
30 data, err := os.ReadFile(out)
31 if err != nil {
32 t.Fatal(err)
33 }
34 want := "dbus-update-activation-environment --systemd WAYLAND_DISPLAY DISPLAY XDG_CURRENT_DESKTOP XDG_SESSION_TYPE wayland-9\n" +
35 "systemctl --user --no-block try-restart xdg-desktop-portal*.service wayland-9\n" +
36 "systemctl --user unset-environment WAYLAND_DISPLAY DISPLAY XDG_CURRENT_DESKTOP XDG_SESSION_TYPE wayland-9\n" +
37 "systemctl --user --no-block stop xdg-desktop-portal*.service wayland-9\n"
38 if string(data) != want {
39 t.Fatalf("calls:\n%s", data)
40 }
41 // Missing tools are skipped, not fatal.
42 ExportSession(ctx, []string{"PATH=" + t.TempDir()}, logging.For(ctx, "launcher"))
43 if strings.Count(string(data), "\n") != 4 {
44 t.Fatal(string(data))
45 }
46}
47
48// A failed export restarts no portal: it would read the old variables again.
49func TestExportSessionFailedSkipsPortals(t *testing.T) {
50 dir := t.TempDir()
51 out := filepath.Join(dir, "calls")
52 scripts := map[string]string{
53 "dbus-update-activation-environment": "#!/bin/sh\nexit 1\n",
54 "systemctl": "#!/bin/sh\necho \"$*\" >> " + out + "\n",
55 }
56 for name, script := range scripts {
57 if err := os.WriteFile(filepath.Join(dir, name), []byte(script), 0o755); err != nil {
58 t.Fatal(err)
59 }
60 }
61 ctx := context.Background()
62 ExportSession(ctx, []string{"PATH=" + dir}, logging.For(ctx, "launcher"))
63 if data, err := os.ReadFile(out); err == nil {
64 t.Fatalf("systemctl called: %s", data)
65 }
66}
67
68func TestNotifyReady(t *testing.T) {
69 ctx := context.Background()
70 log := logging.For(ctx, "launcher")
71 NotifyReady("", log)
72 path := filepath.Join(t.TempDir(), "notify")
73 listener, err := net.ListenUnixgram("unixgram", &net.UnixAddr{Name: path, Net: "unixgram"})
74 if err != nil {
75 t.Fatal(err)
76 }
77 defer listener.Close()
78 NotifyReady(path, log)
79 if err := listener.SetReadDeadline(time.Now().Add(time.Second)); err != nil {
80 t.Fatal(err)
81 }
82 buf := make([]byte, 64)
83 n, _, err := listener.ReadFromUnix(buf)
84 if err != nil {
85 t.Fatal(err)
86 }
87 if string(buf[:n]) != "READY=1" {
88 t.Fatalf("notification: %q", buf[:n])
89 }
90}