Skip to content

Commit

Permalink
Merge pull request maidsafe#2255 from b-zee/test-js-wasm
Browse files Browse the repository at this point in the history
JS test with Mocha (DRAFT)
  • Loading branch information
b-zee authored Oct 18, 2024
2 parents 0ccde60 + 68060f9 commit f5b6b24
Show file tree
Hide file tree
Showing 8 changed files with 1,683 additions and 51 deletions.
40 changes: 35 additions & 5 deletions autonomi/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -35,9 +35,9 @@ cargo run --bin=safenode-manager --features=local -- local run --build --clean -
4. Then run the tests with the `local` feature and pass the EVM params again:

```sh
$ EVM_NETWORK=local cargo test --package=autonomi --features=local
EVM_NETWORK=local cargo test --package=autonomi --features=local
# Or with logs
$ RUST_LOG=autonomi EVM_NETWORK=local cargo test --package=autonomi --features=local -- --nocapture
RUST_LOG=autonomi EVM_NETWORK=local cargo test --package=autonomi --features=local -- --nocapture
```

### Using a live testnet or mainnet
Expand All @@ -55,9 +55,9 @@ cargo run --bin=safenode-manager --features=local -- local run --build --clean -
payment tokens on the network (in this case Arbitrum One):

```sh
$ EVM_NETWORK=arbitrum-one EVM_PRIVATE_KEY=<PRIVATE_KEY> cargo test --package=autonomi --features=local
EVM_NETWORK=arbitrum-one EVM_PRIVATE_KEY=<PRIVATE_KEY> cargo test --package=autonomi --features=local
# Or with logs
$ RUST_LOG=autonomi EVM_NETWORK=arbitrum-one EVM_PRIVATE_KEY=<PRIVATE_KEY> cargo test --package=autonomi --features=local -- --nocapture
RUST_LOG=autonomi EVM_NETWORK=arbitrum-one EVM_PRIVATE_KEY=<PRIVATE_KEY> cargo test --package=autonomi --features=local -- --nocapture
```

### WebAssembly
Expand All @@ -70,10 +70,40 @@ To run a WASM test
- Optionally specify the specific test, e.g. `-- put` to run `put()` in `wasm.rs` only.

Example:
````sh
```sh
SAFE_PEERS=/ip4/<ip>/tcp/<port>/ws/p2p/<peer ID> wasm-pack test --release --firefox autonomi --features=data,files --test wasm -- put
```

#### Test from JS in the browser

`wasm-pack test` does not execute JavaScript, but runs mostly WebAssembly. Again make sure the environment variables are set and build the JS package:

```sh
wasm-pack build --dev --target=web autonomi --features=vault
```

Then cd into `autonomi/tests-js`, and use `npm` to install and serve the test html file.
```
cd autonomi/tests-js
npm install
npm run serve
```

Then go to `http://127.0.0.1:8080/tests-js` in the browser. Here, enter a `ws` multiaddr of a local node and press 'run'.


#### `index.html`

There is also a simple `index.html` file that runs some JavaScript.

Build the package (again with the env variables) and run a webserver, e.g. with Python:
```sh
wasm-pack build --dev --target=web autonomi
python -m http.server --directory=autonomi 8000
```

Then visit `http://127.0.0.1:8000/` in your (modern) browser.


## Faucet (local)

Expand Down
91 changes: 47 additions & 44 deletions autonomi/index.html
Original file line number Diff line number Diff line change
@@ -1,72 +1,75 @@
<html>

<head>
<meta content="text/html;charset=utf-8" http-equiv="Content-Type"/>
<meta content="text/html;charset=utf-8" http-equiv="Content-Type" />
</head>

<body>
<!-- credits: https://rustwasm.github.io/docs/wasm-bindgen/examples/without-a-bundler.html -->
<script type="module">
<!-- credits: https://rustwasm.github.io/docs/wasm-bindgen/examples/without-a-bundler.html -->
<script type="module">
import init, * as aut from './pkg/autonomi.js';

