Files
fenrir/internal/console/input_watcher_linux_test.go

117 lines
2.8 KiB
Go

// Fenrir console screen reader.
// Copyright (c) 2026 Storm Dragon
// SPDX-License-Identifier: GPL-3.0-or-later
//
// This program is free software: you can redistribute it and/or modify it
// under the terms of the GNU General Public License as published by the Free
// Software Foundation, either version 3 of the License, or (at your option)
// any later version.
//
// This program is distributed in the hope that it will be useful, but WITHOUT
// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
// more details.
//
// You should have received a copy of the GNU General Public License along with
// this program. If not, see <https://www.gnu.org/licenses/gpl-3.0.html>.
//go:build linux && cgo
package console
import (
"os"
"syscall"
"testing"
"time"
)
func TestInputWatcherReadinessRearmAndHotplug(t *testing.T) {
watcher, err := newReadinessWatcher(syscall.EPOLLIN)
if err != nil {
t.Fatal(err)
}
defer watcher.close()
for device := 0; device < 2; device++ {
readEnd, writeEnd, err := os.Pipe()
if err != nil {
t.Fatal(err)
}
t.Cleanup(func() { readEnd.Close(); writeEnd.Close() })
if err := watcher.add(int(readEnd.Fd())); err != nil {
t.Fatal(err)
}
for press := 0; press < 2; press++ {
if _, err := writeEnd.Write([]byte{1}); err != nil {
t.Fatal(err)
}
select {
case err := <-watcher.events:
if err != nil {
t.Fatal(err)
}
case <-time.After(time.Second):
t.Fatal("input did not wake epoll")
}
var data [1]byte
if _, err := readEnd.Read(data[:]); err != nil {
t.Fatal(err)
}
if err := watcher.arm(int(readEnd.Fd())); err != nil {
t.Fatal(err)
}
}
readEnd.Close()
writeEnd.Close()
}
}
func TestInputWatcherIdleShutdown(t *testing.T) {
watcher, err := newReadinessWatcher(syscall.EPOLLIN)
if err != nil {
t.Fatal(err)
}
closed := make(chan error, 1)
go func() { closed <- watcher.close() }()
select {
case err := <-closed:
if err != nil {
t.Fatal(err)
}
case <-time.After(time.Second):
t.Fatal("idle watcher failed to wake on shutdown")
}
}
func BenchmarkInputReadiness(b *testing.B) {
watcher, err := newReadinessWatcher(syscall.EPOLLIN)
if err != nil {
b.Fatal(err)
}
defer watcher.close()
readEnd, writeEnd, err := os.Pipe()
if err != nil {
b.Fatal(err)
}
defer readEnd.Close()
defer writeEnd.Close()
if err := watcher.add(int(readEnd.Fd())); err != nil {
b.Fatal(err)
}
var data [1]byte
for b.Loop() {
if _, err := writeEnd.Write(data[:]); err != nil {
b.Fatal(err)
}
if err := <-watcher.events; err != nil {
b.Fatal(err)
}
if _, err := readEnd.Read(data[:]); err != nil {
b.Fatal(err)
}
if err := watcher.arm(int(readEnd.Fd())); err != nil {
b.Fatal(err)
}
}
}