Commit cd352f52 authored by ale's avatar ale
Browse files

Refactor the test LDAP server to use a different port each time

Resolves potential conflict when tests are run in parallel.
parent 80f179d7
Pipeline #24819 passed with stages
in 4 minutes and 38 seconds
......@@ -15,35 +15,32 @@ import (
)
const (
testLDAPPort = 42871
testLDAPAddr = "ldap://127.0.0.1:42871"
testUser1 = "uno@investici.org"
testUser2 = "due@investici.org" // has encryption keys
testUser3 = "tre@investici.org" // has OTP
testUser4 = "quattro@investici.org" // has mailing lists
testBaseDN = "dc=example,dc=com"
testUser1 = "uno@investici.org"
testUser2 = "due@investici.org" // has encryption keys
testUser3 = "tre@investici.org" // has OTP
testUser4 = "quattro@investici.org" // has mailing lists
testBaseDN = "dc=example,dc=com"
)
func startServerAndGetUser(t testing.TB) (func(), as.Backend, *as.RawUser) {
func startServerAndGetUser(t testing.TB) (*ldaptest.TestLDAPServer, as.Backend, *as.RawUser) {
return startServerAndGetUserWithName(t, testUser1)
}
func startServerAndGetUser2(t testing.TB) (func(), as.Backend, *as.RawUser) {
func startServerAndGetUser2(t testing.TB) (*ldaptest.TestLDAPServer, as.Backend, *as.RawUser) {
return startServerAndGetUserWithName(t, testUser2)
}
func startServerAndGetUser3(t testing.TB) (func(), as.Backend, *as.RawUser) {
func startServerAndGetUser3(t testing.TB) (*ldaptest.TestLDAPServer, as.Backend, *as.RawUser) {
return startServerAndGetUserWithName(t, testUser3)
}
func startServerAndGetUser4(t testing.TB) (func(), as.Backend, *as.RawUser) {
func startServerAndGetUser4(t testing.TB) (*ldaptest.TestLDAPServer, as.Backend, *as.RawUser) {
return startServerAndGetUserWithName(t, testUser4)
}
func startServer(t testing.TB) (func(), as.Backend) {
stop := ldaptest.StartServer(t, &ldaptest.Config{
func startServer(t testing.TB) (*ldaptest.TestLDAPServer, as.Backend) {
srv := ldaptest.StartServer(t, &ldaptest.Config{
Dir: "../../ldaptest",
Port: testLDAPPort,
Base: "dc=example,dc=com",
LDIFs: []string{
"testdata/base.ldif",
......@@ -54,16 +51,16 @@ func startServer(t testing.TB) (func(), as.Backend) {
},
})
b, err := NewLDAPBackend(testLDAPAddr, "cn=manager,dc=example,dc=com", "password", "dc=example,dc=com")
b, err := NewLDAPBackend(srv.Addr, "cn=manager,dc=example,dc=com", "password", "dc=example,dc=com")
if err != nil {
t.Fatal("NewLDAPBackend", err)
}
return stop, b
return srv, b
}
func startServerAndGetUserWithName(t testing.TB, username string) (func(), as.Backend, *as.RawUser) {
stop, b := startServer(t)
func startServerAndGetUserWithName(t testing.TB, username string) (*ldaptest.TestLDAPServer, as.Backend, *as.RawUser) {
srv, b := startServer(t)
tx, _ := b.NewTransaction()
user, err := tx.GetUser(context.Background(), username)
......@@ -74,12 +71,12 @@ func startServerAndGetUserWithName(t testing.TB, username string) (func(), as.Ba
t.Fatalf("could not find test user %s", username)
}
return stop, b, user
return srv, b, user
}
func TestModel_GetUser_NotFound(t *testing.T) {
stop, b := startServer(t)
defer stop()
srv, b := startServer(t)
defer srv.Close()
tx, _ := b.NewTransaction()
user, err := tx.GetUser(context.Background(), "wrong_user")
......@@ -92,8 +89,8 @@ func TestModel_GetUser_NotFound(t *testing.T) {
}
func TestModel_GetUser(t *testing.T) {
stop, _, user := startServerAndGetUser(t)
defer stop()
srv, _, user := startServerAndGetUser(t)
defer srv.Close()
if user.Name != testUser1 {
t.Errorf("bad username: expected %s, got %s", testUser1, user.Name)
......@@ -127,8 +124,8 @@ func TestModel_GetUser(t *testing.T) {
}
func TestModel_GetUser_HasEncryptionKeys(t *testing.T) {
stop, _, user := startServerAndGetUser2(t)
defer stop()
srv, _, user := startServerAndGetUser2(t)
defer srv.Close()
if !user.HasEncryptionKeys {
t.Errorf("user %s does not appear to have encryption keys", user.Name)
......@@ -136,8 +133,8 @@ func TestModel_GetUser_HasEncryptionKeys(t *testing.T) {
}
func TestModel_GetUser_Has2FA(t *testing.T) {
stop, _, user := startServerAndGetUser3(t)
defer stop()
srv, _, user := startServerAndGetUser3(t)
defer srv.Close()
if !user.Has2FA {
t.Errorf("user %s does not appear to have 2FA enabled", user.Name)
......@@ -145,8 +142,8 @@ func TestModel_GetUser_Has2FA(t *testing.T) {
}
func TestModel_GetUser_HasU2FRegistrations(t *testing.T) {
stop, _, user := startServerAndGetUser4(t)
defer stop()
srv, _, user := startServerAndGetUser4(t)
defer srv.Close()
if n := len(user.U2FRegistrations); n != 2 {
t.Errorf("user %s has %d u2f registrations, expected 2", user.Name, n)
......@@ -163,8 +160,8 @@ func TestModel_GetUser_HasU2FRegistrations(t *testing.T) {
}
func TestModel_GetUser_Resources(t *testing.T) {
stop, b, user := startServerAndGetUser(t)
defer stop()
srv, b, user := startServerAndGetUser(t)
defer srv.Close()
// Ensure that the user *has* resources.
if len(user.Resources) < 1 {
......@@ -195,8 +192,8 @@ func TestModel_GetUser_Resources(t *testing.T) {
}
func TestModel_GetUser_MailingListsAndNewsletters(t *testing.T) {
stop, _, user := startServerAndGetUser4(t)
defer stop()
srv, _, user := startServerAndGetUser4(t)
defer srv.Close()
// Ensure that the user has the expected number of list resources.
// The backend should find two lists, one of which has an alias as the owner.
......@@ -213,8 +210,8 @@ func TestModel_GetUser_MailingListsAndNewsletters(t *testing.T) {
}
func TestModel_SearchUser(t *testing.T) {
stop, b := startServer(t)
defer stop()
srv, b := startServer(t)
defer srv.Close()
tx, _ := b.NewTransaction()
users, err := tx.SearchUser(context.Background(), "uno", 0)
if err != nil {
......@@ -229,15 +226,14 @@ func TestModel_SearchUser(t *testing.T) {
}
func TestModel_SetResourceStatus(t *testing.T) {
stop := ldaptest.StartServer(t, &ldaptest.Config{
srv := ldaptest.StartServer(t, &ldaptest.Config{
Dir: "../../ldaptest",
Port: testLDAPPort,
Base: "dc=example,dc=com",
LDIFs: []string{"testdata/base.ldif", "testdata/test1.ldif"},
})
defer stop()
defer srv.Close()
b, err := NewLDAPBackend(testLDAPAddr, "cn=manager,dc=example,dc=com", "password", "dc=example,dc=com")
b, err := NewLDAPBackend(srv.Addr, "cn=manager,dc=example,dc=com", "password", "dc=example,dc=com")
if err != nil {
t.Fatal("NewLDAPBackend", err)
}
......@@ -262,15 +258,14 @@ func TestModel_SetResourceStatus(t *testing.T) {
}
func TestModel_HasAnyResource(t *testing.T) {
stop := ldaptest.StartServer(t, &ldaptest.Config{
srv := ldaptest.StartServer(t, &ldaptest.Config{
Dir: "../../ldaptest",
Port: testLDAPPort,
Base: "dc=example,dc=com",
LDIFs: []string{"testdata/base.ldif", "testdata/test1.ldif"},
})
defer stop()
defer srv.Close()
b, err := NewLDAPBackend(testLDAPAddr, "cn=manager,dc=example,dc=com", "password", "dc=example,dc=com")
b, err := NewLDAPBackend(srv.Addr, "cn=manager,dc=example,dc=com", "password", "dc=example,dc=com")
if err != nil {
t.Fatal("NewLDAPBackend", err)
}
......@@ -302,8 +297,8 @@ func TestModel_HasAnyResource(t *testing.T) {
}
func TestModel_SearchResource(t *testing.T) {
stop, b := startServer(t)
defer stop()
srv, b := startServer(t)
defer srv.Close()
for _, pattern := range []string{"uno@investici.org", "uno*"} {
tx, _ := b.NewTransaction()
......@@ -321,8 +316,8 @@ func TestModel_SearchResource(t *testing.T) {
}
func TestModel_SetUserPassword(t *testing.T) {
stop, b, user := startServerAndGetUser(t)
defer stop()
srv, b, user := startServerAndGetUser(t)
defer srv.Close()
encPass := "encrypted password"
......@@ -352,8 +347,8 @@ func TestModel_SetUserPassword(t *testing.T) {
}
func TestModel_SetUserEncryptionKeys_Add(t *testing.T) {
stop, b, user := startServerAndGetUser(t)
defer stop()
srv, b, user := startServerAndGetUser(t)
defer srv.Close()
tx, _ := b.NewTransaction()
keys := []*ct.EncryptedKey{
......@@ -371,8 +366,8 @@ func TestModel_SetUserEncryptionKeys_Add(t *testing.T) {
}
func TestModel_SetUserEncryptionKeys_Replace(t *testing.T) {
stop, b, user := startServerAndGetUser2(t)
defer stop()
srv, b, user := startServerAndGetUser2(t)
defer srv.Close()
tx, _ := b.NewTransaction()
keys := []*ct.EncryptedKey{
......@@ -390,8 +385,8 @@ func TestModel_SetUserEncryptionKeys_Replace(t *testing.T) {
}
func TestModel_NextUID(t *testing.T) {
stop, b, user := startServerAndGetUser(t)
defer stop()
srv, b, user := startServerAndGetUser(t)
defer srv.Close()
tx, _ := b.NewTransaction()
// User UID should not be available.
......
......@@ -30,9 +30,6 @@ import (
)
const (
testLDAPPort = 42872
testLDAPAddr = "ldap://127.0.0.1:42872"
testSSODomain = "domain"
testSSOService = "accountserver.domain/"
testAdminUser = "admin"
......@@ -71,8 +68,12 @@ func withAuthServer(t testing.TB, configFiles map[string]string) (func(), string
socketPath := filepath.Join(dir, "auth-socket")
for path, data := range configFiles {
os.MkdirAll(filepath.Dir(filepath.Join(dir, path)), 0700)
ioutil.WriteFile(filepath.Join(dir, path), []byte(data), 0600)
if err := os.MkdirAll(filepath.Dir(filepath.Join(dir, path)), 0700); err != nil {
t.Fatal(err)
}
if err := ioutil.WriteFile(filepath.Join(dir, path), []byte(data), 0600); err != nil {
t.Fatal(err)
}
}
config, err := authserver.LoadConfig(filepath.Join(dir, "config.yml"))
......@@ -143,9 +144,8 @@ func (c *testClient) request(uri string, req, out interface{}) error {
}
func startServiceWithConfigAndCache(t testing.TB, svcConfig as.Config, enableCache bool) (func(), as.Backend, *testClient) {
stop := ldaptest.StartServer(t, &ldaptest.Config{
ldapsrv := ldaptest.StartServer(t, &ldaptest.Config{
Dir: "../ldaptest",
Port: testLDAPPort,
Base: "dc=example,dc=com",
LDIFs: []string{
"testdata/base.ldif",
......@@ -155,7 +155,7 @@ func startServiceWithConfigAndCache(t testing.TB, svcConfig as.Config, enableCac
},
})
be, err := ldapbackend.NewLDAPBackend(testLDAPAddr, "cn=manager,dc=example,dc=com", "password", "dc=example,dc=com")
be, err := ldapbackend.NewLDAPBackend(ldapsrv.Addr, "cn=manager,dc=example,dc=com", "password", "dc=example,dc=com")
if err != nil {
t.Fatal("NewLDAPBackend", err)
}
......@@ -169,10 +169,10 @@ func startServiceWithConfigAndCache(t testing.TB, svcConfig as.Config, enableCac
ssoStop, signer, ssoPubKeyFile := withSSO(t)
authCleanup, authSocketPath := withAuthServer(t, map[string]string{
"config.yml": `---
"config.yml": fmt.Sprintf(`---
backends:
ldap:
uri: "ldap://127.0.0.1:42872"
uri: "%s"
bind_dn: "cn=manager,dc=example,dc=com"
bind_pw: "password"
services:
......@@ -181,7 +181,7 @@ services:
backends:
- backend: ldap
params:
search_base: "uid=%s,ou=People,dc=example,dc=com"
search_base: "uid=%%s,ou=People,dc=example,dc=com"
search_filter: "(status=active)"
scope: "base"
accountserver-recovery:
......@@ -189,12 +189,15 @@ services:
backends:
- backend: ldap
params:
search_base: "uid=%s,ou=People,dc=example,dc=com"
search_base: "uid=%%s,ou=People,dc=example,dc=com"
search_filter: "(status=active)"
scope: "base"
attrs:
password: recoverAnswer
`,
webauthn:
rp_display_name: Auth
rp_id: https://login.example.com
`, ldapsrv.Addr),
})
svcConfig.AuthSocket = authSocketPath
......@@ -221,7 +224,7 @@ services:
service, err := as.NewAccountService(be, &svcConfig)
if err != nil {
stop()
ldapsrv.Close()
t.Fatal("NewAccountService", err)
}
......@@ -237,7 +240,7 @@ services:
}
return func() {
stop()
ldapsrv.Close()
srv.Close()
authCleanup()
ssoStop()
......
......@@ -8,6 +8,7 @@ import (
"os"
"os/exec"
"path/filepath"
"sync"
"testing"
"time"
)
......@@ -16,10 +17,37 @@ import (
type Config struct {
Dir string
Base string
Port int
LDIFs []string
}
type TestLDAPServer struct {
tempf string
proc *exec.Cmd
Addr string
}
const (
minPort = 11042
maxPort = 65535
)
var (
portMx sync.Mutex
lastPort = minPort
)
func nextPort() int {
portMx.Lock()
defer portMx.Unlock()
port := lastPort
lastPort++
if lastPort >= maxPort {
lastPort = minPort
}
return port
}
func waitForPort(port int, timeout time.Duration) error {
addr := fmt.Sprintf("127.0.0.1:%d", port)
deadline := time.Now().Add(timeout)
......@@ -37,7 +65,9 @@ func waitForPort(port int, timeout time.Duration) error {
}
// StartServer starts a test LDAP server with the specified configuration.
func StartServer(t testing.TB, config *Config) func() {
func StartServer(t testing.TB, config *Config) *TestLDAPServer {
port := nextPort()
tmpf, err := ioutil.TempFile("", "")
if err != nil {
t.Fatal(err)
......@@ -46,7 +76,7 @@ func StartServer(t testing.TB, config *Config) func() {
ldap.managerDn=cn=manager,%s
ldap.managerPassword=password
ldap.port=%d
`, config.Base, config.Base, config.Port)
`, config.Base, config.Base, port)
defer tmpf.Close()
args := []string{
......@@ -63,11 +93,17 @@ ldap.port=%d
t.Fatalf("error starting LDAP server: %v", err)
}
waitForPort(config.Port, 5*time.Second)
waitForPort(port, 5*time.Second)
return func() {
proc.Process.Kill()
proc.Wait()
os.Remove(tmpf.Name())
return &TestLDAPServer{
proc: proc,
tempf: tmpf.Name(),
Addr: fmt.Sprintf("ldap://127.0.0.1:%d", port),
}
}
func (s *TestLDAPServer) Close() {
s.proc.Process.Kill()
s.proc.Wait()
os.Remove(s.tempf)
}
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment