Add automated test for the release device iPhone/iPad flow (#23416)

Follow-up to #23340 

# Checklist for submitter
- [x] Added/updated tests
This commit is contained in:
Martin Angers 2024-10-30 21:58:52 -04:00 committed by GitHub
parent 19be0b649d
commit 2d929115ad
No known key found for this signature in database
GPG key ID: B5690EEEBB952194

View file

@ -221,6 +221,70 @@ func (s *integrationMDMTestSuite) TestDEPEnrollReleaseDeviceTeam() {
}
}
func (s *integrationMDMTestSuite) TestDEPEnrollReleaseIphoneTeam() {
t := s.T()
ctx := context.Background()
// Set up a mock DEP Apple API
s.enableABM(t.Name())
s.mockDEPResponse(t.Name(), http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
encoder := json.NewEncoder(w)
switch r.URL.Path {
case "/session":
_, _ = w.Write([]byte(`{"auth_session_token": "session123"}`))
case "/account":
_, _ = w.Write([]byte(fmt.Sprintf(`{"admin_id": "admin123", "org_name": "%s"}`, "foo")))
case "/profile":
require.NoError(t, encoder.Encode(godep.ProfileResponse{ProfileUUID: "profile123"}))
}
}))
teamDevice := godep.Device{SerialNumber: "IOS0_SERIAL", Model: "iPhone 16 Pro", OS: "ios", DeviceFamily: "iPhone", OpType: "added"}
tm, err := s.ds.NewTeam(ctx, &fleet.Team{Name: "test-team-device-release"})
require.NoError(t, err)
enrollSecret := "test-release-dep-device-team"
err = s.ds.ApplyEnrollSecrets(ctx, &tm.ID, []*fleet.EnrollSecret{{Secret: enrollSecret}})
require.NoError(t, err)
// add a custom setup assistant and ensure enable_release_device_manually is
// false (the default)
teamProf := `{"y": 2}`
s.Do("POST", "/api/latest/fleet/enrollment_profiles/automatic", createMDMAppleSetupAssistantRequest{
TeamID: &tm.ID,
Name: "team",
EnrollmentProfile: json.RawMessage(teamProf),
}, http.StatusOK)
payload := map[string]any{
"enable_release_device_manually": false,
}
s.Do("PATCH", "/api/latest/fleet/setup_experience", json.RawMessage(jsonMustMarshal(t, payload)), http.StatusNoContent)
var acResp appConfigResponse
s.enableABM("fleet_ade_test")
s.DoJSON("PATCH", "/api/latest/fleet/config", json.RawMessage(fmt.Sprintf(`{
"mdm": {
"apple_business_manager": [{
"organization_name": %q,
"macos_team": %q,
"ios_team": %q,
"ipados_team": %q
}]
}
}`, "fleet_ade_test", tm.Name, tm.Name, tm.Name)), http.StatusOK, &acResp)
// add a team profile
teamProfile := mobileconfigForTest("N2", "I2")
s.Do("POST", "/api/v1/fleet/mdm/apple/profiles/batch", batchSetMDMAppleProfilesRequest{Profiles: [][]byte{teamProfile}}, http.StatusNoContent, "team_id", fmt.Sprint(tm.ID))
for _, enableReleaseManually := range []bool{false, true} {
t.Run(fmt.Sprintf("enableReleaseManually=%t", enableReleaseManually), func(t *testing.T) {
s.runDEPEnrollReleaseDeviceTest(t, teamDevice, enableReleaseManually, &tm.ID, "I2", false)
})
}
}
func (s *integrationMDMTestSuite) runDEPEnrollReleaseDeviceTest(t *testing.T, device godep.Device, enableReleaseManually bool, teamID *uint, customProfileIdent string, useOldFleetdFlow bool) {
ctx := context.Background()
@ -297,6 +361,11 @@ func (s *integrationMDMTestSuite) runDEPEnrollReleaseDeviceTest(t *testing.T, de
// enroll the host
depURLToken := loadEnrollmentProfileDEPToken(t, s.ds)
mdmDevice := mdmtest.NewTestMDMClientAppleDEP(s.server.URL, depURLToken)
var isIphone bool
if device.DeviceFamily == "iPhone" {
mdmDevice.Model = "iPhone 14,6"
isIphone = true
}
mdmDevice.SerialNumber = device.SerialNumber
err := mdmDevice.Enroll()
require.NoError(t, err)
@ -333,10 +402,17 @@ func (s *integrationMDMTestSuite) runDEPEnrollReleaseDeviceTest(t *testing.T, de
require.NoError(t, err)
}
// expected commands: install fleetd, install bootstrap, install CA, install profiles
// (custom one, fleetd configuration, FileVault) (not expected: account
// configuration, since enrollment_reference not set)
require.Len(t, cmds, 6)
if isIphone {
// expected commands: install CA, install profile (only the custom one),
// not expected: account configuration, since enrollment_reference not set
require.Len(t, cmds, 2)
} else {
// expected commands: install fleetd, install bootstrap, install CA, install profiles
// (custom one, fleetd configuration, FileVault) (not expected: account
// configuration, since enrollment_reference not set)
require.Len(t, cmds, 6)
}
var installProfileCount, installEnterpriseCount, otherCount int
var profileCustomSeen, profileFleetdSeen, profileFleetCASeen, profileFileVaultSeen bool
for _, cmd := range cmds {
@ -361,6 +437,68 @@ func (s *integrationMDMTestSuite) runDEPEnrollReleaseDeviceTest(t *testing.T, de
otherCount++
}
}
if isIphone {
require.Equal(t, 2, installProfileCount)
require.Equal(t, 0, installEnterpriseCount)
require.Equal(t, 0, otherCount)
require.True(t, profileCustomSeen)
require.False(t, profileFleetdSeen)
require.True(t, profileFleetCASeen)
require.False(t, profileFileVaultSeen)
// for iDevices, fleetd is not installed so the rest of this test does not apply.
if enableReleaseManually {
// get the worker's pending job from the future, there should not be any
// because it needs to be released manually
pending, err := s.ds.GetQueuedJobs(ctx, 1, time.Now().UTC().Add(time.Minute))
require.NoError(t, err)
require.Empty(t, pending)
} else {
// otherwise the device release job should be enqueued
pending, err := s.ds.GetQueuedJobs(ctx, 1, time.Now().UTC().Add(time.Minute))
require.NoError(t, err)
require.Len(t, pending, 1)
require.Equal(t, "apple_mdm", pending[0].Name)
require.Contains(t, string(*pending[0].Args), worker.AppleMDMPostDEPReleaseDeviceTask)
// make the pending job ready to run immediately and run the job
mysql.ExecAdhocSQL(t, s.ds, func(q sqlx.ExtContext) error {
_, err := q.ExecContext(ctx, `UPDATE jobs SET not_before = ? WHERE id = ?`, time.Now().Add(-1*time.Minute).UTC(), pending[0].ID)
return err
})
s.runWorker()
// make the device process the commands, it should receive the
// DeviceConfigured one.
cmds = cmds[:0]
cmd, err = mdmDevice.Idle()
require.NoError(t, err)
for cmd != nil {
var fullCmd micromdm.CommandPayload
require.NoError(t, plist.Unmarshal(cmd.Raw, &fullCmd))
cmds = append(cmds, &fullCmd)
cmd, err = mdmDevice.Acknowledge(cmd.CommandUUID)
require.NoError(t, err)
}
require.Len(t, cmds, 1)
var deviceConfiguredCount int
for _, cmd := range cmds {
switch cmd.Command.RequestType {
case "DeviceConfigured":
deviceConfiguredCount++
default:
otherCount++
}
}
require.Equal(t, 1, deviceConfiguredCount)
require.Equal(t, 0, otherCount)
}
return
}
require.Equal(t, 4, installProfileCount)
require.Equal(t, 2, installEnterpriseCount)
require.Equal(t, 0, otherCount)