system: improve tests of the I struct
All checks were successful
Test / Create distribution (push) Successful in 35s
Test / Sandbox (push) Successful in 2m5s
Test / Hakurei (push) Successful in 3m20s
Test / Hpkg (push) Successful in 3m57s
Test / Sandbox (race detector) (push) Successful in 4m41s
Test / Hakurei (race detector) (push) Successful in 5m25s
Test / Flake checks (push) Successful in 1m39s
All checks were successful
Test / Create distribution (push) Successful in 35s
Test / Sandbox (push) Successful in 2m5s
Test / Hakurei (push) Successful in 3m20s
Test / Hpkg (push) Successful in 3m57s
Test / Sandbox (race detector) (push) Successful in 4m41s
Test / Hakurei (race detector) (push) Successful in 5m25s
Test / Flake checks (push) Successful in 1m39s
This cleans up for the test overhaul of this package. Signed-off-by: Ophestra <cat@gensokyo.uk>
This commit is contained in:
parent
6f719bc3c1
commit
024d2ff782
@ -36,7 +36,7 @@ func (a *ACLUpdateOp) apply(sys *I) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (a *ACLUpdateOp) revert(sys *I, ec *Criteria) error {
|
func (a *ACLUpdateOp) revert(sys *I, ec *Criteria) error {
|
||||||
if ec.hasType(a) {
|
if ec.hasType(a.Type()) {
|
||||||
msg.Verbose("stripping ACL", a)
|
msg.Verbose("stripping ACL", a)
|
||||||
err := acl.Update(a.path, sys.uid)
|
err := acl.Update(a.path, sys.uid)
|
||||||
if errors.Is(err, os.ErrNotExist) {
|
if errors.Is(err, os.ErrNotExist) {
|
||||||
|
@ -28,7 +28,7 @@ func (l *HardlinkOp) apply(*I) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (l *HardlinkOp) revert(_ *I, ec *Criteria) error {
|
func (l *HardlinkOp) revert(_ *I, ec *Criteria) error {
|
||||||
if ec.hasType(l) {
|
if ec.hasType(l.Type()) {
|
||||||
msg.Verbosef("removing hard link %q", l.dst)
|
msg.Verbosef("removing hard link %q", l.dst)
|
||||||
return newOpError("hardlink", os.Remove(l.dst), true)
|
return newOpError("hardlink", os.Remove(l.dst), true)
|
||||||
} else {
|
} else {
|
||||||
|
@ -50,7 +50,7 @@ func (m *MkdirOp) revert(_ *I, ec *Criteria) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
if ec.hasType(m) {
|
if ec.hasType(m.Type()) {
|
||||||
msg.Verbose("destroying ephemeral directory", m)
|
msg.Verbose("destroying ephemeral directory", m)
|
||||||
return newOpError("mkdir", os.Remove(m.path), true)
|
return newOpError("mkdir", os.Remove(m.path), true)
|
||||||
} else {
|
} else {
|
||||||
|
@ -209,18 +209,22 @@ func (ptc tcOp) test(t *testing.T, gotOps []Op, wantOps []Op, fn string) {
|
|||||||
t.Run("criteria", func(t *testing.T) {
|
t.Run("criteria", func(t *testing.T) {
|
||||||
testCases := []struct {
|
testCases := []struct {
|
||||||
name string
|
name string
|
||||||
ec *Criteria
|
ec Enablement
|
||||||
want bool
|
want bool
|
||||||
}{
|
}{
|
||||||
{"nil", nil, ptc.et != User},
|
{"nil", 0xff, ptc.et != User},
|
||||||
{"self", newCriteria(ptc.et), true},
|
{"self", ptc.et, true},
|
||||||
{"all", newCriteria(EWayland | EX11 | EDBus | EPulse | User | Process), true},
|
{"all", EWayland | EX11 | EDBus | EPulse | User | Process, true},
|
||||||
{"enablements", newCriteria(EWayland | EX11 | EDBus | EPulse), ptc.et != User && ptc.et != Process},
|
{"enablements", EWayland | EX11 | EDBus | EPulse, ptc.et != User && ptc.et != Process},
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, tc := range testCases {
|
for _, tc := range testCases {
|
||||||
t.Run(tc.name, func(t *testing.T) {
|
t.Run(tc.name, func(t *testing.T) {
|
||||||
if got := tc.ec.hasType(o); got != tc.want {
|
var criteria *Criteria
|
||||||
|
if tc.ec != 0xff {
|
||||||
|
criteria = (*Criteria)(&tc.ec)
|
||||||
|
}
|
||||||
|
if got := criteria.hasType(o.Type()); got != tc.want {
|
||||||
t.Errorf("hasType: got %v, want %v",
|
t.Errorf("hasType: got %v, want %v",
|
||||||
got, tc.want)
|
got, tc.want)
|
||||||
}
|
}
|
||||||
@ -229,5 +233,3 @@ func (ptc tcOp) test(t *testing.T, gotOps []Op, wantOps []Op, fn string) {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func newCriteria(e Enablement) *Criteria { return (*Criteria)(&e) }
|
|
||||||
|
@ -20,13 +20,13 @@ const (
|
|||||||
// Criteria specifies types of Op to revert.
|
// Criteria specifies types of Op to revert.
|
||||||
type Criteria Enablement
|
type Criteria Enablement
|
||||||
|
|
||||||
func (ec *Criteria) hasType(o Op) bool {
|
func (ec *Criteria) hasType(t Enablement) bool {
|
||||||
// nil criteria: revert everything except User
|
// nil criteria: revert everything except User
|
||||||
if ec == nil {
|
if ec == nil {
|
||||||
return o.Type() != User
|
return t != User
|
||||||
}
|
}
|
||||||
|
|
||||||
return Enablement(*ec)&o.Type() != 0
|
return Enablement(*ec)&t != 0
|
||||||
}
|
}
|
||||||
|
|
||||||
// Op is a reversible system operation.
|
// Op is a reversible system operation.
|
||||||
@ -92,7 +92,7 @@ func (sys *I) UID() int { return sys.uid }
|
|||||||
|
|
||||||
// Equal returns whether all [Op] instances held by sys matches that of target.
|
// Equal returns whether all [Op] instances held by sys matches that of target.
|
||||||
func (sys *I) Equal(target *I) bool {
|
func (sys *I) Equal(target *I) bool {
|
||||||
if target == nil || sys.uid != target.uid || len(sys.ops) != len(target.ops) {
|
if sys == nil || target == nil || sys.uid != target.uid || len(sys.ops) != len(target.ops) {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -149,7 +149,6 @@ func (sys *I) Revert(ec *Criteria) error {
|
|||||||
|
|
||||||
// collect errors
|
// collect errors
|
||||||
errs := make([]error, len(sys.ops))
|
errs := make([]error, len(sys.ops))
|
||||||
|
|
||||||
for i := range sys.ops {
|
for i := range sys.ops {
|
||||||
errs[i] = sys.ops[len(sys.ops)-i-1].revert(sys, ec)
|
errs[i] = sys.ops[len(sys.ops)-i-1].revert(sys, ec)
|
||||||
}
|
}
|
||||||
|
@ -1,28 +1,37 @@
|
|||||||
package system_test
|
package system_test
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"reflect"
|
||||||
"strconv"
|
"strconv"
|
||||||
"testing"
|
"testing"
|
||||||
|
_ "unsafe"
|
||||||
|
|
||||||
"hakurei.app/system"
|
"hakurei.app/system"
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestNew(t *testing.T) {
|
//go:linkname criteriaHasType hakurei.app/system.(*Criteria).hasType
|
||||||
|
func criteriaHasType(_ *system.Criteria, _ system.Enablement) bool
|
||||||
|
|
||||||
|
func TestCriteria(t *testing.T) {
|
||||||
testCases := []struct {
|
testCases := []struct {
|
||||||
uid int
|
name string
|
||||||
|
ec, t system.Enablement
|
||||||
|
want bool
|
||||||
}{
|
}{
|
||||||
{150},
|
{"nil", 0xff, system.EWayland, true},
|
||||||
{149},
|
{"nil user", 0xff, system.User, false},
|
||||||
{148},
|
{"all", system.EWayland | system.EX11 | system.EDBus | system.EPulse | system.User | system.Process, system.Process, true},
|
||||||
{147},
|
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, tc := range testCases {
|
for _, tc := range testCases {
|
||||||
t.Run("sys initialised with uid "+strconv.Itoa(tc.uid), func(t *testing.T) {
|
t.Run(tc.name, func(t *testing.T) {
|
||||||
if got := system.New(t.Context(), tc.uid); got.UID() != tc.uid {
|
var criteria *system.Criteria
|
||||||
t.Errorf("New(%d) uid = %d, want %d",
|
if tc.ec != 0xff {
|
||||||
tc.uid,
|
criteria = (*system.Criteria)(&tc.ec)
|
||||||
got.UID(), tc.uid)
|
}
|
||||||
|
if got := criteriaHasType(criteria, tc.t); got != tc.want {
|
||||||
|
t.Errorf("hasType: got %v, want %v",
|
||||||
|
got, tc.want)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@ -45,86 +54,108 @@ func TestTypeString(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
for _, tc := range testCases {
|
for _, tc := range testCases {
|
||||||
t.Run("label type string "+tc.want, func(t *testing.T) {
|
t.Run("label type string "+strconv.Itoa(int(tc.e)), func(t *testing.T) {
|
||||||
if got := system.TypeString(tc.e); got != tc.want {
|
if got := system.TypeString(tc.e); got != tc.want {
|
||||||
t.Errorf("TypeString: %q, want %q",
|
t.Errorf("TypeString: %q, want %q", got, tc.want)
|
||||||
got, tc.want)
|
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestI_Equal(t *testing.T) {
|
func TestNew(t *testing.T) {
|
||||||
|
t.Run("panic", func(t *testing.T) {
|
||||||
|
t.Run("ctx", func(t *testing.T) {
|
||||||
|
defer func() {
|
||||||
|
want := "invalid call to New"
|
||||||
|
if r := recover(); r != want {
|
||||||
|
t.Errorf("recover: %v, want %v", r, want)
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
system.New(nil, 0)
|
||||||
|
})
|
||||||
|
|
||||||
|
t.Run("uid", func(t *testing.T) {
|
||||||
|
defer func() {
|
||||||
|
want := "invalid call to New"
|
||||||
|
if r := recover(); r != want {
|
||||||
|
t.Errorf("recover: %v, want %v", r, want)
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
system.New(t.Context(), -1)
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
sys := system.New(t.Context(), 0xdeadbeef)
|
||||||
|
if got := reflect.ValueOf(sys).Elem().FieldByName("ctx"); got.IsNil() {
|
||||||
|
t.Errorf("New: ctx = %#v", got)
|
||||||
|
}
|
||||||
|
if got := sys.UID(); got != 0xdeadbeef {
|
||||||
|
t.Errorf("UID: %d", got)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestEqual(t *testing.T) {
|
||||||
testCases := []struct {
|
testCases := []struct {
|
||||||
name string
|
name string
|
||||||
sys *system.I
|
sys *system.I
|
||||||
v *system.I
|
v *system.I
|
||||||
want bool
|
want bool
|
||||||
}{
|
}{
|
||||||
{
|
{"simple UID",
|
||||||
"simple UID",
|
|
||||||
system.New(t.Context(), 150),
|
system.New(t.Context(), 150),
|
||||||
system.New(t.Context(), 150),
|
system.New(t.Context(), 150),
|
||||||
true,
|
true},
|
||||||
},
|
|
||||||
{
|
{"simple UID differ",
|
||||||
"simple UID differ",
|
|
||||||
system.New(t.Context(), 150),
|
system.New(t.Context(), 150),
|
||||||
system.New(t.Context(), 151),
|
system.New(t.Context(), 151),
|
||||||
false,
|
false},
|
||||||
},
|
|
||||||
{
|
{"simple UID nil",
|
||||||
"simple UID nil",
|
|
||||||
system.New(t.Context(), 150),
|
system.New(t.Context(), 150),
|
||||||
nil,
|
nil,
|
||||||
false,
|
false},
|
||||||
},
|
|
||||||
{
|
{"op length mismatch",
|
||||||
"op length mismatch",
|
|
||||||
system.New(t.Context(), 150).
|
system.New(t.Context(), 150).
|
||||||
ChangeHosts("chronos"),
|
ChangeHosts("chronos"),
|
||||||
system.New(t.Context(), 150).
|
system.New(t.Context(), 150).
|
||||||
ChangeHosts("chronos").
|
ChangeHosts("chronos").
|
||||||
Ensure("/run", 0755),
|
Ensure("/run", 0755),
|
||||||
false,
|
false},
|
||||||
},
|
|
||||||
{
|
{"op value mismatch",
|
||||||
"op value mismatch",
|
|
||||||
system.New(t.Context(), 150).
|
system.New(t.Context(), 150).
|
||||||
ChangeHosts("chronos").
|
ChangeHosts("chronos").
|
||||||
Ensure("/run", 0644),
|
Ensure("/run", 0644),
|
||||||
system.New(t.Context(), 150).
|
system.New(t.Context(), 150).
|
||||||
ChangeHosts("chronos").
|
ChangeHosts("chronos").
|
||||||
Ensure("/run", 0755),
|
Ensure("/run", 0755),
|
||||||
false,
|
false},
|
||||||
},
|
|
||||||
{
|
{"op type mismatch",
|
||||||
"op type mismatch",
|
|
||||||
system.New(t.Context(), 150).
|
system.New(t.Context(), 150).
|
||||||
ChangeHosts("chronos").
|
ChangeHosts("chronos").
|
||||||
CopyFile(new([]byte), "/home/ophestra/xdg/config/pulse/cookie", 0, 256),
|
CopyFile(new([]byte), "/home/ophestra/xdg/config/pulse/cookie", 0, 256),
|
||||||
system.New(t.Context(), 150).
|
system.New(t.Context(), 150).
|
||||||
ChangeHosts("chronos").
|
ChangeHosts("chronos").
|
||||||
Ensure("/run", 0755),
|
Ensure("/run", 0755),
|
||||||
false,
|
false},
|
||||||
},
|
|
||||||
{
|
{"op equals",
|
||||||
"op equals",
|
|
||||||
system.New(t.Context(), 150).
|
system.New(t.Context(), 150).
|
||||||
ChangeHosts("chronos").
|
ChangeHosts("chronos").
|
||||||
Ensure("/run", 0755),
|
Ensure("/run", 0755),
|
||||||
system.New(t.Context(), 150).
|
system.New(t.Context(), 150).
|
||||||
ChangeHosts("chronos").
|
ChangeHosts("chronos").
|
||||||
Ensure("/run", 0755),
|
Ensure("/run", 0755),
|
||||||
true,
|
true},
|
||||||
},
|
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, tc := range testCases {
|
for _, tc := range testCases {
|
||||||
t.Run(tc.name, func(t *testing.T) {
|
t.Run(tc.name, func(t *testing.T) {
|
||||||
if tc.sys.Equal(tc.v) != tc.want {
|
if tc.sys.Equal(tc.v) != tc.want {
|
||||||
t.Errorf("Equal: got %v; want %v",
|
t.Errorf("Equal: %v, want %v", !tc.want, tc.want)
|
||||||
!tc.want, tc.want)
|
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
@ -59,7 +59,7 @@ func (w *WaylandOp) apply(sys *I) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (w *WaylandOp) revert(_ *I, ec *Criteria) error {
|
func (w *WaylandOp) revert(_ *I, ec *Criteria) error {
|
||||||
if ec.hasType(w) {
|
if ec.hasType(w.Type()) {
|
||||||
msg.Verbosef("removing wayland socket on %q", w.dst)
|
msg.Verbosef("removing wayland socket on %q", w.dst)
|
||||||
if err := os.Remove(w.dst); err != nil && !errors.Is(err, os.ErrNotExist) {
|
if err := os.Remove(w.dst); err != nil && !errors.Is(err, os.ErrNotExist) {
|
||||||
return newOpError("wayland", err, true)
|
return newOpError("wayland", err, true)
|
||||||
|
@ -22,7 +22,7 @@ func (x XHostOp) apply(*I) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (x XHostOp) revert(_ *I, ec *Criteria) error {
|
func (x XHostOp) revert(_ *I, ec *Criteria) error {
|
||||||
if ec.hasType(x) {
|
if ec.hasType(x.Type()) {
|
||||||
msg.Verbosef("deleting entry %s from X11", x)
|
msg.Verbosef("deleting entry %s from X11", x)
|
||||||
return newOpError("xhost",
|
return newOpError("xhost",
|
||||||
xcb.ChangeHosts(xcb.HostModeDelete, xcb.FamilyServerInterpreted, "localuser\x00"+string(x)), false)
|
xcb.ChangeHosts(xcb.HostModeDelete, xcb.FamilyServerInterpreted, "localuser\x00"+string(x)), false)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user