Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

JS test with Mocha (DRAFT) #2255

Merged
merged 5 commits into from
Oct 18, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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]]);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe we should be using the new API for Archives here:

let archive = new Archive
archive.add_new_file("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
Loading