<!-- Add the related story/sub-task/bug number, like Resolves #123, or remove if NA --> **Related issue:** Resolves #40679 https://github.com/fleetdm/fleet/actions/runs/22472807405/job/65093438743 By looking at the logs, looks like there's a race condition between two goroutines calling NewActivity, causing NewActivityFuncInvoked to be stale: <img width="678" height="166" alt="Screenshot 2026-02-27 at 9 48 21 AM" src="https://github.com/user-attachments/assets/0b96f423-bec6-4634-9d83-d4c3fc2e5e8f" /> <img width="675" height="209" alt="Screenshot 2026-02-27 at 9 47 48 AM" src="https://github.com/user-attachments/assets/3497991e-2c15-41a0-bda9-511721117b68" />
49 lines
1.6 KiB
Go
49 lines
1.6 KiB
Go
package mock
|
|
|
|
import (
|
|
"context"
|
|
"sync"
|
|
|
|
activity_api "github.com/fleetdm/fleet/v4/server/activity/api"
|
|
)
|
|
|
|
// NewActivityFunc is the callback function type for MockNewActivityService.
|
|
type NewActivityFunc func(ctx context.Context, user *activity_api.User, activity activity_api.ActivityDetails) error
|
|
|
|
// NoopNewActivityFunc is a no-op implementation of NewActivityFunc for tests
|
|
// that don't need to intercept activity creation.
|
|
var NoopNewActivityFunc NewActivityFunc = func(_ context.Context, _ *activity_api.User, _ activity_api.ActivityDetails) error {
|
|
return nil
|
|
}
|
|
|
|
// MockNewActivityService is a mock implementation of activity_api.NewActivityService
|
|
// for unit tests that use mock.Store instead of real MySQL connections.
|
|
// When Delegate is set, it is called before the mock's NewActivityFunc,
|
|
// allowing real behavior (e.g. webhooks) while still capturing calls.
|
|
type MockNewActivityService struct {
|
|
NewActivityFunc NewActivityFunc // defaults to NoopNewActivityFunc if nil
|
|
NewActivityFuncInvoked bool
|
|
Delegate activity_api.NewActivityService
|
|
|
|
mu sync.Mutex
|
|
}
|
|
|
|
// Ensure MockNewActivityService implements activity_api.NewActivityService.
|
|
var _ activity_api.NewActivityService = (*MockNewActivityService)(nil)
|
|
|
|
func (m *MockNewActivityService) NewActivity(ctx context.Context, user *activity_api.User, activity activity_api.ActivityDetails) error {
|
|
m.mu.Lock()
|
|
m.NewActivityFuncInvoked = true
|
|
m.mu.Unlock()
|
|
if m.Delegate != nil {
|
|
if err := m.Delegate.NewActivity(ctx, user, activity); err != nil {
|
|
return err
|
|
}
|
|
}
|
|
fn := m.NewActivityFunc
|
|
if fn == nil {
|
|
fn = NoopNewActivityFunc
|
|
}
|
|
return fn(ctx, user, activity)
|
|
}
|