Updated some documentation.
This commit is contained in:
1 parent
0e50de4c76
commit
4f5a875d0e
17 files changed
+2416
-6207
No files matched your search
@@ -21,6 +21,7 @@ package console
|
||||
|
||||
import (
|
||||
"encoding/binary"
|
||||
"errors"
|
||||
"fmt"
|
||||
"os"
|
||||
"path/filepath"
|
||||
@@ -28,6 +29,122 @@ import (
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestSourceWaitsForConsoleOwner(t *testing.T) {
|
||||
for _, terminal := range []int{2, 15} {
|
||||
t.Run(fmt.Sprint(terminal), func(t *testing.T) {
|
||||
root := t.TempDir()
|
||||
activePath := filepath.Join(root, "sys/devices/virtual/tty/tty0/active")
|
||||
if err := os.MkdirAll(filepath.Dir(activePath), 0700); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if err := os.WriteFile(activePath, fmt.Appendf(nil, "tty%d\n", terminal), 0600); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
// Other occupied consoles (including tty1) must not make this one
|
||||
// appear occupied. There are deliberately no target device files yet.
|
||||
mask := uint16(3)
|
||||
stateCalls := 0
|
||||
source := &Source{
|
||||
root: root,
|
||||
usage: func(path string) (uint16, error) {
|
||||
if path != filepath.Join(root, "dev/tty1") {
|
||||
t.Fatalf("usage query opened target or foreground alias: %s", path)
|
||||
}
|
||||
return mask, nil
|
||||
},
|
||||
state: func(path string) (bool, bool, bool, error) {
|
||||
stateCalls++
|
||||
if mask&(uint16(1)<<uint(terminal)) == 0 {
|
||||
t.Fatal("opened unused console")
|
||||
}
|
||||
if path != filepath.Join(root, "dev", fmt.Sprintf("tty%d", terminal)) {
|
||||
t.Fatal("queried wrong console", path)
|
||||
}
|
||||
return true, true, true, nil
|
||||
},
|
||||
}
|
||||
for range 2 {
|
||||
if number, active, _, err := source.State(); err != nil || active || number != terminal {
|
||||
t.Fatal("unused console accepted input", number, active, err)
|
||||
}
|
||||
if snapshot, err := source.Read(); err != nil || snapshot.Active || snapshot.Terminal != terminal || len(snapshot.Cells) != 0 {
|
||||
t.Fatal("unused console read screen devices", snapshot, err)
|
||||
}
|
||||
}
|
||||
if stateCalls != 0 {
|
||||
t.Fatal("probed unused console", stateCalls)
|
||||
}
|
||||
if err := os.Mkdir(filepath.Join(root, "dev"), 0700); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
text := "login: "
|
||||
attributes := append([]byte{1, byte(len(text)), 0, 0}, make([]byte, len(text)*2)...)
|
||||
if err := os.WriteFile(filepath.Join(root, "dev", fmt.Sprintf("vcsa%d", terminal)), attributes, 0600); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
var data []byte
|
||||
for _, value := range text {
|
||||
data = binary.NativeEndian.AppendUint32(data, uint32(value))
|
||||
}
|
||||
if err := os.WriteFile(filepath.Join(root, "dev", fmt.Sprintf("vcsu%d", terminal)), data, 0600); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
// A login prompt is enough; there is no authenticated user/session.
|
||||
mask |= uint16(1) << uint(terminal)
|
||||
if number, active, numLock, err := source.State(); err != nil || !active || !numLock || number != terminal {
|
||||
t.Fatal("login prompt did not activate input", number, active, numLock, err)
|
||||
}
|
||||
if snapshot, err := source.Read(); err != nil || !snapshot.Active || string(snapshot.Cells) != text || !snapshot.NumLock || !snapshot.CapsLock {
|
||||
t.Fatal("login prompt was not readable", snapshot, err)
|
||||
}
|
||||
mask = 3
|
||||
if _, active, _, err := source.State(); err != nil || active {
|
||||
t.Fatal("console owner disappeared but input stayed active", active, err)
|
||||
}
|
||||
problem := errors.New("console usage unavailable")
|
||||
source.usage = func(string) (uint16, error) { return 0, problem }
|
||||
if _, active, _, err := source.State(); !errors.Is(err, problem) || active {
|
||||
t.Fatal("usage failure permitted a target probe", active, err)
|
||||
}
|
||||
source.Configure_ignored_vts([]int{terminal})
|
||||
if _, active, _, err := source.State(); err != nil || active {
|
||||
t.Fatal("ignored console queried usage", active, err)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestSourcePreservesBootAndHighConsoleProbes(t *testing.T) {
|
||||
for _, terminal := range []int{1, 16, 63} {
|
||||
t.Run(fmt.Sprint(terminal), func(t *testing.T) {
|
||||
root := t.TempDir()
|
||||
activePath := filepath.Join(root, "sys/devices/virtual/tty/tty0/active")
|
||||
if err := os.MkdirAll(filepath.Dir(activePath), 0700); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if err := os.WriteFile(activePath, fmt.Appendf(nil, "tty%d\n", terminal), 0600); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
source := &Source{
|
||||
root: root,
|
||||
usage: func(string) (uint16, error) {
|
||||
t.Fatal("boot/high console gated on truncated bitmap")
|
||||
return 0, nil
|
||||
},
|
||||
state: func(path string) (bool, bool, bool, error) {
|
||||
if path != filepath.Join(root, "dev", fmt.Sprintf("tty%d", terminal)) {
|
||||
t.Fatal("queried wrong console", path)
|
||||
}
|
||||
return true, false, false, nil
|
||||
},
|
||||
}
|
||||
if number, active, _, err := source.State(); err != nil || !active || number != terminal {
|
||||
t.Fatal("boot/high console lost input", number, active, err)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestSourceRetriesUnicodeSizeChange(t *testing.T) {
|
||||
for _, cols := range []int{1, 3} {
|
||||
t.Run(fmt.Sprint(cols), func(t *testing.T) {
|
||||
|
||||
Reference in new issue
Block a user