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

Add mithril-client-wasm tests in multi platform test #1462

Merged
merged 4 commits into from
Jan 31, 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
20 changes: 20 additions & 0 deletions .github/workflows/scripts/parse-wasm-headless-tests-results.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
FILENAME=$1

if [ ! -e "$FILENAME" ]; then
echo "Error: File '$FILENAME' not found."
exit 1
fi

echo "Parse headless test results from file: '$FILENAME'"
if grep -q 'title="FAILED"' "$FILENAME"; then
FAILED_INFO=$(grep -oE '<div id="[^"]+" title="FAILED">([^<]+)' "$FILENAME" | awk 'NR==1 {print substr($0, index($0,$4))}')
echo "$FAILED_INFO"
exit 1
elif grep -q 'title="OK"' "$FILENAME"; then
grep -oE '<div id="[^"]+" title="OK">([^<]+)' "$FILENAME" | awk '{print substr($0, index($0,$4))}'
echo "Success: all tests passed."
else
cat "$FILENAME"
echo "No test results found. Check '$FILENAME' output."
exit 1
fi
44 changes: 44 additions & 0 deletions .github/workflows/scripts/run-wasm-tests-browser-headless.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
import logging
import argparse
import sys
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC

def run_headless_test():
parser = argparse.ArgumentParser(description='Run headless browser test.')
parser.add_argument('browser_type', choices=['chrome', 'firefox'], help='Browser type (chrome or firefox)')
args = parser.parse_args()

if args.browser_type.lower() == 'chrome':
options = webdriver.ChromeOptions()
options.add_argument("--headless=new")
driver = webdriver.Chrome(options=options)
elif args.browser_type.lower() == 'firefox':
options = webdriver.FirefoxOptions()
options.add_argument("--headless")
driver = webdriver.Firefox(options=options)
else:
logging.error("Invalid browser type. Supported types are 'chrome' and 'firefox'.")
return

try:
driver.get('http://localhost:8080/')

# Adjust the timeout to 3 minutes
wait = WebDriverWait(driver, 180)

# Wait until the div with id "tests_finished" is displayed
tests_finished_element = wait.until(EC.presence_of_element_located((By.ID, "tests_finished")))

html = driver.page_source
result_file = f"{args.browser_type.lower()}-results.html"
with open(result_file, "w", encoding="utf-8") as file:
file.write(html)

finally:
driver.quit()

if __name__ == "__main__":
run_headless_test()
74 changes: 74 additions & 0 deletions .github/workflows/test-client.yml
Original file line number Diff line number Diff line change
Expand Up @@ -159,3 +159,77 @@ jobs:
- name: Mithril Stake Distribution / download & restore latest
shell: bash
run: ${{ steps.command.outputs.mithril_client }} ${{ steps.prepare.outputs.debug_level }} mithril-stake-distribution download $MITHRIL_STAKE_DISTRIBUTION_HASH --download-dir /app

test-mithril-client-wasm:
strategy:
fail-fast: false
matrix:
os: [ ubuntu-22.04 ]
runs-on: ${{ matrix.os }}
steps:
- name: Checkout sources
uses: actions/checkout@v3

- name: Download built artifacts
uses: dawidd6/action-download-artifact@v2
with:
name: mithril-distribution-wasm
path: ./mithril-client-wasm
commit: ${{ steps.prepare.outputs.sha }}
branch: ${{ steps.prepare.outputs.branch }}
workflow: ci.yml
workflow_conclusion: success

