From 2a9782278108cbbda917950209283582f8592abd Mon Sep 17 00:00:00 2001 From: Francois Beutin Date: Mon, 29 Jul 2024 19:27:23 +0200 Subject: [PATCH] Improve documentation and prepare it being included in the plugin guide website --- .github/workflows/README.md | 40 ++++++++++++++ README.md | 2 +- fuzzing/README.md | 19 +++---- tests/README.md | 102 +++++++++++++++++++++++++++--------- 4 files changed, 127 insertions(+), 36 deletions(-) create mode 100644 .github/workflows/README.md diff --git a/.github/workflows/README.md b/.github/workflows/README.md new file mode 100644 index 00000000..2f6941ca --- /dev/null +++ b/.github/workflows/README.md @@ -0,0 +1,40 @@ +# CI with Github workflows + +[//]: # (Comment) +[//]: # (This file when in the plugin-bp repository is included in the Ethereum Plugin SDK Github page, keep that in mind when editing it.) + +The following Github workflows are provided for your application: + +## build_and_functional_tests.yml + +Example of full integration of the build system and Ragger testing tool in the CI. +This workflow will run your functionnal tests and ensure they are passing on each pull-request. + +While this workflow itself is not mandatory, some form of functional tests in CI is mandatory. + +## cflite_cron.yml and cflite_pr.yml + +This CIs will run the fuzzer tool on your plugin. + +This CIs are mandatory. + +## check_sdk.yml + +This CI will ensure that you are using the latest version of the Ethereum Plugin SDK. + +This CI is mandatory. + +## guidelines_enforcer.yml + +This CI will perform checks to ensure that you meet the Ledger application guidelines. + +You can find more information [here](https://github.com/LedgerHQ/ledger-app-workflows/) + +This CI is mandatory. + +## lint-workflow.yml + +This CI will ensure that your application is properly linted. + +While this CI is mandatory, the content of the `.clang-format` file is not and you can tweak it to your liking.
+(Please stay reasonable). diff --git a/README.md b/README.md index 68ce6dd5..6f03ba3c 100644 --- a/README.md +++ b/README.md @@ -17,7 +17,7 @@ The code has been commented, and special "EDIT THIS" comments indicate where developers are expected to adapt the code to their own needs. It is STRONGLY recommended to follow the -[plugin guide](https://developers.ledger.com/docs/dapp/embedded-plugin/code-overview/) +[plugin guide](https://ethereum-plugin-sdk.ledger.com/) in order to better understand the flow and the context for plugins. ## Ethereum SDK diff --git a/fuzzing/README.md b/fuzzing/README.md index 393e38c1..4227ba44 100644 --- a/fuzzing/README.md +++ b/fuzzing/README.md @@ -1,6 +1,7 @@ # Fuzzing on transaction parser -## Fuzzing +[//]: # (Comment) +[//]: # (This file when in the plugin-bp repository is included in the Ethereum Plugin SDK Github page, keep that in mind when editing it.) Fuzzing allows us to test how a program behaves when provided with invalid, unexpected, or random data as input. @@ -17,19 +18,19 @@ If the application crashes, or a [sanitizer](https://github.com/google/sanitizer Before being able to use the fuzzing tests, the environment must be prepared with all submodules. To install them, use the following command in the repository root directory: -```console +```shell git submodule update --init ``` The fuzzer can run from the docker `ledger-app-builder-legacy`. You can download it from the `ghcr.io` docker repository: -```console +```shell sudo docker pull ghcr.io/ledgerhq/ledger-app-builder/ledger-app-builder-legacy:latest ``` You can then enter this development environment by executing the following command from the repository root directory: -```console +```shell sudo docker run --rm -ti --user "$(id -u):$(id -g)" -v "$(realpath .):/app" ghcr.io/ledgerhq/ledger-app-builder/ledger-app-builder-legacy:latest ``` @@ -37,7 +38,7 @@ sudo docker run --rm -ti --user "$(id -u):$(id -g)" -v "$(realpath .):/app" ghcr Once in the container, go into the `fuzzing` folder to compile the fuzzer: -```console +```shell cd fuzzing # cmake initialization @@ -49,7 +50,7 @@ make -C build ### Run -```console +```shell ./build/fuzz ``` @@ -66,7 +67,7 @@ The principle is to build the container, and run it to perform the fuzzing. > **Note**: The container contains a copy of the sources (they are not cloned), which means the `docker build` command must be re-executed after each code modification. -```console +```shell # Prepare directory tree mkdir fuzzing/{corpus,out} # Container generation @@ -75,12 +76,12 @@ docker build -t app-plugin-boilerplate --file .clusterfuzzlite/Dockerfile . ### Compilation -```console +```shell docker run --rm --privileged -e FUZZING_LANGUAGE=c -v "$(realpath .)/fuzzing/out:/out" -ti app-plugin-boilerplate ``` ### Run -```console +```shell docker run --rm --privileged -e FUZZING_ENGINE=libfuzzer -e RUN_FUZZER_MODE=interactive -v "$(realpath .)/fuzzing/corpus:/tmp/fuzz_corpus" -v "$(realpath .)/fuzzing/out:/out" -ti gcr.io/oss-fuzz-base/base-runner run_fuzzer fuzz ``` diff --git a/tests/README.md b/tests/README.md index 20aa1bcb..9f9ca4af 100644 --- a/tests/README.md +++ b/tests/README.md @@ -1,43 +1,65 @@ -# Tests +# Functional tests -This directory contains non-regression tests for the Boilerplate plugin. -The tests craft APDUs, send them to the application, and assert the RAPDUs results and the screen content. -You will need to adapt / enrich the test database with tests relevant to your plugin. +[//]: # (Comment) +[//]: # (This file when in the plugin-bp repository is included in the Ethereum Plugin SDK Github page, keep that in mind when editing it.) + +The tests craft APDUs, send them to the application, and assert the RAPDUs results and the screen content.
+You will need to adapt / enrich the test database with tests relevant to your plugin.
The presence of functional testing of your plugin and an associated CI is mandatory. -The [Speculos](https://github.com/LedgerHQ/speculos) tool is used to emulate the device and its applications. -The [Ragger](https://github.com/LedgerHQ/ragger) test framework (pytest based) is used to manage the Speculos instance and provide useful helper functions (APDU exchanges, screen navigation, etc). -Both framework are developed by Ledger, if you have trouble using them, we invite you to get in touch with us on our [Discord](https://developers.ledger.com/contact/). -For this reason, the usage of the Ragger framework for your tests is greatly recommended. +## Tools used + +- The [Speculos](https://github.com/LedgerHQ/speculos) tool is used to emulate the device and its applications. +- The [Ragger](https://github.com/LedgerHQ/ragger) test framework (pytest based) is used to manage the Speculos instance and provide useful helper functions (APDU exchanges, screen navigation, etc). +- The [Ledger VSCode extension](https://github.com/LedgerHQ/ledger-vscode-extension) can optionnaly be used to compile the application and run the tests. This documentation will describe using the `VSCode extension` and `bash` command lines. +- The [Ledger Ethereum client](https://pypi.org/project/ledger-app-clients.ethereum/) ([Web3](https://pypi.org/project/web3/) based) can be used to craft the smart contract transactions. +This frameworks are developed by Ledger, if you have trouble using them, we invite you to get in touch with us on our [Discord](https://developers.ledger.com/contact/).
+The usage of the Ragger framework for your tests is greatly recommended. -## Binaries +## Compiling the binaries In order to run the tests you need to provide the binaries for both the plugin and the Ethereum application. -Compiling the plugin will produce the binary for the targeted device. They will be used as-is by the test framework. +### Plugin binaries + +Compiling the plugin will produce the binary for the targeted device. They will be used in-place by the test framework. -The binaries of the Ethereum application must be gathered and placed in the directory `tests/.test_dependencies/ethereum/`. -Example of the correct file tree with Ethereum compiled for all targets. -* `tests/.test_dependencies/ethereum/build/nanos2/bin/app.elf` -* `tests/.test_dependencies/ethereum/build/nanox/bin/app.elf` -* `tests/.test_dependencies/ethereum/build/stax/bin/app.elf` -* `tests/.test_dependencies/ethereum/build/flex/bin/app.elf` +### Ethereum binaries -The first method is to use the Ledger VSCode extension to automatically manage dependencies -The second method is to go in the Ethereum project, compile the application, and dispatch the `build/` output directory. -A third method is to re-use the Ethereum build used in the CI, and available as artifact. -For example in the [plugin-boilerplate CI](https://github.com/LedgerHQ/app-plugin-boilerplate/actions/workflows/build_and_functional_tests.yml). +The binaries of the Ethereum application must be gathered and placed in the directory `tests/.test_dependencies/ethereum/` of your plugin. + +Example of the correct file tree with Ethereum compiled for all targets: +```shell +$ tree -a -L 3 .test_dependencies/ +.test_dependencies/ +└── ethereum + ├── .ethereum_application_build_goes_there + └── build + ├── flex + ├── nanos + ├── nanos2 + ├── nanox + └── stax +``` + +Several methods are available: + +- Use the Ledger VSCode extension to automatically manage dependencies. +- Clone the [Ethereum application](https://github.com/LedgerHQ/app-ethereum) in the `.test_dependencies/` directory and compile it. + - You will need to set the compilation flags manually to compile for tests. + - Open the [Ethereum application manifest](https://github.com/LedgerHQ/app-ethereum/blob/develop/ledger_app.toml) and use the flags from `use_test_keys` +- Re-use the Ethereum build produced by a test CI, and available as artifact. Example here with the [plugin-boilerplate CI](https://github.com/LedgerHQ/app-plugin-boilerplate/actions/workflows/build_and_functional_tests.yml). ## Launching the tests -The plugin boilerplate app comes with functional tests +The plugin boilerplate application comes with some template functional tests. ### macOS / Windows -To test your app on macOS or Windows, it is recommended to use [Ledger's VS Code extension](#with-vscode) to quickly setup a working test environment. +To test your application on macOS or Windows, it is recommended to use [Ledger VSCode extension](https://github.com/LedgerHQ/ledger-vscode-extension) to quickly setup a working test environment. You can use the following task (accessible in the **extension sidebar menu**) : @@ -45,20 +67,48 @@ You can use the following task (accessible in the **extension sidebar menu**) : ### Linux (Ubuntu) -On Linux, you can use [Ledger's VS Code extension](#with-vscode) to run the tests. +On Linux, you can use [Ledger VSCode extension](https://github.com/LedgerHQ/ledger-vscode-extension) to run the tests. Alternatively, you can run the test by command lines in your terminal. -First, run this command once to install the tests requirements: +Install the tests requirements (only needed once): ```shell pip install -r tests/requirements.txt ``` -Then you can run the tests. For example, run the following command to run all tests on all devices: +Run the tests. For example, run the following command to run all tests on all devices: ```shell -pytest tests/ +pytest -v tests/ --device all ``` Please refer to the Ragger repository for a documentation on the many parameters and features offered by the framework. + + +## Developing your tests + +The test provided in `test_swap.py` is a simple test of a successful parsing, display, and signature of smart contract `swapExactETHForTokens`. + +When forking the boilerplate to develop your own plugin, you will need to adapt the tests to use your own smart contract. + + +## Using the [Ledger Ethereum client](https://pypi.org/project/ledger-app-clients.ethereum/) + +The [Ledger Ethereum client](https://pypi.org/project/ledger-app-clients.ethereum/) is a Python module that abstracts the APDU crafting and response parsing. It comes from the Ethereum app itself and is what's used to test it in its CI. Conveniently, it also has everything needed for testing plugins. + +### CAL signature mock + +This module supports the official Ethereum appplication test signing keys, so that APDUs that are signed by the [Ledger backend CAL](https://github.com/LedgerHQ/ledger-live/tree/develop/libs/ledgerjs/packages/cryptoassets) in production can be mocked during the tests. + +The Ethereum application must be compiled with the test keys flags. Please refer to the Ethereum application compilation section to know more about this. + +### ABIs + +The Ethereum Ragger client relies on the [Web3](https://pypi.org/project/web3/) python module for transaction crafting and it can leverage a smart contract's ABI (Application Binary Interface) to craft contracts.
+ABIs are obtainable from a website like [Etherscan](https://etherscan.io/) for example. + +### Signature verification + +The Ragger client can also easily verify a transaction's signature by recovering the Ethereum address of the wallet that signed the transaction.
+Testing the UI is crucial but so is testing the signatures we produce.