Commit 23164147 by Oleg Gaidarenko Committed by GitHub

Add tests for multildap (#17358)

That should get us to 100% coverage
parent b17967e0
...@@ -22,6 +22,9 @@ var ErrNoLDAPServers = errors.New("No LDAP servers are configured") ...@@ -22,6 +22,9 @@ var ErrNoLDAPServers = errors.New("No LDAP servers are configured")
// ErrDidNotFindUser if request for user is unsuccessful // ErrDidNotFindUser if request for user is unsuccessful
var ErrDidNotFindUser = errors.New("Did not find a user") var ErrDidNotFindUser = errors.New("Did not find a user")
// newLDAP return instance of the single LDAP server
var newLDAP = ldap.New
// IMultiLDAP is interface for MultiLDAP // IMultiLDAP is interface for MultiLDAP
type IMultiLDAP interface { type IMultiLDAP interface {
Login(query *models.LoginUserQuery) ( Login(query *models.LoginUserQuery) (
...@@ -53,12 +56,13 @@ func New(configs []*ldap.ServerConfig) IMultiLDAP { ...@@ -53,12 +56,13 @@ func New(configs []*ldap.ServerConfig) IMultiLDAP {
func (multiples *MultiLDAP) Login(query *models.LoginUserQuery) ( func (multiples *MultiLDAP) Login(query *models.LoginUserQuery) (
*models.ExternalUserInfo, error, *models.ExternalUserInfo, error,
) { ) {
if len(multiples.configs) == 0 { if len(multiples.configs) == 0 {
return nil, ErrNoLDAPServers return nil, ErrNoLDAPServers
} }
for _, config := range multiples.configs { for _, config := range multiples.configs {
server := ldap.New(config) server := newLDAP(config)
if err := server.Dial(); err != nil { if err := server.Dial(); err != nil {
return nil, err return nil, err
...@@ -67,7 +71,6 @@ func (multiples *MultiLDAP) Login(query *models.LoginUserQuery) ( ...@@ -67,7 +71,6 @@ func (multiples *MultiLDAP) Login(query *models.LoginUserQuery) (
defer server.Close() defer server.Close()
user, err := server.Login(query) user, err := server.Login(query)
if user != nil { if user != nil {
return user, nil return user, nil
} }
...@@ -80,8 +83,6 @@ func (multiples *MultiLDAP) Login(query *models.LoginUserQuery) ( ...@@ -80,8 +83,6 @@ func (multiples *MultiLDAP) Login(query *models.LoginUserQuery) (
if err != nil { if err != nil {
return nil, err return nil, err
} }
return user, nil
} }
// Return invalid credentials if we couldn't find the user anywhere // Return invalid credentials if we couldn't find the user anywhere
...@@ -100,7 +101,7 @@ func (multiples *MultiLDAP) User(login string) ( ...@@ -100,7 +101,7 @@ func (multiples *MultiLDAP) User(login string) (
search := []string{login} search := []string{login}
for _, config := range multiples.configs { for _, config := range multiples.configs {
server := ldap.New(config) server := newLDAP(config)
if err := server.Dial(); err != nil { if err := server.Dial(); err != nil {
return nil, err return nil, err
...@@ -133,7 +134,7 @@ func (multiples *MultiLDAP) Users(logins []string) ( ...@@ -133,7 +134,7 @@ func (multiples *MultiLDAP) Users(logins []string) (
} }
for _, config := range multiples.configs { for _, config := range multiples.configs {
server := ldap.New(config) server := newLDAP(config)
if err := server.Dial(); err != nil { if err := server.Dial(); err != nil {
return nil, err return nil, err
......
package multildap
import (
"errors"
"testing"
. "github.com/smartystreets/goconvey/convey"
"github.com/grafana/grafana/pkg/models"
"github.com/grafana/grafana/pkg/services/ldap"
)
func TestMultiLDAP(t *testing.T) {
Convey("Multildap", t, func() {
Convey("Login()", func() {
Convey("Should return error for absent config list", func() {
setup()
multi := New([]*ldap.ServerConfig{})
_, err := multi.Login(&models.LoginUserQuery{})
So(err, ShouldBeError)
So(err, ShouldEqual, ErrNoLDAPServers)
teardown()
})
Convey("Should return a dial error", func() {
mock := setup()
expected := errors.New("Dial error")
mock.dialErrReturn = expected
multi := New([]*ldap.ServerConfig{
{}, {},
})
_, err := multi.Login(&models.LoginUserQuery{})
So(err, ShouldBeError)
So(err, ShouldEqual, expected)
teardown()
})
Convey("Should call underlying LDAP methods", func() {
mock := setup()
multi := New([]*ldap.ServerConfig{
{}, {},
})
_, err := multi.Login(&models.LoginUserQuery{})
So(mock.dialCalledTimes, ShouldEqual, 2)
So(mock.loginCalledTimes, ShouldEqual, 2)
So(mock.closeCalledTimes, ShouldEqual, 2)
So(err, ShouldEqual, ErrInvalidCredentials)
teardown()
})
Convey("Should get login result", func() {
mock := setup()
mock.loginReturn = &models.ExternalUserInfo{
Login: "killa",
}
multi := New([]*ldap.ServerConfig{
{}, {},
})
result, err := multi.Login(&models.LoginUserQuery{})
So(mock.dialCalledTimes, ShouldEqual, 1)
So(mock.loginCalledTimes, ShouldEqual, 1)
So(mock.closeCalledTimes, ShouldEqual, 1)
So(result.Login, ShouldEqual, "killa")
So(err, ShouldBeNil)
teardown()
})
Convey("Should still call a second error for invalid cred error", func() {
mock := setup()
mock.loginErrReturn = ErrInvalidCredentials
multi := New([]*ldap.ServerConfig{
{}, {},
})
_, err := multi.Login(&models.LoginUserQuery{})
So(mock.dialCalledTimes, ShouldEqual, 2)
So(mock.loginCalledTimes, ShouldEqual, 2)
So(mock.closeCalledTimes, ShouldEqual, 2)
So(err, ShouldEqual, ErrInvalidCredentials)
teardown()
})
Convey("Should return unknown error", func() {
mock := setup()
expected := errors.New("Something unknown")
mock.loginErrReturn = expected
multi := New([]*ldap.ServerConfig{
{}, {},
})
_, err := multi.Login(&models.LoginUserQuery{})
So(mock.dialCalledTimes, ShouldEqual, 1)
So(mock.loginCalledTimes, ShouldEqual, 1)
So(mock.closeCalledTimes, ShouldEqual, 1)
So(err, ShouldEqual, expected)
teardown()
})
})
Convey("User()", func() {
Convey("Should return error for absent config list", func() {
setup()
multi := New([]*ldap.ServerConfig{})
_, err := multi.User("test")
So(err, ShouldBeError)
So(err, ShouldEqual, ErrNoLDAPServers)
teardown()
})
Convey("Should return a dial error", func() {
mock := setup()
expected := errors.New("Dial error")
mock.dialErrReturn = expected
multi := New([]*ldap.ServerConfig{
{}, {},
})
_, err := multi.User("test")
So(err, ShouldBeError)
So(err, ShouldEqual, expected)
teardown()
})
Convey("Should call underlying LDAP methods", func() {
mock := setup()
multi := New([]*ldap.ServerConfig{
{}, {},
})
_, err := multi.User("test")
So(mock.dialCalledTimes, ShouldEqual, 2)
So(mock.usersCalledTimes, ShouldEqual, 2)
So(mock.closeCalledTimes, ShouldEqual, 2)
So(err, ShouldEqual, ErrDidNotFindUser)
teardown()
})
Convey("Should return some error", func() {
mock := setup()
expected := errors.New("Killa Gorilla")
mock.usersErrReturn = expected
multi := New([]*ldap.ServerConfig{
{}, {},
})
_, err := multi.User("test")
So(mock.dialCalledTimes, ShouldEqual, 1)
So(mock.usersCalledTimes, ShouldEqual, 1)
So(mock.closeCalledTimes, ShouldEqual, 1)
So(err, ShouldEqual, expected)
teardown()
})
Convey("Should get only one user", func() {
mock := setup()
mock.usersFirstReturn = []*models.ExternalUserInfo{
{
Login: "one",
},
{
Login: "two",
},
}
multi := New([]*ldap.ServerConfig{
{}, {},
})
user, err := multi.User("test")
So(mock.dialCalledTimes, ShouldEqual, 1)
So(mock.usersCalledTimes, ShouldEqual, 1)
So(mock.closeCalledTimes, ShouldEqual, 1)
So(err, ShouldBeNil)
So(user.Login, ShouldEqual, "one")
teardown()
})
})
Convey("Users()", func() {
Convey("Should return error for absent config list", func() {
setup()
multi := New([]*ldap.ServerConfig{})
_, err := multi.Users([]string{"test"})
So(err, ShouldBeError)
So(err, ShouldEqual, ErrNoLDAPServers)
teardown()
})
Convey("Should return a dial error", func() {
mock := setup()
expected := errors.New("Dial error")
mock.dialErrReturn = expected
multi := New([]*ldap.ServerConfig{
{}, {},
})
_, err := multi.Users([]string{"test"})
So(err, ShouldBeError)
So(err, ShouldEqual, expected)
teardown()
})
Convey("Should call underlying LDAP methods", func() {
mock := setup()
multi := New([]*ldap.ServerConfig{
{}, {},
})
_, err := multi.Users([]string{"test"})
So(mock.dialCalledTimes, ShouldEqual, 2)
So(mock.usersCalledTimes, ShouldEqual, 2)
So(mock.closeCalledTimes, ShouldEqual, 2)
So(err, ShouldBeNil)
teardown()
})
Convey("Should return some error", func() {
mock := setup()
expected := errors.New("Killa Gorilla")
mock.usersErrReturn = expected
multi := New([]*ldap.ServerConfig{
{}, {},
})
_, err := multi.Users([]string{"test"})
So(mock.dialCalledTimes, ShouldEqual, 1)
So(mock.usersCalledTimes, ShouldEqual, 1)
So(mock.closeCalledTimes, ShouldEqual, 1)
So(err, ShouldEqual, expected)
teardown()
})
Convey("Should get users", func() {
mock := setup()
mock.usersFirstReturn = []*models.ExternalUserInfo{
{
Login: "one",
},
{
Login: "two",
},
}
mock.usersRestReturn = []*models.ExternalUserInfo{
{
Login: "three",
},
}
multi := New([]*ldap.ServerConfig{
{}, {},
})
users, err := multi.Users([]string{"test"})
So(mock.dialCalledTimes, ShouldEqual, 2)
So(mock.usersCalledTimes, ShouldEqual, 2)
So(mock.closeCalledTimes, ShouldEqual, 2)
So(err, ShouldBeNil)
So(users[0].Login, ShouldEqual, "one")
So(users[1].Login, ShouldEqual, "two")
So(users[2].Login, ShouldEqual, "three")
teardown()
})
})
})
}
package multildap
import (
"github.com/grafana/grafana/pkg/models"
"github.com/grafana/grafana/pkg/services/ldap"
)
type mockLDAP struct {
dialCalledTimes int
loginCalledTimes int
closeCalledTimes int
usersCalledTimes int
dialErrReturn error
loginErrReturn error
loginReturn *models.ExternalUserInfo
usersErrReturn error
usersFirstReturn []*models.ExternalUserInfo
usersRestReturn []*models.ExternalUserInfo
}
func (mock *mockLDAP) Login(*models.LoginUserQuery) (*models.ExternalUserInfo, error) {
mock.loginCalledTimes = mock.loginCalledTimes + 1
return mock.loginReturn, mock.loginErrReturn
}
func (mock *mockLDAP) Users([]string) ([]*models.ExternalUserInfo, error) {
mock.usersCalledTimes = mock.usersCalledTimes + 1
if mock.usersCalledTimes == 1 {
return mock.usersFirstReturn, mock.usersErrReturn
}
return mock.usersRestReturn, mock.usersErrReturn
}
func (mock *mockLDAP) InitialBind(string, string) error {
return nil
}
func (mock *mockLDAP) Dial() error {
mock.dialCalledTimes = mock.dialCalledTimes + 1
return mock.dialErrReturn
}
func (mock *mockLDAP) Close() {
mock.closeCalledTimes = mock.closeCalledTimes + 1
}
func setup() *mockLDAP {
mock := &mockLDAP{}
newLDAP = func(config *ldap.ServerConfig) ldap.IServer {
return mock
}
return mock
}
func teardown() {
newLDAP = ldap.New
}
Markdown is supported
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