labgrid-boardkit 0.1.0__tar.gz
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.
- labgrid_boardkit-0.1.0/LICENSE +21 -0
- labgrid_boardkit-0.1.0/PKG-INFO +108 -0
- labgrid_boardkit-0.1.0/README.md +88 -0
- labgrid_boardkit-0.1.0/pyproject.toml +65 -0
- labgrid_boardkit-0.1.0/pyproject.toml.orig +62 -0
- labgrid_boardkit-0.1.0/src/labgrid_boardkit/__init__.py +0 -0
- labgrid_boardkit-0.1.0/src/labgrid_boardkit/fixtures.py +77 -0
- labgrid_boardkit-0.1.0/src/labgrid_boardkit/helpers.py +58 -0
- labgrid_boardkit-0.1.0/src/labgrid_boardkit/loader.py +27 -0
- labgrid_boardkit-0.1.0/src/labgrid_boardkit/manifest.py +53 -0
- labgrid_boardkit-0.1.0/src/labgrid_boardkit/ptest/__init__.py +0 -0
- labgrid_boardkit-0.1.0/src/labgrid_boardkit/ptest/test_ptests.py +28 -0
- labgrid_boardkit-0.1.0/src/labgrid_boardkit/render.py +147 -0
- labgrid_boardkit-0.1.0/src/labgrid_boardkit/schema/board.schema.json +145 -0
- labgrid_boardkit-0.1.0/src/labgrid_boardkit/strategies/__init__.py +25 -0
- labgrid_boardkit-0.1.0/src/labgrid_boardkit/strategies/base.py +32 -0
- labgrid_boardkit-0.1.0/src/labgrid_boardkit/strategies/fastboot.py +141 -0
- labgrid_boardkit-0.1.0/src/labgrid_boardkit/strategies/qemu.py +86 -0
- labgrid_boardkit-0.1.0/src/labgrid_boardkit/strategies/sdmux.py +81 -0
- labgrid_boardkit-0.1.0/src/labgrid_boardkit/strategies/tftp.py +109 -0
- labgrid_boardkit-0.1.0/src/labgrid_boardkit/templates/client-fastboot.yaml.j2 +55 -0
- labgrid_boardkit-0.1.0/src/labgrid_boardkit/templates/client-qemu.yaml.j2 +44 -0
- labgrid_boardkit-0.1.0/src/labgrid_boardkit/templates/client-sdmux.yaml.j2 +58 -0
- labgrid_boardkit-0.1.0/src/labgrid_boardkit/templates/client-tftp.yaml.j2 +59 -0
- labgrid_boardkit-0.1.0/src/labgrid_boardkit/templates/strategy.py.j2 +19 -0
- labgrid_boardkit-0.1.0/src/labgrid_boardkit/tests/__init__.py +0 -0
- labgrid_boardkit-0.1.0/src/labgrid_boardkit/tests/test_fastboot.py +23 -0
- labgrid_boardkit-0.1.0/src/labgrid_boardkit/tests/test_sd.py +28 -0
- labgrid_boardkit-0.1.0/src/labgrid_boardkit/tests/test_tftp.py +35 -0
- labgrid_boardkit-0.1.0/src/labgrid_boardkit/validate.py +72 -0
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Trevor Gamblin
|
|
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.
|
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: labgrid-boardkit
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: Board manifests, boot strategies, fixtures and test suites for labgrid
|
|
5
|
+
Author: Trevor Gamblin
|
|
6
|
+
Author-email: Trevor Gamblin <tgamblin@baylibre.com>
|
|
7
|
+
License-Expression: MIT
|
|
8
|
+
License-File: LICENSE
|
|
9
|
+
Classifier: Framework :: Pytest
|
|
10
|
+
Classifier: Topic :: Software Development :: Embedded Systems
|
|
11
|
+
Classifier: Topic :: Software Development :: Testing
|
|
12
|
+
Requires-Dist: jinja2
|
|
13
|
+
Requires-Dist: jsonschema
|
|
14
|
+
Requires-Dist: labgrid>=26.0
|
|
15
|
+
Requires-Dist: pytest
|
|
16
|
+
Requires-Dist: pyyaml
|
|
17
|
+
Requires-Python: >=3.11
|
|
18
|
+
Project-URL: Repository, https://github.com/threexc/labgrid-boardkit
|
|
19
|
+
Description-Content-Type: text/markdown
|
|
20
|
+
|
|
21
|
+
# labgrid-boardkit
|
|
22
|
+
|
|
23
|
+
Board manifests, boot strategies, pytest fixtures and test suites for
|
|
24
|
+
[labgrid](https://github.com/labgrid-project/labgrid).
|
|
25
|
+
|
|
26
|
+
Describe a board once in a `board.yaml` manifest, and labgrid-boardkit
|
|
27
|
+
generates its labgrid `client.yaml` and drives it through a reusable boot
|
|
28
|
+
strategy family:
|
|
29
|
+
|
|
30
|
+
| Family | Boots via |
|
|
31
|
+
|------------|---------------------------------------------|
|
|
32
|
+
| `tftp` | U-Boot `tftpboot` (kernel, DTB, initramfs/FIT) |
|
|
33
|
+
| `sdmux` | an SD card image written through a USB-SD-Mux |
|
|
34
|
+
| `fastboot` | images flashed to eMMC/NOR over fastboot |
|
|
35
|
+
| `qemu` | QEMU, no hardware needed |
|
|
36
|
+
|
|
37
|
+
## Install
|
|
38
|
+
|
|
39
|
+
```
|
|
40
|
+
pip install labgrid-boardkit
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
## Usage
|
|
44
|
+
|
|
45
|
+
Lay out your boards as `boards/<name>/board.yaml`. Shared settings can go in
|
|
46
|
+
a file listed under `inherits:`. For example (`tests/fixtures/boards/` has one
|
|
47
|
+
board per family, plus a shared `families/` file and a variant):
|
|
48
|
+
|
|
49
|
+
```yaml
|
|
50
|
+
name: example-qemu
|
|
51
|
+
yocto_machine: qemuriscv64
|
|
52
|
+
strategy: qemu
|
|
53
|
+
arch: riscv64
|
|
54
|
+
description: QEMU RISC-V virt machine, no hardware needed
|
|
55
|
+
|
|
56
|
+
boot:
|
|
57
|
+
bootargs: root=/dev/vda rw console=ttyS0
|
|
58
|
+
|
|
59
|
+
qemu:
|
|
60
|
+
binary: qemu-system-riscv64
|
|
61
|
+
machine: virt
|
|
62
|
+
cpu: rv64
|
|
63
|
+
memory: 2048
|
|
64
|
+
ssh_port: 2222
|
|
65
|
+
telnet_port: 2323
|
|
66
|
+
|
|
67
|
+
images:
|
|
68
|
+
bios: /srv/images/example-qemu/fw_jump.elf
|
|
69
|
+
kernel: /srv/images/example-qemu/Image
|
|
70
|
+
ext4: /srv/images/example-qemu/rootfs.ext4
|
|
71
|
+
|
|
72
|
+
shell:
|
|
73
|
+
username: root
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
From the directory that contains `boards/`:
|
|
77
|
+
|
|
78
|
+
```
|
|
79
|
+
boardkit-validate # check every boards/*/board.yaml against the schema
|
|
80
|
+
boardkit-render # write each board's client.yaml/env.yaml and boards/machines.tsv
|
|
81
|
+
boardkit-render --check # exit 1 if any rendered file is out of date (for CI)
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
Installing the package also registers a pytest plugin. It picks `--lg-env`
|
|
85
|
+
from `$BOARD` or the nearest `client.yaml`, and provides the `tftp`, `sd` and
|
|
86
|
+
`fastboot` fixtures. Generic on-target suites ship with the package:
|
|
87
|
+
|
|
88
|
+
```
|
|
89
|
+
BOARD=boards/my-board pytest --pyargs labgrid_boardkit.tests
|
|
90
|
+
pytest --lg-env boards/example-qemu/env.yaml --pyargs labgrid_boardkit.ptest
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
## Adding a strategy family
|
|
94
|
+
|
|
95
|
+
Families are found through the `labgrid_boardkit.strategies` entry-point
|
|
96
|
+
group, so another package can add one without changing this one:
|
|
97
|
+
|
|
98
|
+
```toml
|
|
99
|
+
[project.entry-points."labgrid_boardkit.strategies"]
|
|
100
|
+
myfamily = "my_package.strategies:MyBootStrategy"
|
|
101
|
+
```
|
|
102
|
+
|
|
103
|
+
## Development
|
|
104
|
+
|
|
105
|
+
```
|
|
106
|
+
uv run pytest
|
|
107
|
+
uv run ruff check . && uv run ruff format --check .
|
|
108
|
+
```
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
# labgrid-boardkit
|
|
2
|
+
|
|
3
|
+
Board manifests, boot strategies, pytest fixtures and test suites for
|
|
4
|
+
[labgrid](https://github.com/labgrid-project/labgrid).
|
|
5
|
+
|
|
6
|
+
Describe a board once in a `board.yaml` manifest, and labgrid-boardkit
|
|
7
|
+
generates its labgrid `client.yaml` and drives it through a reusable boot
|
|
8
|
+
strategy family:
|
|
9
|
+
|
|
10
|
+
| Family | Boots via |
|
|
11
|
+
|------------|---------------------------------------------|
|
|
12
|
+
| `tftp` | U-Boot `tftpboot` (kernel, DTB, initramfs/FIT) |
|
|
13
|
+
| `sdmux` | an SD card image written through a USB-SD-Mux |
|
|
14
|
+
| `fastboot` | images flashed to eMMC/NOR over fastboot |
|
|
15
|
+
| `qemu` | QEMU, no hardware needed |
|
|
16
|
+
|
|
17
|
+
## Install
|
|
18
|
+
|
|
19
|
+
```
|
|
20
|
+
pip install labgrid-boardkit
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
## Usage
|
|
24
|
+
|
|
25
|
+
Lay out your boards as `boards/<name>/board.yaml`. Shared settings can go in
|
|
26
|
+
a file listed under `inherits:`. For example (`tests/fixtures/boards/` has one
|
|
27
|
+
board per family, plus a shared `families/` file and a variant):
|
|
28
|
+
|
|
29
|
+
```yaml
|
|
30
|
+
name: example-qemu
|
|
31
|
+
yocto_machine: qemuriscv64
|
|
32
|
+
strategy: qemu
|
|
33
|
+
arch: riscv64
|
|
34
|
+
description: QEMU RISC-V virt machine, no hardware needed
|
|
35
|
+
|
|
36
|
+
boot:
|
|
37
|
+
bootargs: root=/dev/vda rw console=ttyS0
|
|
38
|
+
|
|
39
|
+
qemu:
|
|
40
|
+
binary: qemu-system-riscv64
|
|
41
|
+
machine: virt
|
|
42
|
+
cpu: rv64
|
|
43
|
+
memory: 2048
|
|
44
|
+
ssh_port: 2222
|
|
45
|
+
telnet_port: 2323
|
|
46
|
+
|
|
47
|
+
images:
|
|
48
|
+
bios: /srv/images/example-qemu/fw_jump.elf
|
|
49
|
+
kernel: /srv/images/example-qemu/Image
|
|
50
|
+
ext4: /srv/images/example-qemu/rootfs.ext4
|
|
51
|
+
|
|
52
|
+
shell:
|
|
53
|
+
username: root
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
From the directory that contains `boards/`:
|
|
57
|
+
|
|
58
|
+
```
|
|
59
|
+
boardkit-validate # check every boards/*/board.yaml against the schema
|
|
60
|
+
boardkit-render # write each board's client.yaml/env.yaml and boards/machines.tsv
|
|
61
|
+
boardkit-render --check # exit 1 if any rendered file is out of date (for CI)
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
Installing the package also registers a pytest plugin. It picks `--lg-env`
|
|
65
|
+
from `$BOARD` or the nearest `client.yaml`, and provides the `tftp`, `sd` and
|
|
66
|
+
`fastboot` fixtures. Generic on-target suites ship with the package:
|
|
67
|
+
|
|
68
|
+
```
|
|
69
|
+
BOARD=boards/my-board pytest --pyargs labgrid_boardkit.tests
|
|
70
|
+
pytest --lg-env boards/example-qemu/env.yaml --pyargs labgrid_boardkit.ptest
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
## Adding a strategy family
|
|
74
|
+
|
|
75
|
+
Families are found through the `labgrid_boardkit.strategies` entry-point
|
|
76
|
+
group, so another package can add one without changing this one:
|
|
77
|
+
|
|
78
|
+
```toml
|
|
79
|
+
[project.entry-points."labgrid_boardkit.strategies"]
|
|
80
|
+
myfamily = "my_package.strategies:MyBootStrategy"
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
## Development
|
|
84
|
+
|
|
85
|
+
```
|
|
86
|
+
uv run pytest
|
|
87
|
+
uv run ruff check . && uv run ruff format --check .
|
|
88
|
+
```
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
[build-system]
|
|
2
|
+
requires = ["uv_build>=0.7,<0.14"]
|
|
3
|
+
build-backend = "uv_build"
|
|
4
|
+
|
|
5
|
+
[project]
|
|
6
|
+
name = "labgrid-boardkit"
|
|
7
|
+
version = "0.1.0"
|
|
8
|
+
description = "Board manifests, boot strategies, fixtures and test suites for labgrid"
|
|
9
|
+
readme = "README.md"
|
|
10
|
+
license = "MIT"
|
|
11
|
+
license-files = ["LICENSE"]
|
|
12
|
+
requires-python = ">=3.11"
|
|
13
|
+
classifiers = [
|
|
14
|
+
"Framework :: Pytest",
|
|
15
|
+
"Topic :: Software Development :: Embedded Systems",
|
|
16
|
+
"Topic :: Software Development :: Testing",
|
|
17
|
+
]
|
|
18
|
+
dependencies = [
|
|
19
|
+
"jinja2",
|
|
20
|
+
"jsonschema",
|
|
21
|
+
"labgrid>=26.0",
|
|
22
|
+
"pytest",
|
|
23
|
+
"pyyaml",
|
|
24
|
+
]
|
|
25
|
+
|
|
26
|
+
[[project.authors]]
|
|
27
|
+
name = "Trevor Gamblin"
|
|
28
|
+
email = "tgamblin@baylibre.com"
|
|
29
|
+
|
|
30
|
+
[project.urls]
|
|
31
|
+
Repository = "https://github.com/threexc/labgrid-boardkit"
|
|
32
|
+
|
|
33
|
+
[project.scripts]
|
|
34
|
+
boardkit-validate = "labgrid_boardkit.validate:main"
|
|
35
|
+
boardkit-render = "labgrid_boardkit.render:main"
|
|
36
|
+
|
|
37
|
+
[project.entry-points.pytest11]
|
|
38
|
+
labgrid_boardkit = "labgrid_boardkit.fixtures"
|
|
39
|
+
|
|
40
|
+
[project.entry-points."labgrid_boardkit.strategies"]
|
|
41
|
+
tftp = "labgrid_boardkit.strategies.tftp:TftpBootStrategy"
|
|
42
|
+
sdmux = "labgrid_boardkit.strategies.sdmux:SdMuxBootStrategy"
|
|
43
|
+
fastboot = "labgrid_boardkit.strategies.fastboot:FastbootFlashStrategy"
|
|
44
|
+
qemu = "labgrid_boardkit.strategies.qemu:QemuBootStrategy"
|
|
45
|
+
|
|
46
|
+
[tool.pytest.ini_options]
|
|
47
|
+
testpaths = ["tests"]
|
|
48
|
+
|
|
49
|
+
[tool.ruff]
|
|
50
|
+
line-length = 100
|
|
51
|
+
target-version = "py311"
|
|
52
|
+
|
|
53
|
+
[tool.ruff.lint]
|
|
54
|
+
select = [
|
|
55
|
+
"E",
|
|
56
|
+
"F",
|
|
57
|
+
"I",
|
|
58
|
+
"UP",
|
|
59
|
+
"B",
|
|
60
|
+
"SIM",
|
|
61
|
+
]
|
|
62
|
+
ignore = ["E501"]
|
|
63
|
+
|
|
64
|
+
[dependency-groups]
|
|
65
|
+
dev = ["ruff>=0.14"]
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
[build-system]
|
|
2
|
+
requires = ["uv_build>=0.7,<0.14"]
|
|
3
|
+
build-backend = "uv_build"
|
|
4
|
+
|
|
5
|
+
[project]
|
|
6
|
+
name = "labgrid-boardkit"
|
|
7
|
+
version = "0.1.0"
|
|
8
|
+
description = "Board manifests, boot strategies, fixtures and test suites for labgrid"
|
|
9
|
+
readme = "README.md"
|
|
10
|
+
license = "MIT"
|
|
11
|
+
license-files = ["LICENSE"]
|
|
12
|
+
authors = [{ name = "Trevor Gamblin", email = "tgamblin@baylibre.com" }]
|
|
13
|
+
requires-python = ">=3.11"
|
|
14
|
+
classifiers = [
|
|
15
|
+
"Framework :: Pytest",
|
|
16
|
+
"Topic :: Software Development :: Embedded Systems",
|
|
17
|
+
"Topic :: Software Development :: Testing",
|
|
18
|
+
]
|
|
19
|
+
dependencies = [
|
|
20
|
+
"jinja2",
|
|
21
|
+
"jsonschema",
|
|
22
|
+
"labgrid>=26.0",
|
|
23
|
+
"pytest",
|
|
24
|
+
"pyyaml",
|
|
25
|
+
]
|
|
26
|
+
|
|
27
|
+
[project.urls]
|
|
28
|
+
Repository = "https://github.com/threexc/labgrid-boardkit"
|
|
29
|
+
|
|
30
|
+
[project.scripts]
|
|
31
|
+
boardkit-validate = "labgrid_boardkit.validate:main"
|
|
32
|
+
boardkit-render = "labgrid_boardkit.render:main"
|
|
33
|
+
|
|
34
|
+
# Auto-loaded into any pytest run inside this venv:
|
|
35
|
+
[project.entry-points.pytest11]
|
|
36
|
+
labgrid_boardkit = "labgrid_boardkit.fixtures"
|
|
37
|
+
|
|
38
|
+
# Strategy family registry. Add a line here to expose a new family; third-party
|
|
39
|
+
# packages register in the same group.
|
|
40
|
+
[project.entry-points."labgrid_boardkit.strategies"]
|
|
41
|
+
tftp = "labgrid_boardkit.strategies.tftp:TftpBootStrategy"
|
|
42
|
+
sdmux = "labgrid_boardkit.strategies.sdmux:SdMuxBootStrategy"
|
|
43
|
+
fastboot = "labgrid_boardkit.strategies.fastboot:FastbootFlashStrategy"
|
|
44
|
+
qemu = "labgrid_boardkit.strategies.qemu:QemuBootStrategy"
|
|
45
|
+
|
|
46
|
+
[tool.pytest.ini_options]
|
|
47
|
+
# src/labgrid_boardkit/{tests,ptest} are on-target suites needing labgrid
|
|
48
|
+
# hardware or QEMU; run those with `pytest --pyargs labgrid_boardkit.tests`.
|
|
49
|
+
testpaths = ["tests"]
|
|
50
|
+
|
|
51
|
+
[dependency-groups]
|
|
52
|
+
dev = [
|
|
53
|
+
"ruff>=0.14",
|
|
54
|
+
]
|
|
55
|
+
|
|
56
|
+
[tool.ruff]
|
|
57
|
+
line-length = 100
|
|
58
|
+
target-version = "py311"
|
|
59
|
+
|
|
60
|
+
[tool.ruff.lint]
|
|
61
|
+
select = ["E", "F", "I", "UP", "B", "SIM"]
|
|
62
|
+
ignore = ["E501"]
|
|
File without changes
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
"""pytest fixtures + hooks shared across all board test suites.
|
|
2
|
+
|
|
3
|
+
Auto-loaded via the ``pytest11`` entry point in
|
|
4
|
+
``pyproject.toml``. No per-board conftest.py needed for these.
|
|
5
|
+
"""
|
|
6
|
+
|
|
7
|
+
import os
|
|
8
|
+
import traceback
|
|
9
|
+
from pathlib import Path
|
|
10
|
+
|
|
11
|
+
import pytest
|
|
12
|
+
|
|
13
|
+
from labgrid_boardkit.strategies.fastboot import FastbootFlashStrategy
|
|
14
|
+
from labgrid_boardkit.strategies.sdmux import SdMuxBootStrategy
|
|
15
|
+
from labgrid_boardkit.strategies.tftp import TftpBootStrategy
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
def pytest_configure(config):
|
|
19
|
+
"""Auto-set ``--lg-env``.
|
|
20
|
+
|
|
21
|
+
Resolution order:
|
|
22
|
+
1. Skip if user already passed ``--lg-env``.
|
|
23
|
+
2. ``BOARD`` env var → ``$BOARD/client.yaml`` (or ``env.yaml``) rel to cwd.
|
|
24
|
+
3. Walk upward from each CLI arg looking for ``client.yaml`` / ``env.yaml``.
|
|
25
|
+
"""
|
|
26
|
+
if config.getoption("--lg-env", default=None):
|
|
27
|
+
return
|
|
28
|
+
|
|
29
|
+
board = os.environ.get("BOARD")
|
|
30
|
+
if board:
|
|
31
|
+
for candidate in (Path(board) / "client.yaml", Path(board) / "env.yaml"):
|
|
32
|
+
if candidate.is_file():
|
|
33
|
+
config.option.lg_env = str(candidate.resolve())
|
|
34
|
+
return
|
|
35
|
+
|
|
36
|
+
for arg in config.args:
|
|
37
|
+
for p in Path(arg).resolve().parents:
|
|
38
|
+
for candidate in (p / "client.yaml", p / "env.yaml"):
|
|
39
|
+
if candidate.is_file():
|
|
40
|
+
config.option.lg_env = str(candidate)
|
|
41
|
+
return
|
|
42
|
+
|
|
43
|
+
|
|
44
|
+
def _transition(strategy, target, state: str):
|
|
45
|
+
try:
|
|
46
|
+
strategy.transition(state)
|
|
47
|
+
except Exception as e:
|
|
48
|
+
traceback.print_exc()
|
|
49
|
+
pytest.exit(f"Transition into {state} boot shell failed: {e}", returncode=3)
|
|
50
|
+
return target.get_driver("ShellDriver")
|
|
51
|
+
|
|
52
|
+
|
|
53
|
+
@pytest.fixture(scope="module")
|
|
54
|
+
def tftp(strategy, target):
|
|
55
|
+
if not isinstance(strategy, TftpBootStrategy):
|
|
56
|
+
pytest.skip("board does not use TFTP boot strategy")
|
|
57
|
+
return _transition(strategy, target, "tftp")
|
|
58
|
+
|
|
59
|
+
|
|
60
|
+
@pytest.fixture(scope="module")
|
|
61
|
+
def sd(strategy, target):
|
|
62
|
+
if not isinstance(strategy, SdMuxBootStrategy):
|
|
63
|
+
pytest.skip("board does not use SD-mux boot strategy")
|
|
64
|
+
return _transition(strategy, target, "sd")
|
|
65
|
+
|
|
66
|
+
|
|
67
|
+
@pytest.fixture(scope="module")
|
|
68
|
+
def fastboot(strategy, target):
|
|
69
|
+
if not isinstance(strategy, FastbootFlashStrategy):
|
|
70
|
+
pytest.skip("board does not use fastboot flash strategy")
|
|
71
|
+
return _transition(strategy, target, "shell")
|
|
72
|
+
|
|
73
|
+
|
|
74
|
+
@pytest.fixture(scope="module")
|
|
75
|
+
def shell(strategy, target):
|
|
76
|
+
"""Generic shell fixture: transitions to the ``shell`` state (qemu)."""
|
|
77
|
+
return _transition(strategy, target, "shell")
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
# Helper functions for the labgrid-boardkit test suites and strategies
|
|
2
|
+
|
|
3
|
+
import re
|
|
4
|
+
|
|
5
|
+
default_bootargs = (
|
|
6
|
+
"console=tty1 "
|
|
7
|
+
"console=ttyS0,115200 "
|
|
8
|
+
"consoleblank=0 "
|
|
9
|
+
"earlycon=sbi "
|
|
10
|
+
"fsck.fix=yes "
|
|
11
|
+
"fsck.repair=yes "
|
|
12
|
+
"loglevel=7 "
|
|
13
|
+
"net.ifnames=0 "
|
|
14
|
+
"no_console_suspend "
|
|
15
|
+
"plymouth.ignore-serial-consoles "
|
|
16
|
+
"rootwait "
|
|
17
|
+
"rw "
|
|
18
|
+
"splash "
|
|
19
|
+
"systemd.journald.storage=volatile "
|
|
20
|
+
)
|
|
21
|
+
|
|
22
|
+
default_serverip = "192.168.40.166"
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
def kernel_version_in(version: str, uname: str) -> bool:
|
|
26
|
+
"""True if the kernel recipe's version (as CI takes it from the deployed
|
|
27
|
+
kernel's file name, e.g. "7.4-rc1") is the one ``uname`` reports. The
|
|
28
|
+
kernel always has a sublevel, so an rc reports "7.4.0-rc1"."""
|
|
29
|
+
return version in uname or re.sub(r"^(\d+\.\d+)(?=-|$)", r"\1.0", version) in uname
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
def uboot_stage(strategy):
|
|
33
|
+
if strategy.staged:
|
|
34
|
+
return
|
|
35
|
+
strategy.target.activate(strategy.tftp)
|
|
36
|
+
|
|
37
|
+
for name, image in strategy.target.env.config.get_images().items():
|
|
38
|
+
if name.startswith("tftp-"):
|
|
39
|
+
strategy.tftp.stage(image)
|
|
40
|
+
|
|
41
|
+
strategy.target.deactivate(strategy.tftp)
|
|
42
|
+
strategy.staged = True
|
|
43
|
+
|
|
44
|
+
|
|
45
|
+
def uboot_set_server_ip(strategy, serverip=default_serverip):
|
|
46
|
+
strategy.uboot.run("setenv autoload no")
|
|
47
|
+
# run_check: a failed dhcp/tftpboot should fail here, not as a confusing
|
|
48
|
+
# boot timeout later.
|
|
49
|
+
strategy.uboot.run_check("dhcp", timeout=10)
|
|
50
|
+
strategy.uboot.run(f"setenv serverip {serverip}")
|
|
51
|
+
|
|
52
|
+
|
|
53
|
+
def uboot_set_bootargs(strategy, bootargs=default_bootargs):
|
|
54
|
+
strategy.uboot.run(f"setenv bootargs {bootargs}")
|
|
55
|
+
|
|
56
|
+
|
|
57
|
+
def uboot_tftpboot_file(strategy, loadaddr, board_name, file_name):
|
|
58
|
+
strategy.uboot.run_check(f"tftpboot {loadaddr} {board_name}/{file_name}")
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
"""Registry lookup for strategy families.
|
|
2
|
+
|
|
3
|
+
Strategies are registered as ``labgrid_boardkit.strategies`` entry points in
|
|
4
|
+
``pyproject.toml``. Third-party packages can add families the same way.
|
|
5
|
+
"""
|
|
6
|
+
|
|
7
|
+
from importlib.metadata import entry_points
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
class UnknownStrategy(KeyError):
|
|
11
|
+
pass
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
def available_strategies() -> dict[str, str]:
|
|
15
|
+
"""Return {family_name: dotted-path} for every registered strategy."""
|
|
16
|
+
return {ep.name: ep.value for ep in entry_points(group="labgrid_boardkit.strategies")}
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
def strategy_for(manifest: dict):
|
|
20
|
+
"""Look up a strategy class by ``manifest['strategy']``."""
|
|
21
|
+
name = manifest.get("strategy")
|
|
22
|
+
if not name:
|
|
23
|
+
raise UnknownStrategy("board.yaml is missing top-level 'strategy: <family>' key")
|
|
24
|
+
eps = {ep.name: ep for ep in entry_points(group="labgrid_boardkit.strategies")}
|
|
25
|
+
if name not in eps:
|
|
26
|
+
raise UnknownStrategy(f"strategy {name!r} not registered (available: {sorted(eps)})")
|
|
27
|
+
return eps[name].load()
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
"""Load and merge board.yaml manifests.
|
|
2
|
+
|
|
3
|
+
``inherits:`` in a board.yaml lists paths (relative to the board dir) to
|
|
4
|
+
defaults files. Files are deep-merged in order; the board.yaml wins.
|
|
5
|
+
|
|
6
|
+
``variants:`` maps a name to overrides describing another way to boot the same
|
|
7
|
+
board, usually for a different Yocto MACHINE (e.g. a mainline-kernel BSP that
|
|
8
|
+
TFTP-boots while the default flashes storage). A variant is deep-merged over
|
|
9
|
+
the base manifest.
|
|
10
|
+
"""
|
|
11
|
+
|
|
12
|
+
from copy import deepcopy
|
|
13
|
+
from pathlib import Path
|
|
14
|
+
|
|
15
|
+
import yaml
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
def _read_yaml(path: Path) -> dict:
|
|
19
|
+
with path.open() as f:
|
|
20
|
+
return yaml.safe_load(f) or {}
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
def _deep_merge(base: dict, over: dict) -> dict:
|
|
24
|
+
"""Recursively merge ``over`` into ``base``. Lists and scalars are replaced."""
|
|
25
|
+
out = deepcopy(base)
|
|
26
|
+
for k, v in over.items():
|
|
27
|
+
if k in out and isinstance(out[k], dict) and isinstance(v, dict):
|
|
28
|
+
out[k] = _deep_merge(out[k], v)
|
|
29
|
+
else:
|
|
30
|
+
out[k] = deepcopy(v)
|
|
31
|
+
return out
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
def load_board(board_dir: str | Path, variant: str | None = None) -> dict:
|
|
35
|
+
"""Load ``board.yaml`` from a board directory, applying ``inherits:`` defaults
|
|
36
|
+
and, if given, the named ``variants:`` entry. The result has no ``variants``."""
|
|
37
|
+
board_dir = Path(board_dir)
|
|
38
|
+
board_yaml = _read_yaml(board_dir / "board.yaml")
|
|
39
|
+
|
|
40
|
+
merged: dict = {}
|
|
41
|
+
for rel in board_yaml.get("inherits", []):
|
|
42
|
+
merged = _deep_merge(merged, _read_yaml((board_dir / rel).resolve()))
|
|
43
|
+
merged = _deep_merge(merged, board_yaml)
|
|
44
|
+
merged.pop("inherits", None)
|
|
45
|
+
variants = merged.pop("variants", {})
|
|
46
|
+
if variant is not None:
|
|
47
|
+
merged = _deep_merge(merged, variants[variant])
|
|
48
|
+
return merged
|
|
49
|
+
|
|
50
|
+
|
|
51
|
+
def board_variants(board_dir: str | Path) -> list[str]:
|
|
52
|
+
"""Names of the ``variants:`` declared in a board's ``board.yaml``."""
|
|
53
|
+
return list(_read_yaml(Path(board_dir) / "board.yaml").get("variants", {}))
|
|
File without changes
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
"""ptest-runner suite for any qemu board, e.g.
|
|
2
|
+
|
|
3
|
+
uv run pytest --lg-env boards/qemux86-64/env.yaml --pyargs labgrid_boardkit.ptest
|
|
4
|
+
"""
|
|
5
|
+
|
|
6
|
+
import os
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
class TestPtests:
|
|
10
|
+
def test_system_booted(self, shell):
|
|
11
|
+
stdout, stderr, rc = shell.run("echo hello")
|
|
12
|
+
assert rc == 0
|
|
13
|
+
assert "hello" in stdout
|
|
14
|
+
|
|
15
|
+
def test_kernel_version(self, shell):
|
|
16
|
+
stdout, stderr, rc = shell.run("uname -r")
|
|
17
|
+
assert rc == 0
|
|
18
|
+
assert len(stdout) > 0
|
|
19
|
+
print(f"Kernel version: {stdout[0]}")
|
|
20
|
+
|
|
21
|
+
def test_ptests(self, shell):
|
|
22
|
+
timeout = int(os.environ.get("PTEST_TIMEOUT", 1200))
|
|
23
|
+
cmd = "ptest-runner"
|
|
24
|
+
# ptest-runner kills a ptest silent for this long (its default: 300s)
|
|
25
|
+
if runner_timeout := os.environ.get("PTEST_RUNNER_TIMEOUT"):
|
|
26
|
+
cmd += f" -t {int(runner_timeout)}"
|
|
27
|
+
stdout, stderr, rc = shell.run(cmd, timeout=timeout)
|
|
28
|
+
assert rc == 0
|