openrazer (the official driver, daemon and library), polychromatic (the AUR tray, kept as found; its i3 line moves out of the i3 module into its own node-display-session contribution), forticlient (the AUR VPN client: its service declared, its configuration never read) and nm-applet (the desktop half of NetworkManager, apart from the server-side module). The openrazer daemon fails on both workstations because the account is not in the openrazer group; openrazer_check names it and the README carries the one-off step, since the account's user resource is zsh's. desktop.go learns to tell a program from another sharing its 15-character command name, so polychromatic's tools never count or end themselves, and a copies test holds the six carriers to one text.
123 lines
4.5 KiB
Go
123 lines
4.5 KiB
Go
package main
|
|
|
|
import (
|
|
"strings"
|
|
"testing"
|
|
)
|
|
|
|
// newTray is a machine with the tray as the module wants it: the module's line in i3's configuration,
|
|
// the package's helper entry with the tray setting off, one tray running, and the daemon answering.
|
|
func newTray(t *testing.T, running bool) *fake {
|
|
f := newFake(t)
|
|
f.write("/etc/xdg/autostart/"+helperEntry, "[Desktop Entry]\nExec=polychromatic-helper --autostart\n")
|
|
f.write(testHome+"/.config/i3/config", "exec --no-startup-id dex --autostart --environment i3\n# polychromatic\n"+
|
|
"exec --no-startup-id polychromatic-tray-applet\n")
|
|
f.write(testHome+"/"+prefsFile, `{"config_version":8,"tray":{"autostart":false,"autostart_delay":0,"mode":0},"editor":{}}`)
|
|
if running {
|
|
f.proc(4122, 1000, trayComm, []string{"polychromatic-tray-applet"}, "session-c1.scope")
|
|
// the tools themselves: the same cut command name
|
|
f.proc(4200, 1000, trayComm, []string{"/usr/lib/mesh/polychromatic-tools"}, "system.slice/mesh-runtime.service")
|
|
}
|
|
f.answer = func(name string, args []string) Output {
|
|
switch {
|
|
case name == "pacman" && args[0] == "-Q":
|
|
return Output{Stdout: "polychromatic 0.9.8-1\n"}
|
|
case name == "pacman" && args[0] == "-Qqm":
|
|
return Output{Stdout: "polychromatic\n"}
|
|
case name == "busctl":
|
|
return Output{Stdout: `{"type":"as","data":[["PM2148H00000001"]]}`}
|
|
}
|
|
return Output{}
|
|
}
|
|
return f
|
|
}
|
|
|
|
func TestStatusSaysWhatStartsTheTrayAndAsksTheDaemonWithoutStartingIt(t *testing.T) {
|
|
f := newTray(t, true)
|
|
s, err := f.Status()
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if s.Installed != "0.9.8-1" || !s.Foreign || len(s.Tray) != 1 || !s.Backend.Answers || s.Backend.Devices != 1 ||
|
|
len(s.StartedBy) != 1 || !strings.HasPrefix(s.StartedBy[0], "window manager: ~/.config/i3/config:3") || s.Setting.Autostart {
|
|
t.Fatalf("%+v", s)
|
|
}
|
|
for _, c := range f.calls {
|
|
if strings.HasPrefix(c, "busctl") && !strings.Contains(c, "--auto-start=no") {
|
|
t.Fatalf("a bus call that could start the daemon: %s", c)
|
|
}
|
|
}
|
|
}
|
|
|
|
func TestTheTraySettingIsReadAndDefaultsOn(t *testing.T) {
|
|
f := newTray(t, false)
|
|
if s := f.setting(); s.Autostart || s.From != "~/"+prefsFile {
|
|
t.Fatalf("%+v", s)
|
|
}
|
|
f.write(testHome+"/"+prefsFile, `{"tray":{"autostart_delay":3}}`)
|
|
if s := f.setting(); !s.Autostart || s.Delay != 3 {
|
|
t.Fatalf("%+v", s)
|
|
}
|
|
f.write(testHome+"/"+prefsFile, `not json`)
|
|
if s := f.setting(); !s.Autostart || !strings.Contains(s.From, "does not parse") {
|
|
t.Fatalf("%+v", s)
|
|
}
|
|
}
|
|
|
|
func TestCheckPassesTheModulesOneStartAndNamesTheHelpersAsASecond(t *testing.T) {
|
|
f := newTray(t, true)
|
|
f.desktopSession()
|
|
c, err := f.Check()
|
|
if err != nil || !c.OK || len(c.Starts) != 1 {
|
|
t.Fatalf("%+v %v", c, err)
|
|
}
|
|
|
|
f.write(testHome+"/"+prefsFile, `{"tray":{"autostart":true}}`)
|
|
f.write(testHome+"/.config/i3/config.d/90-x.conf", "exec_always --no-startup-id polychromatic-tray-applet\n")
|
|
f.proc(4123, 1000, trayComm, []string{"polychromatic-tray-applet"}, "session-c1.scope")
|
|
f.answer = func(name string, args []string) Output {
|
|
switch name {
|
|
case "pacman":
|
|
return Output{Code: 1}
|
|
case "busctl":
|
|
return Output{Code: 1, Stderr: "Call failed: Unit openrazer-daemon.service failed"}
|
|
}
|
|
return Output{}
|
|
}
|
|
c, _ = f.Check()
|
|
var all []string
|
|
for _, x := range c.Findings {
|
|
all = append(all, x.What+" => "+x.Do)
|
|
}
|
|
got := strings.Join(all, "\n")
|
|
for _, want := range []string{"not installed", "a second start: ~/.config/i3/config.d/90-x.conf:1", "the package's login helper starts the tray too",
|
|
"Start the tray applet when I log on", "2 trays run", "openrazer daemon does not answer"} {
|
|
if !strings.Contains(got, want) {
|
|
t.Errorf("no finding %q in\n%s", want, got)
|
|
}
|
|
}
|
|
|
|
none := newTray(t, false)
|
|
none.write(testHome+"/.config/i3/config", "exec --no-startup-id dex --autostart --environment i3\n")
|
|
c, _ = none.Check()
|
|
if c.OK || !strings.Contains(c.Findings[0].What, "does not start the tray") {
|
|
t.Fatalf("%+v", c)
|
|
}
|
|
}
|
|
|
|
func TestRestartEndsTheTrayAndStartsItUnderTheServiceManager(t *testing.T) {
|
|
f := newTray(t, true)
|
|
if _, err := f.Restart(); err == nil || !strings.Contains(err.Error(), "no graphical session") {
|
|
t.Fatalf("without a desktop: %v", err)
|
|
}
|
|
f.desktopSession()
|
|
f.onStart = func(argv []string) { f.proc(9100, 1000, trayComm, argv, "app.slice/"+restartAs+".service") }
|
|
a, err := f.Restart()
|
|
if err != nil || len(a.Ended) != 1 || len(a.Running) != 1 || a.Running[0].PID != 9100 {
|
|
t.Fatalf("%+v %v", a, err)
|
|
}
|
|
if !f.called("systemd-run --user --collect --quiet --unit=" + restartAs + " --setenv=DISPLAY=:1") {
|
|
t.Fatalf("%q", f.calls)
|
|
}
|
|
}
|