Skip to content

Test: Switching update mode without restart (macOS) #324438

Description

@dmitrivMS

Refs: #289144

Complexity: 4

Create Issue

Create Issue


Scenarios can probably be split between different people.

Fixes #289144. Enables changing update.mode without a restart, and lets a
runtime disable (setting → none or the UpdateMode policy) cancel an
in-progress update
via a transient Cancelling… state before Disabled.

What changed (context for the tester)

  • update.mode no longer requires a restart (the relaunch prompt was removed from relauncher).
  • Switching to none (or a disabling policy) while a check/download/pending update is in flight now:
    • shows a transient Cancelling… indicator (title bar / tooltip / menu bar / activity badge), then
    • lands on Disabled, tearing down in-flight work.
  • Re-enabling (nonemanual / start / default) resumes update behavior without a restart.
  • macOS uses the Electron/Squirrel.Mac auto-updater: states progress
    Checking for Updates → Downloading → Downloaded → Ready (Restart to Update), with an
    Overwriting state when a newer update replaces a pending one.

Environment / Prerequisites

  • macOS machine (Apple Silicon and/or Intel; test at least one, ideally both).
  • Install an older VS Code Insiders build so a real update is available when checking:
    • Download an older Insiders .zip/.app from the update server or a saved copy.
    • Move Visual Studio Code - Insiders.app to /Applications (Squirrel.Mac requires the app to be
      in a writable, non-quarantined location and not running from the read-only DMG).
    • Do not let it auto-update before the test starts.
  • View logs: Help → Toggle Developer Tools → Console, and Developer: Open Log File… → Main.
    Look for update#setState, update#reconfigure, update#disable.
  • Optional (policy scenario): configure the UpdateMode policy via a configuration profile / MDM.

Scenario 1 — Change update mode without restart

  1. Launch the older Insiders build from /Applications; confirm Update: Mode = default.
  2. Wait ~30s; confirm an automatic check runs and an update becomes available
    (title-bar indicator, then "Downloading…", ending at Restart to Update).
  3. Set Update: Modemanual.
    • No "restart required" prompt.
    • ✅ Automatic background checks stop; Check for Updates… still works manually.
  4. Set Update: Modestart.
    • ✅ No restart prompt; only a single startup check (verify on next launch).
  5. Set Update: Modedefault.
    • ✅ No restart prompt; automatic checks resume (a check runs within ~30s).
  6. Set Update: Modenone.
    • ✅ No restart prompt; state → Disabled; no further checks.
  7. Set Update: Mode back to default.
    • ✅ Updates re-enable without restart; a check runs and the update reappears.

Scenario 2 — Disable while an update is in flight → Cancelling → Disabled

  1. Start from update.mode = default on the older build.
  2. Trigger a check (auto or Check for Updates…). While the state is one of
    Checking for Updates / Downloading / Downloaded / Ready (Restart to Update) / Overwriting:
  3. Set Update: Modenone.
    • ✅ A transient "Cancelling…" indicator appears (title-bar label "Cancelling...",
      tooltip "Cancelling update, please wait...", activity badge, and menu entry "Cancelling Update...").
    • ✅ State then settles on Disabled
      (log: update#disable - updates are disabled by user preference).
    • ✅ The pending Squirrel update is not applied.
  4. Re-enable update.mode = default.
    • ✅ A fresh check starts; the previously-cancelled update does not silently apply.

Cancelling… is transient and may pass quickly; treat the log entries and the final
Disabled state as the reliable assertions.

Scenario 3 — Overwriting path (newer update replaces a pending one)

  1. With update.mode = default, let an update reach Ready (Restart to Update).
  2. If a newer update is published, confirm the periodic overwrite check (~5 min) picks it up and
    the state transitions through Overwriting back to Ready for the newer version.
  3. While in Overwriting, set Update: Modenone.
    • ✅ Shows transient Cancelling…, then Disabled; no update is applied.

Scenario 4 — Restart to Update completes normally (regression)

  1. With update.mode = default, reach Restart to Update and choose to restart.
    • ✅ The app relaunches on the newer version; version is updated in Code → About.

Scenario 5 — Policy: UpdateMode (optional, requires MDM/profile)

  1. With the app running and an update in flight, apply a UpdateMode policy that disables updates.
    • ✅ In-flight update is cancelled (transient Cancelling…) → Disabled
      (log: update#disable - updates are disabled by policy).
    • Update: Mode becomes policy-controlled (not user-editable) and applies without restart.
  2. Relax the policy.
    • ✅ Updates re-enable without restart; a check runs.

Regression checks

  • Full update path (default) completes end-to-end and relaunches on the new version.
  • Toggling modes repeatedly/rapidly (default→none→default) settles on the latest value, no stuck state.
  • No unexpected repeated checks after switching to manual / start / none.
  • Update indicator / tooltip / menu-bar / activity-badge all reflect Cancelling correctly.
  • Overwriting → Ready flow still works when not cancelled.

Metadata

Metadata

Assignees

Labels

install-updateVS Code installation and upgrade system issuesmacosIssues with VS Code on MAC/OS Xtestplan-item

Type

No type

Fields

No fields configured for issues without a type.

Projects

No projects

Milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions