1#!/bin/bash 2# Copyright (c) 2019 Intel Corporation 3# SPDX-License-Identifier: Apache-2.0 4 5image=net-tools 6name=net-tools 7network=net-tools0 8zephyr_pid=0 9docker_pid=0 10configuration="" 11result=0 12dirs="" 13zephyr_overlay="" 14docker_test_script_name=docker-test.sh 15scan_dirs=0 16 17RUNNING_FROM_MAIN_SCRIPT=1 18 19check_dirs () 20{ 21 local ret_zephyr=0 22 local ret_net_tools=0 23 24 if [ -z "$ZEPHYR_BASE" ]; then 25 echo '$ZEPHYR_BASE is unset' >&2 26 ret_zephyr=1 27 elif [ ! -d "$ZEPHYR_BASE" ]; then 28 echo '$ZEPHYR_BASE is set, but it is not a directory' >&2 29 ret_zephyr=1 30 fi 31 32 if [ -z "$NET_TOOLS_BASE" ]; then 33 local d 34 35 for d in "$ZEPHYR_BASE/../.." "$ZEPHYR_BASE/.." 36 do 37 local l 38 39 l="$d/tools/net-tools" 40 if [ -d "$l" ]; then 41 NET_TOOLS_BASE="$l" 42 break 43 fi 44 done 45 fi 46 47 if [ $ret_zephyr -eq 0 ]; then 48 echo "\$ZEPHYR_BASE $ZEPHYR_BASE" 49 fi 50 51 if [ -z "$NET_TOOLS_BASE" ]; then 52 echo '$NET_TOOLS_BASE is unset, no net-tools found' >&2 53 ret_net_tools=1 54 elif [ ! -d "$NET_TOOLS_BASE" ]; then 55 echo '$NET_TOOLS_BASE set, but it is not a directory' >&2 56 ret_net_tools=1 57 fi 58 59 if [ $ret_net_tools -eq 0 ]; then 60 echo "\$NET_TOOLS_BASE $NET_TOOLS_BASE" 61 fi 62 63 if [ $ret_zephyr -ne 0 -o $ret_net_tools -ne 0 ]; then 64 return 1 65 fi 66 67 return 0 68} 69 70scan_dirs () 71{ 72 echo 73 echo "Following directories under $ZEPHYR_BASE can be used by this script:" 74 find "$ZEPHYR_BASE" -type f -name $docker_test_script_name | \ 75 awk -F "$ZEPHYR_BASE/" '{ print $2 }' | \ 76 sed "s/\/$docker_test_script_name//" 77} 78 79start_configuration () 80{ 81 local bridge_interface="" 82 local addresses="--ip=192.0.2.2 --ip6=2001:db8::2" 83 84 if ! docker image ls | grep "$image" > /dev/null; then 85 echo "Docker image '$image' not found" >&2 86 return 1 87 fi 88 89 if ! docker network ls | grep "$network" > /dev/null; then 90 bridge_interface=$("$NET_TOOLS_BASE/net-setup.sh" \ 91 --config "$NET_TOOLS_BASE/docker.conf" \ 92 start 2>/dev/null | tail -1) 93 if [ $? != 0 ]; then 94 echo "Could not start Docker network '$network'" >&2 95 return 1 96 fi 97 98 echo "Started Docker network '$network' bridge interface" \ 99 "'$bridge_interface'..." 100 fi 101 102 if [ -n "$*" ]; then 103 addresses="$*" 104 fi 105 106 if docker ps | grep "$name" > /dev/null; then 107 docker stop "$name" 108 fi 109 110 if docker run --hostname=$name --name=$name $addresses \ 111 --rm -dit --network=$network $image > /dev/null; then 112 echo -n "Started Docker container '$name'" 113 if [ -n "$*" ]; then 114 echo -n " with extra arguments '$*'" 115 fi 116 117 echo "..." 118 else 119 echo "Could not start Docker container '$image'" 120 return 1 121 fi 122} 123 124stop_configuration () 125{ 126 local bridge_interface="" 127 128 if docker ps | grep "$name" > /dev/null; then 129 docker stop "$name" > /dev/null 130 if [ $? -eq 0 ]; then 131 echo "Stopped Docker container '$name'..." 132 else 133 echo "Could not stop Docker container '$name'" >&2 134 fi 135 fi 136 137 bridge_interface=$(docker network ls | grep "$network" | cut -d " " -f 1) 138 if [ -n "$bridge_interface" ]; then 139 docker network rm "$network" > /dev/null 140 if [ $? -eq 0 ]; then 141 echo "Stopped Docker network '$network' bridge interface" \ 142 "'br-$bridge_interface'..." 143 else 144 echo "Could not stop Docker network '$network'" >&2 145 fi 146 fi 147 148 # No need to keep the zephyr eth interface around 149 "$NET_TOOLS_BASE/net-setup.sh" --config "$NET_TOOLS_BASE/docker.conf" \ 150 stop > /dev/null 2>&1 151} 152 153start_zephyr () 154{ 155 if [ -n "$*" ]; then 156 echo "Building Zephyr with additional arguments '$@'..." >&2 157 fi 158 159 rm -rf build && mkdir build && \ 160 cmake -GNinja -DBOARD=native_posix -B build "$@" . && \ 161 ninja -C build 162 163 # Run the binary directly so that ninja does not print errors that 164 # could be confusing. 165 #ninja -C build run & 166 build/zephyr/zephyr.exe & 167 zephyr_pid=$! 168 169 sleep 3 170 echo "Zephyr PID $zephyr_pid" 171} 172 173list_children () { 174 local pid="$(ps -o pid= --ppid "$1")" 175 176 for p in $pid 177 do 178 list_children $p 179 done 180 181 if [ -n "$pid" ]; then 182 echo -n "$pid " 183 fi 184} 185 186stop_zephyr () 187{ 188 if [ "$zephyr_pid" -ne 0 ]; then 189 local zephyrs="$zephyr_pid $(list_children "$zephyr_pid")" 190 191 echo "Stopping Zephyr PIDs $zephyrs" 192 kill $zephyrs 2> /dev/null 193 fi 194 195 zephyr_pid=0 196} 197 198wait_zephyr () 199{ 200 local result="" 201 202 echo "Waiting for Zephyr $zephyr_pid..." 203 wait $zephyr_pid 204 result=$? 205 206 zephyr_pid=0 207 208 return $result 209} 210 211 212docker_run () 213{ 214 local test="" 215 local result=0 216 217 for test in "$@" 218 do 219 echo "Running '$test' in the container..." 220 docker container exec net-tools $test || return $? 221 done 222} 223 224start_docker () 225{ 226 docker_run "$@" & 227 docker_pid=$! 228 229 echo "Docker PID $docker_pid" 230} 231 232stop_docker () 233{ 234 if [ "$docker_pid" -ne 0 -a "$configuration" != "keep" ]; then 235 local dockers="$docker_pid $(list_children "$docker_pid")" 236 237 echo "Stopping Docker PIDs $dockers" 238 kill $dockers 2> /dev/null 239 fi 240 241 docker_pid=0 242} 243 244wait_docker () 245{ 246 local result="" 247 248 echo "Waiting for Docker PID $docker_pid..." 249 wait $docker_pid 250 result=$? 251 252 docker_pid=0 253 254 echo "Docker returned '$result'" 255 return $result 256} 257 258run_test () 259{ 260 local test="$(basename $(pwd))" 261 local result=0 262 local overlay="" 263 264 if [ -n "$zephyr_overlay" ]; then 265 overlay="-DOVERLAY_CONFIG=$zephyr_overlay" 266 fi 267 268 source "$1" 269 result=$? 270 271 if [ $result -eq 0 ]; then 272 echo "Sample '$test' successful" 273 else 274 echo "Sample '$test' failed with return value '$result'" 275 fi 276 277 return $result 278} 279 280usage () 281{ 282 BASENAME=`basename $0` 283 284 cat <<EOF 285 286$BASENAME [-Z <zephyr base directory>] [-N <net-tools base directory>] [<list of test directories>] 287 288This script runs Zephyr sample tests using Docker container and 289network implemented by the 'net-tools' subproject. 290 291-Z|--zephyr-dir <dir> 292 set Zephyr base directory 293-N|--net-tools-dir <dir> 294 set net-tools directory 295--start 296 only start Docker container and network and exit 297--stop 298 only stop Docker container and network 299--keep 300 keep Docker container and network after test 301--overlay <config files> 302 additional configuration/overlay files for the Zephyr build process 303--scan 304 find out the directories that can be used for this testing 305<list of test directories> 306 run the tests in these directories instead of current directory 307 308The automatically detected directories are: 309EOF 310 check_dirs 311} 312 313stop_sample_test () { 314 echo "Interrupted..." >&2 315 316 stop_zephyr 317 stop_docker 318 319 stop_configuration 320 exit 2 321} 322 323trap stop_sample_test ABRT INT HUP TERM 324 325while test -n "$1" 326do 327 case "$1" in 328 -Z|--zephyr-dir) 329 shift 330 ZEPHYR_BASE="$1" 331 ;; 332 333 -N|--net-tools-dir) 334 shift 335 NET_TOOLS_BASE="$1" 336 ;; 337 338 -h|--help) 339 usage 340 exit 341 ;; 342 --start) 343 if [ -n "$configuration" ]; then 344 echo "--start or --stop specified multiple times" >&2 345 exit 1 346 fi 347 configuration=start_only 348 ;; 349 --stop) 350 if [ -n "$configuration" ]; then 351 echo "--start or --stop specified multiple times" >&2 352 exit 1 353 fi 354 configuration=stop_only 355 ;; 356 --keep) 357 configuration=keep 358 ;; 359 360 --overlay) 361 shift 362 if [ -n "$zephyr_overlay" ]; then 363 zephyr_overlay="$zephyr_overlay $1" 364 else 365 zephyr_overlay="$1" 366 fi 367 ;; 368 369 --scan) 370 scan_dirs=1 371 ;; 372 -*) 373 echo "Argument '$1' not recognised" >&2 374 usage 375 return 0 376 ;; 377 *) 378 dirs="$dirs $1" 379 ;; 380 esac 381 382 shift 383done 384 385check_dirs || exit $? 386 387if [ $scan_dirs -eq 1 ]; then 388 scan_dirs 389 exit 0 390fi 391 392if [ -z "$configuration" -o "$configuration" = "start_only" -o \ 393 "$configuration" = "keep" ]; then 394 if [ "$configuration" = start_only ]; then 395 start_configuration 396 result=$? 397 else 398 result=0 399 found=0 400 401 if [ -z "$dirs" ]; then 402 dirs="." 403 fi 404 405 for d in $dirs; do 406 if [ ! -d "$d" ]; then 407 echo "No such directory $d, skipping it" 408 continue 409 fi 410 411 if [ ! -f "$d/$docker_test_script_name" ]; then 412 echo "No such file $d/$docker_test_script_name, skipping directory" 413 continue 414 fi 415 416 found=$(expr $found + 1) 417 418 CURR_DIR=`pwd` 419 cd "$d" 420 run_test "./$docker_test_script_name" 421 test_result=$? 422 cd "$CURR_DIR" 423 424 if [ $test_result -ne 0 ]; then 425 result=1 426 fi 427 done 428 429 if [ $found -eq 0 ]; then 430 exit 1 431 fi 432 fi 433fi 434 435if [ -z "$configuration" -o "$configuration" = stop_only ]; then 436 stop_configuration 437fi 438 439exit $result 440