Skip to content

Commit 3507aef

Browse files
committed
workflow tests for zephyr 4.3 and 4.1
1 parent 6074a2d commit 3507aef

3 files changed

Lines changed: 465 additions & 0 deletions

File tree

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
# Force EXTERNAL_LIBC to match customer's native_sim build
2+
CONFIG_EXTERNAL_LIBC=y
Lines changed: 384 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,384 @@
1+
#!/bin/bash
2+
#
3+
# zephyr-test.sh - Build and test wolfSSL Zephyr samples in a Docker container
4+
#
5+
# Usage:
6+
# ./zephyr-test.sh [options]
7+
#
8+
# Options:
9+
# -r, --repo <url> wolfSSL git repo URL
10+
# -b, --branch <branch> wolfSSL branch/revision
11+
# -z, --zephyr <version> Zephyr version tag
12+
# -t, --target <board> Board target
13+
# -s, --sample <name> Sample to build
14+
# -v, --verbose Verbose compile output (show full compiler commands)
15+
# -W, --werror Build with -Werror (treat warnings as errors)
16+
# --commit <sha> Checkout specific commit after fetching branch
17+
# -c, --cmake-args <str> Extra CMake args passed after -- to west build
18+
# --extra-conf <file> Extra Kconfig overlay (copied into container)
19+
# -i, --interactive Drop into interactive shell
20+
# -h, --help Show this help
21+
#
22+
# Examples:
23+
# # Test master against Zephyr 4.1.0 for native_sim
24+
# ./zephyr-test.sh
25+
#
26+
# # Test a specific branch for frdm_rw612 on Zephyr 4.3.0
27+
# ./zephyr-test.sh -b zephyr-4_3_0-posix-fix -z v4.3.0 -t frdm_rw612/rw612
28+
#
29+
# # Test with Zephyr 4.3.0 on native_sim
30+
# ./zephyr-test.sh -z v4.3.0
31+
#
32+
# # Interactive shell to debug
33+
# ./zephyr-test.sh -z v4.3.0 -i
34+
#
35+
# # Test a fork
36+
# ./zephyr-test.sh -r https://github.com/myuser/wolfssl -b my-fix -z v4.3.0
37+
#
38+
# # Build with -Werror like customer
39+
# ./zephyr-test.sh -z v4.3.0 -W
40+
#
41+
# # Pass extra cmake args
42+
# ./zephyr-test.sh -z v4.3.0 -c "-DCMAKE_C_FLAGS=-U_POSIX_C_SOURCE"
43+
44+
set -euo pipefail
45+
46+
# Defaults
47+
WOLFSSL_REPO="https://github.com/wolfSSL/wolfssl"
48+
WOLFSSL_BRANCH="master"
49+
ZEPHYR_VERSION="v4.1.0"
50+
BOARD_TARGET="native_sim"
51+
SAMPLE_NAME="wolfssl_tls_sock"
52+
INTERACTIVE=0
53+
VERBOSE=0
54+
WERROR=0
55+
WOLFSSL_COMMIT=""
56+
CMAKE_EXTRA=""
57+
EXTRA_CONF=""
58+
CONTAINER_NAME="" # set dynamically after arg parsing
59+
60+
GHCR="ghcr.io/zephyrproject-rtos/zephyr-build"
61+
62+
usage() {
63+
sed -n '3,/^$/s/^# \?//p' "$0"
64+
exit 0
65+
}
66+
67+
select_docker_image() {
68+
local ver="${1#v}"
69+
local major="${ver%%.*}"
70+
local minor="${ver#*.}"
71+
minor="${minor%%.*}"
72+
73+
if [[ "$major" -ge 4 && "$minor" -ge 2 ]]; then
74+
# Zephyr 4.2+ needs SDK 0.17.x (v0.28.7 image)
75+
echo "${GHCR}:v0.28.7"
76+
elif [[ "$major" -ge 4 ]]; then
77+
# Zephyr 4.0-4.1 needs SDK 0.17.0 (v0.27.4 image; v0.26.18/v0.28.7 picolibc is incompatible)
78+
echo "${GHCR}:v0.27.4"
79+
else
80+
# Zephyr 3.x and older
81+
echo "${GHCR}:v0.26.18"
82+
fi
83+
}
84+
85+
while [[ $# -gt 0 ]]; do
86+
case "$1" in
87+
-r|--repo) WOLFSSL_REPO="$2"; shift 2 ;;
88+
-b|--branch) WOLFSSL_BRANCH="$2"; shift 2 ;;
89+
-z|--zephyr) ZEPHYR_VERSION="$2"; shift 2 ;;
90+
-t|--target) BOARD_TARGET="$2"; shift 2 ;;
91+
-s|--sample) SAMPLE_NAME="$2"; shift 2 ;;
92+
-v|--verbose) VERBOSE=1; shift ;;
93+
-W|--werror) WERROR=1; shift ;;
94+
--commit) WOLFSSL_COMMIT="$2"; shift 2 ;;
95+
-c|--cmake-args) CMAKE_EXTRA="$2"; shift 2 ;;
96+
--extra-conf) EXTRA_CONF="$2"; shift 2 ;;
97+
-i|--interactive) INTERACTIVE=1; shift ;;
98+
-h|--help) usage ;;
99+
*) echo "Unknown option: $1"; usage ;;
100+
esac
101+
done
102+
103+
DOCKER_IMAGE=$(select_docker_image "$ZEPHYR_VERSION")
104+
105+
# Build a unique container name from version, board, sample, and PID to avoid collisions
106+
ZVER_SLUG="${ZEPHYR_VERSION#v}"
107+
BOARD_SLUG="${BOARD_TARGET//\//-}"
108+
CONTAINER_NAME="wolfssl-zephyr-${ZVER_SLUG}-${BOARD_SLUG}-${SAMPLE_NAME}-$$"
109+
110+
SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
111+
LOG_DIR="${SCRIPT_DIR}/logs"
112+
mkdir -p "${LOG_DIR}"
113+
TIMESTAMP=$(date +%Y%m%d_%H%M%S)
114+
ZVER="${ZEPHYR_VERSION#v}"
115+
LOG_FILE="${LOG_DIR}/${ZVER}_${WOLFSSL_BRANCH}_${BOARD_TARGET//\//-}_${TIMESTAMP}.log"
116+
117+
echo "==> wolfSSL repo: ${WOLFSSL_REPO}"
118+
echo "==> wolfSSL branch: ${WOLFSSL_BRANCH}"
119+
echo "==> Zephyr version: ${ZEPHYR_VERSION}"
120+
echo "==> Board target: ${BOARD_TARGET}"
121+
echo "==> Sample: ${SAMPLE_NAME}"
122+
echo "==> Docker image: ${DOCKER_IMAGE}"
123+
[[ -n "$WOLFSSL_COMMIT" ]] && echo "==> Commit: ${WOLFSSL_COMMIT}"
124+
[[ "$WERROR" == "1" ]] && echo "==> Werror: enabled"
125+
[[ -n "$CMAKE_EXTRA" ]] && echo "==> CMake args: ${CMAKE_EXTRA}"
126+
[[ -n "$EXTRA_CONF" ]] && echo "==> Extra conf: ${EXTRA_CONF}"
127+
echo "==> Log file: ${LOG_FILE}"
128+
echo ""
129+
130+
# Pull the Docker image
131+
echo "==> Pulling Docker image..."
132+
docker pull "${DOCKER_IMAGE}"
133+
134+
# Build the script that runs inside the container
135+
BUILD_SCRIPT=$(cat <<'INNER_SCRIPT'
136+
#!/bin/bash
137+
set -euo pipefail
138+
139+
ZEPHYR_VERSION="__ZEPHYR_VERSION__"
140+
BOARD_TARGET="__BOARD_TARGET__"
141+
SAMPLE_NAME="__SAMPLE_NAME__"
142+
WOLFSSL_REPO="__WOLFSSL_REPO__"
143+
WOLFSSL_BRANCH="__WOLFSSL_BRANCH__"
144+
WOLFSSL_COMMIT="__WOLFSSL_COMMIT__"
145+
INTERACTIVE="__INTERACTIVE__"
146+
VERBOSE="__VERBOSE__"
147+
WERROR="__WERROR__"
148+
CMAKE_EXTRA="__CMAKE_EXTRA__"
149+
EXTRA_CONF="__EXTRA_CONF__"
150+
EXTRA_CONF_CONTENT="__EXTRA_CONF_CONTENT__"
151+
152+
WORKDIR="/workdir"
153+
cd "$WORKDIR"
154+
155+
# --- 1. Initialize Zephyr workspace ---
156+
echo "==> [container] Initializing Zephyr workspace (${ZEPHYR_VERSION})..."
157+
west init --mr "${ZEPHYR_VERSION}" zephyrproject
158+
cd zephyrproject
159+
160+
# --- 2. Add wolfSSL to the west manifest ---
161+
echo "==> [container] Adding wolfSSL to west.yml (${WOLFSSL_REPO}@${WOLFSSL_BRANCH})..."
162+
cd zephyr
163+
164+
# Use sed to inject wolfSSL remote and project into west.yml,
165+
# same approach as the wolfSSL CI workflow
166+
REPO_BASE=$(echo "${WOLFSSL_REPO}" | sed 's|/[^/]*$||')
167+
REF=$(echo "${WOLFSSL_BRANCH}" | sed 's/\//\\\//g')
168+
169+
sed -i "s|remotes:|remotes:\n - name: wolfssl\n url-base: ${REPO_BASE}|" west.yml
170+
sed -i "s|projects:|projects:\n - name: wolfssl\n path: modules/crypto/wolfssl\n remote: wolfssl\n revision: ${REF}|" west.yml
171+
172+
echo "==> [container] Updated west.yml:"
173+
grep -A2 "wolfssl" west.yml
174+
cd ..
175+
176+
# --- 3. Update all modules (including wolfSSL) ---
177+
echo "==> [container] Running west update..."
178+
west update -n -o=--depth=1
179+
180+
# --- 3b. Checkout specific commit if requested ---
181+
if [[ -n "$WOLFSSL_COMMIT" ]]; then
182+
echo "==> [container] Checking out commit ${WOLFSSL_COMMIT}..."
183+
cd modules/crypto/wolfssl
184+
git fetch --unshallow "${WOLFSSL_REPO}" "${WOLFSSL_BRANCH}"
185+
git checkout "${WOLFSSL_COMMIT}"
186+
cd "${WORKDIR}/zephyrproject"
187+
fi
188+
189+
# --- 4. Export and install deps ---
190+
echo "==> [container] Exporting Zephyr..."
191+
west zephyr-export
192+
193+
echo "==> [container] Installing host packages (newlib, python3-venv)..."
194+
sudo apt-get update -qq && sudo apt-get install -y -qq python3-venv libnewlib-dev >/dev/null 2>&1 || true
195+
python3 -m venv .venv
196+
source .venv/bin/activate
197+
pip3 install west
198+
echo "==> [container] Installing Python dependencies..."
199+
pip3 install -r zephyr/scripts/requirements.txt
200+
201+
export ZEPHYR_BASE="${WORKDIR}/zephyrproject/zephyr"
202+
203+
# Ensure Zephyr SDK is found (enables newlib for native_sim)
204+
if [[ -z "${ZEPHYR_SDK_INSTALL_DIR:-}" ]]; then
205+
SDK_DIR=$(find /opt -maxdepth 2 -name "zephyr-sdk-*" -type d 2>/dev/null | head -1)
206+
if [[ -n "$SDK_DIR" ]]; then
207+
export ZEPHYR_SDK_INSTALL_DIR="$SDK_DIR"
208+
echo "==> [container] Found SDK: ${ZEPHYR_SDK_INSTALL_DIR}"
209+
fi
210+
fi
211+
212+
# --- 5. Build or interactive ---
213+
if [[ "$INTERACTIVE" == "1" ]]; then
214+
echo ""
215+
echo "=========================================="
216+
echo " Interactive mode - workspace is ready"
217+
echo " Workspace: ${WORKDIR}/zephyrproject"
218+
echo " wolfSSL: modules/crypto/wolfssl"
219+
echo ""
220+
echo " Example build commands:"
221+
echo " west build -p always -b ${BOARD_TARGET} modules/crypto/wolfssl/zephyr/samples/${SAMPLE_NAME}"
222+
echo " west build -t run"
223+
echo ""
224+
echo " To run twister tests:"
225+
echo " ./zephyr/scripts/twister -T modules/crypto/wolfssl/zephyr/samples/${SAMPLE_NAME} -vvv"
226+
echo "=========================================="
227+
echo ""
228+
exec /bin/bash
229+
else
230+
if [[ -n "$EXTRA_CONF" ]]; then
231+
echo "$EXTRA_CONF_CONTENT" > /workdir/zephyrproject/extra.conf
232+
echo "==> [container] Extra conf written to /workdir/zephyrproject/extra.conf"
233+
cat /workdir/zephyrproject/extra.conf
234+
fi
235+
236+
echo "==> [container] Building sample: ${SAMPLE_NAME} for ${BOARD_TARGET}..."
237+
CMAKE_ARGS=""
238+
if [[ "$VERBOSE" == "1" ]]; then
239+
CMAKE_ARGS="${CMAKE_ARGS} -DCMAKE_VERBOSE_MAKEFILE=ON"
240+
fi
241+
if [[ "$WERROR" == "1" ]]; then
242+
CMAKE_ARGS="${CMAKE_ARGS} -DCMAKE_C_FLAGS=-Werror"
243+
fi
244+
if [[ -n "$CMAKE_EXTRA" ]]; then
245+
CMAKE_ARGS="${CMAKE_ARGS} ${CMAKE_EXTRA}"
246+
fi
247+
248+
if [[ -n "$EXTRA_CONF" ]]; then
249+
CMAKE_ARGS="${CMAKE_ARGS} -DOVERLAY_CONFIG=/workdir/zephyrproject/extra.conf"
250+
fi
251+
252+
west build -p always -b "${BOARD_TARGET}" \
253+
"modules/crypto/wolfssl/zephyr/samples/${SAMPLE_NAME}" \
254+
${CMAKE_ARGS:+-- $CMAKE_ARGS}
255+
256+
echo ""
257+
echo "==> [container] Build succeeded!"
258+
259+
# Run the app for emulator targets and watch for completion
260+
case "${BOARD_TARGET}" in
261+
native_sim*|qemu_*)
262+
echo "==> [container] Running sample on ${BOARD_TARGET}..."
263+
RUN_TIMEOUT=300 # 5 minutes
264+
RUN_LOG="/tmp/run_output.log"
265+
APP_RC=1
266+
267+
west build -t run > "${RUN_LOG}" 2>&1 &
268+
RUN_PID=$!
269+
270+
ELAPSED=0
271+
while kill -0 "${RUN_PID}" 2>/dev/null; do
272+
if [[ $ELAPSED -ge $RUN_TIMEOUT ]]; then
273+
echo "==> [container] TIMEOUT: app did not complete within ${RUN_TIMEOUT}s"
274+
kill "${RUN_PID}" 2>/dev/null || true
275+
wait "${RUN_PID}" 2>/dev/null || true
276+
cat "${RUN_LOG}"
277+
exit 1
278+
fi
279+
# Check for success strings
280+
if grep -q "Benchmark complete\|Test complete\|Client Return: 0" "${RUN_LOG}" 2>/dev/null; then
281+
echo "==> [container] App completed successfully!"
282+
APP_RC=0
283+
kill "${RUN_PID}" 2>/dev/null || true
284+
wait "${RUN_PID}" 2>/dev/null || true
285+
break
286+
fi
287+
sleep 2
288+
ELAPSED=$((ELAPSED + 2))
289+
done
290+
291+
cat "${RUN_LOG}"
292+
293+
if [[ $APP_RC -ne 0 ]]; then
294+
# Process exited on its own - check if it printed a success string
295+
if grep -q "Benchmark complete\|Test complete\|Client Return: 0" "${RUN_LOG}" 2>/dev/null; then
296+
APP_RC=0
297+
else
298+
echo "==> [container] App exited without a success string"
299+
exit 1
300+
fi
301+
fi
302+
;;
303+
*)
304+
echo "==> [container] Board '${BOARD_TARGET}' is not an emulator target, skipping run."
305+
echo " Build artifacts are in: ${WORKDIR}/zephyrproject/build/zephyr/"
306+
;;
307+
esac
308+
fi
309+
INNER_SCRIPT
310+
)
311+
312+
# Substitute variables into the inner script
313+
BUILD_SCRIPT="${BUILD_SCRIPT//__ZEPHYR_VERSION__/$ZEPHYR_VERSION}"
314+
BUILD_SCRIPT="${BUILD_SCRIPT//__BOARD_TARGET__/$BOARD_TARGET}"
315+
BUILD_SCRIPT="${BUILD_SCRIPT//__SAMPLE_NAME__/$SAMPLE_NAME}"
316+
BUILD_SCRIPT="${BUILD_SCRIPT//__WOLFSSL_REPO__/$WOLFSSL_REPO}"
317+
BUILD_SCRIPT="${BUILD_SCRIPT//__WOLFSSL_BRANCH__/$WOLFSSL_BRANCH}"
318+
BUILD_SCRIPT="${BUILD_SCRIPT//__WOLFSSL_COMMIT__/$WOLFSSL_COMMIT}"
319+
BUILD_SCRIPT="${BUILD_SCRIPT//__INTERACTIVE__/$INTERACTIVE}"
320+
BUILD_SCRIPT="${BUILD_SCRIPT//__VERBOSE__/$VERBOSE}"
321+
BUILD_SCRIPT="${BUILD_SCRIPT//__WERROR__/$WERROR}"
322+
BUILD_SCRIPT="${BUILD_SCRIPT//__CMAKE_EXTRA__/$CMAKE_EXTRA}"
323+
if [[ -n "$EXTRA_CONF" ]]; then
324+
EXTRA_CONF_CONTENT=$(cat "$EXTRA_CONF")
325+
BUILD_SCRIPT="${BUILD_SCRIPT//__EXTRA_CONF__/yes}"
326+
BUILD_SCRIPT="${BUILD_SCRIPT//__EXTRA_CONF_CONTENT__/$EXTRA_CONF_CONTENT}"
327+
else
328+
BUILD_SCRIPT="${BUILD_SCRIPT//__EXTRA_CONF__/}"
329+
BUILD_SCRIPT="${BUILD_SCRIPT//__EXTRA_CONF_CONTENT__/}"
330+
fi
331+
332+
# Clean up container on exit (covers crashes, interrupts, and normal exit)
333+
cleanup() {
334+
docker rm -f "${CONTAINER_NAME}" 2>/dev/null || true
335+
}
336+
trap cleanup EXIT
337+
338+
# Stop any existing container with the same name
339+
docker rm -f "${CONTAINER_NAME}" 2>/dev/null || true
340+
341+
# Build docker run args
342+
DOCKER_ARGS=(
343+
--name "${CONTAINER_NAME}"
344+
--rm
345+
)
346+
347+
if [[ "$INTERACTIVE" == "1" ]]; then
348+
DOCKER_ARGS+=(-it)
349+
fi
350+
351+
echo "==> Starting container..."
352+
echo ""
353+
354+
if [[ "$INTERACTIVE" == "1" ]]; then
355+
docker run "${DOCKER_ARGS[@]}" \
356+
"${DOCKER_IMAGE}" \
357+
bash -c "${BUILD_SCRIPT}"
358+
else
359+
{
360+
echo "===== wolfSSL Zephyr Test Log ====="
361+
echo "Date: $(date)"
362+
echo "Zephyr: ${ZEPHYR_VERSION}"
363+
echo "Repo: ${WOLFSSL_REPO}"
364+
echo "Branch: ${WOLFSSL_BRANCH}"
365+
echo "Board: ${BOARD_TARGET}"
366+
echo "Sample: ${SAMPLE_NAME}"
367+
echo "Docker: ${DOCKER_IMAGE}"
368+
echo "==================================="
369+
echo ""
370+
} > "${LOG_FILE}"
371+
372+
set +e
373+
set -o pipefail
374+
docker run "${DOCKER_ARGS[@]}" \
375+
"${DOCKER_IMAGE}" \
376+
bash -c "${BUILD_SCRIPT}" 2>&1 \
377+
| tee -a "${LOG_FILE}"
378+
RC=$?
379+
set -e
380+
381+
echo ""
382+
echo "${LOG_FILE}"
383+
exit $RC
384+
fi

0 commit comments

Comments
 (0)