diff --git a/changes/36644-randomize-apns-query b/changes/36644-randomize-apns-query new file mode 100644 index 0000000000..21f850c749 --- /dev/null +++ b/changes/36644-randomize-apns-query @@ -0,0 +1 @@ +- Randomized APNS query to ensure all pending Apple hosts gets a push notification \ No newline at end of file diff --git a/server/datastore/mysql/apple_mdm.go b/server/datastore/mysql/apple_mdm.go index 750edf7973..17f05f8f0e 100644 --- a/server/datastore/mysql/apple_mdm.go +++ b/server/datastore/mysql/apple_mdm.go @@ -6248,12 +6248,20 @@ GROUP BY h.id` func (ds *Datastore) GetEnrollmentIDsWithPendingMDMAppleCommands(ctx context.Context) (uuids []string, err error) { const stmt = ` -SELECT DISTINCT neq.id -FROM nano_enrollment_queue neq -INNER JOIN nano_enrollments ne ON ne.id = neq.id -LEFT JOIN nano_command_results ncr ON ncr.command_uuid = neq.command_uuid AND ncr.id = neq.id -WHERE neq.active = 1 AND ne.enabled=1 AND ncr.status IS NULL -AND neq.created_at >= NOW() - INTERVAL 7 DAY +SELECT DISTINCT + neq.id +FROM + nano_enrollment_queue neq + INNER JOIN nano_enrollments ne ON ne.id = neq.id + LEFT JOIN nano_command_results ncr ON ncr.command_uuid = neq.command_uuid + AND ncr.id = neq.id +WHERE + neq.active = 1 + AND ne.enabled = 1 + AND ncr.status IS NULL + AND neq.created_at >= NOW() - INTERVAL 7 DAY + AND neq.priority IN (0, 1) +ORDER BY RAND() LIMIT 500 ` @@ -7090,7 +7098,6 @@ func (ds *Datastore) InsertHostLocationData(ctx context.Context, locData fleet.H } func (ds *Datastore) GetHostLocationData(ctx context.Context, hostID uint) (*fleet.HostLocationData, error) { - var ret fleet.HostLocationData err := sqlx.GetContext(ctx, ds.reader(ctx), &ret, "SELECT host_id, latitude, longitude FROM host_last_known_locations WHERE host_id = ?", hostID) diff --git a/server/datastore/mysql/apple_mdm_test.go b/server/datastore/mysql/apple_mdm_test.go index 90e4af9e09..09f6afca0b 100644 --- a/server/datastore/mysql/apple_mdm_test.go +++ b/server/datastore/mysql/apple_mdm_test.go @@ -7155,9 +7155,23 @@ func testGetEnrollmentIDsWithPendingMDMAppleCommands(t *testing.T, ds *Datastore err = commander.EnqueueCommand(ctx, []string{hostUUIDToUserEnrollmentID[hosts[3].UUID], hostUUIDToUserEnrollmentID[hosts[4].UUID], hostUUIDToUserEnrollmentID[hosts[5].UUID]}, rawCmd2) require.NoError(t, err) - ids, err = ds.GetEnrollmentIDsWithPendingMDMAppleCommands(ctx) + firstIds, err := ds.GetEnrollmentIDsWithPendingMDMAppleCommands(ctx) require.NoError(t, err) - require.ElementsMatch(t, []string{hosts[1].UUID, hosts[2].UUID, hostUUIDToUserEnrollmentID[hosts[3].UUID], hostUUIDToUserEnrollmentID[hosts[4].UUID], hostUUIDToUserEnrollmentID[hosts[5].UUID]}, ids) + require.ElementsMatch(t, []string{hosts[1].UUID, hosts[2].UUID, hostUUIDToUserEnrollmentID[hosts[3].UUID], hostUUIDToUserEnrollmentID[hosts[4].UUID], hostUUIDToUserEnrollmentID[hosts[5].UUID]}, firstIds) + + // Get a list of pending ID's 3 times and match against the first list, to avoid test flakiness. + // In a real world scenario it's okay for it to be the same as we will fetch it again later. + allAttemptsWereEqual := true + for range 3 { + secondIds, err := ds.GetEnrollmentIDsWithPendingMDMAppleCommands(ctx) + require.NoError(t, err) + isIdsEqual := assert.ObjectsAreEqualValues(firstIds, secondIds) + if !isIdsEqual { + allAttemptsWereEqual = false + break + } + } + require.False(t, allAttemptsWereEqual, "GetEnrollmentIDsWithPendingMDMAppleCommands returned the same result 3 times in a row") err = storage.StoreCommandReport(&mdm.Request{ EnrollID: &mdm.EnrollID{ID: hostUUIDToUserEnrollmentID[hosts[3].UUID]}, @@ -9627,5 +9641,4 @@ func testDeviceLocation(t *testing.T, ds *Datastore) { _, err = ds.GetHostLocationData(ctx, iOSHost.ID) require.True(t, fleet.IsNotFound(err)) - }