Skip to content

Commit 52a8a5b

Browse files
committed
Add initial infrastructure to build and run tests on hardware.
Signed-off-by: Abdelatif Guettouche <[email protected]>
1 parent caef400 commit 52a8a5b

File tree

8 files changed

+170
-0
lines changed

8 files changed

+170
-0
lines changed

Diff for: .github/workflows/hil.yml

+113
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,113 @@
1+
name: Run tests in hardware
2+
3+
on:
4+
pull_request:
5+
types: [opened, reopened, synchronize, labeled]
6+
7+
# schedule:
8+
# - cron: '0 2 * * *'
9+
10+
concurrency:
11+
group: build-${{github.event.pull_request.number || github.ref}}
12+
cancel-in-progress: true
13+
14+
jobs:
15+
prep_sketches:
16+
if: contains(github.event.pull_request.labels.*.name, 'hil_test')
17+
name: Prepare Sketches
18+
runs-on: ubuntu-latest
19+
outputs:
20+
sketches: ${{ steps.prep-sketches.outputs.sketches }}
21+
steps:
22+
- name: Checkout Repository
23+
uses: actions/checkout@v2
24+
25+
- name: Prepare Sketches
26+
id: prep-sketches
27+
run: |
28+
SKETCHES=$(jq -c -n '{sketches: $ARGS.positional}' --args `find tests -mindepth 1 -type d | cut -d"/" -f2`)
29+
echo "::set-output name=sketches::${SKETCHES}"
30+
31+
Build:
32+
needs: prep_sketches
33+
name: Build ${{matrix.sketches}}
34+
runs-on: ubuntu-latest
35+
strategy:
36+
matrix: ${{fromJson(needs.prep_sketches.outputs.sketches)}}
37+
38+
steps:
39+
- name: Checkout Repository
40+
uses: actions/checkout@v2
41+
42+
- name: Build sketches
43+
uses: arduino/compile-sketches@v1
44+
with:
45+
fqbn: 'esp32:esp32:esp32'
46+
platforms: |
47+
- name: esp32:esp32
48+
source-url: https://raw.githubusercontent.com/espressif/arduino-esp32/gh-pages/package_esp32_index.json
49+
cli-compile-flags: |
50+
- --build-path
51+
- tests/${{matrix.sketches}}/build
52+
sketch-paths: |
53+
- tests/${{matrix.sketches}}
54+
55+
- name: Upload ${{matrix.sketches}} artifacts
56+
uses: actions/upload-artifact@v2
57+
with:
58+
name: ${{matrix.sketches}}.artifacts
59+
path: |
60+
tests/${{matrix.sketches}}/build/*.bin
61+
tests/${{matrix.sketches}}/build/*.json
62+
63+
Test:
64+
needs: [prep_sketches, Build]
65+
name: Test ${{matrix.sketches}}
66+
runs-on: ESP32
67+
env:
68+
PYTHON_VERSION: 3.10.1
69+
PYENV_VERSION: v2.2.3
70+
strategy:
71+
matrix: ${{fromJson(needs.prep_sketches.outputs.sketches)}}
72+
73+
steps:
74+
- name: Checkout repository
75+
uses: actions/checkout@v2
76+
77+
- name: Download ${{matrix.sketches}} artifacts
78+
uses: actions/download-artifact@v2
79+
with:
80+
name: ${{matrix.sketches}}.artifacts
81+
path: tests/${{matrix.sketches}}/build
82+
83+
# Our self-hosted runners run on an RPI, the setup-python action doesn't
84+
# support an ARM architecture.
85+
86+
- name: Cache Python
87+
id: cache-python
88+
uses: actions/cache@v2
89+
with:
90+
path: ~/.pyenv
91+
key: pyenv-${{env.PYENV_VERSION}}-${{env.PYTHON_VERSION}}
92+
93+
- name: Install Python
94+
if: steps.cache-python.outputs.cache-hit != 'true'
95+
run: |
96+
rm -rf ~/.pyenv
97+
git clone https://github.com/pyenv/pyenv.git -b ${{env.PYENV_VERSION}} ~/.pyenv
98+
export PYENV_ROOT=~/.pyenv
99+
export PATH=$PYENV_ROOT/bin:$PATH
100+
pyenv install ${{env.PYTHON_VERSION}}
101+
102+
- name: Install dependencies
103+
run: |
104+
~/.pyenv/versions/${{env.PYTHON_VERSION}}/bin/python -m venv test_venv
105+
source test_venv/bin/activate
106+
pip install -U pip
107+
pip install -r tests/requirements.txt
108+
109+
- name: Run Tests
110+
run: |
111+
~/.pyenv/versions/${{env.PYTHON_VERSION}}/bin/python -m venv test_venv
112+
source test_venv/bin/activate
113+
pytest tests -k test_${{matrix.sketches}}

Diff for: tests/.gitignore

+3
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
build/
2+
__pycache__/
3+
*.log

Diff for: tests/hello_world/hello_world.ino

+12
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
void setup(){
2+
// Open serial communications and wait for port to open:
3+
Serial.begin(115200);
4+
while (!Serial) {
5+
;
6+
}
7+
8+
Serial.println("Hello Arduino!");
9+
}
10+
11+
void loop(){
12+
}

Diff for: tests/hello_world/test_hello_world.py

+2
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
def test_hello_arduino(dut):
2+
dut.expect('Hello Arduino!')

Diff for: tests/pytest.ini

+13
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
[pytest]
2+
addopts = --embedded-services esp,arduino
3+
4+
# log related
5+
log_cli = True
6+
log_cli_level = INFO
7+
log_cli_format = %(asctime)s %(levelname)s %(message)s
8+
log_cli_date_format = %Y-%m-%d %H:%M:%S
9+
10+
log_file = test.log
11+
log_file_level = INFO
12+
log_file_format = %(asctime)s %(levelname)s %(message)s
13+
log_file_date_format = %Y-%m-%d %H:%M:%S

Diff for: tests/requirements.txt

+13
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
pyserial>=3.0
2+
esptool>=3.1
3+
pytest-cov
4+
cryptography<3.4; platform_machine == "armv7l"
5+
6+
pytest>=6.2.0
7+
pexpect>=4.4
8+
9+
pytest-embedded==0.5.0rc0
10+
pytest-embedded-serial==0.5.0rc0
11+
pytest-embedded-serial-esp==0.5.0rc0
12+
pytest-embedded-arduino==0.5.0rc0
13+

Diff for: tests/serial/serial.ino

+12
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
void setup(){
2+
// Open serial communications and wait for port to open:
3+
Serial.begin(115200);
4+
while (!Serial) {
5+
;
6+
}
7+
8+
Serial.println("Hello Serial!");
9+
}
10+
11+
void loop(){
12+
}

Diff for: tests/serial/test_serial.py

+2
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
def test_serial(dut):
2+
dut.expect('Hello Serial!')

0 commit comments

Comments
 (0)