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

Speculos tests #4

Merged
merged 21 commits into from
Oct 11, 2023
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
34 changes: 34 additions & 0 deletions .github/workflows/build-workflow.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
name: Compilation

on:
push:
branches:
- master
pull_request:
branches:
- master
- develop
workflow_dispatch:

jobs:
nano_release_build:
name: Build release application for NanoS, X and S+
strategy:
matrix:
sdk: ["$NANOS_SDK", "$NANOX_SDK", "$NANOSP_SDK"]
runs-on: ubuntu-latest
container:
image: ghcr.io/ledgerhq/ledger-app-builder/ledger-app-builder-lite:latest

steps:
- name: Clone
uses: actions/checkout@v3

- name: Build Everscale
run: |
make -j BOLOS_SDK=${{ matrix.sdk }}

- name: Build Venom
run: |
make clean
make -j BOLOS_SDK=${{ matrix.sdk }} CHAIN=venom
97 changes: 97 additions & 0 deletions .github/workflows/ci-workflow.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
name: CI

on:
push:
branches:
- master
pull_request:
branches:
- master
- develop
workflow_dispatch:

jobs:
scan-build:
name: Clang Static Analyzer
runs-on: ubuntu-latest
container:
image: ghcr.io/ledgerhq/ledger-app-builder/ledger-app-builder-lite:latest

steps:
- uses: actions/checkout@v3

- name: Build with Clang Static Analyzer
run: |
make clean
scan-build --use-cc=clang -analyze-headers -enable-checker security -enable-checker unix -enable-checker valist -o scan-build --status-bugs make default

- uses: actions/upload-artifact@v3
if: failure()
with:
name: scan-build
path: scan-build


# =====================================================
# SPECULOS TESTS
# =====================================================


building_for_e2e_speculos_tests:
name: Building binaries for E2E Speculos tests
runs-on: ubuntu-latest
container:
image: ghcr.io/ledgerhq/ledger-app-builder/ledger-app-builder-lite:latest

steps:
- uses: actions/checkout@v3

- name: Build testing binaries
run: |
mkdir tests/speculos/elfs
make clean && make -j DEBUG=1 BOLOS_SDK=$NANOS_SDK && mv bin/app.elf tests/speculos/elfs/nanos.elf
make clean && make -j DEBUG=1 BOLOS_SDK=$NANOX_SDK && mv bin/app.elf tests/speculos/elfs/nanox.elf
make clean && make -j DEBUG=1 BOLOS_SDK=$NANOSP_SDK && mv bin/app.elf tests/speculos/elfs/nanosp.elf

- name: Upload app binaries
uses: actions/upload-artifact@v3
with:
name: e2e_speculos_elfs
path: ./tests/speculos/elfs


jobs-e2e-speculos-tests:
name: Speculos tests
strategy:
fail-fast: false
matrix:
model: ["nanos", "nanox", "nanosp"]

needs: [building_for_e2e_speculos_tests]
runs-on: ubuntu-latest

steps:
- name: Clone
uses: actions/checkout@v3

- name: Create tmp folder for artifacts
run: mkdir tests/speculos/elfs

- name: Download app binaries
uses: actions/download-artifact@v3
with:
path: tmp/

- name: Gather elfs
run: cp `find tmp/e2e_speculos_elfs/ -name "*.elf"` tests/speculos/elfs/

- name: Install dependencies
run: |
cd tests/speculos
sudo apt-get update && sudo apt-get install -y qemu-user-static
pip install -r requirements.txt

- name: Run speculos tests
run: |
cd tests/speculos
pytest --model ${{ matrix.model }} --path ./elfs/${{ matrix.model }}.elf --display headless
53 changes: 0 additions & 53 deletions .github/workflows/ci.yml

This file was deleted.

Empty file added tests/python/apps/__init__.py
Empty file.
40 changes: 40 additions & 0 deletions tests/speculos/conftest.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
from pathlib import Path
import pytest

from speculos.client import SpeculosClient

from ledger_client.ledger_cmd import LedgerCommand


