Skip to content

Commit

Permalink
Merge pull request #39 from holochain/2020-12-01-agent-inject
Browse files Browse the repository at this point in the history
Update api to include agent inject feature
  • Loading branch information
zippy authored Dec 5, 2020
2 parents ac08e2c + 49a4371 commit 1d52442
Show file tree
Hide file tree
Showing 10 changed files with 110 additions and 17 deletions.
6 changes: 3 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down
2 changes: 1 addition & 1 deletion install-holochain.sh
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
#!/bin/bash

REV=2dfe85db10a5d9ba3ee25ff33f4bedb1a28f875f
REV=b337f81080d35821344d7565778d8e70e2947a92

cargo install --force holochain \
--git https://github.com/holochain/holochain.git \
Expand Down
2 changes: 1 addition & 1 deletion package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -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",
Expand Down
15 changes: 15 additions & 0 deletions src/api/admin.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,19 @@ export type ListCellIdsResponse = Array<CellId>
export type ListActiveAppsRequest = void
export type ListActiveAppsResponse = Array<InstalledAppId>

// 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<AgentInfoSigned>
export type AddAgentInfoRequest = { agent_infos: Array<AgentInfoSigned> }
export type AddAgentInfoResponse = any

export interface AdminApi {
activateApp: Requester<ActivateAppRequest, ActivateAppResponse>
attachAppInterface: Requester<AttachAppInterfaceRequest, AttachAppInterfaceResponse>
Expand All @@ -42,6 +55,8 @@ export interface AdminApi {
listDnas: Requester<ListDnasRequest, ListDnasResponse>
listCellIds: Requester<ListCellIdsRequest, ListCellIdsResponse>
listActiveApps: Requester<ListActiveAppsRequest, ListActiveAppsResponse>
requestAgentInfo: Requester<RequestAgentInfoRequest, RequestAgentInfoResponse>
addAgentInfo: Requester<AddAgentInfoRequest, AddAgentInfoResponse>
}


Expand Down
4 changes: 4 additions & 0 deletions src/websocket/admin.ts
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,10 @@ export class AdminWebsocket implements Api.AdminApi {
= this._requester('list_cell_ids')
listActiveApps: Requester<Api.ListActiveAppsRequest, Api.ListActiveAppsResponse>
= this._requester('list_active_apps')
requestAgentInfo: Requester<Api.RequestAgentInfoRequest, Api.RequestAgentInfoResponse>
= this._requester('request_agent_info')
addAgentInfo: Requester<Api.AddAgentInfoRequest, Api.AddAgentInfoResponse>
= this._requester('add_agent_info')
}


Expand Down
1 change: 1 addition & 0 deletions test/e2e/fixture/.gitignore
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
*.dna.gz
test-config.yml
test-config-1.yml
zomes/foo/target
2 changes: 1 addition & 1 deletion test/e2e/fixture/zomes/foo/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -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" }
75 changes: 73 additions & 2 deletions test/e2e/index.ts
Original file line number Diff line number Diff line change
@@ -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'

Expand Down Expand Up @@ -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()
}

})
18 changes: 10 additions & 8 deletions test/e2e/util.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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({
Expand All @@ -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}`)
}

Expand All @@ -49,9 +51,9 @@ const awaitInterfaceReady = (handle): Promise<null> => 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'))
})
Expand All @@ -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) {
Expand All @@ -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,
},
],
Expand Down

0 comments on commit 1d52442

Please sign in to comment.