fix: checkForUpdate reports restartRequired when current patch is rolled back (#312)
Previously, checkForUpdate returned upToDate after a rollback because the condition `next != null && current?.number != next.number` treated a null next patch as "up to date". After a rollback, the Rust updater correctly uninstalls the patch (next becomes null), but the app is still running the rolled-back patch (current is non-null). The simplified condition `current?.number != next?.number` correctly detects this mismatch and returns restartRequired. Fixes https://github.com/shorebirdtech/shorebird/issues/3206
This commit is contained in:
@@ -81,7 +81,12 @@ class ShorebirdUpdaterImpl implements ShorebirdUpdater {
|
||||
// If no new update is available for download, see if a new patch exists
|
||||
// on disk that requires a restart.
|
||||
final (current, next) = await (readCurrentPatch(), readNextPatch()).wait;
|
||||
return next != null && current?.number != next.number
|
||||
// A restart is required when the current and next patches differ. This
|
||||
// covers both the "new patch downloaded" case (next differs from current)
|
||||
// and the "current patch was rolled back" case (current is non-null but
|
||||
// next is null, meaning the app needs to restart to revert to the base
|
||||
// release).
|
||||
return current?.number != next?.number
|
||||
? UpdateStatus.restartRequired
|
||||
: UpdateStatus.upToDate;
|
||||
}
|
||||
|
||||
@@ -270,6 +270,22 @@ void main() {
|
||||
});
|
||||
});
|
||||
|
||||
group('when no patches are installed and none available', () {
|
||||
setUp(() {
|
||||
when(updater.currentPatchNumber).thenReturn(0);
|
||||
when(updater.nextPatchNumber).thenReturn(0);
|
||||
when(updater.checkForDownloadableUpdate).thenReturn(false);
|
||||
shorebirdUpdater = ShorebirdUpdaterImpl(updater: updater, run: run);
|
||||
});
|
||||
|
||||
test('returns UpdateStatus.upToDate', () async {
|
||||
await expectLater(
|
||||
shorebirdUpdater.checkForUpdate(),
|
||||
completion(equals(UpdateStatus.upToDate)),
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
group('when updater installed an update and is up to date', () {
|
||||
setUp(() {
|
||||
when(updater.currentPatchNumber).thenReturn(1);
|
||||
@@ -286,6 +302,24 @@ void main() {
|
||||
});
|
||||
});
|
||||
|
||||
group('when current patch has been rolled back', () {
|
||||
setUp(() {
|
||||
// The app is currently running patch 1, but checkForDownloadableUpdate
|
||||
// triggered a rollback which set next_boot_patch to None (0).
|
||||
when(updater.currentPatchNumber).thenReturn(1);
|
||||
when(updater.nextPatchNumber).thenReturn(0);
|
||||
when(updater.checkForDownloadableUpdate).thenReturn(false);
|
||||
shorebirdUpdater = ShorebirdUpdaterImpl(updater: updater, run: run);
|
||||
});
|
||||
|
||||
test('returns UpdateStatus.restartRequired', () async {
|
||||
await expectLater(
|
||||
shorebirdUpdater.checkForUpdate(),
|
||||
completion(equals(UpdateStatus.restartRequired)),
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
group('when a track is provided', () {
|
||||
const track = UpdateTrack.beta;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user