Files
mesh-catalog/modules/mounts/cmd/mounts/exports_test.go
T

109 lines
3.5 KiB
Go

package main
import (
"encoding/json"
"strings"
"testing"
)
func TestParseExports(t *testing.T) {
text := `# comment
/srv/media 192.0.2.0/24(rw,sync,root_squash) 198.51.100.7(ro)
"/srv/with space" -ro,sync host.example \
other.example(rw)
/srv/bare
`
got := ParseExports(text, "/etc/exports")
want := []Export{
{"/srv/media", "192.0.2.0/24", "rw,sync,root_squash", "/etc/exports", 2},
{"/srv/media", "198.51.100.7", "ro", "/etc/exports", 2},
{"/srv/with space", "host.example", "ro,sync", "/etc/exports", 3},
{"/srv/with space", "other.example", "rw", "/etc/exports", 3},
{"/srv/bare", "*", "", "/etc/exports", 5},
}
if len(got) != len(want) {
t.Fatalf("got %d, want %d: %+v", len(got), len(want), got)
}
for i := range want {
if got[i] != want[i] {
t.Errorf("export %d = %+v, want %+v", i, got[i], want[i])
}
}
}
func TestParseSMBConfLeavesSecretsOut(t *testing.T) {
text := `[global]
workgroup = WORKGROUP
passdb backend = tdbsam
; comment
[media]
comment = Media
path = /srv/media/
valid users = media
Read Only = no
force user = media
smb encrypt = required
username map script = /bin/secret
[homes]
browseable = no
`
got := ParseSMBConf(text)
if len(got) != 2 || got[0].Name != "media" || got[0].Path != "/srv/media/" {
t.Fatalf("got %+v", got)
}
if got[0].Settings["read only"] != "no" || got[0].Settings["force user"] != "media" {
t.Errorf("settings = %+v", got[0].Settings)
}
b, _ := json.Marshal(got)
for _, leak := range []string{"tdbsam", "WORKGROUP", "/bin/secret"} {
if strings.Contains(string(b), leak) {
t.Errorf("%q was answered: %s", leak, b)
}
}
}
func TestExports(t *testing.T) {
f := newFake(t)
f.zfs = true
f.file("/etc/exports", "# only comments\n")
f.file("/etc/exports.d/zfs.exports", "/storage/media 192.0.2.0/24(sec=sys,rw,no_subtree_check,mountpoint)\n")
f.file("/var/lib/nfs/etab", "/storage/media\t192.0.2.0/24(rw,sync,root_squash,sec=sys)\n/old\t198.51.100.0/24(ro)\n")
f.file("/etc/samba/smb.conf", "[global]\nworkgroup = W\n[media]\npath = /storage/media/\nvalid users = media\nforce user = media\n")
f.answers["systemctl is-active nfs-server.service smb.service"] = "active\ninactive\n"
f.answers["zfs get -H -o name,property,value,source -t filesystem sharenfs,sharesmb"] =
"storage\tsharenfs\toff\tdefault\nstorage/media\tsharenfs\trw=@192.0.2.0/24\tlocal\nstorage/media\tsharesmb\ton\tlocal\n"
r := f.machine().Exports()
said := strings.Join(r.Said, "\n")
for _, want := range []string{
"nfs-server.service: active",
"smb.service: inactive",
"NFS /storage/media to 192.0.2.0/24 (sec=sys,rw,no_subtree_check,mountpoint), in /etc/exports.d/zfs.exports",
"NFS /old to 198.51.100.0/24 is live but in no exports file",
"ZFS storage/media sharenfs=rw=@192.0.2.0/24 (local)",
"SMB [media] /storage/media/, for media, writes as media",
} {
if !strings.Contains(said, want) {
t.Errorf("said lacks %q:\n%s", want, said)
}
}
if len(r.ZFS) != 2 {
t.Errorf("a share property that is off must be left out: %+v", r.ZFS)
}
}
func TestExportsUnreadableIsSaid(t *testing.T) {
r := newFake(t).machine().Exports()
notes := strings.Join(r.Notes, "\n")
for _, want := range []string{"/etc/exports: not present", "/var/lib/nfs/etab: not present", "/etc/samba/smb.conf: not present"} {
if !strings.Contains(notes, want) {
t.Errorf("notes lack %q: %s", want, notes)
}
}
if r.Services["nfs-server.service"] != "not read" {
t.Errorf("services = %+v", r.Services)
}
if !strings.Contains(strings.Join(r.Said, "\n"), "shares nothing") {
t.Errorf("said = %v", r.Said)
}
}