Skip to content
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
2 changes: 0 additions & 2 deletions .github/workflows/tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,6 @@ jobs:
sudo apt-get install -y gnupg2 pinentry-curses pinentry-tty libzbar0 libpcsclite-dev pcscd swig
python -m pip install --upgrade pip
pip install -r requirements.txt -r tests/requirements.txt
pip install .
- name: Test with pytest
run: |
mkdir artifacts
Expand Down Expand Up @@ -103,7 +102,6 @@ jobs:
run: |
python -m pip install --upgrade pip
pip install -r requirements.txt -r requirements-desktop.txt -r tests/requirements.txt
pip install .
- name: Test with pytest
run: |
python -m pytest \
Expand Down
54 changes: 54 additions & 0 deletions AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -166,6 +166,60 @@ For changes touching entropy, seed generation/import, key derivation, signing, o
- Document threat assumptions and failure modes in code comments or PR notes.
- Call out any remaining risk tradeoffs explicitly.

## Testing guidance

### Running the test suite

After making changes, always run the full pytest suite to verify nothing is broken:

```bash
pytest tests/ -v --tb=short
```

Tests run directly against `src/` (configured via `[tool.pytest.ini_options].pythonpath = ["src"]` in `pyproject.toml`). **No `pip install .` required.**

For a quick smoke test of just the affected area, target specific files:

```bash
pytest tests/test_<relevant_file>.py -v --tb=short
```

### Expected platform-dependent failures

Some tests are skipped or fail on certain platforms due to missing hardware or dependencies. These are **expected** and not regressions:

| Test file | Platform(s) affected | Reason |
|-----------|---------------------|--------|
| `test_flows_seed.py` (satochip tests) | All (without hardware) | Requires pysatochip + physical Satochip device |
| `test_flows_tools.py` (satochip test) | All (without hardware) | Requires pysatochip + physical Satochip device |

When reviewing test results, focus on **new** failures compared to the baseline. The current baseline on a typical development machine with GPG installed is **716 passing, 134 skipped, 7 failing** (satochip tests only — requires physical hardware). On machines without GPG, `test_gpg_message.py` and `test_gpg_time_update.py` will additionally fail — this is expected.

**Note:** The `_msys2_path()` helper in `test_gpg_message.py` auto-detects whether the installed GPG binary is from Git-for-Windows (needs MSYS2-style `/c/...` paths) or native Windows Gpg4win (needs native `C:\...` paths). If GPG tests fail on Windows with a "no writable keyring found" error, check that `_msys2_path()` correctly identifies the installed GPG variant.

### Star import caveat for underscore-prefixed names

The codebase uses `from .module import *` extensively in `tools_views.py` to re-export symbols from split modules (`gpg_views`, `smartcard_views`, `password_generator_views`). **Python's star imports silently skip all names starting with `_`** unless `__all__` is defined.

When moving or renaming an underscore-prefixed function:
- If it's imported by tests or other modules via `tools_views._func_name`, add an explicit re-export in `tools_views.py`:
```python
from .source_module import _func_name as _func_name_alias
# Re-export for backward compatibility
_func_name = _func_name_alias # noqa: F401 W0603
```
- If tests monkeypatch a function in `tools_views` but the actual code runs in another module, patch **both** modules:
```python
monkeypatch.setattr(tools_views, "_func", fake_func)
monkeypatch.setattr(source_module, "_func", fake_func)
```

### Adding new tests

- Place new test files in `tests/` with prefix `test_`.
- Use the same patterns as existing tests: `object.__new__(ViewClass)` to create view instances without triggering `__init__`, then monkeypatch dependencies.
- For views that reference symbols from split modules, ensure those symbols are accessible through `tools_views` (see star import caveat above).

## Unicode and locale-safe string handling

SeedSigner must produce identical results regardless of the host locale or input method. Follow these rules when processing user-supplied or externally-sourced strings:
Expand Down
Binary file added javacard-cap/Keycard_v3.2.cap
Binary file not shown.
Binary file added javacard-cap/SatoChip-0.12-official.cap
Binary file not shown.
Binary file added javacard-cap/SatoDime-0.1.2-official.cap
Binary file not shown.
Binary file added javacard-cap/SeedKeeper-0.2-official.cap
Binary file not shown.
Binary file added javacard-cap/SeedKeeper-Ndef-v0.2-0.1.cap
Binary file not shown.
Binary file added javacard-cap/SmartPGP-RSA2048.cap
Binary file not shown.
Binary file added javacard-cap/SmartPGP-RSA4096.cap
Binary file not shown.
Binary file added javacard-cap/SpecterDIY.cap
Binary file not shown.
Binary file added javacard-cap/Vivokey-OTP.cap
Binary file not shown.
9 changes: 9 additions & 0 deletions javacard-cap/javacard-cap.sha256
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
9ed83c56e64cfb00d732cab4705e6f339fa1f039507ad86de7028bb3056675e8 Keycard_v3.2.cap
b608d1a1a53956d58e53e1aceb417a10d3492fa744528a08904eb0b068e293ce SatoChip-0.12-official.cap
d106503ae273a6f9193f9a6199e3565b0e02d3dd2ad57aa313a1ea16143197d9 SatoDime-0.1.2-official.cap
28dbae3c7c130a6f7d0e6d05f41386ffd93976fd290eaa5d8db708b9903dabcd SeedKeeper-0.2-official.cap
ef776360415ee0c64881b1e36339ffba815231aab2406014559d18fdaa632c9b SeedKeeper-Ndef-v0.2-0.1.cap
9aa779f3615083b02df0acd1eb7268e370c9fefee99727581c8560c7efeafa09 SmartPGP-RSA2048.cap
8df7523e24117e0d3a289f511179b25b82b1bc1df39c203f03b21c568ac2b6b8 SmartPGP-RSA4096.cap
5f855f0c490402ac2f1e4cb1fc39cf6e4ce3d633fcb407fe024d275677f0efb4 SpecterDIY.cap
f2b7909a75a15f93aae5fa1c1c3bfe69cc613f3a74072db6c25e57b5423f16e0 Vivokey-OTP.cap
1 change: 1 addition & 0 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@ branch = true

[tool.pytest.ini_options]
testpaths = ["tests"]
pythonpath = ["src"]
log_level = "DEBUG"

[tool.setuptools]
Expand Down
Loading
Loading