func TestGroupEntryFor(t *testing.T) { var testCases = []struct { name string cacheSeed map[string]*ldap.Entry queryBaseDNOverride string client ldap.Client expectedError error expectedEntry *ldap.Entry }{ { name: "cached get", cacheSeed: map[string]*ldap.Entry{"cn=testGroup,ou=groups,dc=example,dc=com": newTestGroup("testGroup", "cn=testUser,ou=users,dc=example,dc=com")}, expectedError: nil, expectedEntry: newTestGroup("testGroup", "cn=testUser,ou=users,dc=example,dc=com"), }, { name: "search request failure", queryBaseDNOverride: "dc=foo", expectedError: ldaputil.NewQueryOutOfBoundsError("cn=testGroup,ou=groups,dc=example,dc=com", "dc=foo"), expectedEntry: nil, }, { name: "query failure", client: testclient.NewMatchingSearchErrorClient( testclient.New(), "cn=testGroup,ou=groups,dc=example,dc=com", errors.New("generic search error"), ), expectedError: errors.New("generic search error"), expectedEntry: nil, }, { name: "no errors", client: testclient.NewDNMappingClient( testclient.New(), map[string][]*ldap.Entry{ "cn=testGroup,ou=groups,dc=example,dc=com": {newTestGroup("testGroup", "cn=testUser,ou=users,dc=example,dc=com")}, }, ), expectedError: nil, expectedEntry: newTestGroup("testGroup", "cn=testUser,ou=users,dc=example,dc=com"), }, } for _, testCase := range testCases { ldapInterface := newTestLDAPInterface(testCase.client) if len(testCase.cacheSeed) > 0 { ldapInterface.cachedGroups = testCase.cacheSeed } if len(testCase.queryBaseDNOverride) > 0 { ldapInterface.groupQuery.BaseDN = testCase.queryBaseDNOverride } entry, err := ldapInterface.GroupEntryFor("cn=testGroup,ou=groups,dc=example,dc=com") if !reflect.DeepEqual(err, testCase.expectedError) { t.Errorf("%s: incorrect error returned:\n\texpected:\n\t%v\n\tgot:\n\t%v\n", testCase.name, testCase.expectedError, err) } if !reflect.DeepEqual(entry, testCase.expectedEntry) { t.Errorf("%s: incorrect entry returned:\n\texpected:\n\t%v\n\tgot:\n\t%v\n", testCase.name, testCase.expectedEntry, entry) } } }
func TestSuppressMemberLookupErrorOutOfBounds(t *testing.T) { var testCases = []struct { name string err error expectedHandled bool expectedFatalError error }{ { name: "nil error", err: nil, expectedHandled: false, expectedFatalError: nil, }, { name: "other error", err: errors.New("generic error"), expectedHandled: false, expectedFatalError: nil, }, { name: "non-out-of-bounds member lookup error", err: NewMemberLookupError("", "", nil), expectedHandled: false, expectedFatalError: nil, }, { name: "out-of-bounds member lookup error", err: NewMemberLookupError("", "", ldaputil.NewQueryOutOfBoundsError("", "")), expectedHandled: true, expectedFatalError: nil, }, } for _, testCase := range testCases { handler := NewMemberLookupOutOfBoundsSuppressor(ioutil.Discard) actualHandled, actualFatalErr := handler.HandleError(testCase.err) if actualHandled != testCase.expectedHandled { t.Errorf("%s: handler did not handle as expected: wanted handled=%t, got handled=%t", testCase.name, testCase.expectedHandled, actualHandled) } if !reflect.DeepEqual(actualFatalErr, testCase.expectedFatalError) { t.Errorf("%s: handler did not return correct error:\n\twanted\n\t%v,\n\tgot\n\t%v", testCase.name, testCase.expectedFatalError, actualFatalErr) } } }
func TestExtractMembers(t *testing.T) { var testCases = []struct { name string client ldap.Client expectedError error expectedMembers []*ldap.Entry }{ { name: "group lookup errors", client: testclient.NewMatchingSearchErrorClient( testclient.New(), "cn=testGroup,ou=groups,dc=example,dc=com", errors.New("generic search error"), ), expectedError: errors.New("generic search error"), expectedMembers: nil, }, { name: "member lookup errors", // this is a nested test client, the first nest tries to error on the user DN // the second nest attempts to give back from the DN mapping // the third nest is the default "safe" impl from ldaputil client: testclient.NewMatchingSearchErrorClient( testclient.NewDNMappingClient( testclient.New(), map[string][]*ldap.Entry{ "cn=testGroup,ou=groups,dc=example,dc=com": {newTestGroup("testGroup", "cn=testUser,ou=users,dc=example,dc=com")}, }, ), "cn=testUser,ou=users,dc=example,dc=com", errors.New("generic search error"), ), expectedError: syncerror.NewMemberLookupError("cn=testGroup,ou=groups,dc=example,dc=com", "cn=testUser,ou=users,dc=example,dc=com", errors.New("generic search error")), expectedMembers: nil, }, { name: "out of scope member lookup suppressed", client: testclient.NewMatchingSearchErrorClient( testclient.NewDNMappingClient( testclient.New(), map[string][]*ldap.Entry{ "cn=testGroup,ou=groups,dc=example,dc=com": {newTestGroup("testGroup", "cn=testUser,ou=users,dc=other-example,dc=com")}, }, ), "cn=testUser,ou=users,dc=other-example,dc=com", ldaputil.NewQueryOutOfBoundsError("cn=testUser,ou=users,dc=other-example,dc=com", "cn=testGroup,ou=groups,dc=example,dc=com"), ), expectedError: nil, expectedMembers: []*ldap.Entry{}, }, { name: "no such object member lookup error suppressed", client: testclient.NewMatchingSearchErrorClient( testclient.NewDNMappingClient( testclient.New(), map[string][]*ldap.Entry{ "cn=testGroup,ou=groups,dc=example,dc=com": {newTestGroup("testGroup", "cn=testUser,ou=users,dc=other-example,dc=com")}, }, ), "cn=testUser,ou=users,dc=other-example,dc=com", ldaputil.NewNoSuchObjectError("cn=testUser,ou=users,dc=other-example,dc=com"), ), expectedError: nil, expectedMembers: []*ldap.Entry{}, }, { name: "member not found member lookup error suppressed", client: testclient.NewMatchingSearchErrorClient( testclient.NewDNMappingClient( testclient.New(), map[string][]*ldap.Entry{ "cn=testGroup,ou=groups,dc=example,dc=com": {newTestGroup("testGroup", "cn=testUser,ou=users,dc=other-example,dc=com")}, }, ), "cn=testUser,ou=users,dc=other-example,dc=com", ldaputil.NewEntryNotFoundError("cn=testUser,ou=users,dc=other-example,dc=com", "objectClass=groupOfNames"), ), expectedError: nil, expectedMembers: []*ldap.Entry{}, }, { name: "no errors", client: testclient.NewDNMappingClient( testclient.New(), map[string][]*ldap.Entry{ "cn=testGroup,ou=groups,dc=example,dc=com": {newTestGroup("testGroup", "cn=testUser,ou=users,dc=example,dc=com")}, "cn=testUser,ou=users,dc=example,dc=com": {newTestUser("testUser")}, }, ), expectedError: nil, expectedMembers: []*ldap.Entry{newTestUser("testUser")}, }, } for _, testCase := range testCases { ldapInterface := newTestLDAPInterface(testCase.client) members, err := ldapInterface.ExtractMembers("cn=testGroup,ou=groups,dc=example,dc=com") if !reflect.DeepEqual(err, testCase.expectedError) { t.Errorf("%s: incorrect error returned:\n\texpected:\n\t%v\n\tgot:\n\t%v\n", testCase.name, testCase.expectedError, err) } if !reflect.DeepEqual(members, testCase.expectedMembers) { t.Errorf("%s: incorrect members returned:\n\texpected:\n\t%v\n\tgot:\n\t%v\n", testCase.name, testCase.expectedMembers, members) } } }
return g.returnVal[0], nil } return nil, nil } func (g *puppetGetterExtractor) ExtractMembers(ldapGroupUID string) ([]*ldap.Entry, error) { if len(g.returnVal) > 0 { return g.returnVal, nil } return nil, nil } // the following generators are both GroupGetters and MemberExtractors that generate specific errors // whenever their corresponding methods are called. They are used for the tests for this package var outOfBoundsError error = ldaputil.NewQueryOutOfBoundsError("baseDN", "queryDN") var entryNotFoundError error = ldaputil.NewEntryNotFoundError("baseDN", "filter") var noSuchObjectError error = ldaputil.NewNoSuchObjectError("baseDN") var genericError error = errors.New("generic error") type errOutOfBoundsGetterExtractor struct{} func (g *errOutOfBoundsGetterExtractor) GroupEntryFor(ldapGroupUID string) (*ldap.Entry, error) { return nil, outOfBoundsError } func (g *errOutOfBoundsGetterExtractor) ExtractMembers(ldapGroupUID string) ([]*ldap.Entry, error) { return nil, outOfBoundsError } type errEntryNotFoundGetterExtractor struct{}