diff --git a/src/lib/device/retry_updater.test.ts b/src/lib/device/retry_updater.test.ts new file mode 100644 index 0000000..d67b2fe --- /dev/null +++ b/src/lib/device/retry_updater.test.ts @@ -0,0 +1,57 @@ +/* + * SPDX-FileCopyrightText: 2026 Tendry Lab + * SPDX-License-Identifier: Apache-2.0 + */ + +import { describe, test, expect } from "vitest"; + +import { Updater } from "@device-ui/lib/device/updater"; +import { RetryUpdater } from "@device-ui/lib/device/retry_updater"; + +class TestUpdater implements Updater { + constructor( + private error: Error | null, + private errorRetryCount: number = -1, + ) {} + + async update(data: Uint8Array): Promise { + const error: Error | null = this.error; + + if (this.errorRetryCount > 0) { + this.errorRetryCount--; + } + if (!this.errorRetryCount) { + this.error = null; + } + + return error; + } +} + +describe("Retry Updater", () => { + test("Faile to update with retries", async () => { + const updateError: Error = new Error("unable to update"); + const retryCount: number = 3; + + const testUpdater: TestUpdater = new TestUpdater(updateError, retryCount); + const retryUpdater: Updater = new RetryUpdater(testUpdater, retryCount); + + expect(await retryUpdater.update(new Uint8Array([1, 2, 3, 4, 5]))).toEqual( + updateError, + ); + }); + test("Successfully update after retries", async () => { + const updateError: Error = new Error("unable to update"); + const retryCount: number = 3; + + const testUpdater: TestUpdater = new TestUpdater( + updateError, + retryCount - 1, + ); + const retryUpdater: Updater = new RetryUpdater(testUpdater, retryCount); + + expect( + await retryUpdater.update(new Uint8Array([1, 2, 3, 4, 5])), + ).toBeNull(); + }); +}); diff --git a/src/lib/device/retry_updater.ts b/src/lib/device/retry_updater.ts new file mode 100644 index 0000000..e23cdfe --- /dev/null +++ b/src/lib/device/retry_updater.ts @@ -0,0 +1,32 @@ +/* + * SPDX-FileCopyrightText: 2026 Tendry Lab + * SPDX-License-Identifier: Apache-2.0 + */ + +import { Updater } from "@device-ui/lib/device/updater"; + +export class RetryUpdater implements Updater { + // Initialize. + // + // @params + // - @p updater to handle the actual update process. + // - @p retryCount - number of times to retry update process in case of error. + constructor( + private updater: Updater, + private retryCount: number, + ) {} + + // Update with retries. + async update(data: Uint8Array) { + let error: Error | null = null; + + for (let n: number = 0; n < this.retryCount; n++) { + error = await this.updater.update(data); + if (!error) { + break; + } + } + + return error; + } +}