After commit c018f5fd29 Fenrir is being switched over to go. If you do not want to be part of the testing process, please switch to master.

This commit is contained in:
Storm Dragon committed 2026-10-27 20:30:55 -04:00
1 parent c018f5fd29
commit 0e50de4c76
1047 files changed
+58364 -63747

No files matched your search

+138
View File
@@ -0,0 +1,138 @@
// Copyright (c) 2026 Storm Dragon
// SPDX-License-Identifier: GPL-3.0-or-later
package app
import (
"context"
"os"
"reflect"
"testing"
"git.stormux.org/storm/fenrir/internal/config"
"git.stormux.org/storm/fenrir/internal/control"
"git.stormux.org/storm/fenrir/internal/input"
"git.stormux.org/storm/fenrir/internal/screen"
)
// Model the console's policy boundary independently of the shared application.
type policySource struct {
fakeSource
ignoredVTs []int
}
func (s *policySource) Configure_ignored_vts(numbers []int) {
s.ignoredVTs = append([]int(nil), numbers...)
}
func (s *policySource) Read() (screen.Snapshot, error) {
for _, number := range s.ignoredVTs {
if number == s.snapshot.Terminal {
return screen.Snapshot{Terminal: number}, nil
}
}
return s.fakeSource.Read()
}
func (s *policySource) State() (int, bool, bool, error) {
snapshot, err := s.Read()
return snapshot.Terminal, snapshot.Active, snapshot.NumLock, err
}
func TestRemoteIgnoredVTListsAreAtomic(t *testing.T) {
base := config.Defaults()
base.Screen.IgnoredVTs = []int{2, 3}
for _, text := range []string{
"SET screen#ignore_screen=7, 8,10;speech#enabled=False",
"SET screen#ignore_screen=7, 8,10,speech#enabled=False",
} {
updated, err := remote_settings(base, text)
if err != nil || !reflect.DeepEqual(updated.Screen.IgnoredVTs, []int{7, 8, 10}) || updated.Presentation.Speech.Enabled {
t.Fatal("lost list or following assignment", updated, err)
}
}
for _, value := range []string{"0", "64", "-1", "7,7", "7,", "7,,8", "tty7", "7;unknown#setting=True"} {
failed, err := remote_settings(base, "SET speech#enabled=False;screen#ignore_screen="+value)
if err == nil || !reflect.DeepEqual(failed, base) || !reflect.DeepEqual(base.Screen.IgnoredVTs, []int{2, 3}) {
t.Fatal("invalid list partially applied", value, failed, base, err)
}
}
updated, err := remote_settings(base, "SET screen#ignore_screen=")
if err != nil || len(updated.Screen.IgnoredVTs) != 0 {
t.Fatal("empty list did not clear policy", updated.Screen, err)
}
}
func TestIgnoredVTStartupRemoteReleaseRecoveryAndTerminalIsolation(t *testing.T) {
for _, terminalMode := range []bool{false, true} {
settings := config.Defaults()
settings.Screen.IgnoredVTs = []int{2, 7, 8, 10}
source := &policySource{fakeSource: fakeSource{snapshot: screen.Snapshot{Terminal: 2, Active: true, Rows: 1, Cols: 5, Cells: []rune("alpha")}}}
voice := &fakeVoice{}
var modes []bool
keys := &fakeKeys{poll: func(active bool, _ func(input.Decision)) error {
modes = append(modes, active)
return nil
}}
a, err := new_application(context.Background(), source, keys, voice, RunOptions{Settings: settings, TerminalMode: terminalMode})
if err != nil {
t.Fatal(err)
}
t.Cleanup(a.ui.close)
if err := a.read_screen(); err != nil {
t.Fatal(err)
}
if err := a.poll_input(true); err != nil {
t.Fatal(err)
}
if a.lastActive != terminalMode || (!terminalMode && len(voice.messages) != 0) {
t.Fatal("wrong startup policy", terminalMode, a.lastActive, voice.messages)
}
request := func(uid int, text string) string {
t.Helper()
replies := make(chan string, 1)
a.remote_request(control.Request{UID: uid, Text: "SETTING " + text, Reply: replies})
return <-replies
}
if reply := request(os.Geteuid()+1, "SET screen#ignore_screen="); reply == "" || !reflect.DeepEqual(a.settings.live.Screen, settings.Screen) {
t.Fatal("unauthorized policy change", reply, a.settings.live.Screen)
}
if reply := request(os.Geteuid(), "SET screen#ignore_screen="); reply != "" {
t.Fatal(reply)
}
if err := a.poll_input(true); err != nil || !a.lastActive {
t.Fatal("did not recover after remote clear", err)
}
a.ui.open_tutorial(nil, nil, nil)
interrupts := voice.interrupts
if reply := request(os.Geteuid(), "SET screen#ignore_screen=2,7,8,10"); reply != "" {
t.Fatal(reply)
}
if err := a.poll_input(false); err != nil {
t.Fatal(err)
}
if !terminalMode && (a.lastActive || a.ui.active || voice.interrupts <= interrupts || !reflect.DeepEqual(keys.captures, []bool{true, false})) {
t.Fatal("handoff retained modal capture or speech", a.lastActive, a.ui.active, keys.captures, voice.interrupts)
}
if terminalMode && (!a.lastActive || !a.ui.active) {
t.Fatal("console policy affected X11 session")
}
source.snapshot.Terminal = 3
if err := a.poll_input(false); err != nil || !a.lastActive {
t.Fatal("allowed VT did not resume", err)
}
if !terminalMode && !reflect.DeepEqual(modes, []bool{false, true, false, true}) {
t.Fatal("wrong handoff order", modes)
}
// Applying a saved draft uses the same policy; quick-save must retain it.
saved := settings
saved.Screen.IgnoredVTs = []int{3}
a.apply_saved_settings(saved, false)
if err := a.poll_input(false); err != nil || a.lastActive != terminalMode {
t.Fatal("saved policy was not applied", err, a.lastActive)
}
if !reflect.DeepEqual(a.settings.saveDraft.Screen.IgnoredVTs, []int{3}) {
t.Fatal("lost saved policy")
}
}
}