system: tests for all Op implementations except DBus
Signed-off-by: Ophestra Umiker <cat@ophivana.moe>
This commit is contained in:
parent
064db9f020
commit
679e719f9e
89
internal/system/acl_test.go
Normal file
89
internal/system/acl_test.go
Normal file
@ -0,0 +1,89 @@
|
||||
package system
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"git.ophivana.moe/cat/fortify/acl"
|
||||
)
|
||||
|
||||
func TestUpdatePerm(t *testing.T) {
|
||||
testCases := []struct {
|
||||
path string
|
||||
perms []acl.Perm
|
||||
}{
|
||||
{"/run/user/1971/fortify", []acl.Perm{acl.Execute}},
|
||||
{"/tmp/fortify.1971/tmpdir/150", []acl.Perm{acl.Read, acl.Write, acl.Execute}},
|
||||
}
|
||||
|
||||
for _, tc := range testCases {
|
||||
t.Run(tc.path+permSubTestSuffix(tc.perms), func(t *testing.T) {
|
||||
sys := New(150)
|
||||
sys.UpdatePerm(tc.path, tc.perms...)
|
||||
(&tcOp{Process, tc.path}).test(t, sys.ops, []Op{&ACL{Process, tc.path, tc.perms}}, "UpdatePerm")
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestUpdatePermType(t *testing.T) {
|
||||
testCases := []struct {
|
||||
perms []acl.Perm
|
||||
tcOp
|
||||
}{
|
||||
{[]acl.Perm{acl.Execute}, tcOp{User, "/tmp/fortify.1971/tmpdir"}},
|
||||
{[]acl.Perm{acl.Read, acl.Write, acl.Execute}, tcOp{User, "/tmp/fortify.1971/tmpdir/150"}},
|
||||
{[]acl.Perm{acl.Execute}, tcOp{Process, "/run/user/1971/fortify/fcb8a12f7c482d183ade8288c3de78b5"}},
|
||||
{[]acl.Perm{acl.Read}, tcOp{Process, "/tmp/fortify.1971/fcb8a12f7c482d183ade8288c3de78b5/passwd"}},
|
||||
{[]acl.Perm{acl.Read}, tcOp{Process, "/tmp/fortify.1971/fcb8a12f7c482d183ade8288c3de78b5/group"}},
|
||||
{[]acl.Perm{acl.Read, acl.Write, acl.Execute}, tcOp{EWayland, "/run/user/1971/wayland-0"}},
|
||||
}
|
||||
|
||||
for _, tc := range testCases {
|
||||
t.Run(tc.path+"_"+TypeString(tc.et)+permSubTestSuffix(tc.perms), func(t *testing.T) {
|
||||
sys := New(150)
|
||||
sys.UpdatePermType(tc.et, tc.path, tc.perms...)
|
||||
tc.test(t, sys.ops, []Op{&ACL{tc.et, tc.path, tc.perms}}, "UpdatePermType")
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestACL_String(t *testing.T) {
|
||||
testCases := []struct {
|
||||
want string
|
||||
perms []acl.Perm
|
||||
}{
|
||||
{"---", []acl.Perm{}},
|
||||
{"r--", []acl.Perm{acl.Read}},
|
||||
{"-w-", []acl.Perm{acl.Write}},
|
||||
{"--x", []acl.Perm{acl.Execute}},
|
||||
{"rw-", []acl.Perm{acl.Read, acl.Write}},
|
||||
{"r-x", []acl.Perm{acl.Read, acl.Execute}},
|
||||
{"rwx", []acl.Perm{acl.Read, acl.Write, acl.Execute}},
|
||||
{"rwx", []acl.Perm{acl.Read, acl.Write, acl.Write, acl.Execute}},
|
||||
}
|
||||
|
||||
for _, tc := range testCases {
|
||||
t.Run(tc.want, func(t *testing.T) {
|
||||
a := &ACL{perms: tc.perms}
|
||||
if got := a.String(); got != tc.want {
|
||||
t.Errorf("String() = %v, want %v",
|
||||
got, tc.want)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func permSubTestSuffix(perms []acl.Perm) (suffix string) {
|
||||
for _, perm := range perms {
|
||||
switch perm {
|
||||
case acl.Read:
|
||||
suffix += "_read"
|
||||
case acl.Write:
|
||||
suffix += "_write"
|
||||
case acl.Execute:
|
||||
suffix += "_execute"
|
||||
default:
|
||||
panic("unreachable")
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
73
internal/system/mkdir_test.go
Normal file
73
internal/system/mkdir_test.go
Normal file
@ -0,0 +1,73 @@
|
||||
package system
|
||||
|
||||
import (
|
||||
"os"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestEnsure(t *testing.T) {
|
||||
testCases := []struct {
|
||||
name string
|
||||
perm os.FileMode
|
||||
}{
|
||||
{"/tmp/fortify.1971", 0701},
|
||||
{"/tmp/fortify.1971/tmpdir", 0700},
|
||||
{"/tmp/fortify.1971/tmpdir/150", 0700},
|
||||
{"/run/user/1971/fortify", 0700},
|
||||
}
|
||||
for _, tc := range testCases {
|
||||
t.Run(tc.name+"_"+tc.perm.String(), func(t *testing.T) {
|
||||
sys := New(150)
|
||||
sys.Ensure(tc.name, tc.perm)
|
||||
(&tcOp{User, tc.name}).test(t, sys.ops, []Op{&Mkdir{User, tc.name, tc.perm, false}}, "Ensure")
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestEphemeral(t *testing.T) {
|
||||
testCases := []struct {
|
||||
perm os.FileMode
|
||||
tcOp
|
||||
}{
|
||||
{0700, tcOp{Process, "/run/user/1971/fortify/ec07546a772a07cde87389afc84ffd13"}},
|
||||
{0701, tcOp{Process, "/tmp/fortify.1971/ec07546a772a07cde87389afc84ffd13"}},
|
||||
}
|
||||
for _, tc := range testCases {
|
||||
t.Run(tc.path+"_"+tc.perm.String()+"_"+TypeString(tc.et), func(t *testing.T) {
|
||||
sys := New(150)
|
||||
sys.Ephemeral(tc.et, tc.path, tc.perm)
|
||||
tc.test(t, sys.ops, []Op{&Mkdir{tc.et, tc.path, tc.perm, true}}, "Ephemeral")
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestMkdir_String(t *testing.T) {
|
||||
testCases := []struct {
|
||||
want string
|
||||
ephemeral bool
|
||||
et Enablement
|
||||
}{
|
||||
{"Ensure", false, User},
|
||||
{"Ensure", false, Process},
|
||||
{"Ensure", false, EWayland},
|
||||
|
||||
{"Wayland", true, EWayland},
|
||||
{"X11", true, EX11},
|
||||
{"D-Bus", true, EDBus},
|
||||
{"PulseAudio", true, EPulse},
|
||||
}
|
||||
for _, tc := range testCases {
|
||||
t.Run(tc.want, func(t *testing.T) {
|
||||
m := &Mkdir{
|
||||
et: tc.et,
|
||||
path: "/nonexistent",
|
||||
perm: 0701,
|
||||
ephemeral: tc.ephemeral,
|
||||
}
|
||||
want := "mode: " + os.FileMode(0701).String() + " type: " + tc.want + " path: \"/nonexistent\""
|
||||
if got := m.String(); got != want {
|
||||
t.Errorf("String() = %v, want %v", got, want)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
79
internal/system/op_internal_test.go
Normal file
79
internal/system/op_internal_test.go
Normal file
@ -0,0 +1,79 @@
|
||||
package system
|
||||
|
||||
import "testing"
|
||||
|
||||
type tcOp struct {
|
||||
et Enablement
|
||||
path string
|
||||
}
|
||||
|
||||
// test an instance of the Op interface
|
||||
func (ptc tcOp) test(t *testing.T, gotOps []Op, wantOps []Op, fn string) {
|
||||
if len(gotOps) != len(wantOps) {
|
||||
t.Errorf("%s: inserted %v Ops, want %v", fn,
|
||||
len(gotOps), len(wantOps))
|
||||
return
|
||||
}
|
||||
|
||||
t.Run("path", func(t *testing.T) {
|
||||
if len(gotOps) > 0 {
|
||||
if got := gotOps[0].Path(); got != ptc.path {
|
||||
t.Errorf("Path() = %q, want %q",
|
||||
got, ptc.path)
|
||||
return
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
for i := range gotOps {
|
||||
o := gotOps[i]
|
||||
|
||||
t.Run("is", func(t *testing.T) {
|
||||
if !o.Is(o) {
|
||||
t.Errorf("Is returned false on self")
|
||||
return
|
||||
}
|
||||
if !o.Is(wantOps[i]) {
|
||||
t.Errorf("%s: inserted %#v, want %#v",
|
||||
fn,
|
||||
o, wantOps[i])
|
||||
return
|
||||
}
|
||||
})
|
||||
|
||||
t.Run("criteria", func(t *testing.T) {
|
||||
testCases := []struct {
|
||||
name string
|
||||
ec *Criteria
|
||||
want bool
|
||||
}{
|
||||
{"nil", newCriteria(), ptc.et != User},
|
||||
{"self", newCriteria(ptc.et), true},
|
||||
{"all", newCriteria(EWayland, EX11, EDBus, EPulse, User, Process), true},
|
||||
{"enablements", newCriteria(EWayland, EX11, EDBus, EPulse), ptc.et != User && ptc.et != Process},
|
||||
}
|
||||
|
||||
for _, tc := range testCases {
|
||||
t.Run(tc.name, func(t *testing.T) {
|
||||
if got := tc.ec.hasType(o); got != tc.want {
|
||||
t.Errorf("hasType: got %v, want %v",
|
||||
got, tc.want)
|
||||
}
|
||||
})
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func newCriteria(labels ...Enablement) *Criteria {
|
||||
ec := new(Criteria)
|
||||
if len(labels) == 0 {
|
||||
return ec
|
||||
}
|
||||
|
||||
ec.Enablements = new(Enablements)
|
||||
for _, e := range labels {
|
||||
ec.Set(e)
|
||||
}
|
||||
return ec
|
||||
}
|
53
internal/system/op_test.go
Normal file
53
internal/system/op_test.go
Normal file
@ -0,0 +1,53 @@
|
||||
package system_test
|
||||
|
||||
import (
|
||||
"strconv"
|
||||
"testing"
|
||||
|
||||
"git.ophivana.moe/cat/fortify/internal/system"
|
||||
)
|
||||
|
||||
func TestNew(t *testing.T) {
|
||||
testCases := []struct {
|
||||
uid int
|
||||
}{
|
||||
{150},
|
||||
{149},
|
||||
{148},
|
||||
{147},
|
||||
}
|
||||
|
||||
for _, tc := range testCases {
|
||||
t.Run("sys initialised with uid "+strconv.Itoa(tc.uid), func(t *testing.T) {
|
||||
if got := system.New(tc.uid); got.UID() != tc.uid {
|
||||
t.Errorf("New(%d) uid = %d, want %d",
|
||||
tc.uid,
|
||||
got.UID(), tc.uid)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestTypeString(t *testing.T) {
|
||||
testCases := []struct {
|
||||
e system.Enablement
|
||||
want string
|
||||
}{
|
||||
{system.EWayland, system.EWayland.String()},
|
||||
{system.EX11, system.EX11.String()},
|
||||
{system.EDBus, system.EDBus.String()},
|
||||
{system.EPulse, system.EPulse.String()},
|
||||
{system.User, "User"},
|
||||
{system.Process, "Process"},
|
||||
}
|
||||
|
||||
for _, tc := range testCases {
|
||||
t.Run("label type string "+tc.want, func(t *testing.T) {
|
||||
if got := system.TypeString(tc.e); got != tc.want {
|
||||
t.Errorf("TypeString(%d) = %v, want %v",
|
||||
tc.e,
|
||||
got, tc.want)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
167
internal/system/tmpfiles_test.go
Normal file
167
internal/system/tmpfiles_test.go
Normal file
@ -0,0 +1,167 @@
|
||||
package system
|
||||
|
||||
import (
|
||||
"strconv"
|
||||
"testing"
|
||||
|
||||
"git.ophivana.moe/cat/fortify/acl"
|
||||
)
|
||||
|
||||
func TestCopyFile(t *testing.T) {
|
||||
testCases := []struct {
|
||||
dst, src string
|
||||
}{
|
||||
{"/tmp/fortify.1971/f587afe9fce3c8e1ad5b64deb6c41ad5/pulse-cookie", "/home/ophestra/xdg/config/pulse/cookie"},
|
||||
{"/tmp/fortify.1971/62154f708b5184ab01f9dcc2bbe7a33b/pulse-cookie", "/home/ophestra/xdg/config/pulse/cookie"},
|
||||
}
|
||||
for _, tc := range testCases {
|
||||
t.Run("copy file "+tc.dst+" from "+tc.src, func(t *testing.T) {
|
||||
sys := New(150)
|
||||
sys.CopyFile(tc.dst, tc.src)
|
||||
(&tcOp{Process, tc.src}).test(t, sys.ops, []Op{
|
||||
&Tmpfile{Process, tmpfileCopy, tc.dst, tc.src},
|
||||
&ACL{Process, tc.dst, []acl.Perm{acl.Read}},
|
||||
}, "CopyFile")
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestCopyFileType(t *testing.T) {
|
||||
testCases := []struct {
|
||||
tcOp
|
||||
dst string
|
||||
}{
|
||||
{tcOp{User, "/tmp/fortify.1971/f587afe9fce3c8e1ad5b64deb6c41ad5/pulse-cookie"}, "/home/ophestra/xdg/config/pulse/cookie"},
|
||||
{tcOp{Process, "/tmp/fortify.1971/62154f708b5184ab01f9dcc2bbe7a33b/pulse-cookie"}, "/home/ophestra/xdg/config/pulse/cookie"},
|
||||
}
|
||||
for _, tc := range testCases {
|
||||
t.Run("copy file "+tc.dst+" from "+tc.path+" with type "+TypeString(tc.et), func(t *testing.T) {
|
||||
sys := New(150)
|
||||
sys.CopyFileType(tc.et, tc.dst, tc.path)
|
||||
tc.test(t, sys.ops, []Op{
|
||||
&Tmpfile{tc.et, tmpfileCopy, tc.dst, tc.path},
|
||||
&ACL{tc.et, tc.dst, []acl.Perm{acl.Read}},
|
||||
}, "CopyFileType")
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestLink(t *testing.T) {
|
||||
testCases := []struct {
|
||||
dst, src string
|
||||
}{
|
||||
{"/tmp/fortify.1971/f587afe9fce3c8e1ad5b64deb6c41ad5/pulse-cookie", "/home/ophestra/xdg/config/pulse/cookie"},
|
||||
{"/tmp/fortify.1971/62154f708b5184ab01f9dcc2bbe7a33b/pulse-cookie", "/home/ophestra/xdg/config/pulse/cookie"},
|
||||
}
|
||||
for _, tc := range testCases {
|
||||
t.Run("link file "+tc.dst+" from "+tc.src, func(t *testing.T) {
|
||||
sys := New(150)
|
||||
sys.Link(tc.src, tc.dst)
|
||||
(&tcOp{Process, tc.src}).test(t, sys.ops, []Op{
|
||||
&Tmpfile{Process, tmpfileLink, tc.dst, tc.src},
|
||||
}, "Link")
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestLinkFileType(t *testing.T) {
|
||||
testCases := []struct {
|
||||
tcOp
|
||||
dst string
|
||||
}{
|
||||
{tcOp{User, "/tmp/fortify.1971/f587afe9fce3c8e1ad5b64deb6c41ad5/pulse-cookie"}, "/home/ophestra/xdg/config/pulse/cookie"},
|
||||
{tcOp{Process, "/tmp/fortify.1971/62154f708b5184ab01f9dcc2bbe7a33b/pulse-cookie"}, "/home/ophestra/xdg/config/pulse/cookie"},
|
||||
}
|
||||
for _, tc := range testCases {
|
||||
t.Run("link file "+tc.dst+" from "+tc.path+" with type "+TypeString(tc.et), func(t *testing.T) {
|
||||
sys := New(150)
|
||||
sys.LinkFileType(tc.et, tc.path, tc.dst)
|
||||
tc.test(t, sys.ops, []Op{
|
||||
&Tmpfile{tc.et, tmpfileLink, tc.dst, tc.path},
|
||||
}, "LinkFileType")
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestWrite(t *testing.T) {
|
||||
testCases := []struct {
|
||||
dst, src string
|
||||
}{
|
||||
{"/etc/passwd", "chronos:x:65534:65534:Fortify:/home/chronos:/run/current-system/sw/bin/zsh\n"},
|
||||
{"/etc/group", "fortify:x:65534:\n"},
|
||||
}
|
||||
for _, tc := range testCases {
|
||||
t.Run("write "+strconv.Itoa(len(tc.src))+" bytes to "+tc.dst, func(t *testing.T) {
|
||||
sys := New(150)
|
||||
sys.Write(tc.dst, tc.src)
|
||||
(&tcOp{Process, "(" + strconv.Itoa(len(tc.src)) + " bytes of data)"}).test(t, sys.ops, []Op{
|
||||
&Tmpfile{Process, tmpfileWrite, tc.dst, tc.src},
|
||||
&ACL{Process, tc.dst, []acl.Perm{acl.Read}},
|
||||
}, "Write")
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestWriteType(t *testing.T) {
|
||||
testCases := []struct {
|
||||
et Enablement
|
||||
dst, src string
|
||||
}{
|
||||
{Process, "/etc/passwd", "chronos:x:65534:65534:Fortify:/home/chronos:/run/current-system/sw/bin/zsh\n"},
|
||||
{Process, "/etc/group", "fortify:x:65534:\n"},
|
||||
{User, "/etc/passwd", "chronos:x:65534:65534:Fortify:/home/chronos:/run/current-system/sw/bin/zsh\n"},
|
||||
{User, "/etc/group", "fortify:x:65534:\n"},
|
||||
}
|
||||
for _, tc := range testCases {
|
||||
t.Run("write "+strconv.Itoa(len(tc.src))+" bytes to "+tc.dst+" with type "+TypeString(tc.et), func(t *testing.T) {
|
||||
sys := New(150)
|
||||
sys.WriteType(tc.et, tc.dst, tc.src)
|
||||
(&tcOp{tc.et, "(" + strconv.Itoa(len(tc.src)) + " bytes of data)"}).test(t, sys.ops, []Op{
|
||||
&Tmpfile{tc.et, tmpfileWrite, tc.dst, tc.src},
|
||||
&ACL{tc.et, tc.dst, []acl.Perm{acl.Read}},
|
||||
}, "WriteType")
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestTmpfile_String(t *testing.T) {
|
||||
t.Run("invalid method panic", func(t *testing.T) {
|
||||
defer func() {
|
||||
wantPanic := "invalid tmpfile method 255"
|
||||
if r := recover(); r != wantPanic {
|
||||
t.Errorf("String() panic = %v, want %v",
|
||||
r, wantPanic)
|
||||
}
|
||||
}()
|
||||
_ = (&Tmpfile{method: 255}).String()
|
||||
})
|
||||
|
||||
testCases := []struct {
|
||||
method uint8
|
||||
dst, src string
|
||||
want string
|
||||
}{
|
||||
{tmpfileCopy, "/tmp/fortify.1971/4b6bdc9182fb2f1d3a965c5fa8b9b66e/pulse-cookie", "/home/ophestra/xdg/config/pulse/cookie",
|
||||
`"/tmp/fortify.1971/4b6bdc9182fb2f1d3a965c5fa8b9b66e/pulse-cookie" from "/home/ophestra/xdg/config/pulse/cookie"`},
|
||||
{tmpfileLink, "/run/user/1971/fortify/4b6bdc9182fb2f1d3a965c5fa8b9b66e/wayland", "/run/user/1971/wayland-0",
|
||||
`"/run/user/1971/fortify/4b6bdc9182fb2f1d3a965c5fa8b9b66e/wayland" from "/run/user/1971/wayland-0"`},
|
||||
{tmpfileLink, "/run/user/1971/fortify/4b6bdc9182fb2f1d3a965c5fa8b9b66e/pulse", "/run/user/1971/pulse/native",
|
||||
`"/run/user/1971/fortify/4b6bdc9182fb2f1d3a965c5fa8b9b66e/pulse" from "/run/user/1971/pulse/native"`},
|
||||
{tmpfileWrite, "/tmp/fortify.1971/4b6bdc9182fb2f1d3a965c5fa8b9b66e/passwd", "chronos:x:65534:65534:Fortify:/home/chronos:/run/current-system/sw/bin/zsh\n",
|
||||
`75 bytes of data to "/tmp/fortify.1971/4b6bdc9182fb2f1d3a965c5fa8b9b66e/passwd"`},
|
||||
{tmpfileWrite, "/tmp/fortify.1971/4b6bdc9182fb2f1d3a965c5fa8b9b66e/group", "fortify:x:65534:\n",
|
||||
`17 bytes of data to "/tmp/fortify.1971/4b6bdc9182fb2f1d3a965c5fa8b9b66e/group"`},
|
||||
}
|
||||
|
||||
for _, tc := range testCases {
|
||||
t.Run(tc.want, func(t *testing.T) {
|
||||
if got := (&Tmpfile{
|
||||
method: tc.method,
|
||||
dst: tc.dst,
|
||||
src: tc.src,
|
||||
}).String(); got != tc.want {
|
||||
t.Errorf("String() = %v, want %v", got, tc.want)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
34
internal/system/xhost_test.go
Normal file
34
internal/system/xhost_test.go
Normal file
@ -0,0 +1,34 @@
|
||||
package system
|
||||
|
||||
import (
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestChangeHosts(t *testing.T) {
|
||||
testCases := []string{"chronos", "keyring", "cat", "kbd", "yonah"}
|
||||
for _, tc := range testCases {
|
||||
t.Run("append ChangeHosts operation for "+tc, func(t *testing.T) {
|
||||
sys := New(150)
|
||||
sys.ChangeHosts(tc)
|
||||
(&tcOp{EX11, tc}).test(t, sys.ops, []Op{
|
||||
XHost(tc),
|
||||
}, "ChangeHosts")
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestXHost_String(t *testing.T) {
|
||||
testCases := []struct {
|
||||
username string
|
||||
want string
|
||||
}{
|
||||
{"chronos", "SI:localuser:chronos"},
|
||||
}
|
||||
for _, tc := range testCases {
|
||||
t.Run(tc.want, func(t *testing.T) {
|
||||
if got := XHost(tc.username).String(); got != tc.want {
|
||||
t.Errorf("String() = %v, want %v", got, tc.want)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user