-
Notifications
You must be signed in to change notification settings - Fork 11
287 lines (252 loc) · 11.8 KB
/
notecard-binary-tests.yml
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
name: note-c card.binary HIL tests
on:
pull_request:
branches: [ master ]
workflow_dispatch:
schedule:
# * is a special character in YAML so you have to quote this string
- cron: '45 4 * * 1' # 4.45am every Monday
permissions:
checks: write
jobs:
md5srv-test:
uses: ./.github/workflows/md5srv-tests.yml
notecard-binary-test:
needs: md5srv-test
runs-on: ubuntu-latest
defaults:
run:
shell: bash
env:
MD5SRV_PORT: 9178
NOTEHUB: "notehub.io"
NOTEHUB_API: "api.notefile.net"
NOTEHUB_PROJECT_UID: "app:458d7b93-8e19-45f8-b030-fb96d03eb1cc"
NOTEHUB_PRODUCT_UID: "com.blues.hitl"
NOTEHUB_ROUTE_TIMEOUT: 180
PIO_PROJECT_DIR: ./test/hitl/card.binary
NOTEHUB_PROXY_ROUTE_ALIAS: card.binary.${{github.run_id}}
NOTEHUB_PROXY_ROUTE_LABEL: card.binary.proxy.${{github.run_id}}
NOTEHUB_HTTP_ROUTE_LABEL: card.binary.http.${{github.run_id}}
# Troubleshooting helpers
# DELETE_NOTEHUB_ROUTES set to false to see the created routes on notehub
DELETE_NOTEHUB_ROUTES: true
# CREATE_NOTEHUB_ROUTES set to false to use the already created routes on notehub
CREATE_NOTEHUB_ROUTES: true
steps:
- name: Connect to Tailscale
uses: tailscale/github-action@v2
with:
oauth-client-id: ${{ secrets.TS_OAUTH_CLIENT_ID }}
oauth-secret: ${{ secrets.TS_OAUTH_CLIENT_SECRET }}
tags: tag:ci
# Needed for asyncio.TaskGroup, which the card_client code uses.
- name: Set up Python 3.11
uses: actions/setup-python@v4
with:
python-version: '3.11'
- name: Checkout note-c repo
uses: actions/checkout@v4
- name: Checkout hil_lab repo
uses: actions/checkout@v4
with:
repository: blues/hil_lab
ref: master
path: hil_lab
# Since hil_lab is a private repo, we need to authenticate. This uses
# the "deploy keys" approach described here:
# https://stackoverflow.com/a/70283191
ssh-key: ${{ secrets.HIL_LAB_CLONE_PRIV_KEY }}
- name: Generate MD5 Server Token
run: |
[ -n "$MD5SRV_TOKEN" ] || echo "MD5SRV_TOKEN=`uuidgen`" >> $GITHUB_ENV
# gdb-multiarch: We used gdb to remotely flash the test firmware onto the
# Swan attached to the Notestation. Apparently "regular" gdb (i.e.
# installed via apt install gdb) can't cope with the fact that the target
# is ARM.
# ngrok: Used to get a public IP for the MD5 server.
# jq: Used for JSON parsing.
- name: Install apt dependencies
run: |
curl -sSL https://ngrok-agent.s3.amazonaws.com/ngrok.asc | \
sudo tee /etc/apt/trusted.gpg.d/ngrok.asc >/dev/null
echo "deb https://ngrok-agent.s3.amazonaws.com buster main" | \
sudo tee /etc/apt/sources.list.d/ngrok.list
sudo apt update
sudo apt install gdb-multiarch ngrok jq
# We need socat 1.7.4.4 because prior to that there are some issues with
# setting the baud rate properly. socat is used by the card_client code
# for various tunnels (e.g. Swan USB port, Swan OpenOCD server, etc.).
- name: Install socat 1.7.4.4
run: |
wget http://www.dest-unreach.org/socat/download/socat-1.7.4.4.tar.gz
tar xvf socat-1.7.4.4.tar.gz
cd socat-1.7.4.4
./configure
make -j
sudo make install
- name: Install PlatformIO dependencies
run: |
python -m pip install --upgrade pip
pip install platformio
cd $PIO_PROJECT_DIR
pio pkg install -l "Blues Wireless Notecard" -e debug
# Remove the bundled note-c and put the local working copy there
NOTE_C_DEP="$GITHUB_WORKSPACE/$PIO_PROJECT_DIR/.pio/libdeps/debug/Blues Wireless Notecard/src/note-c"
rm -rf "$NOTE_C_DEP"
mkdir "$NOTE_C_DEP"
# copy only files in note-c
find "$GITHUB_WORKSPACE" -maxdepth 1 -type f -exec cp "{}" "${NOTE_C_DEP}" \;
- name: Start MD5 server
run: |
mkdir md5srv-files
./scripts/run_md5srv.sh
- name: Start ngrok
run: |
ngrok config add-authtoken ${{ secrets.NGROK_AUTH_TOKEN }}
./scripts/run_ngrok.sh
- name: Check MD5 server is available
run: |
# The request will return a 401 from md5srv, but that's expected without the access token
# Curl still returns success because it could contact the server
code=`curl -s -o /dev/null -w "%{http_code}" $MD5SRV_URL`
if [ "$code" -ge "500" ]; then
echo "5xx error ($code) from tunnel."
exit 1
else
echo "MD5 server is available."
fi
- name: Create Notehub accesss token
if: env.CREATE_NOTEHUB_ROUTES!='false'
run: |
curl -f -X POST \
-L 'https://${{ env.NOTEHUB }}/oauth2/token' \
-H 'content-type: application/x-www-form-urlencoded' \
-d grant_type=client_credentials \
-d client_id=${{ secrets.NOTEHUB_HIL_CLIENT_ID }} \
-d client_secret=${{ secrets.NOTEHUB_HIL_CLIENT_SECRET }} | \
{ token=$(jq -r .access_token); echo "NOTEHUB_ACCESS_TOKEN=$token" >> $GITHUB_ENV; }
- name: Create Notehub HTTP route
if: env.CREATE_NOTEHUB_ROUTES!='false'
run: |
# ?note=1 instructs the MD5 server to process the content as an event, extracting the path
# from the event body.
route_req=`jq -n --arg TOKEN "$MD5SRV_TOKEN" --arg LABEL "$NOTEHUB_HTTP_ROUTE_LABEL" --arg URL "$MD5SRV_URL/?note=1" --argjson TIMEOUT $NOTEHUB_ROUTE_TIMEOUT \
'{ "label":$LABEL, "type":"http", "http":{ "timeout":$TIMEOUT, "filter": { "type":"include", "files": ["cardbinary.qo"] }, "url":$URL, "http_headers": { "X-Access-Token":$TOKEN } } }'`
echo "Notehub HTTP route request: $route_req"
route=`echo "$route_req" | curl -s -f -X POST -L "https://$NOTEHUB_API/v1/projects/${NOTEHUB_PROJECT_UID}/routes" \
-H "Authorization: Bearer $NOTEHUB_ACCESS_TOKEN" -d @-`
echo "Notehub HTTP route: $route"
route_uid=`echo $route | jq -r .uid`
if [ -n "$route_uid" ]; then
echo "NOTEHUB_HTTP_ROUTE_UID=$route_uid" >> $GITHUB_ENV
else
echo "Failed to create or parse Notehub HTTP route."
exit 1
fi
- name: Create Notehub proxy route
if: env.CREATE_NOTEHUB_ROUTES!='false'
run: |
ALIAS="$NOTEHUB_PROXY_ROUTE_ALIAS"
route=`jq -n --arg TOKEN "$MD5SRV_TOKEN" --arg LABEL "$NOTEHUB_PROXY_ROUTE_LABEL" --arg URL "$MD5SRV_URL" --arg ALIAS "$ALIAS" --argjson TIMEOUT $NOTEHUB_ROUTE_TIMEOUT \
'{ "label":$LABEL, "type":"proxy", "proxy":{ "timeout":$TIMEOUT, "url":$URL, "alias":$ALIAS, "http_headers": { "X-Access-Token":$TOKEN } } }' \
| curl -s -f -X POST -L "https://api.notefile.net/v1/projects/${NOTEHUB_PROJECT_UID}/routes" \
-H "Authorization: Bearer $NOTEHUB_ACCESS_TOKEN" -d @-`
echo "Notehub proxy route: $route"
route_uid=`echo "$route" | jq -r .uid`
if [ -n $route_uid ]; then
echo "NOTEHUB_PROXY_ROUTE_UID=$route_uid" >> $GITHUB_ENV
echo "NOTEHUB_PROXY_ROUTE_ALIAS=$ALIAS" >> $GITHUB_ENV
else
echo "Failed to create or parse Notehub proxy route."
exit 1
fi
- name: Build and upload test firmware and run tests
run: |
cd hil_lab/
pip install -r requirements.txt
# Reserve a Notestation with the label "note_c_card_binary_test",
# which means it has everything needed to run the note-c card.binary
# tests.
cd notestation/
nohup python -m core.card_client \
--mcu-debug \
--notestation los-angeles-notestation-1 \
--res-file ./reservation.json &> card_client.log &
PID=$!
timeout=600 # 10 minutes in seconds
interval=1 # Check every second
elapsed=0
# If we aren't able to reserve a Notestation after 10 minutes, or if
# the card_client fails, bail.
while [ ! -f ./reservation.json ]; do
sleep $interval
elapsed=$((elapsed + interval))
# Check if the Python process is still running
if ! kill -0 $PID 2>/dev/null; then
echo "Error: Process $PID has terminated unexpectedly."
echo "$(cat card_client.log)"
exit 1
fi
if [ $elapsed -ge $timeout ]; then
echo "Timeout reached: reservation.json did not appear."
kill $PID 2>/dev/null
exit 1
fi
done
echo "Notestation reserved."
# Set these environment variables, which are read in platformio.ini in
# order to flash the Swan with the test firmware.
export MCU_GDB_SERVER_IP="$(jq -r '.notestation' ./reservation.json)"
export MCU_GDB_SERVER_PORT="$(jq -r '.mcu_openocd.gdb' ./reservation.json)"
export GDB_CMD="gdb-multiarch"
if [ -z "$MCU_GDB_SERVER_IP" ] || [ "$MCU_GDB_SERVER_IP" == "null" ]; then
echo "Error: MCU_GDB_SERVER_IP is empty or not defined."
exit 1
fi
if [ -z "$MCU_GDB_SERVER_PORT" ] || [ "$MCU_GDB_SERVER_PORT" -eq 0 ]; then
echo "Error: MCU_GDB_SERVER_PORT is empty or zero."
exit 1
fi
export PLATFORMIO_BUILD_FLAGS="'-D NOTEHUB_PROXY_ROUTE_ALIAS=\"$NOTEHUB_PROXY_ROUTE_ALIAS\"' '-D PRODUCT_UID=\"$NOTEHUB_PRODUCT_UID\"'"
echo "build flags $PLATFORMIO_BUILD_FLAGS"
cd $GITHUB_WORKSPACE/$PIO_PROJECT_DIR
# Run the tests. It's important that we provided --no-reset here. If
# we don't, PlatformIO tries to fiddle with DTR and RTS, and that
# causes an exception because the serial port for the Swan isn't a
# local serial port. It's a virtual serial device hooked up to the
# Notestation over TCP, and from there it's connected to the actual
# Swan USB port. Trying to do DTR/RTS on the port causes an ioctl
# error, because PlatformIO is expecting a genuine serial device that
# plays nicely with the ioctl stuff it wants to use.
platformio test -v -e debug \
--no-reset \
--json-output-path test.json \
--junit-output-path test.xml
- name: Publish test report
uses: mikepenz/action-junit-report@v3
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
if: env.GITHUB_TOKEN && (success() || failure()) # always run even if the previous step fails
with:
report_paths: '**/test/hitl/card.binary/test*.xml'
check_name: Notecard Binary HIL Tests
require_tests: true
- name: Cleanup Notehub proxy route
if: always()
run: |
if [ "$DELETE_NOTEHUB_ROUTES" == "true" ] && [ -n "$NOTEHUB_PROXY_ROUTE_UID" ]; then
echo "Deleting Notehub proxy route."
curl -f -s -X DELETE \
-L "https://api.notefile.net/v1/projects/$NOTEHUB_PROJECT_UID/routes/$NOTEHUB_PROXY_ROUTE_UID" \
-H "Authorization: Bearer $NOTEHUB_ACCESS_TOKEN"
fi
- name: Cleanup Notehub HTTP route
if: always()
run: |
if [ "$DELETE_NOTEHUB_ROUTES" == "true" ] && [ -n "$NOTEHUB_HTTP_ROUTE_UID" ]; then
echo "Deleting Notehub HTTP route."
curl -f -s -X DELETE \
-L "https://$NOTEHUB_API/v1/projects/$NOTEHUB_PROJECT_UID/routes/$NOTEHUB_HTTP_ROUTE_UID" \
-H "Authorization: Bearer $NOTEHUB_ACCESS_TOKEN"
fi