- name: Unpack 'mithril-client-wasm' package
working-directory: mithril-client-wasm
run: tar -xvzf pkg/*.tgz -C pkg/ && mv pkg/package/* pkg/

- name: Install dependencies
working-directory: mithril-client-wasm
run: make www-test-install

- name: Create .env file
working-directory: mithril-client-wasm
run: |
echo "AGGREGATOR_ENDPOINT=${{ inputs.aggregator_endpoint }}" > ./www-test/.env
echo "GENESIS_VERIFICATION_KEY=$(curl -s ${{ inputs.genesis_verification_key }})" >> ./www-test/.env

- name: Start the server
working-directory: mithril-client-wasm
shell: bash
run: make www-test-serve &

- name: Wait for the server to be ready
shell: bash
run: |
MAX_ATTEMPTS=30
CURRENT_ATTEMPT=0
while true
do
sleep 1
CURRENT_ATTEMPT=$(( ${CURRENT_ATTEMPT} + 1 ))
if nc -z localhost 8080; then
echo "Server is ready."
break
fi
if [ "$CURRENT_ATTEMPT" -ge "$MAX_ATTEMPTS" ]; then
echo "Error: Server not ready after $MAX_ATTEMPTS attempts."
exit 1
fi
done

- name: Install selenium
shell: bash
run: pip install selenium

- name: Run Chrome headless
shell: bash
run: |
python3 ./.github/workflows/scripts/run-wasm-tests-browser-headless.py chrome
./.github/workflows/scripts/parse-wasm-headless-tests-results.sh chrome-results.html

- name: Run Firefox headless
shell: bash
run: |
python3 ./.github/workflows/scripts/run-wasm-tests-browser-headless.py firefox
./.github/workflows/scripts/parse-wasm-headless-tests-results.sh firefox-results.html
6 changes: 6 additions & 0 deletions mithril-client-wasm/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -38,3 +38,9 @@ www-install:

www-serve:
npm --prefix www run start

www-test-install:
npm --prefix www-test install

www-test-serve:
npm --prefix www-test run start
3 changes: 3 additions & 0 deletions mithril-client-wasm/www-test/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
node_modules
dist
.env
29 changes: 29 additions & 0 deletions mithril-client-wasm/www-test/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
# Mithril client wasm: www-test

* A set of tests for the Mithril client WASM library, which is a client for interacting with a Mithril network. The tests cover functionalities provided by the MithrilClient class.

## Download source code

```bash
# Download sources from github
git clone https://github.com/input-output-hk/mithril

# Go to sources directory
cd mithril-client-wasm/
```

* Before running the tests, make sure to install the required dependencies. Use the following command:

```bash
make www-test-install
```

## Running the tests in the browser

```bash
make www-test-serve
```

## Test Results Display

The results of each test are displayed in the DOM dynamically. Open [http://localhost:8080](http://localhost:8080) with your browser. (port 8080 is the default port)
5 changes: 5 additions & 0 deletions mithril-client-wasm/www-test/bootstrap.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
// A dependency graph that contains any wasm must all be imported
// asynchronously. This `bootstrap.js` file does the single async import, so
// that no one else needs to worry about it again.
import("./index.js")
.catch(e => console.error("Error importing `index.js`:", e));
10 changes: 10 additions & 0 deletions mithril-client-wasm/www-test/index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>Hello wasm-pack!</title>
</head>
<body>
<script src="./bootstrap.js"></script>
</body>
</html>
127 changes: 127 additions & 0 deletions mithril-client-wasm/www-test/index.js
dlachaume marked this conversation as resolved.
Show resolved Hide resolved
Original file line number Diff line number Diff line change
@@ -0,0 +1,127 @@
import initMithrilClient, {
MithrilClient,
} from "@mithril-dev/mithril-client-wasm";

async function run_test(test_name, test_number, fun) {
try {
const result = await fun();
display_test_result_in_dom(test_name, test_number, "OK");
return result;
} catch (error) {
handle_error(test_name, test_number, error);
}
}

function display_test_result_in_dom(test_name, test_number, result, error) {
let div = document.createElement("div");
div.id = test_name;
div.title = result;
div.innerHTML = `Result test n°${test_number}: ${result}; function_name: ${test_name}${
error ? `; reason: ${error}` : ""
}`;
document.body.appendChild(div);
}

function handle_error(test_name, test_number, error) {
display_test_result_in_dom(test_name, test_number, "FAILED", error);
console.error(`Error at step ${test_number} (${test_name}):`, error);
add_finished_div();
throw new Error(
`Stopping script due to error at step ${test_number}: ${error}`
);
}

function add_finished_div() {
let div = document.createElement("div");
div.id = "tests_finished";
document.body.appendChild(div);
}

await initMithrilClient();
const aggregator_endpoint = process.env.AGGREGATOR_ENDPOINT;
const genesis_verification_key = process.env.GENESIS_VERIFICATION_KEY;
let client;
let test_number = 1;

await run_test("constructor", test_number, async () => {
client = new MithrilClient(aggregator_endpoint, genesis_verification_key);
});

let snapshots;
test_number++;
await run_test("list_snapshots", test_number, async () => {
snapshots = await client.list_snapshots();
console.log("snapshots", snapshots);
});

test_number++;
await run_test("get_snapshot", test_number, async () => {
const snapshot = await client.get_snapshot(snapshots[0].digest);
console.log("snapshot", snapshot);
});

let mithril_stake_distributions;
test_number++;
await run_test("list_mithril_stake_distributions", test_number, async () => {
mithril_stake_distributions = await client.list_mithril_stake_distributions();
console.log("mithril_stake_distributions", mithril_stake_distributions);
});

let mithril_stake_distribution;
test_number++;
await run_test("get_mithril_stake_distribution", test_number, async () => {
mithril_stake_distribution = await client.get_mithril_stake_distribution(
mithril_stake_distributions[0].hash
);
console.log("mithril_stake_distribution", mithril_stake_distribution);
});

let certificate;
test_number++;
await run_test("get_mithril_certificate", test_number, async () => {
certificate = await client.get_mithril_certificate(
mithril_stake_distribution.certificate_hash
);
console.log("certificate", certificate);
});

let last_certificate_from_chain;
test_number++;
await run_test("verify_certificate_chain", test_number, async () => {
last_certificate_from_chain = await client.verify_certificate_chain(
certificate.hash
);
console.log("last_certificate_from_chain", last_certificate_from_chain);
});

let mithril_stake_distribution_message;
test_number++;
await run_test(
"compute_mithril_stake_distribution_message",
test_number,
async () => {
mithril_stake_distribution_message =
await client.compute_mithril_stake_distribution_message(
mithril_stake_distribution
);
console.log(
"mithril_stake_distribution_message",
mithril_stake_distribution_message
);
}
);

test_number++;
await run_test("verify_message_match_certificate", test_number, async () => {
const valid_stake_distribution_message =
await client.verify_message_match_certificate(
mithril_stake_distribution_message,
last_certificate_from_chain
);
console.log(
"valid_stake_distribution_message",
valid_stake_distribution_message
);
});

add_finished_div();
Loading
Loading