From c9610384cbb9d5b1577e4b1a4116e6a031a1e200 Mon Sep 17 00:00:00 2001 From: Kyle Peacock Date: Thu, 29 Sep 2022 09:52:20 -0700 Subject: [PATCH 1/2] fix: time tests only use faketimers once --- packages/agent/src/agent/http/http.test.ts | 182 ++++++++++----------- 1 file changed, 86 insertions(+), 96 deletions(-) diff --git a/packages/agent/src/agent/http/http.test.ts b/packages/agent/src/agent/http/http.test.ts index c0a1893a7..5c4613acf 100644 --- a/packages/agent/src/agent/http/http.test.ts +++ b/packages/agent/src/agent/http/http.test.ts @@ -550,120 +550,110 @@ describe('retry failures', () => { expect(mockFetch.mock.calls.length).toBe(4); }); }); +jest.useFakeTimers({ legacyFakeTimers: true }); +test('should change nothing if time is within 30 seconds of replica', async () => { + const systemTime = new Date('August 19, 1975 23:15:30'); + // jest.setSystemTime(systemTime); + const mockFetch = jest.fn(); -describe('reconcile time', () => { - it('should change nothing if time is within 30 seconds of replica', async () => { - const systemTime = new Date('August 19, 1975 23:15:30'); - jest.setSystemTime(systemTime); - const mockFetch = jest.fn(); + const agent = new HttpAgent({ host: 'http://localhost:8000', fetch: mockFetch }); - const agent = new HttpAgent({ host: 'http://localhost:8000', fetch: mockFetch }); - - await agent.syncTime(); + await agent.syncTime(); - agent - .call(Principal.managementCanister(), { - methodName: 'test', - arg: new Uint8Array().buffer, - }) - // eslint-disable-next-line @typescript-eslint/no-empty-function, @typescript-eslint/no-unused-vars - .catch(function (_) {}); + agent + .call(Principal.managementCanister(), { + methodName: 'test', + arg: new Uint8Array().buffer, + }) + // eslint-disable-next-line @typescript-eslint/no-empty-function, @typescript-eslint/no-unused-vars + .catch(function (_) {}); + + const requestBody = cbor.decode(mockFetch.mock.calls[0][1].body); + expect((requestBody as unknown as any).content.ingress_expiry).toMatchInlineSnapshot( + `1240000000000`, + ); +}); +test('should adjust the Expiry if the clock is more than 30 seconds behind', async () => { + const mockFetch = jest.fn(); - const requestBody = cbor.decode(mockFetch.mock.calls[0][1].body); - expect((requestBody as unknown as any).content.ingress_expiry).toMatchInlineSnapshot( - `1240000000000`, - ); + const replicaTime = new Date(Date.now() + 31_000); + jest.mock('../../canisterStatus', () => { + return { + request: () => { + return { + // 31 seconds ahead + get: () => replicaTime, + }; + }, + }; }); - // TODO - fix broken test - it.skip('should adjust the Expiry if the clock is more than 30 seconds behind', async () => { - const systemTime = new Date('August 19, 1975 23:15:30'); - jest.useFakeTimers({ legacyFakeTimers: true }); - const mockFetch = jest.fn(); - - const replicaTime = new Date(Number(systemTime) + 31_000); - jest.mock('../../canisterStatus', () => { - return { - request: () => { - return { - // 31 seconds ahead - get: () => replicaTime, - }; - }, - }; - }); - await import('../../canisterStatus'); - const { HttpAgent } = await import('../index'); + await import('../../canisterStatus'); + const { HttpAgent } = await import('../index'); - const agent = new HttpAgent({ host: 'http://localhost:8000', fetch: mockFetch }); + const agent = new HttpAgent({ host: 'http://localhost:8000', fetch: mockFetch }); - await agent.syncTime(); + await agent.syncTime(); - await agent - .call(Principal.managementCanister(), { - methodName: 'test', - arg: new Uint8Array().buffer, - }) - // eslint-disable-next-line @typescript-eslint/no-empty-function, @typescript-eslint/no-unused-vars - .catch(function (_) {}); + await agent + .call(Principal.managementCanister(), { + methodName: 'test', + arg: new Uint8Array().buffer, + }) + // eslint-disable-next-line @typescript-eslint/no-empty-function, @typescript-eslint/no-unused-vars + .catch(function (_) {}); + + const requestBody: any = cbor.decode(mockFetch.mock.calls[0][1].body); + + // Expiry should be: ingress expiry + replica time + const expiryInMs = requestBody.content.ingress_expiry / NANOSECONDS_PER_MILLISECONDS; - const requestBody: any = cbor.decode(mockFetch.mock.calls[0][1].body); + const delay = expiryInMs + REPLICA_PERMITTED_DRIFT_MILLISECONDS - Number(replicaTime); - // Expiry should be: ingress expiry + replica time - const expiryInMs = requestBody.content.ingress_expiry / NANOSECONDS_PER_MILLISECONDS; + expect(requestBody.content.ingress_expiry).toMatchInlineSnapshot(`1271000000000`); - const delay = expiryInMs + REPLICA_PERMITTED_DRIFT_MILLISECONDS - Number(replicaTime); + expect(delay).toBe(DEFAULT_INGRESS_EXPIRY_DELTA_IN_MSECS); + jest.resetModules(); +}); - expect(requestBody.content.ingress_expiry).toMatchInlineSnapshot(`"177747601000000000"`); +// TODO - fix broken test +test('should adjust the Expiry if the clock is more than 30 seconds ahead', async () => { + const mockFetch = jest.fn(); - expect(delay).toBe(DEFAULT_INGRESS_EXPIRY_DELTA_IN_MSECS); - jest.autoMockOff(); + const replicaTime = new Date(Date.now() - 31_000); + jest.mock('../../canisterStatus', () => { + return { + request: () => { + return { + // 31 seconds behind + get: () => replicaTime, + }; + }, + }; }); - // TODO - fix broken test - it.skip('should adjust the Expiry if the clock is more than 30 seconds ahead', async () => { - jest.useFakeTimers(); - const systemTime = new Date('August 19, 1975 23:15:30'); - jest.setSystemTime(systemTime); - const mockFetch = jest.fn(); - jest.useFakeTimers(); - - const replicaTime = new Date(Number(systemTime) - 31_000); - // jest.mock('../../canisterStatus', () => { - // return { - // request: () => { - // return { - // // 31 seconds ahead - // get: () => replicaTime, - // }; - // }, - // }; - // }); - await import('../../canisterStatus'); - const { HttpAgent } = await import('../index'); - - const agent = new HttpAgent({ host: 'https://ic0.app', fetch: fetch }); - - await agent.syncTime(); + await import('../../canisterStatus'); + const { HttpAgent } = await import('../index'); - await agent - .call(Principal.managementCanister(), { - methodName: 'test', - arg: new Uint8Array().buffer, - }) - // eslint-disable-next-line @typescript-eslint/no-empty-function, @typescript-eslint/no-unused-vars - .catch(function (_) { - console.error(_); - }); + const agent = new HttpAgent({ host: 'http://localhost:8000', fetch: mockFetch }); - // const requestBody: any = cbor.decode(mockFetch.mock.calls[0][1].body); + await agent.syncTime(); - // Expiry should be: ingress expiry + replica time - // const expiryInMs = requestBody.content.ingress_expiry / NANOSECONDS_PER_MILLISECONDS; + await agent + .call(Principal.managementCanister(), { + methodName: 'test', + arg: new Uint8Array().buffer, + }) + // eslint-disable-next-line @typescript-eslint/no-empty-function, @typescript-eslint/no-unused-vars + .catch(function (_) {}); - // const delay = expiryInMs + REPLICA_PERMITTED_DRIFT_MILLISECONDS - Number(replicaTime); + const requestBody: any = cbor.decode(mockFetch.mock.calls[0][1].body); - // expect(expiryInMs).toMatchInlineSnapshot(`177747539000`); + // Expiry should be: replica time - ingress expiry + const expiryInMs = requestBody.content.ingress_expiry / NANOSECONDS_PER_MILLISECONDS; - // expect(delay).toBe(DEFAULT_INGRESS_EXPIRY_DELTA_IN_MSECS); - }); - jest.autoMockOff(); + const delay = Number(replicaTime) - (expiryInMs + REPLICA_PERMITTED_DRIFT_MILLISECONDS); + + expect(requestBody.content.ingress_expiry).toMatchInlineSnapshot(`1209000000000`); + + expect(delay).toBe(-1 * DEFAULT_INGRESS_EXPIRY_DELTA_IN_MSECS); + jest.resetModules(); }); From 9ffe00a49f67946741992aaac381a1b62c4e3de8 Mon Sep 17 00:00:00 2001 From: Kyle Peacock Date: Thu, 29 Sep 2022 09:54:04 -0700 Subject: [PATCH 2/2] changelog --- docs/generated/changelog.html | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/docs/generated/changelog.html b/docs/generated/changelog.html index aee071bf8..37cdbfd16 100644 --- a/docs/generated/changelog.html +++ b/docs/generated/changelog.html @@ -16,9 +16,7 @@

Version 0.14.0

Adds retry logic to HttpAgent. By default, retries three times before throwing an error, to offer a more cohesive workflow - -

Version 0.13.4

-