async function run() {
document.getElementById("btn-run").disabled = true;
const peer_addr = document.getElementById('peer_id').value;
document.getElementById("btn-run").disabled = true;
const peer_addr = document.getElementById('peer_id').value;

await init();
await init();

aut.logInit("sn_networking=warn,autonomi=trace");
aut.logInit("sn_networking=warn,autonomi=trace");

updateProgress("Connecting...");
const client = await new aut.Client([peer_addr]);
updateProgress("Connected");
updateProgress("Connecting...");
const client = await aut.Client.connect([peer_addr]);
updateProgress("Connected");

updateProgress("Getting wallet...");
const wallet = aut.getFundedWallet();
updateProgress("Wallet retrieved");
updateProgress("Getting wallet...");
const wallet = aut.getFundedWallet();
updateProgress("Wallet retrieved");

// Random 32 byte data
const data = [...Array(16)].map(() => Math.floor(Math.random() * 9));
updateProgress("Our data: " + data);
// Random 32 byte data
const data = [...Array(16)].map(() => Math.floor(Math.random() * 9));
updateProgress("Our data: " + data);

updateProgress("Calculating cost...");
let result = await client.dataCost(data, wallet);
updateProgress("Calculated cost: " + result.toString());
updateProgress("Calculating cost...");
let result = await client.dataCost(data, wallet);
updateProgress("Calculated cost: " + result.toString());

updateProgress("Putting data...");
const dataAddr = await client.dataPut(data, wallet);
updateProgress("Put done: " + dataAddr.toString());
updateProgress("Putting data...");
const dataAddr = await client.dataPut(data, wallet);
updateProgress("Put done: " + dataAddr.toString());

let archive = new Map([["README.md", dataAddr]]);
updateProgress("Putting data as archive... " + archive);
let archiveAddr = await client.archivePut(archive, wallet);
updateProgress("Archive put done: " + archiveAddr);
let archive = new Map([["README.md", dataAddr]]);
updateProgress("Putting data as archive... " + archive);
let archiveAddr = await client.archivePut(archive, wallet);
updateProgress("Archive put done: " + archiveAddr);

updateProgress("Fetching archive...");
let archiveFetched = await client.archiveGet(archiveAddr);
updateProgress("Archive fetched: " + archiveFetched);
updateProgress("Fetching archive...");
let archiveFetched = await client.archiveGet(archiveAddr);
updateProgress("Archive fetched: " + archiveFetched);

for (const [path, addr] of archiveFetched) {
updateProgress("Fetching data: " + path + ", addr: " + addr);
const dataFetched = await client.dataGet(addr);
updateProgress("Data fetched: " + dataFetched);
}
for (const [path, addr] of archiveFetched) {
updateProgress("Fetching data: " + path + ", addr: " + addr);
const dataFetched = await client.dataGet(addr);
updateProgress("Data fetched: " + dataFetched);
}

// Generate random secret key
const secretKey = [...Array(32)].map(() => Math.floor(Math.random() * 9));
await client.writeBytesToVault(data, wallet, secretKey);
// Generate random secret key
const secretKey = [...Array(32)].map(() => Math.floor(Math.random() * 9));
await client.writeBytesToVault(data, wallet, secretKey);

const vault = await client.fetchAndDecryptVault(secretKey);
updateProgress("Vault: " + vault);
const vault = await client.fetchAndDecryptVault(secretKey);
updateProgress("Vault: " + vault);
}

function updateProgress(message) {
document.getElementById('progress').textContent = message;
document.getElementById('progress').textContent = message;
}

document.getElementById("btn-run").addEventListener("click", run, false);
</script>
</script>

<label for="peer_id">Peer MultiAddr: <input type="text" id="peer_id"/></label>
<button id="btn-run">Run</button>
<span id="progress"></span>
<label for="peer_id">Peer MultiAddr: <input type="text" id="peer_id" /></label>
<button id="btn-run">Run</button>
<span id="progress"></span>
</body>

