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
|
// If no new update is available for download, see if a new patch exists
|
||||||
// on disk that requires a restart.
|
// on disk that requires a restart.
|
||||||
final (current, next) = await (readCurrentPatch(), readNextPatch()).wait;
|
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.restartRequired
|
||||||
: UpdateStatus.upToDate;
|
: 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', () {
|
group('when updater installed an update and is up to date', () {
|
||||||
setUp(() {
|
setUp(() {
|
||||||
when(updater.currentPatchNumber).thenReturn(1);
|
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', () {
|
group('when a track is provided', () {
|
||||||
const track = UpdateTrack.beta;
|
const track = UpdateTrack.beta;
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user