pytest-gpu-proof 0.1.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- pytest_gpu_proof/__init__.py +1 -0
- pytest_gpu_proof/__main__.py +3 -0
- pytest_gpu_proof/cli.py +95 -0
- pytest_gpu_proof/compare.py +49 -0
- pytest_gpu_proof/config.py +82 -0
- pytest_gpu_proof/fingerprint.py +38 -0
- pytest_gpu_proof/gitutils.py +112 -0
- pytest_gpu_proof/plugin.py +331 -0
- pytest_gpu_proof/receipt.py +143 -0
- pytest_gpu_proof/signers/__init__.py +0 -0
- pytest_gpu_proof/signers/base.py +20 -0
- pytest_gpu_proof/signers/ed25519.py +178 -0
- pytest_gpu_proof/verify.py +339 -0
- pytest_gpu_proof-0.1.0.dist-info/METADATA +400 -0
- pytest_gpu_proof-0.1.0.dist-info/RECORD +18 -0
- pytest_gpu_proof-0.1.0.dist-info/WHEEL +4 -0
- pytest_gpu_proof-0.1.0.dist-info/entry_points.txt +5 -0
- pytest_gpu_proof-0.1.0.dist-info/licenses/LICENSE +21 -0
|
@@ -0,0 +1,400 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: pytest-gpu-proof
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: pytest plugin for GPU equivalence testing with signed receipts verified via GitHub SSH keys
|
|
5
|
+
Project-URL: Homepage, https://github.com/A2R-Lab/pytest-gpu-proof
|
|
6
|
+
Project-URL: Documentation, https://a2r-lab.github.io/pytest-gpu-proof/
|
|
7
|
+
Project-URL: Repository, https://github.com/A2R-Lab/pytest-gpu-proof
|
|
8
|
+
Project-URL: Issues, https://github.com/A2R-Lab/pytest-gpu-proof/issues
|
|
9
|
+
Project-URL: Changelog, https://github.com/A2R-Lab/pytest-gpu-proof/blob/main/CHANGELOG.md
|
|
10
|
+
License: MIT
|
|
11
|
+
License-File: LICENSE
|
|
12
|
+
Keywords: attestation,cuda,gpu,pytest,signing,testing
|
|
13
|
+
Classifier: Development Status :: 4 - Beta
|
|
14
|
+
Classifier: Framework :: Pytest
|
|
15
|
+
Classifier: Intended Audience :: Developers
|
|
16
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
17
|
+
Classifier: Operating System :: OS Independent
|
|
18
|
+
Classifier: Programming Language :: Python :: 3
|
|
19
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
20
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
21
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
22
|
+
Classifier: Topic :: Security :: Cryptography
|
|
23
|
+
Classifier: Topic :: Software Development :: Testing
|
|
24
|
+
Requires-Python: >=3.11
|
|
25
|
+
Requires-Dist: cryptography>=41.0
|
|
26
|
+
Requires-Dist: pytest>=7.0
|
|
27
|
+
Provides-Extra: dev
|
|
28
|
+
Requires-Dist: numpy; extra == 'dev'
|
|
29
|
+
Requires-Dist: pytest-cov; extra == 'dev'
|
|
30
|
+
Provides-Extra: sigstore
|
|
31
|
+
Requires-Dist: sigstore; extra == 'sigstore'
|
|
32
|
+
Description-Content-Type: text/markdown
|
|
33
|
+
|
|
34
|
+
# pytest-gpu-proof
|
|
35
|
+
|
|
36
|
+
A pytest plugin that lets you run GPU equivalence tests locally, sign the results with your existing SSH key, and have GitHub Actions verify the receipt — **without re-running the GPU tests in CI**.
|
|
37
|
+
|
|
38
|
+
The trust model is simple: if you can push to GitHub, you can sign a receipt. Verification fetches your public keys from `github.com/{username}.keys`, exactly as SSH does.
|
|
39
|
+
|
|
40
|
+
> **Requirements:** Python 3.11+ · pytest 7.0+ · cryptography 41.0+
|
|
41
|
+
> The package is not yet on PyPI — install from source with `pip install -e .` (see [Installation](#installation)).
|
|
42
|
+
|
|
43
|
+
---
|
|
44
|
+
|
|
45
|
+
## Why this exists
|
|
46
|
+
|
|
47
|
+
GPU CI is expensive. For many teams, the typical workflow is:
|
|
48
|
+
|
|
49
|
+
1. Run GPU correctness tests locally (or on a lab machine).
|
|
50
|
+
2. Push code and let CI run only CPU tests.
|
|
51
|
+
3. Hope the GPU tests still pass.
|
|
52
|
+
|
|
53
|
+
This plugin closes that gap by producing a **cryptographically signed receipt** that proves a specific person ran specific tests against specific code at a specific time — verifiable in ordinary CPU-only CI with no GPU and no secrets.
|
|
54
|
+
|
|
55
|
+
---
|
|
56
|
+
|
|
57
|
+
## How it works
|
|
58
|
+
|
|
59
|
+
```
|
|
60
|
+
Local machine (GPU) GitHub Actions (CPU only)
|
|
61
|
+
───────────────────────────── ──────────────────────────────────────
|
|
62
|
+
pytest --gpu-proof-enable → → gpu-proof verify --receipt gpu-proof.json
|
|
63
|
+
runs your GPU tests fetches your public keys from
|
|
64
|
+
computes code fingerprint github.com/{you}.keys
|
|
65
|
+
signs receipt with SSH key verifies signature + fingerprint
|
|
66
|
+
writes gpu-proof.json exits 0 (pass) or 1 (fail)
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
**Zero new key management.** The plugin uses the SSH key you already have in `~/.ssh/` (the same one you use to push to GitHub). Your public key is already on GitHub. The verifier reads it from there.
|
|
70
|
+
|
|
71
|
+
---
|
|
72
|
+
|
|
73
|
+
## Installation
|
|
74
|
+
|
|
75
|
+
From PyPI (v0.1.0+):
|
|
76
|
+
|
|
77
|
+
```bash
|
|
78
|
+
pip install pytest-gpu-proof
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
Or from a clone / git submodule (how the A2R-Lab consumers pin exact versions):
|
|
82
|
+
|
|
83
|
+
```bash
|
|
84
|
+
git clone https://github.com/A2R-Lab/pytest-gpu-proof
|
|
85
|
+
cd pytest-gpu-proof
|
|
86
|
+
pip install -e . # base install (pytest + cryptography)
|
|
87
|
+
pip install -e ".[dev]" # also installs numpy, pytest-cov
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
Or use the helper script (checks your Python version first):
|
|
91
|
+
|
|
92
|
+
```bash
|
|
93
|
+
bash install.sh # base install
|
|
94
|
+
bash install.sh dev # dev install
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
Maintainers: release process in [RELEASING.md](RELEASING.md).
|
|
98
|
+
|
|
99
|
+
---
|
|
100
|
+
|
|
101
|
+
## Quick start
|
|
102
|
+
|
|
103
|
+
### Step 1 — Install from source
|
|
104
|
+
|
|
105
|
+
```bash
|
|
106
|
+
git clone <this-repo>
|
|
107
|
+
cd pytest-gpu-proof
|
|
108
|
+
pip install -e .
|
|
109
|
+
```
|
|
110
|
+
|
|
111
|
+
### Step 2 — Run the bundled demo (no GPU needed)
|
|
112
|
+
|
|
113
|
+
The repo includes a no-GPU demo that works on any machine:
|
|
114
|
+
|
|
115
|
+
```bash
|
|
116
|
+
cd examples/minimal_python_only
|
|
117
|
+
pytest test_minimal.py --gpu-proof-enable -v
|
|
118
|
+
```
|
|
119
|
+
|
|
120
|
+
Expected output:
|
|
121
|
+
```
|
|
122
|
+
PASSED test_minimal.py::test_relu
|
|
123
|
+
PASSED test_minimal.py::test_softmax
|
|
124
|
+
...
|
|
125
|
+
[gpu-proof] Receipt written to gpu-proof.json
|
|
126
|
+
[gpu-proof] Signed with key SHA256:...
|
|
127
|
+
```
|
|
128
|
+
|
|
129
|
+
### Step 3 — Verify the receipt
|
|
130
|
+
|
|
131
|
+
```bash
|
|
132
|
+
gpu-proof verify --receipt gpu-proof.json
|
|
133
|
+
```
|
|
134
|
+
|
|
135
|
+
The verifier fetches your public keys from `github.com/{you}.keys` automatically — no secrets needed.
|
|
136
|
+
|
|
137
|
+
### Step 4 — Use it in your own project
|
|
138
|
+
|
|
139
|
+
Add the marker and fixture to your tests:
|
|
140
|
+
|
|
141
|
+
```python
|
|
142
|
+
import pytest
|
|
143
|
+
|
|
144
|
+
@pytest.mark.gpu_proof
|
|
145
|
+
def test_my_kernel(gpu_proof_check):
|
|
146
|
+
gpu_proof_check(
|
|
147
|
+
name="relu",
|
|
148
|
+
reference=python_relu, # your reference implementation
|
|
149
|
+
candidate=cuda_relu, # your GPU wrapper
|
|
150
|
+
args=([1.0, -2.0, 3.0],),
|
|
151
|
+
metadata={"kernel": "relu"},
|
|
152
|
+
)
|
|
153
|
+
```
|
|
154
|
+
|
|
155
|
+
Run from **your project's root** (not the pytest-gpu-proof source directory):
|
|
156
|
+
|
|
157
|
+
```bash
|
|
158
|
+
pytest path/to/your/tests/ --gpu-proof-enable -v
|
|
159
|
+
# → writes gpu-proof.json in the current directory
|
|
160
|
+
```
|
|
161
|
+
|
|
162
|
+
> **Note:** The `--gpu-proof-enable` flag only writes a receipt if at least one test is marked with `@pytest.mark.gpu_proof` or uses the `gpu_proof_check` fixture. Running it against the plugin's own `tests/` directory (which tests the plugin internals) will not produce a receipt.
|
|
163
|
+
|
|
164
|
+
### Step 5 — Commit and verify in CI
|
|
165
|
+
|
|
166
|
+
```bash
|
|
167
|
+
git add gpu-proof.json
|
|
168
|
+
git commit -m "update GPU proof receipt"
|
|
169
|
+
git push
|
|
170
|
+
```
|
|
171
|
+
|
|
172
|
+
```yaml
|
|
173
|
+
# .github/workflows/ci.yml
|
|
174
|
+
- name: Verify GPU proof
|
|
175
|
+
run: gpu-proof verify --receipt gpu-proof.json
|
|
176
|
+
```
|
|
177
|
+
|
|
178
|
+
---
|
|
179
|
+
|
|
180
|
+
## The `gpu_proof_check` fixture
|
|
181
|
+
|
|
182
|
+
```python
|
|
183
|
+
gpu_proof_check(
|
|
184
|
+
name="my_op", # unique name within the test
|
|
185
|
+
reference=python_fn, # callable: the ground truth
|
|
186
|
+
candidate=cuda_fn, # callable: the GPU implementation
|
|
187
|
+
args=(arg1, arg2), # positional arguments (tuple)
|
|
188
|
+
kwargs={"key": "val"}, # keyword arguments (dict, optional)
|
|
189
|
+
compare=my_compare_fn, # optional: (ref_out, cand_out) -> None, raises on mismatch
|
|
190
|
+
metadata={"info": "..."}, # optional: included verbatim in the receipt
|
|
191
|
+
)
|
|
192
|
+
```
|
|
193
|
+
|
|
194
|
+
**Default comparison:** `numpy.allclose` for float arrays/tensors, `==` otherwise.
|
|
195
|
+
|
|
196
|
+
**Custom comparison:** any callable that raises `AssertionError` on mismatch and returns `None` on success.
|
|
197
|
+
|
|
198
|
+
---
|
|
199
|
+
|
|
200
|
+
## Markers
|
|
201
|
+
|
|
202
|
+
| Marker | Effect |
|
|
203
|
+
|---|---|
|
|
204
|
+
| `@pytest.mark.gpu_proof` | Include test outcomes in the receipt |
|
|
205
|
+
| `@pytest.mark.gpu_equivalence` | Alias for `gpu_proof` |
|
|
206
|
+
| `@pytest.mark.gpu_required` | Skip test if no GPU is detected (via `nvidia-smi` or `torch.cuda`) |
|
|
207
|
+
|
|
208
|
+
---
|
|
209
|
+
|
|
210
|
+
## CLI options
|
|
211
|
+
|
|
212
|
+
| Option | Default | Description |
|
|
213
|
+
|---|---|---|
|
|
214
|
+
| `--gpu-proof-enable` | off | Enable receipt generation |
|
|
215
|
+
| `--gpu-proof-mode` | `local` | `local` or `ci-gpu` |
|
|
216
|
+
| `--gpu-proof-out` | `gpu-proof.json` | Receipt output path |
|
|
217
|
+
| `--gpu-proof-key` | auto | SSH private key path |
|
|
218
|
+
| `--gpu-proof-signing-backend` | `ed25519` | `ed25519` or `none` (writes an **unsigned** receipt with `"signature": null`; the verifier rejects it unless `--allow-unsigned` is passed) |
|
|
219
|
+
| `--gpu-proof-required-marker` | `gpu_proof` | Marker name that flags a test for the receipt |
|
|
220
|
+
| `--gpu-proof-fingerprint-paths` | `src,tests` | Comma-separated paths to fingerprint |
|
|
221
|
+
| `--gpu-proof-github-user` | auto | GitHub username (auto-detected from git remote) |
|
|
222
|
+
| `--gpu-proof-policy` | — | Path to policy YAML |
|
|
223
|
+
| `--gpu-proof-fail-on-skip` | off | Exit non-zero and write no receipt if any marked or `gpu_required` test is skipped |
|
|
224
|
+
|
|
225
|
+
Defaults for most of these can also be set in your project's `pyproject.toml`
|
|
226
|
+
under `[tool.gpu_proof]` (CLI flags take precedence):
|
|
227
|
+
|
|
228
|
+
```toml
|
|
229
|
+
[tool.gpu_proof]
|
|
230
|
+
mode = "local"
|
|
231
|
+
output = "gpu-proof.json"
|
|
232
|
+
fingerprint_paths = ["src", "tests"]
|
|
233
|
+
required_marker = "gpu_proof"
|
|
234
|
+
max_age_days = 30 # used by the verifier
|
|
235
|
+
require_gpu = false # used by the verifier (see below)
|
|
236
|
+
```
|
|
237
|
+
|
|
238
|
+
---
|
|
239
|
+
|
|
240
|
+
## Verification CLI
|
|
241
|
+
|
|
242
|
+
```bash
|
|
243
|
+
gpu-proof verify \
|
|
244
|
+
--receipt gpu-proof.json \
|
|
245
|
+
--repo . \
|
|
246
|
+
--max-age-days 30
|
|
247
|
+
|
|
248
|
+
# With an explicit GitHub username (non-GitHub remotes):
|
|
249
|
+
gpu-proof verify --receipt gpu-proof.json --github-user myusername
|
|
250
|
+
```
|
|
251
|
+
|
|
252
|
+
Also callable as:
|
|
253
|
+
|
|
254
|
+
```bash
|
|
255
|
+
python -m pytest_gpu_proof verify --receipt gpu-proof.json
|
|
256
|
+
```
|
|
257
|
+
|
|
258
|
+
### What the verifier checks
|
|
259
|
+
|
|
260
|
+
1. **Signature** — fetches `github.com/{signer}.keys`, verifies Ed25519/ECDSA/RSA signature
|
|
261
|
+
2. **Fingerprint** — recomputes SHA-256 digest of `src/` and `tests/`, compares to receipt
|
|
262
|
+
3. **Commit SHA** — compares receipt commit SHA to current HEAD
|
|
263
|
+
4. **Test outcomes** — all tests recorded in the receipt must have passed; skipped marked tests fail verification unless `--allow-skipped` is passed, or an `--expected-skips` baseline is given and the receipt's skip set matches it exactly
|
|
264
|
+
5. **Freshness** — receipt must be younger than `max_age_days` (default: 30)
|
|
265
|
+
6. **Dirty policy** — configurable via policy file
|
|
266
|
+
7. **GPU info** (optional) — with `--require-gpu` (or `require_gpu = true` in `[tool.gpu_proof]`), the receipt's `environment.gpu_info` must be present
|
|
267
|
+
|
|
268
|
+
Additional flags:
|
|
269
|
+
|
|
270
|
+
- `--allow-unsigned` — accept receipts with `"signature": null` (produced by `--gpu-proof-signing-backend=none`). This disables the entire trust story; the verifier prints a loud warning.
|
|
271
|
+
- `--allow-skipped` — accept receipts that contain skipped marked tests (any skips, no questions asked).
|
|
272
|
+
- `--expected-skips PATH` — the strict alternative to `--allow-skipped` (the two are mutually exclusive): a baseline file of node IDs (one per line, `#` comments) that the receipt's skipped tests must match **exactly**. A skip not in the baseline fails verification, and a baseline entry that no longer skips fails too (stale baseline — update it). Use this when a project has a small set of permanent, documented skips. Can also be set as an inline list via `expected_skips = [...]` in `[tool.gpu_proof]`.
|
|
273
|
+
- `--require-gpu` — reject receipts whose `environment.gpu_info` is null/absent. This is **modest hardening, not proof**: `gpu_info` is self-reported by the recording machine, so it only guards against accidentally signing on a GPU-less box, not against a dishonest signer.
|
|
274
|
+
|
|
275
|
+
---
|
|
276
|
+
|
|
277
|
+
## Key management
|
|
278
|
+
|
|
279
|
+
**Local mode:** Uses your existing `~/.ssh/id_ed25519` (or whatever `git config user.signingKey` points to). No new keys to generate.
|
|
280
|
+
|
|
281
|
+
**CI-GPU mode:** Generate a dedicated CI signing key, store the private key as a GitHub Actions secret, and add the public key to your GitHub account.
|
|
282
|
+
|
|
283
|
+
```bash
|
|
284
|
+
ssh-keygen -t ed25519 -f ci-signing-key -N ""
|
|
285
|
+
# Add ci-signing-key.pub to github.com/settings/keys
|
|
286
|
+
# Add contents of ci-signing-key to GitHub Actions secrets as GPU_PROOF_SIGNING_KEY
|
|
287
|
+
```
|
|
288
|
+
|
|
289
|
+
---
|
|
290
|
+
|
|
291
|
+
## Receipt format
|
|
292
|
+
|
|
293
|
+
```json
|
|
294
|
+
{
|
|
295
|
+
"schema_version": "1",
|
|
296
|
+
"mode": "local",
|
|
297
|
+
"repo": {
|
|
298
|
+
"remote_url": "git@github.com:you/myrepo.git",
|
|
299
|
+
"github_username": "you",
|
|
300
|
+
"commit_sha": "abc123...",
|
|
301
|
+
"branch": "main",
|
|
302
|
+
"dirty": false
|
|
303
|
+
},
|
|
304
|
+
"fingerprint": {
|
|
305
|
+
"algorithm": "sha256",
|
|
306
|
+
"included_paths": ["src", "tests"],
|
|
307
|
+
"file_count": 12,
|
|
308
|
+
"digest": "deadbeef..."
|
|
309
|
+
},
|
|
310
|
+
"session": {
|
|
311
|
+
"started_at": "2024-01-01T10:00:00Z",
|
|
312
|
+
"ended_at": "2024-01-01T10:01:30Z",
|
|
313
|
+
"node_ids": ["tests/test_relu.py::test_relu"]
|
|
314
|
+
},
|
|
315
|
+
"tests": [
|
|
316
|
+
{
|
|
317
|
+
"node_id": "tests/test_relu.py::test_relu",
|
|
318
|
+
"outcome": "passed",
|
|
319
|
+
"duration_s": 1.23,
|
|
320
|
+
"checks": [{"name": "relu", "outcome": "passed", "metadata": {}}]
|
|
321
|
+
}
|
|
322
|
+
],
|
|
323
|
+
"environment": {
|
|
324
|
+
"python_version": "3.11.0",
|
|
325
|
+
"platform": "linux",
|
|
326
|
+
"pytest_version": "7.4.0",
|
|
327
|
+
"gpu_info": {"name": "NVIDIA RTX 3090", "driver_version": "535.104"}
|
|
328
|
+
},
|
|
329
|
+
"signature": {
|
|
330
|
+
"algorithm": "ed25519",
|
|
331
|
+
"backend": "ssh-local",
|
|
332
|
+
"signer": "you",
|
|
333
|
+
"key_fingerprint": "SHA256:...",
|
|
334
|
+
"value": "<base64-encoded signature>"
|
|
335
|
+
}
|
|
336
|
+
}
|
|
337
|
+
```
|
|
338
|
+
|
|
339
|
+
---
|
|
340
|
+
|
|
341
|
+
## Security model
|
|
342
|
+
|
|
343
|
+
A signed receipt proves that **an accepted signer attested to a specific test run over a specific code state**. It does not prove:
|
|
344
|
+
|
|
345
|
+
- The local machine was fully trustworthy or uncompromised.
|
|
346
|
+
- The GPU execution environment was hardware-attested.
|
|
347
|
+
- The signing key was protected with a hardware security module.
|
|
348
|
+
|
|
349
|
+
This is appropriate for **team workflows where the signer is a trusted team member** and the goal is to avoid paying for GPU CI on every merge, not to provide adversarial security guarantees.
|
|
350
|
+
|
|
351
|
+
The optional `--require-gpu` verifier flag adds a modest extra check — the receipt must contain self-reported `environment.gpu_info` — but this is hardening against mistakes (signing on a GPU-less machine), not proof of GPU execution.
|
|
352
|
+
|
|
353
|
+
**SSH key support caveats:**
|
|
354
|
+
|
|
355
|
+
- The plugin signs the raw receipt bytes with the key loaded from disk — it does **not** produce SSHSIG-format signatures, so `ssh-keygen -Y verify` cannot validate receipts. Use `gpu-proof verify` instead.
|
|
356
|
+
- Keys that live only in an SSH agent, and FIDO/hardware-backed `sk-ssh-ed25519`/`sk-ecdsa` keys, are **not** supported: signing needs direct access to a private key file readable by the `cryptography` library.
|
|
357
|
+
|
|
358
|
+
See [docs/security_model.md](docs/security_model.md) for a full discussion.
|
|
359
|
+
|
|
360
|
+
---
|
|
361
|
+
|
|
362
|
+
## Examples
|
|
363
|
+
|
|
364
|
+
| Example | Location | What it shows |
|
|
365
|
+
|---|---|---|
|
|
366
|
+
| Minimal (no GPU needed) | `examples/minimal_python_only/` | Full plugin flow with pure-Python "fake GPU" |
|
|
367
|
+
| Wrapped CUDA via ctypes (fake library) | `examples/wrapped_cuda_ctypes/` | ctypes-style wrapper pattern that runs without CUDA |
|
|
368
|
+
| Real CUDA via ctypes | `examples/cuda_ctypes_matmul/` | C ABI CUDA shared library loaded with Python `ctypes` |
|
|
369
|
+
| Real CUDA via pybind11 | `examples/cuda_pybind11_matmul/` | CUDA-backed Python extension using `pybind11_add_module` |
|
|
370
|
+
| Real CUDA via nanobind | `examples/cuda_nanobind_matmul/` | CUDA-backed Python extension using `nanobind_add_module` |
|
|
371
|
+
| Real CUDA via JAX FFI | `examples/jax_ffi_cuda_matmul/` | Typed CUDA custom call registered with `jax.ffi` |
|
|
372
|
+
| Local sign, CI verify | `examples/local_receipt_verify/` | GitHub Actions workflow for CPU-only verification |
|
|
373
|
+
| CI-GPU execution | `examples/github_gpu_runner/` | GitHub Actions workflow on a GPU runner |
|
|
374
|
+
|
|
375
|
+
---
|
|
376
|
+
|
|
377
|
+
## Development
|
|
378
|
+
|
|
379
|
+
```bash
|
|
380
|
+
python3 -m pip install -e ".[dev]"
|
|
381
|
+
pytest tests/ -v
|
|
382
|
+
```
|
|
383
|
+
|
|
384
|
+
If you do not want to install the package, run tests directly from the source
|
|
385
|
+
tree with:
|
|
386
|
+
|
|
387
|
+
```bash
|
|
388
|
+
PYTHONPATH=src pytest -q
|
|
389
|
+
```
|
|
390
|
+
|
|
391
|
+
Tests are CPU-only. No GPU or network access required.
|
|
392
|
+
|
|
393
|
+
---
|
|
394
|
+
|
|
395
|
+
## Compatibility
|
|
396
|
+
|
|
397
|
+
- Python 3.11+
|
|
398
|
+
- pytest 7.0+
|
|
399
|
+
- `cryptography` 41.0+
|
|
400
|
+
- `pytest-xdist` is **not** supported in v1 (parallel workers would write conflicting receipts)
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
pytest_gpu_proof/__init__.py,sha256=kUR5RAFc7HCeiqdlX36dZOHkUI5wI6V_43RpEcD8b-0,22
|
|
2
|
+
pytest_gpu_proof/__main__.py,sha256=I2k_Y-0KCU8V4bbV0edDEoaSP1MjJrwqNZMNbap_VOM,46
|
|
3
|
+
pytest_gpu_proof/cli.py,sha256=7Vqlp_xRBDSfXcmUn_1wjlFcrHceaq4Atyf-K7rw1Os,3010
|
|
4
|
+
pytest_gpu_proof/compare.py,sha256=7oDgspsB5dj0EStzDELpoOw1VfGk7cDZlerd6p29UBQ,1653
|
|
5
|
+
pytest_gpu_proof/config.py,sha256=gWSsKQdUSEoal77uiKY20E65FBNZapqPDP5LG6oS6lo,3076
|
|
6
|
+
pytest_gpu_proof/fingerprint.py,sha256=yZCsPDTK-OiFq8m5xp7yjaQaY1ziPWho9pn2UfrNiV0,972
|
|
7
|
+
pytest_gpu_proof/gitutils.py,sha256=ZDxY5nSXNCTrSuKg-updJwzKw_oNi8Pp6SsCJn1_XOE,3558
|
|
8
|
+
pytest_gpu_proof/plugin.py,sha256=l2t-6i0QCLZp40-d7Nw0EvCrDFU_6aNKuXOyLJ6Gcmc,11385
|
|
9
|
+
pytest_gpu_proof/receipt.py,sha256=ZaIfb1z5xE5bbUVmMmkdqL6wY9hKCWon0W00jgBqriU,4395
|
|
10
|
+
pytest_gpu_proof/verify.py,sha256=U3kJzd_2XeaJ4TVW92u8j1OsI1Vtey_SvYi1SwNEaEI,12375
|
|
11
|
+
pytest_gpu_proof/signers/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
12
|
+
pytest_gpu_proof/signers/base.py,sha256=emZApFpLHdiq_87edw2b2OfbE1TkYRtRVj__nGAJtMs,392
|
|
13
|
+
pytest_gpu_proof/signers/ed25519.py,sha256=J5_lx913ermZsYbpwlUmk0DLvnD_TvZEH9TyMgGtjpg,6089
|
|
14
|
+
pytest_gpu_proof-0.1.0.dist-info/METADATA,sha256=Dr7dAK5943kCYrJYq7WtNGRMJiqwUv_y_ZM4VnMqp8Q,14694
|
|
15
|
+
pytest_gpu_proof-0.1.0.dist-info/WHEEL,sha256=mffPy8wBnZQn2VnJUU5jE99KsxaSfiyMHV9Yt0aLVxs,87
|
|
16
|
+
pytest_gpu_proof-0.1.0.dist-info/entry_points.txt,sha256=KUVolKsUWq-aqFBXgaI25_TD8PcYrg4mq0Ndiz9pgHY,104
|
|
17
|
+
pytest_gpu_proof-0.1.0.dist-info/licenses/LICENSE,sha256=KXfdMIlN2d_t6pY6UbLXCh7jpl6UfFsBdcIhqmCMFFU,1064
|
|
18
|
+
pytest_gpu_proof-0.1.0.dist-info/RECORD,,
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 A2R Lab
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|