</html>
10 changes: 8 additions & 2 deletions autonomi/src/client/wasm.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ impl AttoTokens {

#[wasm_bindgen(js_class = Client)]
impl JsClient {
#[wasm_bindgen(constructor)]
#[wasm_bindgen]
pub async fn connect(peers: Vec<String>) -> Result<JsClient, JsError> {
let peers = peers
.into_iter()
Expand Down Expand Up @@ -136,7 +136,7 @@ mod vault {
pub async fn put_user_data_to_vault(
&self,
user_data: JsUserData,
wallet: &mut JsWallet,
wallet: &JsWallet,
secret_key: Vec<u8>,
) -> Result<(), JsError> {
let secret_key: [u8; 32] = secret_key[..].try_into()?;
Expand All @@ -151,6 +151,12 @@ mod vault {
}
}

#[wasm_bindgen(js_name = genSecretKey)]
pub fn gen_secret_key() -> Vec<u8> {
let secret_key = bls::SecretKey::random();
secret_key.to_bytes().to_vec()
}

#[wasm_bindgen(js_name = Wallet)]
pub struct JsWallet(evmlib::wallet::Wallet);

Expand Down
1 change: 1 addition & 0 deletions autonomi/tests-js/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
node_modules
36 changes: 36 additions & 0 deletions autonomi/tests-js/index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
<!DOCTYPE html>
<html lang="en">

<head>
<meta charset="utf-8" />
<title>Mocha Tests</title>
<link rel="shortcut icon" href="data:image/x-icon;," type="image/x-icon">
<link href="./node_modules/mocha/mocha.css" rel="stylesheet" />
</head>

<body>

<div id="mocha"></div>

<script type="module" class="mocha-init">
import './node_modules/mocha/mocha.js';
mocha.setup('bdd');
mocha.checkLeaks();
</script>
<script type="module" src="index.js"></script>
<script type="module" class="mocha-exec">
document.getElementById("btn-run").addEventListener("click", run, false);

function run() {
document.getElementById("btn-run").disabled = true;
window.peer_addr = document.getElementById('peer_addr').value;
mocha.run();
}
</script>

<label for="peer_addr">Peer multiaddr: <input type="text" id="peer_addr" style="width: 75%;"
placeholder="/ip4/127.0.0.1/tcp/1234/ws/p2p/12D3Koo..." /></label>
<button id="btn-run">Run</button>
</body>

</html>
64 changes: 64 additions & 0 deletions autonomi/tests-js/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
import init, * as atnm from '../pkg/autonomi.js';
import { assert } from './node_modules/chai/chai.js';

function randomData(len) {
const array = new Uint8Array(len);
window.crypto.getRandomValues(array);
return array;
}

describe('autonomi', function () {
this.timeout(180 * 1000);

let client;
let wallet;
before(async () => {
await init();
atnm.logInit("sn_networking=warn,autonomi=trace");
client = await atnm.Client.connect([window.peer_addr]);
wallet = atnm.getFundedWallet();
});

it('calculates cost', async () => {
const data = randomData(32);
const cost = await client.dataCost(data);

assert.typeOf(Number.parseFloat(cost.toString()), 'number');
});

it('puts data (32 bytes)', async () => {
const data = randomData(32);
const addr = await client.dataPut(data, wallet);

assert.typeOf(addr, 'string');
});

it('puts data and gets it (32 bytes)', async () => {
const data = randomData(32);
const addr = await client.dataPut(data, wallet);
const fetchedData = await client.dataGet(addr);

assert.deepEqual(Array.from(data), Array.from(fetchedData));
});

it('puts data, creates archive and retrieves it', async () => {
const data = randomData(32);
const addr = await client.dataPut(data, wallet);
const archive = new Map([["foo", addr]]);
const archiveAddr = await client.archivePut(archive, wallet);

const archiveFetched = await client.archiveGet(archiveAddr);

assert.deepEqual(archive, archiveFetched);
});

it('writes bytes to vault and fetches it', async () => {
const data = randomData(32);
const secretKey = atnm.genSecretKey();

await client.writeBytesToVault(data, wallet, secretKey);
const dataFetched = await client.fetchAndDecryptVault(secretKey);

assert.deepEqual(data, dataFetched);
});
});
Loading

0 comments on commit f5b6b24

Please sign in to comment.