SCRIPT_DIR = Path(__file__).absolute().parent
API_URL = "http://127.0.0.1:5000"
#http://10.66.66.8:5000


def pytest_addoption(parser):
# nanos, nanox, nanosp
parser.addoption("--model", action="store", default="nanos")
# qt: default, requires a X server
# headless: nothing is displayed
parser.addoption("--display", action="store", default="qt")

path: str = SCRIPT_DIR.parent.parent / "bin" / "app.elf"
parser.addoption("--path", action="store", default=path)

@pytest.fixture()
def client(pytestconfig):
file_path = pytestconfig.getoption("path")
model = pytestconfig.getoption("model")

args = ['--log-level', 'speculos:DEBUG','--model', model, '--display', pytestconfig.getoption("display")]
with SpeculosClient(app=str(file_path), args=args) as client:
yield client


@pytest.fixture()
def cmd(client, pytestconfig):
yield LedgerCommand(
client=client,
debug=True,
model=pytestconfig.getoption("model"),
)
Empty file.
35 changes: 35 additions & 0 deletions tests/speculos/ledger_client/exception/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
from .device_exception import DeviceException
from .errors import (UnknownDeviceError,
DenyError,
WrongP1P2Error,
WrongDataLengthError,
InsNotSupportedError,
ClaNotSupportedError,
WrongResponseLengthError,
DisplayBip32PathFailError,
DisplayAddressFailError,
DisplayAmountFailError,
WrongTxLengthError,
TxParsingFailError,
TxHashFail,
BadStateError,
SignatureFailError)

__all__ = [
"DeviceException",
"DenyError",
"UnknownDeviceError",
"WrongP1P2Error",
"WrongDataLengthError",
"InsNotSupportedError",
"ClaNotSupportedError",
"WrongResponseLengthError",
"DisplayBip32PathFailError",
"DisplayAddressFailError",
"DisplayAmountFailError",
"WrongTxLengthError",
"TxParsingFailError",
"TxHashFail",
"BadStateError",
"SignatureFailError"
]
38 changes: 38 additions & 0 deletions tests/speculos/ledger_client/exception/device_exception.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
import enum
from typing import Dict, Any, Union

from .errors import *


class DeviceException(Exception): # pylint: disable=too-few-public-methods
exc: Dict[int, Any] = {
0x6985: DenyError,
0x6A86: WrongP1P2Error,
0x6A87: WrongDataLengthError,
0x6D00: InsNotSupportedError,
0x6E00: ClaNotSupportedError,
0xB000: WrongResponseLengthError,
0xB001: DisplayBip32PathFailError,
0xB002: DisplayAddressFailError,
0xB003: DisplayAmountFailError,
0xB004: WrongTxLengthError,
0xB005: TxParsingFailError,
0xB006: TxHashFail,
0xB007: BadStateError,
0xB008: SignatureFailError
}

def __new__(cls,
error_code: int,
ins: Union[int, enum.IntEnum, None] = None,
message: str = ""
) -> Any:
error_message: str = (f"Error in {ins!r} command"
if ins else "Error in command")

if error_code in DeviceException.exc:
return DeviceException.exc[error_code](hex(error_code),
error_message,
message)

return UnknownDeviceError(hex(error_code), error_message, message)
58 changes: 58 additions & 0 deletions tests/speculos/ledger_client/exception/errors.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
class UnknownDeviceError(Exception):
pass


class DenyError(Exception):
pass


class WrongP1P2Error(Exception):
pass


class WrongDataLengthError(Exception):
pass


class InsNotSupportedError(Exception):
pass


class ClaNotSupportedError(Exception):
pass


class WrongResponseLengthError(Exception):
pass


class DisplayBip32PathFailError(Exception):
pass


class DisplayAddressFailError(Exception):
pass


class DisplayAmountFailError(Exception):
pass


class WrongTxLengthError(Exception):
pass


class TxParsingFailError(Exception):
pass


class TxHashFail(Exception):
pass


class BadStateError(Exception):
pass


class SignatureFailError(Exception):
pass
Loading