From d4d3c98cee0f111d82426813a96372bce0ed535d Mon Sep 17 00:00:00 2001 From: Kyle Peacock Date: Thu, 27 Jun 2024 12:42:56 -0700 Subject: [PATCH 1/5] wip --- package-lock.json | 20 ++++++++++++++++++++ packages/agent/package.json | 1 + packages/agent/src/actor.test.ts | 17 +++++++++++++++++ 3 files changed, 38 insertions(+) diff --git a/package-lock.json b/package-lock.json index 4c6beb99b..a928a9af6 100644 --- a/package-lock.json +++ b/package-lock.json @@ -4563,6 +4563,25 @@ "node": ">= 6.0.0" } }, + "node_modules/agent1": { + "name": "@dfinity/agent", + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/@dfinity/agent/-/agent-1.4.0.tgz", + "integrity": "sha512-/zgGajZpxtbu+kLXtFx2e9V2+HbMUjrtGWx9ZEwtVwhVxKgVi/2kGQpFRPEDFJ461V7wdTwCig4OkMxVU4shTw==", + "license": "Apache-2.0", + "dependencies": { + "@noble/curves": "^1.4.0", + "@noble/hashes": "^1.3.1", + "base64-arraybuffer": "^0.2.0", + "borc": "^2.1.1", + "buffer": "^6.0.3", + "simple-cbor": "^0.4.1" + }, + "peerDependencies": { + "@dfinity/candid": "^1.4.0", + "@dfinity/principal": "^1.4.0" + } + }, "node_modules/ajv": { "version": "6.12.6", "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", @@ -18759,6 +18778,7 @@ "dependencies": { "@noble/curves": "^1.4.0", "@noble/hashes": "^1.3.1", + "agent1": "npm:@dfinity/agent@^1.4.0", "base64-arraybuffer": "^0.2.0", "borc": "^2.1.1", "buffer": "^6.0.3", diff --git a/packages/agent/package.json b/packages/agent/package.json index 83aac100c..851c91fb3 100644 --- a/packages/agent/package.json +++ b/packages/agent/package.json @@ -64,6 +64,7 @@ "@types/jest": "^29.5.5", "@typescript-eslint/eslint-plugin": "^5.30.5", "@typescript-eslint/parser": "^5.30.5", + "agent1": "npm:@dfinity/agent@^1.4.0", "esbuild": "^0.15.16", "eslint": "^8.19.0", "isomorphic-fetch": "^3.0.0", diff --git a/packages/agent/src/actor.test.ts b/packages/agent/src/actor.test.ts index aac774204..b8cbf319f 100644 --- a/packages/agent/src/actor.test.ts +++ b/packages/agent/src/actor.test.ts @@ -7,6 +7,7 @@ import * as cbor from './cbor'; import { requestIdOf } from './request_id'; import * as pollingImport from './polling'; import { ActorConfig } from './actor'; +import { HttpAgent as HttpAgent1 } from 'agent1'; const importActor = async (mockUpdatePolling?: () => void) => { jest.dontMock('./polling'); @@ -370,6 +371,22 @@ describe('makeActor', () => { ); }); }); + +test.only("Legacy Agent interface should be accepted by Actor's createActor", async () => { + const { Actor } = await importActor(); + const actorInterface = () => { + return IDL.Service({ + greet: IDL.Func([IDL.Text], [IDL.Text]), + }); + }; + + const actor = Actor.createActor(actorInterface, { + canisterId: Principal.fromText('2chl6-4hpzw-vqaaa-aaaaa-c'), + agent: new HttpAgent1() as unknown as HttpAgent, + }); + + await actor.greet('test'); //? +}); // TODO: tests for rejected, unknown time out jest.setTimeout(20000); From 1a376667a00d903701bfa6f69f72a1558d3541ac Mon Sep 17 00:00:00 2001 From: Kyle Peacock Date: Thu, 27 Jun 2024 16:18:01 -0700 Subject: [PATCH 2/5] wip --- package-lock.json | 3 ++- packages/agent/src/actor.test.ts | 7 +++++-- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/package-lock.json b/package-lock.json index a928a9af6..74c3df48d 100644 --- a/package-lock.json +++ b/package-lock.json @@ -4568,6 +4568,7 @@ "version": "1.4.0", "resolved": "https://registry.npmjs.org/@dfinity/agent/-/agent-1.4.0.tgz", "integrity": "sha512-/zgGajZpxtbu+kLXtFx2e9V2+HbMUjrtGWx9ZEwtVwhVxKgVi/2kGQpFRPEDFJ461V7wdTwCig4OkMxVU4shTw==", + "dev": true, "license": "Apache-2.0", "dependencies": { "@noble/curves": "^1.4.0", @@ -18778,7 +18779,6 @@ "dependencies": { "@noble/curves": "^1.4.0", "@noble/hashes": "^1.3.1", - "agent1": "npm:@dfinity/agent@^1.4.0", "base64-arraybuffer": "^0.2.0", "borc": "^2.1.1", "buffer": "^6.0.3", @@ -18790,6 +18790,7 @@ "@types/jest": "^29.5.5", "@typescript-eslint/eslint-plugin": "^5.30.5", "@typescript-eslint/parser": "^5.30.5", + "agent1": "npm:@dfinity/agent@^1.4.0", "esbuild": "^0.15.16", "eslint": "^8.19.0", "isomorphic-fetch": "^3.0.0", diff --git a/packages/agent/src/actor.test.ts b/packages/agent/src/actor.test.ts index b8cbf319f..e56cba9fa 100644 --- a/packages/agent/src/actor.test.ts +++ b/packages/agent/src/actor.test.ts @@ -8,6 +8,7 @@ import { requestIdOf } from './request_id'; import * as pollingImport from './polling'; import { ActorConfig } from './actor'; import { HttpAgent as HttpAgent1 } from 'agent1'; +HttpAgent1; //? const importActor = async (mockUpdatePolling?: () => void) => { jest.dontMock('./polling'); @@ -372,17 +373,19 @@ describe('makeActor', () => { }); }); +jest.setTimeout(20000); + test.only("Legacy Agent interface should be accepted by Actor's createActor", async () => { const { Actor } = await importActor(); const actorInterface = () => { return IDL.Service({ - greet: IDL.Func([IDL.Text], [IDL.Text]), + greet: IDL.Func([IDL.Text], [IDL.Text], ['query']), }); }; const actor = Actor.createActor(actorInterface, { canisterId: Principal.fromText('2chl6-4hpzw-vqaaa-aaaaa-c'), - agent: new HttpAgent1() as unknown as HttpAgent, + agent: new HttpAgent1({ host: 'https://icp-api.io' }) as unknown as HttpAgent, }); await actor.greet('test'); //? From 7bbc771dacfb74f0880adc007b11531de92602d5 Mon Sep 17 00:00:00 2001 From: Kyle Peacock Date: Wed, 10 Jul 2024 15:13:18 -0700 Subject: [PATCH 3/5] passing test using v1 module --- .../agent/src/actor.compatibility.test.ts | 34 +++++++++++++++++++ packages/agent/src/actor.test.ts | 21 ------------ packages/agent/src/actor.ts | 5 +++ 3 files changed, 39 insertions(+), 21 deletions(-) create mode 100644 packages/agent/src/actor.compatibility.test.ts diff --git a/packages/agent/src/actor.compatibility.test.ts b/packages/agent/src/actor.compatibility.test.ts new file mode 100644 index 000000000..072b77229 --- /dev/null +++ b/packages/agent/src/actor.compatibility.test.ts @@ -0,0 +1,34 @@ +import { Actor } from './actor'; +import { HttpAgent } from './agent/http'; +import { HttpAgent as HttpAgentv1 } from 'agent1'; + +jest.useRealTimers(); +test.only("Legacy Agent interface should be accepted by Actor's createActor", async () => { + const idlFactory = ({ IDL }) => { + return IDL.Service({ + greet: IDL.Func([IDL.Text], [IDL.Text], []), + inc: IDL.Func([], [], []), + inc_read: IDL.Func([], [IDL.Nat], []), + queryGreet: IDL.Func([IDL.Text], [IDL.Text], ['query']), + read: IDL.Func([], [IDL.Nat], ['query']), + write: IDL.Func([IDL.Nat], [], []), + }); + }; + + const actor = Actor.createActor(idlFactory, { + canisterId: 'tnnnb-2yaaa-aaaab-qaiiq-cai', + agent: new HttpAgent({ host: 'https://icp-api.io' }) as unknown as HttpAgent, + }); + + // await actor.write(8); //? + const actor1 = Actor.createActor(idlFactory, { + canisterId: 'tnnnb-2yaaa-aaaab-qaiiq-cai', + agent: new HttpAgentv1({ host: 'https://icp-api.io' }) as unknown as HttpAgent, + }); + + await actor1.write(8); //? + await actor1.read(); //? +}); +// TODO: tests for rejected, unknown time out + +jest.setTimeout(8000); diff --git a/packages/agent/src/actor.test.ts b/packages/agent/src/actor.test.ts index e56cba9fa..8f3ef481e 100644 --- a/packages/agent/src/actor.test.ts +++ b/packages/agent/src/actor.test.ts @@ -7,8 +7,6 @@ import * as cbor from './cbor'; import { requestIdOf } from './request_id'; import * as pollingImport from './polling'; import { ActorConfig } from './actor'; -import { HttpAgent as HttpAgent1 } from 'agent1'; -HttpAgent1; //? const importActor = async (mockUpdatePolling?: () => void) => { jest.dontMock('./polling'); @@ -374,22 +372,3 @@ describe('makeActor', () => { }); jest.setTimeout(20000); - -test.only("Legacy Agent interface should be accepted by Actor's createActor", async () => { - const { Actor } = await importActor(); - const actorInterface = () => { - return IDL.Service({ - greet: IDL.Func([IDL.Text], [IDL.Text], ['query']), - }); - }; - - const actor = Actor.createActor(actorInterface, { - canisterId: Principal.fromText('2chl6-4hpzw-vqaaa-aaaaa-c'), - agent: new HttpAgent1({ host: 'https://icp-api.io' }) as unknown as HttpAgent, - }); - - await actor.greet('test'); //? -}); -// TODO: tests for rejected, unknown time out - -jest.setTimeout(20000); diff --git a/packages/agent/src/actor.ts b/packages/agent/src/actor.ts index a5f145218..88fe7f9d1 100644 --- a/packages/agent/src/actor.ts +++ b/packages/agent/src/actor.ts @@ -531,6 +531,10 @@ function _createActorMethod( effectiveCanisterId: ecid, }); + requestId; + response; + requestDetails; + if (!response.ok || response.body /* IC-1462 */) { throw new UpdateCallRejectedError(cid, methodName, requestId, response); } @@ -544,6 +548,7 @@ function _createActorMethod( pollStrategy, blsVerify, ); + reply; const shouldIncludeHttpDetails = func.annotations.includes(ACTOR_METHOD_WITH_HTTP_DETAILS); const shouldIncludeCertificate = func.annotations.includes(ACTOR_METHOD_WITH_CERTIFICATE); From b978e93806b139a8001870132b63f6937e4b878a Mon Sep 17 00:00:00 2001 From: Kyle Peacock Date: Fri, 12 Jul 2024 11:13:34 -0700 Subject: [PATCH 4/5] test: moves actor integration test to e2e --- e2e/node/canisters/counter.ts | 20 ++++++----- e2e/node/integration/actor.test.ts | 18 ++++++++++ e2e/node/package.json | 1 + package-lock.json | 2 +- packages/agent/package.json | 1 - .../agent/src/actor.compatibility.test.ts | 34 ------------------- 6 files changed, 31 insertions(+), 45 deletions(-) create mode 100644 e2e/node/integration/actor.test.ts delete mode 100644 packages/agent/src/actor.compatibility.test.ts diff --git a/e2e/node/canisters/counter.ts b/e2e/node/canisters/counter.ts index 73076cc1d..0818e5303 100644 --- a/e2e/node/canisters/counter.ts +++ b/e2e/node/canisters/counter.ts @@ -1,4 +1,4 @@ -import { Actor, ActorSubclass, HttpAgentOptions } from '@dfinity/agent'; +import { Actor, ActorSubclass, HttpAgentOptions, Agent } from '@dfinity/agent'; import { IDL } from '@dfinity/candid'; import { Principal } from '@dfinity/principal'; import { readFileSync } from 'fs'; @@ -47,20 +47,22 @@ export default async function (): Promise<{ return cache; } -export const createActor = async (options?: HttpAgentOptions) => { +export const createActor = async (options?: HttpAgentOptions, agent?: Agent) => { const module = readFileSync(path.join(__dirname, 'counter.wasm')); - const agent = await makeAgent({ - ...options, - }); + const effectiveAgent = agent + ? agent + : await makeAgent({ + ...options, + }); try { if (!options?.host?.includes('icp-api')) { - await agent.fetchRootKey(); + await effectiveAgent.fetchRootKey(); } } catch (_) { // } - const canisterId = await Actor.createCanister({ agent }); - await Actor.install({ module }, { canisterId, agent }); - return Actor.createActor(idl, { canisterId, agent }) as ActorSubclass<_SERVICE>; + const canisterId = await Actor.createCanister({ agent: effectiveAgent }); + await Actor.install({ module }, { canisterId, agent: effectiveAgent }); + return Actor.createActor(idl, { canisterId, agent: effectiveAgent }) as ActorSubclass<_SERVICE>; }; diff --git a/e2e/node/integration/actor.test.ts b/e2e/node/integration/actor.test.ts new file mode 100644 index 000000000..cd3c65c37 --- /dev/null +++ b/e2e/node/integration/actor.test.ts @@ -0,0 +1,18 @@ +import { HttpAgent } from '@dfinity/agent'; +import { HttpAgent as HttpAgentv1 } from 'agent1'; +import { createActor } from '../canisters/counter'; +import { vi, test } from 'vitest'; + +vi.useRealTimers(); +test("Legacy Agent interface should be accepted by Actor's createActor", async () => { + const actor = await createActor( + {}, + new HttpAgentv1({ + host: `http://127.0.0.1:${process.env.REPLICA_PORT ?? 4943}`, + }) as unknown as HttpAgent, + ); + + await actor.write(8n); //? + await actor.read(); //? +}, 15_000); +// TODO: tests for rejected, unknown time out diff --git a/e2e/node/package.json b/e2e/node/package.json index 7fbee2052..755ed3076 100644 --- a/e2e/node/package.json +++ b/e2e/node/package.json @@ -32,6 +32,7 @@ "@types/text-encoding": "^0.0.36", "@typescript-eslint/eslint-plugin": "^5.30.5", "@typescript-eslint/parser": "^5.30.5", + "agent1": "npm:@dfinity/agent@^1.4.0", "esbuild": "^0.15.16", "eslint": "^8.19.0", "eslint-plugin-jsdoc": "^39.3.3", diff --git a/package-lock.json b/package-lock.json index 74c3df48d..c956aa8f9 100644 --- a/package-lock.json +++ b/package-lock.json @@ -81,6 +81,7 @@ "@types/text-encoding": "^0.0.36", "@typescript-eslint/eslint-plugin": "^5.30.5", "@typescript-eslint/parser": "^5.30.5", + "agent1": "npm:@dfinity/agent@^1.4.0", "esbuild": "^0.15.16", "eslint": "^8.19.0", "eslint-plugin-jsdoc": "^39.3.3", @@ -18790,7 +18791,6 @@ "@types/jest": "^29.5.5", "@typescript-eslint/eslint-plugin": "^5.30.5", "@typescript-eslint/parser": "^5.30.5", - "agent1": "npm:@dfinity/agent@^1.4.0", "esbuild": "^0.15.16", "eslint": "^8.19.0", "isomorphic-fetch": "^3.0.0", diff --git a/packages/agent/package.json b/packages/agent/package.json index 851c91fb3..83aac100c 100644 --- a/packages/agent/package.json +++ b/packages/agent/package.json @@ -64,7 +64,6 @@ "@types/jest": "^29.5.5", "@typescript-eslint/eslint-plugin": "^5.30.5", "@typescript-eslint/parser": "^5.30.5", - "agent1": "npm:@dfinity/agent@^1.4.0", "esbuild": "^0.15.16", "eslint": "^8.19.0", "isomorphic-fetch": "^3.0.0", diff --git a/packages/agent/src/actor.compatibility.test.ts b/packages/agent/src/actor.compatibility.test.ts deleted file mode 100644 index 072b77229..000000000 --- a/packages/agent/src/actor.compatibility.test.ts +++ /dev/null @@ -1,34 +0,0 @@ -import { Actor } from './actor'; -import { HttpAgent } from './agent/http'; -import { HttpAgent as HttpAgentv1 } from 'agent1'; - -jest.useRealTimers(); -test.only("Legacy Agent interface should be accepted by Actor's createActor", async () => { - const idlFactory = ({ IDL }) => { - return IDL.Service({ - greet: IDL.Func([IDL.Text], [IDL.Text], []), - inc: IDL.Func([], [], []), - inc_read: IDL.Func([], [IDL.Nat], []), - queryGreet: IDL.Func([IDL.Text], [IDL.Text], ['query']), - read: IDL.Func([], [IDL.Nat], ['query']), - write: IDL.Func([IDL.Nat], [], []), - }); - }; - - const actor = Actor.createActor(idlFactory, { - canisterId: 'tnnnb-2yaaa-aaaab-qaiiq-cai', - agent: new HttpAgent({ host: 'https://icp-api.io' }) as unknown as HttpAgent, - }); - - // await actor.write(8); //? - const actor1 = Actor.createActor(idlFactory, { - canisterId: 'tnnnb-2yaaa-aaaab-qaiiq-cai', - agent: new HttpAgentv1({ host: 'https://icp-api.io' }) as unknown as HttpAgent, - }); - - await actor1.write(8); //? - await actor1.read(); //? -}); -// TODO: tests for rejected, unknown time out - -jest.setTimeout(8000); From 9e7d9a2b624d2efa530529fa535ee253c60ff660 Mon Sep 17 00:00:00 2001 From: Kyle Peacock Date: Fri, 12 Jul 2024 11:38:31 -0700 Subject: [PATCH 5/5] changelog --- docs/CHANGELOG.md | 4 ++++ e2e/node/integration/actor.test.ts | 8 ++++++-- 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/docs/CHANGELOG.md b/docs/CHANGELOG.md index 96e145aa1..55bbffbf6 100644 --- a/docs/CHANGELOG.md +++ b/docs/CHANGELOG.md @@ -6,6 +6,10 @@ - ci: removing headless browser tests pending a rewrite +### Added + +- test: adding test for backwards compatibility with actor for v1 agents + ## [1.4.0] - 2024-06-17 ### Added diff --git a/e2e/node/integration/actor.test.ts b/e2e/node/integration/actor.test.ts index cd3c65c37..49b48cf4c 100644 --- a/e2e/node/integration/actor.test.ts +++ b/e2e/node/integration/actor.test.ts @@ -1,10 +1,11 @@ import { HttpAgent } from '@dfinity/agent'; import { HttpAgent as HttpAgentv1 } from 'agent1'; import { createActor } from '../canisters/counter'; -import { vi, test } from 'vitest'; +import { vi, test, expect } from 'vitest'; vi.useRealTimers(); test("Legacy Agent interface should be accepted by Actor's createActor", async () => { + // Use the v1.4.0 agent to create an actor const actor = await createActor( {}, new HttpAgentv1({ @@ -12,7 +13,10 @@ test("Legacy Agent interface should be accepted by Actor's createActor", async ( }) as unknown as HttpAgent, ); + // Verify that update calls work await actor.write(8n); //? - await actor.read(); //? + // Verify that query calls work + const count = await actor.read(); //? + expect(count).toBe(8n); }, 15_000); // TODO: tests for rejected, unknown time out