diff --git a/README.md b/README.md index 74ad8896..72bf20eb 100644 --- a/README.md +++ b/README.md @@ -22,17 +22,17 @@ npm install --save-exact @holochain/conductor-api This version of `holochain-conductor-api` is currently working with `holochain/holochain` at commit: -[2dfe85db10a5d9ba3ee25ff33f4bedb1a28f875f](https://github.com/holochain/holochain/commit/2dfe85db10a5d9ba3ee25ff33f4bedb1a28f875f) (Nov 16, 2020) +[b337f81080d35821344d7565778d8e70e2947a92](https://github.com/holochain/holochain/commit/b337f81080d35821344d7565778d8e70e2947a92) (Dec 4, 2020) If updating this code, please make changes to the git `rev/sha` in 3 places: 1. Here in the README above ^^ 2. This line in `install-holochain.sh` ```bash -REV=2dfe85db10a5d9ba3ee25ff33f4bedb1a28f875f +REV=b337f81080d35821344d7565778d8e70e2947a92 ``` 3. and this line in `test/e2e/fixtures/zomes/foo/Cargo.toml` ``` -hdk3 = { git = "https://github.com/holochain/holochain", rev = "2dfe85db10a5d9ba3ee25ff33f4bedb1a28f875f", package = "hdk3" } +hdk3 = { git = "https://github.com/holochain/holochain", rev = "b337f81080d35821344d7565778d8e70e2947a92", package = "hdk3" } ``` Notice the match between the SHA in both cases. These should always match. diff --git a/install-holochain.sh b/install-holochain.sh index 4832d84f..0b4dd5c1 100755 --- a/install-holochain.sh +++ b/install-holochain.sh @@ -1,6 +1,6 @@ #!/bin/bash -REV=2dfe85db10a5d9ba3ee25ff33f4bedb1a28f875f +REV=b337f81080d35821344d7565778d8e70e2947a92 cargo install --force holochain \ --git https://github.com/holochain/holochain.git \ diff --git a/package-lock.json b/package-lock.json index 109e2d82..0d59499b 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,6 +1,6 @@ { "name": "@holochain/conductor-api", - "version": "0.0.1-dev.13", + "version": "0.0.1-dev.14", "lockfileVersion": 1, "requires": true, "dependencies": { diff --git a/package.json b/package.json index ef960e00..bfe3212c 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@holochain/conductor-api", - "version": "0.0.1-dev.13", + "version": "0.0.1-dev.14", "description": "Encode/decode messages to/from the Holochain Conductor API over Websocket", "repository": { "type": "git", diff --git a/src/api/admin.ts b/src/api/admin.ts index 906a65a6..2f8ede44 100644 --- a/src/api/admin.ts +++ b/src/api/admin.ts @@ -32,6 +32,19 @@ export type ListCellIdsResponse = Array export type ListActiveAppsRequest = void export type ListActiveAppsResponse = Array +// this type is meant to be opaque +export type AgentInfoSigned = any +/*{ + agent: any, + signature: any, + agent_info: any, +}*/ + +export type RequestAgentInfoRequest = { cell_id: CellId|null } +export type RequestAgentInfoResponse = Array +export type AddAgentInfoRequest = { agent_infos: Array } +export type AddAgentInfoResponse = any + export interface AdminApi { activateApp: Requester attachAppInterface: Requester @@ -42,6 +55,8 @@ export interface AdminApi { listDnas: Requester listCellIds: Requester listActiveApps: Requester + requestAgentInfo: Requester + addAgentInfo: Requester } diff --git a/src/websocket/admin.ts b/src/websocket/admin.ts index 6e333212..bd0675e5 100644 --- a/src/websocket/admin.ts +++ b/src/websocket/admin.ts @@ -59,6 +59,10 @@ export class AdminWebsocket implements Api.AdminApi { = this._requester('list_cell_ids') listActiveApps: Requester = this._requester('list_active_apps') + requestAgentInfo: Requester + = this._requester('request_agent_info') + addAgentInfo: Requester + = this._requester('add_agent_info') } diff --git a/test/e2e/fixture/.gitignore b/test/e2e/fixture/.gitignore index 3f7542fc..2228cc53 100644 --- a/test/e2e/fixture/.gitignore +++ b/test/e2e/fixture/.gitignore @@ -1,3 +1,4 @@ *.dna.gz test-config.yml +test-config-1.yml zomes/foo/target diff --git a/test/e2e/fixture/zomes/foo/Cargo.toml b/test/e2e/fixture/zomes/foo/Cargo.toml index 3f35e8e9..d132b1a0 100644 --- a/test/e2e/fixture/zomes/foo/Cargo.toml +++ b/test/e2e/fixture/zomes/foo/Cargo.toml @@ -10,4 +10,4 @@ crate-type = [ "cdylib", "rlib" ] [dependencies] serde = "=1.0.104" -hdk3 = { git = "https://github.com/holochain/holochain", rev = "2dfe85db10a5d9ba3ee25ff33f4bedb1a28f875f", package = "hdk3" } +hdk3 = { git = "https://github.com/holochain/holochain", rev = "b337f81080d35821344d7565778d8e70e2947a92", package = "hdk3" } diff --git a/test/e2e/index.ts b/test/e2e/index.ts index dd39e56e..333c9840 100644 --- a/test/e2e/index.ts +++ b/test/e2e/index.ts @@ -1,13 +1,13 @@ - const test = require('tape') import { AdminWebsocket } from '../../src/websocket/admin' import { AppWebsocket } from '../../src/websocket/app' -import { installAppAndDna, withConductor } from './util' +import { installAppAndDna, withConductor, launch, CONFIG_PATH, CONFIG_PATH_1, FIXTURE_PATH } from './util' import { AgentPubKey, fakeAgentPubKey } from '../../src/api/types' import { AppSignal } from '../../src/api/app' const ADMIN_PORT = 33001 +const ADMIN_PORT_1 = 33002 const TEST_ZOME_NAME = 'foo' @@ -136,3 +136,74 @@ test('error is catchable when holochain socket is unavailable', async (t) => { ) } }) + + +test('can inject agents', async (t) => { + const conductor1 = await launch(ADMIN_PORT, CONFIG_PATH) + const conductor2 = await launch(ADMIN_PORT_1, CONFIG_PATH_1) + try { + const installed_app_id = 'app' + const admin1 = await AdminWebsocket.connect(`http://localhost:${ADMIN_PORT}`) + const admin2 = await AdminWebsocket.connect(`http://localhost:${ADMIN_PORT_1}`) + const agent_key_1 = await admin1.generateAgentPubKey() + t.ok(agent_key_1) + const agent_key_2 = await admin2.generateAgentPubKey() + t.ok(agent_key_2) + const nick = 'thedna' + let result = await admin1.installApp({ + installed_app_id, agent_key: agent_key_1, dnas: [ + { + path: `${FIXTURE_PATH}/test.dna.gz`, + nick, + } + ] + }) + t.ok(result) + const app1_cell = result.cell_data[0][0] + await admin1.activateApp({ installed_app_id }) + // after activating an app requestAgentInfo should return the agentid + // requesting info with null cell_id should return all agents known about. + // otherwise it's just agents know about for that cell + const conductor1_agentInfo = await admin1.requestAgentInfo({cell_id: null}); + t.equal(conductor1_agentInfo.length, 1) + + // agent2 with no activated apps there are no agents + var conductor2_agentInfo = await admin2.requestAgentInfo({cell_id: null}); + t.equal(conductor2_agentInfo.length, 0) + + // but, after explicitly injecting an agent, we should see it + await admin2.addAgentInfo({ agent_infos: conductor1_agentInfo }); + conductor2_agentInfo = await admin2.requestAgentInfo({cell_id: null}); + t.equal(conductor2_agentInfo.length, 1) + t.deepEqual(conductor1_agentInfo,conductor2_agentInfo) + + // now install the app and activate it on agent 2. + result = await admin2.installApp({ + installed_app_id, agent_key: agent_key_2, dnas: [ + { + path: `${FIXTURE_PATH}/test.dna.gz`, + nick, + } + ] + }) + t.ok(result) + const app2_cell = result.cell_data[0][0] + await admin2.activateApp({ installed_app_id }) + // observe 2 agent infos + conductor2_agentInfo = await admin2.requestAgentInfo({cell_id: null}); + t.equal(conductor2_agentInfo.length, 2) + + // now confirm that we can ask for just one cell + await admin1.addAgentInfo({ agent_infos: conductor2_agentInfo }); + const app1_agentInfo = await admin1.requestAgentInfo({cell_id: app1_cell}); + t.equal(app1_agentInfo.length, 1) + const app2_agentInfo = await admin2.requestAgentInfo({cell_id: app2_cell}); + t.equal(app2_agentInfo.length, 1) + + } + finally { + conductor1.kill() + conductor2.kill() + } + +}) diff --git a/test/e2e/util.ts b/test/e2e/util.ts index a629a76f..fe229b33 100644 --- a/test/e2e/util.ts +++ b/test/e2e/util.ts @@ -5,9 +5,11 @@ import { InstalledAppId, CellId, CellNick } from '../../src/api/types' import { AppWebsocket } from '../../src/websocket/app' import { AdminWebsocket } from '../../src/websocket/admin' import yaml from 'js-yaml' -const CONFIG_PATH = './test/e2e/fixture/test-config.yml' +export const FIXTURE_PATH = './test/e2e/fixture' +export const CONFIG_PATH = `${FIXTURE_PATH}/test-config.yml` +export const CONFIG_PATH_1 = `${FIXTURE_PATH}/test-config-1.yml` -const writeConfig = (port) => { +const writeConfig = (port, configPath) => { const dir = fs.mkdtempSync(`${os.tmpdir()}/holochain-test-`) let yamlStr = yaml.safeDump({ @@ -22,7 +24,7 @@ const writeConfig = (port) => { } }] }); - fs.writeFileSync(CONFIG_PATH, yamlStr, 'utf8'); + fs.writeFileSync(configPath, yamlStr, 'utf8'); console.info(`using LMDB environment path: ${dir}`) } @@ -49,9 +51,9 @@ const awaitInterfaceReady = (handle): Promise => new Promise((fulfill, rej const HOLOCHAIN_BIN = 'holochain' -const launch = async (port) => { - await writeConfig(port) - const handle = spawn(HOLOCHAIN_BIN, ['-c', CONFIG_PATH]) +export const launch = async (port, configPath) => { + await writeConfig(port, configPath) + const handle = spawn(HOLOCHAIN_BIN, ['-c', configPath]) handle.stdout.on('data', data => { console.info('conductor: ', data.toString('utf8')) }) @@ -63,7 +65,7 @@ const launch = async (port) => { } export const withConductor = (port, f) => async t => { - const handle = await launch(port) + const handle = await launch(port, CONFIG_PATH) try { await f(t) } catch (e) { @@ -89,7 +91,7 @@ export const installAppAndDna = async ( agent_key: agent, dnas: [ { - path: 'test/e2e/fixture/test.dna.gz', + path: `${FIXTURE_PATH}/test.dna.gz`, nick, }, ],