193 lines
4.4 KiB
Go
193 lines
4.4 KiB
Go
package main
|
|
|
|
import (
|
|
"strings"
|
|
"testing"
|
|
)
|
|
|
|
func TestParseConfigFindsShares(t *testing.T) {
|
|
doc, err := ParseConfig(`
|
|
# comment
|
|
[global]
|
|
workgroup = WORKGROUP
|
|
|
|
[media]
|
|
path = /srv/media
|
|
valid users = alice, bob
|
|
guest ok = no
|
|
`)
|
|
if err != nil {
|
|
t.Fatalf("ParseConfig() error = %v", err)
|
|
}
|
|
|
|
shares := doc.ShareSections()
|
|
if len(shares) != 1 {
|
|
t.Fatalf("expected 1 share, got %d", len(shares))
|
|
}
|
|
|
|
cfg := ShareFromSection(shares[0])
|
|
if cfg.Name != "media" {
|
|
t.Fatalf("expected share name media, got %q", cfg.Name)
|
|
}
|
|
if cfg.Path != "/srv/media" {
|
|
t.Fatalf("expected path /srv/media, got %q", cfg.Path)
|
|
}
|
|
if strings.Join(cfg.ValidUsers, ",") != "alice,bob" {
|
|
t.Fatalf("expected users alice,bob, got %v", cfg.ValidUsers)
|
|
}
|
|
}
|
|
|
|
func TestBuildShareSectionUpdatesValues(t *testing.T) {
|
|
section := &Section{
|
|
Name: "public",
|
|
Lines: []Line{
|
|
{Key: "path", Value: "/old", IsKV: true},
|
|
{Key: "comment", Value: "old", IsKV: true},
|
|
},
|
|
}
|
|
|
|
updated := BuildShareSection(section, ShareConfig{
|
|
Name: "public",
|
|
Path: "/srv/public",
|
|
Comment: "",
|
|
Browseable: "yes",
|
|
ReadOnly: "no",
|
|
GuestOK: "yes",
|
|
ValidUsers: []string{"alice"},
|
|
})
|
|
|
|
cfg := ShareFromSection(updated)
|
|
if cfg.Path != "/srv/public" {
|
|
t.Fatalf("expected updated path, got %q", cfg.Path)
|
|
}
|
|
if cfg.Comment != "" {
|
|
t.Fatalf("expected comment removed, got %q", cfg.Comment)
|
|
}
|
|
if strings.Join(cfg.ValidUsers, ",") != "alice" {
|
|
t.Fatalf("expected alice, got %v", cfg.ValidUsers)
|
|
}
|
|
}
|
|
|
|
func TestSerializeProducesSectionHeaders(t *testing.T) {
|
|
doc := &Document{
|
|
Preamble: []string{"# smb.conf"},
|
|
Sections: []*Section{
|
|
BuildShareSection(nil, ShareConfig{
|
|
Name: "docs",
|
|
Path: "/srv/docs",
|
|
Browseable: "yes",
|
|
ReadOnly: "no",
|
|
GuestOK: "no",
|
|
}),
|
|
},
|
|
}
|
|
|
|
out := doc.Serialize()
|
|
for _, want := range []string{
|
|
"# smb.conf",
|
|
"[docs]",
|
|
"path = /srv/docs",
|
|
"browseable = yes",
|
|
} {
|
|
if !strings.Contains(out, want) {
|
|
t.Fatalf("serialized output missing %q:\n%s", want, out)
|
|
}
|
|
}
|
|
}
|
|
|
|
func TestDetectSambaInstallPlanPrefersApt(t *testing.T) {
|
|
lookPath := func(file string) (string, error) {
|
|
switch file {
|
|
case "apt-get", "sudo":
|
|
return "/usr/bin/" + file, nil
|
|
default:
|
|
return "", execErr(file)
|
|
}
|
|
}
|
|
|
|
plan, ok := DetectSambaInstallPlan(lookPath, false)
|
|
if !ok {
|
|
t.Fatalf("expected install plan")
|
|
}
|
|
if plan.ManagerName != "apt" {
|
|
t.Fatalf("expected apt manager, got %q", plan.ManagerName)
|
|
}
|
|
if plan.DisplayCommand() != "sudo sh -c apt-get update && apt-get install -y samba" {
|
|
t.Fatalf("unexpected command: %q", plan.DisplayCommand())
|
|
}
|
|
}
|
|
|
|
func TestDetectSambaInstallPlanWithoutSudo(t *testing.T) {
|
|
lookPath := func(file string) (string, error) {
|
|
switch file {
|
|
case "pacman":
|
|
return "/usr/bin/pacman", nil
|
|
default:
|
|
return "", execErr(file)
|
|
}
|
|
}
|
|
|
|
plan, ok := DetectSambaInstallPlan(lookPath, false)
|
|
if !ok {
|
|
t.Fatalf("expected install plan")
|
|
}
|
|
if plan.DisplayCommand() != "pacman -Sy --noconfirm samba" {
|
|
t.Fatalf("unexpected command: %q", plan.DisplayCommand())
|
|
}
|
|
}
|
|
|
|
func TestShareUserReferences(t *testing.T) {
|
|
doc := &Document{
|
|
Sections: []*Section{
|
|
BuildShareSection(nil, ShareConfig{
|
|
Name: "media",
|
|
Path: "/srv/media",
|
|
ValidUsers: []string{"alice", "bob"},
|
|
}),
|
|
BuildShareSection(nil, ShareConfig{
|
|
Name: "photos",
|
|
Path: "/srv/photos",
|
|
ValidUsers: []string{"alice"},
|
|
}),
|
|
},
|
|
}
|
|
|
|
refs := shareUserReferences(doc)
|
|
if len(refs) != 2 {
|
|
t.Fatalf("expected 2 refs, got %d", len(refs))
|
|
}
|
|
if refs[0].User != "alice" || strings.Join(refs[0].Shares, ",") != "media,photos" {
|
|
t.Fatalf("unexpected first ref: %+v", refs[0])
|
|
}
|
|
if refs[1].User != "bob" || strings.Join(refs[1].Shares, ",") != "media" {
|
|
t.Fatalf("unexpected second ref: %+v", refs[1])
|
|
}
|
|
}
|
|
|
|
func TestUnusedAccountCandidates(t *testing.T) {
|
|
entries := []PasswdEntry{
|
|
{Name: "alice", UID: 1001, Shell: "/usr/sbin/nologin"},
|
|
{Name: "bob", UID: 1002, Shell: "/bin/bash"},
|
|
{Name: "daemon", UID: 1, Shell: "/usr/sbin/nologin"},
|
|
{Name: "carol", UID: 1003, Shell: "/bin/false"},
|
|
}
|
|
|
|
active := map[string]struct{}{
|
|
"alice": {},
|
|
}
|
|
|
|
candidates := unusedAccountCandidates(entries, active)
|
|
if len(candidates) != 1 {
|
|
t.Fatalf("expected 1 candidate, got %d", len(candidates))
|
|
}
|
|
if candidates[0].Name != "carol" {
|
|
t.Fatalf("unexpected candidate: %+v", candidates[0])
|
|
}
|
|
}
|
|
|
|
type execErr string
|
|
|
|
func (e execErr) Error() string {
|
|
return "not found: " + string(e)
|
|
}
|