|  | #!/bin/bash | 
|  | # Copyright (c) 2019 Intel Corporation | 
|  | # SPDX-License-Identifier: Apache-2.0 | 
|  |  | 
|  | image=net-tools | 
|  | name=net-tools | 
|  | network=net-tools0 | 
|  | zephyr_pid=0 | 
|  | docker_pid=0 | 
|  | configuration="" | 
|  | result=0 | 
|  | dirs="" | 
|  | zephyr_overlay="" | 
|  | docker_test_script_name=docker-test.sh | 
|  | scan_dirs=0 | 
|  |  | 
|  | RUNNING_FROM_MAIN_SCRIPT=1 | 
|  |  | 
|  | check_dirs () | 
|  | { | 
|  | local ret_zephyr=0 | 
|  | local ret_net_tools=0 | 
|  |  | 
|  | if [ -z "$ZEPHYR_BASE" ]; then | 
|  | echo '$ZEPHYR_BASE is unset' >&2 | 
|  | ret_zephyr=1 | 
|  | elif [ ! -d "$ZEPHYR_BASE" ]; then | 
|  | echo '$ZEPHYR_BASE is set, but it is not a directory' >&2 | 
|  | ret_zephyr=1 | 
|  | fi | 
|  |  | 
|  | if [ -z "$NET_TOOLS_BASE" ]; then | 
|  | local d | 
|  |  | 
|  | for d in "$ZEPHYR_BASE/../.." "$ZEPHYR_BASE/.." | 
|  | do | 
|  | local l | 
|  |  | 
|  | l="$d/tools/net-tools" | 
|  | if [ -d "$l" ]; then | 
|  | NET_TOOLS_BASE="$l" | 
|  | break | 
|  | fi | 
|  | done | 
|  | fi | 
|  |  | 
|  | if [ $ret_zephyr -eq 0 ]; then | 
|  | echo "\$ZEPHYR_BASE $ZEPHYR_BASE" | 
|  | fi | 
|  |  | 
|  | if [ -z "$NET_TOOLS_BASE" ]; then | 
|  | echo '$NET_TOOLS_BASE is unset, no net-tools found' >&2 | 
|  | ret_net_tools=1 | 
|  | elif [ ! -d "$NET_TOOLS_BASE" ]; then | 
|  | echo '$NET_TOOLS_BASE set, but it is not a directory' >&2 | 
|  | ret_net_tools=1 | 
|  | fi | 
|  |  | 
|  | if [ $ret_net_tools -eq 0 ]; then | 
|  | echo "\$NET_TOOLS_BASE $NET_TOOLS_BASE" | 
|  | fi | 
|  |  | 
|  | if [ $ret_zephyr -ne 0 -o $ret_net_tools -ne 0 ]; then | 
|  | return 1 | 
|  | fi | 
|  |  | 
|  | return 0 | 
|  | } | 
|  |  | 
|  | scan_dirs () | 
|  | { | 
|  | echo | 
|  | echo "Following directories under $ZEPHYR_BASE can be used by this script:" | 
|  | find "$ZEPHYR_BASE" -type f -name $docker_test_script_name | \ | 
|  | awk -F "$ZEPHYR_BASE/" '{ print $2 }' | \ | 
|  | sed "s/\/$docker_test_script_name//" | 
|  | } | 
|  |  | 
|  | start_configuration () | 
|  | { | 
|  | local bridge_interface="" | 
|  | local addresses="--ip=192.0.2.2 --ip6=2001:db8::2" | 
|  |  | 
|  | if ! docker image ls | grep "$image" > /dev/null; then | 
|  | echo "Docker image '$image' not found" >&2 | 
|  | return 1 | 
|  | fi | 
|  |  | 
|  | if ! docker network ls | grep "$network" > /dev/null; then | 
|  | bridge_interface=$("$NET_TOOLS_BASE/net-setup.sh" \ | 
|  | --config "$NET_TOOLS_BASE/docker.conf" \ | 
|  | start 2>/dev/null | tail -1) | 
|  | if [ $? != 0 ]; then | 
|  | echo "Could not start Docker network '$network'" >&2 | 
|  | return 1 | 
|  | fi | 
|  |  | 
|  | echo "Started Docker network '$network' bridge interface" \ | 
|  | "'$bridge_interface'..." | 
|  | fi | 
|  |  | 
|  | if [ -n "$*" ]; then | 
|  | addresses="$*" | 
|  | fi | 
|  |  | 
|  | if docker ps | grep "$name" > /dev/null; then | 
|  | docker stop "$name" | 
|  | fi | 
|  |  | 
|  | if docker run --hostname=$name --name=$name $addresses \ | 
|  | --rm -dit --network=$network $image > /dev/null; then | 
|  | echo -n "Started Docker container '$name'" | 
|  | if [ -n "$*" ]; then | 
|  | echo -n " with extra arguments '$*'" | 
|  | fi | 
|  |  | 
|  | echo "..." | 
|  | else | 
|  | echo "Could not start Docker container '$image'" | 
|  | return 1 | 
|  | fi | 
|  | } | 
|  |  | 
|  | stop_configuration () | 
|  | { | 
|  | local bridge_interface="" | 
|  |  | 
|  | if docker ps | grep "$name" > /dev/null; then | 
|  | docker stop "$name" > /dev/null | 
|  | if [ $? -eq 0 ]; then | 
|  | echo "Stopped Docker container '$name'..." | 
|  | else | 
|  | echo "Could not stop Docker container '$name'" >&2 | 
|  | fi | 
|  | fi | 
|  |  | 
|  | bridge_interface=$(docker network ls | grep "$network" | cut -d " " -f 1) | 
|  | if [ -n "$bridge_interface" ]; then | 
|  | docker network rm "$network" > /dev/null | 
|  | if [ $? -eq 0 ]; then | 
|  | echo "Stopped Docker network '$network' bridge interface" \ | 
|  | "'br-$bridge_interface'..." | 
|  | else | 
|  | echo "Could not stop Docker network '$network'" >&2 | 
|  | fi | 
|  | fi | 
|  |  | 
|  | # No need to keep the zephyr eth interface around | 
|  | "$NET_TOOLS_BASE/net-setup.sh" --config "$NET_TOOLS_BASE/docker.conf" \ | 
|  | stop > /dev/null 2>&1 | 
|  | } | 
|  |  | 
|  | start_zephyr () | 
|  | { | 
|  | if [ -n "$*" ]; then | 
|  | echo "Building Zephyr with additional arguments '$@'..." >&2 | 
|  | fi | 
|  |  | 
|  | rm -rf build && mkdir build && \ | 
|  | cmake -GNinja -DBOARD=native_sim -B build "$@" . && \ | 
|  | ninja -C build | 
|  |  | 
|  | # Run the binary directly so that ninja does not print errors that | 
|  | # could be confusing. | 
|  | #ninja -C build run & | 
|  | build/zephyr/zephyr.exe & | 
|  | zephyr_pid=$! | 
|  |  | 
|  | sleep 3 | 
|  | echo "Zephyr PID $zephyr_pid" | 
|  | } | 
|  |  | 
|  | list_children () { | 
|  | local pid="$(ps -o pid= --ppid "$1")" | 
|  |  | 
|  | for p in $pid | 
|  | do | 
|  | list_children $p | 
|  | done | 
|  |  | 
|  | if [ -n "$pid" ]; then | 
|  | echo -n "$pid " | 
|  | fi | 
|  | } | 
|  |  | 
|  | stop_zephyr () | 
|  | { | 
|  | if [ "$zephyr_pid" -ne 0 ]; then | 
|  | local zephyrs="$zephyr_pid $(list_children "$zephyr_pid")" | 
|  |  | 
|  | echo "Stopping Zephyr PIDs $zephyrs" | 
|  | kill $zephyrs 2> /dev/null | 
|  | fi | 
|  |  | 
|  | zephyr_pid=0 | 
|  | } | 
|  |  | 
|  | wait_zephyr () | 
|  | { | 
|  | local result="" | 
|  |  | 
|  | echo "Waiting for Zephyr $zephyr_pid..." | 
|  | wait $zephyr_pid | 
|  | result=$? | 
|  |  | 
|  | zephyr_pid=0 | 
|  |  | 
|  | return $result | 
|  | } | 
|  |  | 
|  |  | 
|  | docker_run () | 
|  | { | 
|  | local test="" | 
|  | local result=0 | 
|  |  | 
|  | for test in "$@" | 
|  | do | 
|  | echo "Running '$test' in the container..." | 
|  | docker container exec net-tools $test || return $? | 
|  | done | 
|  | } | 
|  |  | 
|  | start_docker () | 
|  | { | 
|  | docker_run "$@" & | 
|  | docker_pid=$! | 
|  |  | 
|  | echo "Docker PID $docker_pid" | 
|  | } | 
|  |  | 
|  | stop_docker () | 
|  | { | 
|  | if [ "$docker_pid" -ne 0 -a "$configuration" != "keep" ]; then | 
|  | local dockers="$docker_pid $(list_children "$docker_pid")" | 
|  |  | 
|  | echo "Stopping Docker PIDs $dockers" | 
|  | kill $dockers 2> /dev/null | 
|  | fi | 
|  |  | 
|  | docker_pid=0 | 
|  | } | 
|  |  | 
|  | wait_docker () | 
|  | { | 
|  | local result="" | 
|  |  | 
|  | echo "Waiting for Docker PID $docker_pid..." | 
|  | wait $docker_pid | 
|  | result=$? | 
|  |  | 
|  | docker_pid=0 | 
|  |  | 
|  | echo "Docker returned '$result'" | 
|  | return $result | 
|  | } | 
|  |  | 
|  | run_test () | 
|  | { | 
|  | local test="$(basename $(pwd))" | 
|  | local result=0 | 
|  | local overlay="" | 
|  |  | 
|  | if [ -n "$zephyr_overlay" ]; then | 
|  | overlay="-DOVERLAY_CONFIG=$zephyr_overlay" | 
|  | fi | 
|  |  | 
|  | source "$1" | 
|  | result=$? | 
|  |  | 
|  | if [ $result -eq 0 ]; then | 
|  | echo "Sample '$test' successful" | 
|  | else | 
|  | echo "Sample '$test' failed with return value '$result'" | 
|  | fi | 
|  |  | 
|  | return $result | 
|  | } | 
|  |  | 
|  | usage () | 
|  | { | 
|  | BASENAME=`basename $0` | 
|  |  | 
|  | cat <<EOF | 
|  |  | 
|  | $BASENAME [-Z <zephyr base directory>] [-N <net-tools base directory>] [<list of test directories>] | 
|  |  | 
|  | This script runs Zephyr sample tests using Docker container and | 
|  | network implemented by the 'net-tools' subproject. | 
|  |  | 
|  | -Z|--zephyr-dir <dir> | 
|  | set Zephyr base directory | 
|  | -N|--net-tools-dir <dir> | 
|  | set net-tools directory | 
|  | --start | 
|  | only start Docker container and network and exit | 
|  | --stop | 
|  | only stop Docker container and network | 
|  | --keep | 
|  | keep Docker container and network after test | 
|  | --overlay <config files> | 
|  | additional configuration/overlay files for the Zephyr build process | 
|  | --scan | 
|  | find out the directories that can be used for this testing | 
|  | <list of test directories> | 
|  | run the tests in these directories instead of current directory | 
|  |  | 
|  | The automatically detected directories are: | 
|  | EOF | 
|  | check_dirs | 
|  | } | 
|  |  | 
|  | stop_sample_test () { | 
|  | echo "Interrupted..." >&2 | 
|  |  | 
|  | stop_zephyr | 
|  | stop_docker | 
|  |  | 
|  | stop_configuration | 
|  | exit 2 | 
|  | } | 
|  |  | 
|  | trap stop_sample_test ABRT INT HUP TERM | 
|  |  | 
|  | while test -n "$1" | 
|  | do | 
|  | case "$1" in | 
|  | -Z|--zephyr-dir) | 
|  | shift | 
|  | ZEPHYR_BASE="$1" | 
|  | ;; | 
|  |  | 
|  | -N|--net-tools-dir) | 
|  | shift | 
|  | NET_TOOLS_BASE="$1" | 
|  | ;; | 
|  |  | 
|  | -h|--help) | 
|  | usage | 
|  | exit | 
|  | ;; | 
|  | --start) | 
|  | if [ -n "$configuration" ]; then | 
|  | echo "--start or --stop specified multiple times" >&2 | 
|  | exit 1 | 
|  | fi | 
|  | configuration=start_only | 
|  | ;; | 
|  | --stop) | 
|  | if [ -n "$configuration" ]; then | 
|  | echo "--start or --stop specified multiple times" >&2 | 
|  | exit 1 | 
|  | fi | 
|  | configuration=stop_only | 
|  | ;; | 
|  | --keep) | 
|  | configuration=keep | 
|  | ;; | 
|  |  | 
|  | --overlay) | 
|  | shift | 
|  | if [ -n "$zephyr_overlay" ]; then | 
|  | zephyr_overlay="$zephyr_overlay $1" | 
|  | else | 
|  | zephyr_overlay="$1" | 
|  | fi | 
|  | ;; | 
|  |  | 
|  | --scan) | 
|  | scan_dirs=1 | 
|  | ;; | 
|  | -*) | 
|  | echo "Argument '$1' not recognised" >&2 | 
|  | usage | 
|  | return 0 | 
|  | ;; | 
|  | *) | 
|  | dirs="$dirs $1" | 
|  | ;; | 
|  | esac | 
|  |  | 
|  | shift | 
|  | done | 
|  |  | 
|  | check_dirs || exit $? | 
|  |  | 
|  | if [ $scan_dirs -eq 1 ]; then | 
|  | scan_dirs | 
|  | exit 0 | 
|  | fi | 
|  |  | 
|  | if [ -z "$configuration" -o "$configuration" = "start_only" -o \ | 
|  | "$configuration" = "keep" ]; then | 
|  | if [ "$configuration" = start_only ]; then | 
|  | start_configuration | 
|  | result=$? | 
|  | else | 
|  | result=0 | 
|  | found=0 | 
|  |  | 
|  | if [ -z "$dirs" ]; then | 
|  | dirs="." | 
|  | fi | 
|  |  | 
|  | for d in $dirs; do | 
|  | if [ ! -d "$d" ]; then | 
|  | echo "No such directory $d, skipping it" | 
|  | continue | 
|  | fi | 
|  |  | 
|  | if [ ! -f "$d/$docker_test_script_name" ]; then | 
|  | echo "No such file $d/$docker_test_script_name, skipping directory" | 
|  | continue | 
|  | fi | 
|  |  | 
|  | found=$(expr $found + 1) | 
|  |  | 
|  | CURR_DIR=`pwd` | 
|  | cd "$d" | 
|  | run_test "./$docker_test_script_name" | 
|  | test_result=$? | 
|  | cd "$CURR_DIR" | 
|  |  | 
|  | if [ $test_result -ne 0 ]; then | 
|  | result=1 | 
|  | fi | 
|  | done | 
|  |  | 
|  | if [ $found -eq 0 ]; then | 
|  | exit 1 | 
|  | fi | 
|  | fi | 
|  | fi | 
|  |  | 
|  | if [ -z "$configuration" -o "$configuration" = stop_only ]; then | 
|  | stop_configuration | 
|  | fi | 
|  |  | 
|  | exit $result |