1
0
mirror of https://blitiri.com.ar/repos/chasquid synced 2025-12-18 14:47:03 +00:00
Files
go-chasquid-smtp/internal/dovecot/dovecot_test.go
Alberto Bertogli d53d97aba0 dovecot: Test autodetection works with closed sockets
We want to test that autodetection works with closed sockets, as we
explicitly support that scenario: chasquid might be up before dovecot
is, and we still want the detection to work.

The code is written that way, but we had no tests for it until now,
because we were blocked on the unix listeners supporting
SetUnlinkOnClose, which appeared in Go 1.8.

Now that the minimum Go version has been raised past that, we can
implement the test.
2019-07-13 14:06:13 +01:00

133 lines
3.8 KiB
Go

package dovecot
// The dovecot package is mainly tested via integration/external tests using
// the dovecot-auth-cli tool. See cmd/dovecot-auth-cli for more details.
// The tests here are more narrow and only test specific functionality that is
// easier to cover from Go.
import (
"net"
"testing"
"blitiri.com.ar/go/chasquid/internal/testlib"
)
func TestUsernameNotSafe(t *testing.T) {
a := NewAuth("/tmp/nothing", "/tmp/nothing")
cases := []string{
"a b", " ab", "ab ", "a\tb", "a\t", " ", "\t", "\t "}
for _, c := range cases {
ok, err := a.Authenticate(c, "passwd")
if ok || err != errUsernameNotSafe {
t.Errorf("Authenticate(%q, _): got %v, %v", c, ok, err)
}
ok, err = a.Exists(c)
if ok || err != errUsernameNotSafe {
t.Errorf("Exists(%q): got %v, %v", c, ok, err)
}
}
}
func TestAutodetect(t *testing.T) {
// If we give both parameters to autodetect, it should return a new Auth
// using them, even if they're not valid.
a := Autodetect("uDoesNotExist", "cDoesNotExist")
if a == nil {
t.Errorf("Autodetection with two params failed")
} else if *a != *NewAuth("uDoesNotExist", "cDoesNotExist") {
t.Errorf("Autodetection with two params: got %v", a)
}
// We override the default paths, so we can point the "defaults" to our
// test environment as needed.
defaultUserdbPaths = []string{"/dev/null"}
defaultClientPaths = []string{"/dev/null"}
// Autodetect failure: no valid sockets on the list.
a = Autodetect("", "")
if a != nil {
t.Errorf("Autodetection worked with only /dev/null, got %v", a)
}
// Create a temporary directory, and two sockets on it.
dir := testlib.MustTempDir(t)
defer testlib.RemoveIfOk(t, dir)
userdb := dir + "/userdb"
client := dir + "/client"
uL := mustListen(t, userdb)
cL := mustListen(t, client)
defaultUserdbPaths = append(defaultUserdbPaths, userdb)
defaultClientPaths = append(defaultClientPaths, client)
// Autodetect should work fine against open sockets.
a = Autodetect("", "")
if a == nil {
t.Errorf("Autodetection failed (open sockets)")
} else if a.userdbAddr != userdb || a.clientAddr != client {
t.Errorf("Expected autodetect to pick {%q, %q}, but got {%q, %q}",
userdb, client, a.userdbAddr, a.clientAddr)
}
// Close the two sockets, and re-do the test from above: Autodetect should
// work fine against closed sockets.
// We need to tell Go to keep the socket files around explicitly, as the
// default is to delete them since they were creeated by the net library.
uL.SetUnlinkOnClose(false)
uL.Close()
cL.SetUnlinkOnClose(false)
cL.Close()
a = Autodetect("", "")
if a == nil {
t.Errorf("Autodetection failed (closed sockets)")
} else if a.userdbAddr != userdb || a.clientAddr != client {
t.Errorf("Expected autodetect to pick {%q, %q}, but got {%q, %q}",
userdb, client, a.userdbAddr, a.clientAddr)
}
// Autodetect should pick the suggestions passed as parameters (if
// possible).
defaultUserdbPaths = []string{"/dev/null"}
defaultClientPaths = []string{"/dev/null", client}
a = Autodetect(userdb, "")
if a == nil {
t.Errorf("Autodetection failed (single parameter)")
} else if a.userdbAddr != userdb || a.clientAddr != client {
t.Errorf("Expected autodetect to pick {%q, %q}, but got {%q, %q}",
userdb, client, a.userdbAddr, a.clientAddr)
}
}
func TestReload(t *testing.T) {
// Make sure Reload does not fail.
a := Auth{}
if err := a.Reload(); err != nil {
t.Errorf("Reload failed")
}
}
func mustListen(t *testing.T, path string) *net.UnixListener {
addr, err := net.ResolveUnixAddr("unix", path)
if err != nil {
t.Fatalf("failed to resolve unix addr %q: %v", path, err)
}
l, err := net.ListenUnix("unix", addr)
if err != nil {
t.Fatalf("failed to listen on %q: %v", path, err)
}
return l
}
func TestNotASocket(t *testing.T) {
if isUnixSocket("/doesnotexist") {
t.Errorf("isUnixSocket(/doesnotexist) returned true")
}
}