feat: add tray control, priority restoration and session logging
This commit is contained in:
1 parent
4f8f6218ad
commit
4880aa46dc
25 files changed
+3072
-676
No files matched your search
@@ -0,0 +1,288 @@
|
||||
//go:build windows
|
||||
|
||||
package main
|
||||
|
||||
import (
|
||||
"testing"
|
||||
"time"
|
||||
)
|
||||
|
||||
func TestControllerNormalBoostRestoredAtExit(t *testing.T) {
|
||||
f := newFake()
|
||||
p := f.add(10, 150, PriorityClassBelowNormal)
|
||||
c := testController(f)
|
||||
c.Step()
|
||||
assertPriority(t, p, PriorityClassHigh)
|
||||
c.Shutdown()
|
||||
assertPriority(t, p, PriorityClassBelowNormal)
|
||||
assertClosed(t, f)
|
||||
}
|
||||
func TestControllerHeavyRemainsTrackedBelowThresholdAndDuringReadFailure(t *testing.T) {
|
||||
f := newFake()
|
||||
g := f.add(10, 250, PriorityClassNormal)
|
||||
p := f.add(20, 50, PriorityClassNormal)
|
||||
c := testController(f)
|
||||
c.Step()
|
||||
g.info.RSS = 1
|
||||
c.Step()
|
||||
assertPriority(t, g, PriorityClassHigh)
|
||||
g.readable = false
|
||||
c.Step()
|
||||
assertPriority(t, p, PriorityClassIdle)
|
||||
g.alive = false
|
||||
c.Step()
|
||||
assertPriority(t, p, PriorityClassNormal)
|
||||
c.Shutdown()
|
||||
assertClosed(t, f)
|
||||
}
|
||||
func TestControllerProtectedHeavyStillEnablesMode(t *testing.T) {
|
||||
f := newFake()
|
||||
g := f.add(10, 250, PriorityClassNormal)
|
||||
g.writable = false
|
||||
p := f.add(20, 50, PriorityClassNormal)
|
||||
c := testController(f)
|
||||
r := c.Step()
|
||||
assertPriority(t, g, PriorityClassNormal)
|
||||
assertPriority(t, p, PriorityClassIdle)
|
||||
if len(r.Errors) == 0 {
|
||||
t.Fatal("missing denied-write diagnostic")
|
||||
}
|
||||
c.Shutdown()
|
||||
assertClosed(t, f)
|
||||
}
|
||||
func TestControllerDenialPersistsForCurrentInstance(t *testing.T) {
|
||||
f := newFake()
|
||||
p := f.add(10, 150, PriorityClassNormal)
|
||||
p.writable = false
|
||||
c := testController(f)
|
||||
c.Step()
|
||||
p.writable = true
|
||||
c.Step()
|
||||
assertPriority(t, p, PriorityClassNormal)
|
||||
c.now = func() time.Time { return time.Unix(1061, 0) }
|
||||
c.Step()
|
||||
assertPriority(t, p, PriorityClassNormal)
|
||||
c.Shutdown()
|
||||
assertPriority(t, p, PriorityClassNormal)
|
||||
assertClosed(t, f)
|
||||
}
|
||||
func TestControllerPIDReuseNeverRestoresReplacement(t *testing.T) {
|
||||
f := newFake()
|
||||
g := f.add(10, 250, PriorityClassNormal)
|
||||
old := f.add(20, 50, PriorityClassBelowNormal)
|
||||
c := testController(f)
|
||||
c.Step()
|
||||
old.alive = false
|
||||
replacement := f.child(20, 0, 116444736000000000+1001*10000000)
|
||||
replacement.info.Prio = PriorityClassBelowNormal
|
||||
g.alive = false
|
||||
c.Step()
|
||||
assertPriority(t, replacement, PriorityClassBelowNormal)
|
||||
if replacement.writes != 0 {
|
||||
t.Fatal("wrote to a replacement process")
|
||||
}
|
||||
c.Shutdown()
|
||||
assertClosed(t, f)
|
||||
}
|
||||
func TestControllerExternalPriorityBecomesNewBaseline(t *testing.T) {
|
||||
f := newFake()
|
||||
p := f.add(10, 150, PriorityClassNormal)
|
||||
c := testController(f)
|
||||
c.Step()
|
||||
p.info.Prio = PriorityClassAboveNormal
|
||||
c.Shutdown()
|
||||
assertPriority(t, p, PriorityClassAboveNormal)
|
||||
assertClosed(t, f)
|
||||
}
|
||||
func TestControllerExternalChangeBeforeNextPolicyWriteIsPreservedOnExit(t *testing.T) {
|
||||
f := newFake()
|
||||
p := f.add(10, 150, PriorityClassNormal)
|
||||
c := testController(f)
|
||||
c.Step()
|
||||
p.info.Prio = PriorityClassBelowNormal
|
||||
c.Step()
|
||||
assertPriority(t, p, PriorityClassHigh)
|
||||
c.Shutdown()
|
||||
assertPriority(t, p, PriorityClassBelowNormal)
|
||||
assertClosed(t, f)
|
||||
}
|
||||
func TestControllerGameOverlayKeepsOriginalExitBaseline(t *testing.T) {
|
||||
f := newFake()
|
||||
p := f.add(20, 150, PriorityClassBelowNormal)
|
||||
c := testController(f)
|
||||
c.Step()
|
||||
g := f.add(10, 250, PriorityClassNormal)
|
||||
c.Step()
|
||||
assertPriority(t, p, PriorityClassIdle)
|
||||
g.alive = false
|
||||
c.Step()
|
||||
assertPriority(t, p, PriorityClassHigh)
|
||||
c.Shutdown()
|
||||
assertPriority(t, p, PriorityClassBelowNormal)
|
||||
assertClosed(t, f)
|
||||
}
|
||||
func TestControllerFinalSnapshotCatchesNewChild(t *testing.T) {
|
||||
f := newFake()
|
||||
g := f.add(10, 250, PriorityClassNormal)
|
||||
parent := f.add(20, 50, PriorityClassNormal)
|
||||
c := testController(f)
|
||||
c.Step()
|
||||
child := f.child(30, 20, 116444736000000000+1001*10000000)
|
||||
c.Shutdown()
|
||||
assertPriority(t, g, PriorityClassNormal)
|
||||
assertPriority(t, parent, PriorityClassNormal)
|
||||
assertPriority(t, child, PriorityClassNormal)
|
||||
assertClosed(t, f)
|
||||
}
|
||||
func TestControllerDryRunHasNoWritesOrRestores(t *testing.T) {
|
||||
f := newFake()
|
||||
g := f.add(10, 250, PriorityClassNormal)
|
||||
p := f.add(20, 50, PriorityClassBelowNormal)
|
||||
c := testController(f)
|
||||
c.dryRun = true
|
||||
r := c.Step()
|
||||
if !r.DryRun || len(r.Rows) != 2 {
|
||||
t.Fatalf("bad dry-run report: %+v", r)
|
||||
}
|
||||
c.Shutdown()
|
||||
assertPriority(t, g, PriorityClassNormal)
|
||||
assertPriority(t, p, PriorityClassBelowNormal)
|
||||
if g.writes+p.writes != 0 {
|
||||
t.Fatal("dry-run wrote priorities")
|
||||
}
|
||||
assertClosed(t, f)
|
||||
}
|
||||
func TestControllerShutdownWorksWithoutFinalSnapshot(t *testing.T) {
|
||||
f := newFake()
|
||||
p := f.add(10, 150, PriorityClassNormal)
|
||||
c := testController(f)
|
||||
c.Step()
|
||||
f.snapshotErr = true
|
||||
r := c.Shutdown()
|
||||
if r.Unrestored != 0 {
|
||||
t.Fatal(r)
|
||||
}
|
||||
assertPriority(t, p, PriorityClassNormal)
|
||||
assertClosed(t, f)
|
||||
}
|
||||
func TestControllerUnrestoredFailuresReportedAndHandlesClosed(t *testing.T) {
|
||||
f := newFake()
|
||||
p := f.add(10, 150, PriorityClassNormal)
|
||||
c := testController(f)
|
||||
c.Step()
|
||||
p.writable = false
|
||||
r := c.Shutdown()
|
||||
if r.Unrestored != 1 {
|
||||
t.Fatalf("expected one unresolved restoration, got %+v", r)
|
||||
}
|
||||
assertClosed(t, f)
|
||||
}
|
||||
func TestControllerWindowsCoercionIsNotSuccessfulRestoration(t *testing.T) {
|
||||
f := newFake()
|
||||
p := f.add(10, 150, PriorityClassRealtime)
|
||||
c := testController(f)
|
||||
c.Step()
|
||||
p.coerced = PriorityClassHigh
|
||||
r := c.Shutdown()
|
||||
if r.Unrestored != 1 {
|
||||
t.Fatal("coerced REALTIME restoration was falsely reported as successful")
|
||||
}
|
||||
assertClosed(t, f)
|
||||
}
|
||||
func TestControllerNoSynchronizeUsesCompletePIDMembership(t *testing.T) {
|
||||
f := newFake()
|
||||
g := f.add(10, 250, PriorityClassNormal)
|
||||
p := f.add(20, 50, PriorityClassNormal)
|
||||
c := testController(f)
|
||||
c.Step()
|
||||
c.states[g.info.Key].info.Waitable = false
|
||||
g.readable = false
|
||||
c.Step()
|
||||
assertPriority(t, p, PriorityClassIdle)
|
||||
g.alive = false
|
||||
c.Step()
|
||||
assertPriority(t, p, PriorityClassNormal)
|
||||
c.Shutdown()
|
||||
assertClosed(t, f)
|
||||
}
|
||||
func TestControllerSteadyStateDoesNotRepeatChanges(t *testing.T) {
|
||||
f := newFake()
|
||||
g := f.add(10, 250, PriorityClassHigh)
|
||||
p := f.add(20, 50, PriorityClassNormal)
|
||||
c := testController(f)
|
||||
r := c.Step()
|
||||
if len(r.Rows) != 2 || !r.Rows[0].Unchanged {
|
||||
t.Fatal("heavy trigger must be first, without a fictional raise")
|
||||
}
|
||||
writes := g.writes + p.writes
|
||||
r = c.Step()
|
||||
if len(r.Rows) != 0 || g.writes+p.writes != writes {
|
||||
t.Fatal("repeated unchanged work")
|
||||
}
|
||||
c.Shutdown()
|
||||
assertClosed(t, f)
|
||||
}
|
||||
func TestControllerExternalChangeToNetUnchangedOverlayIsRespected(t *testing.T) {
|
||||
f := newFake()
|
||||
p := f.add(20, 150, PriorityClassIdle)
|
||||
c := testController(f)
|
||||
c.Step()
|
||||
g := f.add(10, 250, PriorityClassNormal)
|
||||
p.info.RSS = 50
|
||||
c.Step()
|
||||
assertPriority(t, p, PriorityClassIdle)
|
||||
p.info.Prio = PriorityClassBelowNormal
|
||||
g.alive = false
|
||||
c.Step()
|
||||
assertPriority(t, p, PriorityClassBelowNormal)
|
||||
c.Shutdown()
|
||||
assertClosed(t, f)
|
||||
}
|
||||
func TestControllerRestorationRechecksOwnershipImmediatelyBeforeWrite(t *testing.T) {
|
||||
for _, shutdown := range []bool{false, true} {
|
||||
t.Run(map[bool]string{false: "game exit", true: "shutdown"}[shutdown], func(t *testing.T) {
|
||||
f := newFake()
|
||||
g := f.add(10, 250, PriorityClassNormal)
|
||||
p := f.add(20, 50, PriorityClassNormal)
|
||||
c := testController(f)
|
||||
c.Step()
|
||||
g.alive = false
|
||||
reads := 0
|
||||
f.onRead = func(v *fakeProcess) {
|
||||
if v == p {
|
||||
reads++
|
||||
if reads == 2 {
|
||||
v.info.Prio = PriorityClassBelowNormal
|
||||
}
|
||||
}
|
||||
}
|
||||
if shutdown {
|
||||
c.Shutdown()
|
||||
} else {
|
||||
c.Step()
|
||||
f.onRead = nil
|
||||
assertPriority(t, p, PriorityClassBelowNormal)
|
||||
c.Shutdown()
|
||||
}
|
||||
assertPriority(t, p, PriorityClassBelowNormal)
|
||||
assertClosed(t, f)
|
||||
})
|
||||
}
|
||||
}
|
||||
func TestControllerReadFailureIsBlocked(t *testing.T) {
|
||||
f := newFake()
|
||||
g := f.add(10, 250, PriorityClassNormal)
|
||||
p := f.add(20, 50, PriorityClassNormal)
|
||||
c := testController(f)
|
||||
c.Step()
|
||||
g.alive = false
|
||||
p.failRead = true
|
||||
c.Step()
|
||||
r := c.Step()
|
||||
if len(r.Errors) != 0 {
|
||||
t.Fatal("blocked restoration repeated its error", r.Errors)
|
||||
}
|
||||
p.failRead = false
|
||||
c.Shutdown()
|
||||
assertClosed(t, f)
|
||||
}
|
||||
Reference in new issue
Block a user