mirror of
https://github.com/fleetdm/fleet
synced 2026-05-23 08:58:41 +00:00
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:
parent
19be0b649d
commit
2d929115ad
1 changed files with 142 additions and 4 deletions
|
|
@ -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)
|
||||
|
|
|
|||
Loading…
Reference in a new issue