Skip to content

Commit

Permalink
pam/integration-tests/gdm: Handle broker selection when on such stage
Browse files Browse the repository at this point in the history
We have some races in gdm tests caused by the fact we may send the
brokerSelection event too late, in particular when we received the
broker list, but at that point we may be have done other steps already.

Instead, handle the broker selection only when we're in broker selection
stage, and not too early or too late.
  • Loading branch information
3v1n0 committed Nov 12, 2024
1 parent 0704179 commit 48db852
Show file tree
Hide file tree
Showing 2 changed files with 54 additions and 34 deletions.
76 changes: 48 additions & 28 deletions pam/integration-tests/gdm-module-handler_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -78,23 +78,42 @@ func (gh *gdmTestModuleHandler) exampleHandleGdmData(gdmData *gdm.Data) (*gdm.Da
gdmData.Type.String())
}

func (gh *gdmTestModuleHandler) exampleHandleEvent(event *gdm.EventData) error {
events, ok := gh.eventPollResponses[event.Type]
if ok && len(events) > 0 {
numEvents := 1
if events[0].Type == gdm_test.EventsGroupBegin().Type {
numEvents = slices.IndexFunc(events, func(ev *gdm.EventData) bool {
return ev.Type == gdm_test.EventsGroupEnd().Type
func (gh gdmTestModuleHandler) tunePollEvents(events []*gdm.EventData) []*gdm.EventData {
var sanitized []*gdm.EventData
for _, e := range events {
switch ev := e.Data.(type) {
case *gdm.EventData_BrokerSelected:
idx := slices.IndexFunc(gh.brokersInfos, func(broker *authd.ABResponse_BrokerInfo) bool {
return broker.Id == ev.BrokerSelected.BrokerId || broker.Name == ev.BrokerSelected.BrokerId
})
require.Greater(gh.t, numEvents, 1, "No valid events group found")
events = slices.Delete(events, numEvents, numEvents+1)
events = slices.Delete(events, 0, 1)
numEvents--
require.GreaterOrEqual(gh.t, idx, 0, "Unknown broker: %s", ev.BrokerSelected.BrokerId)
sanitized = append(sanitized, gdm_test.SelectBrokerEvent(gh.brokersInfos[idx].Id))
continue
}
pollEvents := slices.Clone(events[0:numEvents])
gh.eventPollResponses[event.Type] = slices.Delete(events, 0, numEvents)
gh.pollResponses = append(gh.pollResponses, pollEvents...)
sanitized = append(sanitized, e)
}
return sanitized
}

func (gh *gdmTestModuleHandler) exampleHandleEvent(event *gdm.EventData) error {
defer func() {
events, ok := gh.eventPollResponses[event.Type]
if ok && len(events) > 0 {
numEvents := 1
if events[0].Type == gdm_test.EventsGroupBegin().Type {
numEvents = slices.IndexFunc(events, func(ev *gdm.EventData) bool {
return ev.Type == gdm_test.EventsGroupEnd().Type
})
require.Greater(gh.t, numEvents, 1, "No valid events group found")
events = slices.Delete(events, numEvents, numEvents+1)
events = slices.Delete(events, 0, 1)
numEvents--
}
pollEvents := gh.tunePollEvents(events[0:numEvents])
gh.eventPollResponses[event.Type] = slices.Delete(events, 0, numEvents)
gh.pollResponses = append(gh.pollResponses, pollEvents...)
}
}()

switch ev := event.Data.(type) {
case *gdm.EventData_BrokersReceived:
Expand All @@ -103,19 +122,6 @@ func (gh *gdmTestModuleHandler) exampleHandleEvent(event *gdm.EventData) error {
}
gh.brokersInfos = ev.BrokersReceived.BrokersInfos

if gh.selectedBrokerName == ignoredBrokerName {
return nil
}

idx := slices.IndexFunc(gh.brokersInfos, func(bi *authd.ABResponse_BrokerInfo) bool {
return bi.Name == gh.selectedBrokerName
})
if idx < 0 {
return fmt.Errorf("broker '%s' is not known", gh.selectedBrokerName)
}

gh.pollResponses = append(gh.pollResponses, gdm_test.SelectBrokerEvent(gh.brokersInfos[idx].Id))

case *gdm.EventData_BrokerSelected:
idx := slices.IndexFunc(gh.brokersInfos, func(broker *authd.ABResponse_BrokerInfo) bool {
return broker.Id == ev.BrokerSelected.BrokerId
Expand Down Expand Up @@ -150,7 +156,7 @@ func (gh *gdmTestModuleHandler) exampleHandleEvent(event *gdm.EventData) error {
return mode.Id == gh.authModeID
})
if idx < 0 {
return fmt.Errorf("unknown auth mode type: %s", gh.authModeID)
return fmt.Errorf("unknown auth mode type: %q", gh.authModeID)
}
if len(gh.selectedAuthModeIDs) < 1 {
return fmt.Errorf("unexpected authentication started with mode '%s', we've nothing to reply",
Expand Down Expand Up @@ -205,6 +211,20 @@ func (gh *gdmTestModuleHandler) exampleHandleAuthDRequest(gdmData *gdm.Data) (*g
case proto.Stage_brokerSelection:
gh.authModes = nil
gh.brokerID = ""

if gh.selectedBrokerName == ignoredBrokerName {
break
}

idx := slices.IndexFunc(gh.brokersInfos, func(bi *authd.ABResponse_BrokerInfo) bool {
return bi.Name == gh.selectedBrokerName
})
if idx < 0 {
return nil, fmt.Errorf("broker '%s' is not known", gh.selectedBrokerName)
}

gh.pollResponses = append(gh.pollResponses, gdm_test.SelectBrokerEvent(gh.brokersInfos[idx].Id))

case proto.Stage_authModeSelection:
gh.currentUILayout = nil
}
Expand Down
12 changes: 6 additions & 6 deletions pam/integration-tests/gdm_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -640,6 +640,11 @@ func TestGdmModule(t *testing.T) {
},
"Error on missing user": {
pamUser: ptrValue(""),
eventPollResponses: map[gdm.EventType][]*gdm.EventData{
gdm.EventType_brokersReceived: {
gdm_test.SelectBrokerEvent(exampleBrokerName),
},
},
wantPamErrorMessages: []string{
"can't select broker: error InvalidArgument from server: can't start authentication transaction: rpc error: code = InvalidArgument desc = no user name provided",
},
Expand All @@ -656,13 +661,8 @@ func TestGdmModule(t *testing.T) {
},
"Error on unknown broker": {
brokerName: "Not a valid broker!",
eventPollResponses: map[gdm.EventType][]*gdm.EventData{
gdm.EventType_brokersReceived: {
gdm_test.SelectBrokerEvent("some-unknown-broker"),
},
},
wantPamErrorMessages: []string{
"Sending GDM event failed: Conversation error",
"Changing GDM stage failed: Conversation error",
},
wantError: pam.ErrSystem,
wantAcctMgmtErr: pam_test.ErrIgnore,
Expand Down

0 comments on commit 48db852

Please sign in to comment.