1# 2# Copyright (c) 2014 Spectra Logic Corporation 3# All rights reserved. 4# 5# Redistribution and use in source and binary forms, with or without 6# modification, are permitted provided that the following conditions 7# are met: 8# 1. Redistributions of source code must retain the above copyright 9# notice, this list of conditions, and the following disclaimer, 10# without modification. 11# 2. Redistributions in binary form must reproduce at minimum a disclaimer 12# substantially similar to the "NO WARRANTY" disclaimer below 13# ("Disclaimer") and any redistribution must be conditioned upon 14# including a substantially similar Disclaimer requirement for further 15# binary redistribution. 16# 17# NO WARRANTY 18# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 19# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 20# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR 21# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 22# HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 23# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 24# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 25# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 26# STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 27# IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 28# POSSIBILITY OF SUCH DAMAGES. 29# 30# Authors: Alan Somers (Spectra Logic Corporation) 31# 32# $FreeBSD$ 33 34# Outline: 35# For each cloned interface type, do three tests 36# 1) Create and destroy it 37# 2) Create, up, and destroy it 38# 3) Create, disable IPv6 auto address assignment, up, and destroy it 39 40TESTLEN=10 # seconds 41 42atf_test_case epair_stress cleanup 43epair_stress_head() 44{ 45 atf_set "descr" "Simultaneously create and destroy an epair(4)" 46 atf_set "require.user" "root" 47} 48epair_stress_body() 49{ 50 do_stress "epair" 51} 52epair_stress_cleanup() 53{ 54 cleanup_ifaces 55} 56 57atf_test_case epair_up_stress cleanup 58epair_up_stress_head() 59{ 60 atf_set "descr" "Simultaneously up and detroy an epair(4)" 61 atf_set "require.user" "root" 62} 63epair_up_stress_body() 64{ 65 do_up_stress "epair" "" "" 66} 67epair_up_stress_cleanup() 68{ 69 cleanup_ifaces 70} 71 72atf_test_case epair_ipv6_up_stress cleanup 73epair_ipv6_up_stress_head() 74{ 75 atf_set "descr" "Simultaneously up and destroy an epair(4) with IPv6" 76 atf_set "require.user" "root" 77} 78epair_ipv6_up_stress_body() 79{ 80 do_up_stress "epair" "6" "" 81} 82epair_ipv6_up_stress_cleanup() 83{ 84 cleanup_ifaces 85} 86 87atf_test_case faith_stress cleanup 88faith_stress_head() 89{ 90 atf_set "descr" "Simultaneously create and destroy a faith(4)" 91 atf_set "require.user" "root" 92} 93faith_stress_body() 94{ 95 do_stress "faith" 96} 97faith_stress_cleanup() 98{ 99 cleanup_ifaces 100} 101 102atf_test_case faith_up_stress cleanup 103faith_up_stress_head() 104{ 105 atf_set "descr" "Simultaneously up and destroy a faith(4)" 106 atf_set "require.user" "root" 107} 108faith_up_stress_body() 109{ 110 do_up_stress "faith" "" "" 111} 112faith_up_stress_cleanup() 113{ 114 cleanup_ifaces 115} 116 117atf_test_case faith_ipv6_up_stress cleanup 118faith_ipv6_up_stress_head() 119{ 120 atf_set "descr" "Simultaneously up and destroy a faith(4) with IPv6" 121 atf_set "require.user" "root" 122} 123faith_ipv6_up_stress_body() 124{ 125 do_up_stress "faith" "6" "" 126} 127faith_ipv6_up_stress_cleanup() 128{ 129 cleanup_ifaces 130} 131 132atf_test_case gif_stress cleanup 133gif_stress_head() 134{ 135 atf_set "descr" "Simultaneously create and destroy a gif(4)" 136 atf_set "require.user" "root" 137} 138gif_stress_body() 139{ 140 do_stress "gif" 141} 142gif_stress_cleanup() 143{ 144 cleanup_ifaces 145} 146 147atf_test_case gif_up_stress cleanup 148gif_up_stress_head() 149{ 150 atf_set "descr" "Simultaneously up and destroy a gif(4)" 151 atf_set "require.user" "root" 152} 153gif_up_stress_body() 154{ 155 do_up_stress "gif" "" "p2p" 156} 157gif_up_stress_cleanup() 158{ 159 cleanup_ifaces 160} 161 162atf_test_case gif_ipv6_up_stress cleanup 163gif_ipv6_up_stress_head() 164{ 165 atf_set "descr" "Simultaneously up and destroy a gif(4) with IPv6" 166 atf_set "require.user" "root" 167} 168gif_ipv6_up_stress_body() 169{ 170 do_up_stress "gif" "6" "p2p" 171} 172gif_ipv6_up_stress_cleanup() 173{ 174 cleanup_ifaces 175} 176 177atf_test_case lo_stress cleanup 178lo_stress_head() 179{ 180 atf_set "descr" "Simultaneously create and destroy an lo(4)" 181 atf_set "require.user" "root" 182} 183lo_stress_body() 184{ 185 do_stress "lo" 186} 187lo_stress_cleanup() 188{ 189 cleanup_ifaces 190} 191 192atf_test_case lo_up_stress cleanup 193lo_up_stress_head() 194{ 195 atf_set "descr" "Simultaneously up and destroy an lo(4)" 196 atf_set "require.user" "root" 197} 198lo_up_stress_body() 199{ 200 do_up_stress "lo" "" "" 201} 202lo_up_stress_cleanup() 203{ 204 cleanup_ifaces 205} 206 207atf_test_case lo_ipv6_up_stress cleanup 208lo_ipv6_up_stress_head() 209{ 210 atf_set "descr" "Simultaneously up and destroy an lo(4) with IPv6" 211 atf_set "require.user" "root" 212} 213lo_ipv6_up_stress_body() 214{ 215 do_up_stress "lo" "6" "" 216} 217lo_ipv6_up_stress_cleanup() 218{ 219 cleanup_ifaces 220} 221 222atf_test_case tap_stress cleanup 223tap_stress_head() 224{ 225 atf_set "descr" "Simultaneously create and destroy a tap(4)" 226 atf_set "require.user" "root" 227} 228tap_stress_body() 229{ 230 do_stress "tap" 231} 232tap_stress_cleanup() 233{ 234 cleanup_ifaces 235} 236 237atf_test_case tap_up_stress cleanup 238tap_up_stress_head() 239{ 240 atf_set "descr" "Simultaneously up and destroy a tap(4)" 241 atf_set "require.user" "root" 242} 243tap_up_stress_body() 244{ 245 do_up_stress "tap" "" "" 246} 247tap_up_stress_cleanup() 248{ 249 cleanup_ifaces 250} 251 252atf_test_case tap_ipv6_up_stress cleanup 253tap_ipv6_up_stress_head() 254{ 255 atf_set "descr" "Simultaneously up and destroy a tap(4) with IPv6" 256 atf_set "require.user" "root" 257} 258tap_ipv6_up_stress_body() 259{ 260 atf_skip "Quickly panics: if_delmulti_locked: inconsistent ifp 0xfffff80150e44000" 261 do_up_stress "tap" "6" "" 262} 263tap_ipv6_up_stress_cleanup() 264{ 265 cleanup_ifaces 266} 267 268atf_test_case tun_stress cleanup 269tun_stress_head() 270{ 271 atf_set "descr" "Simultaneously create and destroy a tun(4)" 272 atf_set "require.user" "root" 273} 274tun_stress_body() 275{ 276 do_stress "tun" 277} 278tun_stress_cleanup() 279{ 280 cleanup_ifaces 281} 282 283atf_test_case tun_up_stress cleanup 284tun_up_stress_head() 285{ 286 atf_set "descr" "Simultaneously up and destroy a tun(4)" 287 atf_set "require.user" "root" 288} 289tun_up_stress_body() 290{ 291 do_up_stress "tun" "" "p2p" 292} 293tun_up_stress_cleanup() 294{ 295 cleanup_ifaces 296} 297 298atf_test_case tun_ipv6_up_stress cleanup 299tun_ipv6_up_stress_head() 300{ 301 atf_set "descr" "Simultaneously up and destroy a tun(4) with IPv6" 302 atf_set "require.user" "root" 303} 304tun_ipv6_up_stress_body() 305{ 306 do_up_stress "tun" "6" "p2p" 307} 308tun_ipv6_up_stress_cleanup() 309{ 310 cleanup_ifaces 311} 312 313atf_test_case vlan_stress cleanup 314vlan_stress_head() 315{ 316 atf_set "descr" "Simultaneously create and destroy a vlan(4)" 317 atf_set "require.user" "root" 318} 319vlan_stress_body() 320{ 321 do_stress "vlan" 322} 323vlan_stress_cleanup() 324{ 325 cleanup_ifaces 326} 327 328atf_test_case vlan_up_stress cleanup 329vlan_up_stress_head() 330{ 331 atf_set "descr" "Simultaneously up and destroy a vlan(4)" 332 atf_set "require.user" "root" 333} 334vlan_up_stress_body() 335{ 336 do_up_stress "vlan" "" "" 337} 338vlan_up_stress_cleanup() 339{ 340 cleanup_ifaces 341} 342 343atf_test_case vlan_ipv6_up_stress cleanup 344vlan_ipv6_up_stress_head() 345{ 346 atf_set "descr" "Simultaneously up and destroy a vlan(4) with IPv6" 347 atf_set "require.user" "root" 348} 349vlan_ipv6_up_stress_body() 350{ 351 do_up_stress "vlan" "6" "" 352} 353vlan_ipv6_up_stress_cleanup() 354{ 355 cleanup_ifaces 356} 357 358atf_test_case vmnet_stress cleanup 359vmnet_stress_head() 360{ 361 atf_set "descr" "Simultaneously create and destroy a vmnet(4)" 362 atf_set "require.user" "root" 363} 364vmnet_stress_body() 365{ 366 do_stress "vmnet" 367} 368vmnet_stress_cleanup() 369{ 370 cleanup_ifaces 371} 372 373atf_test_case vmnet_up_stress cleanup 374vmnet_up_stress_head() 375{ 376 atf_set "descr" "Simultaneously up and destroy a vmnet(4)" 377 atf_set "require.user" "root" 378} 379vmnet_up_stress_body() 380{ 381 do_up_stress "vmnet" "" "" 382} 383vmnet_up_stress_cleanup() 384{ 385 cleanup_ifaces 386} 387 388atf_test_case vmnet_ipv6_up_stress cleanup 389vmnet_ipv6_up_stress_head() 390{ 391 atf_set "descr" "Simultaneously up and destroy a vmnet(4) with IPv6" 392 atf_set "require.user" "root" 393} 394vmnet_ipv6_up_stress_body() 395{ 396 do_up_stress "vmnet" "6" "" 397} 398vmnet_ipv6_up_stress_cleanup() 399{ 400 cleanup_ifaces 401} 402 403atf_init_test_cases() 404{ 405 atf_add_test_case epair_ipv6_up_stress 406 atf_add_test_case epair_stress 407 atf_add_test_case epair_up_stress 408 atf_add_test_case faith_ipv6_up_stress 409 atf_add_test_case faith_stress 410 atf_add_test_case faith_up_stress 411 atf_add_test_case gif_ipv6_up_stress 412 atf_add_test_case gif_stress 413 atf_add_test_case gif_up_stress 414 # Don't test lagg; it has its own test program 415 atf_add_test_case lo_ipv6_up_stress 416 atf_add_test_case lo_stress 417 atf_add_test_case lo_up_stress 418 atf_add_test_case tap_ipv6_up_stress 419 atf_add_test_case tap_stress 420 atf_add_test_case tap_up_stress 421 atf_add_test_case tun_ipv6_up_stress 422 atf_add_test_case tun_stress 423 atf_add_test_case tun_up_stress 424 atf_add_test_case vlan_ipv6_up_stress 425 atf_add_test_case vlan_stress 426 atf_add_test_case vlan_up_stress 427 atf_add_test_case vmnet_ipv6_up_stress 428 atf_add_test_case vmnet_stress 429 atf_add_test_case vmnet_up_stress 430} 431 432do_stress() 433{ 434 local IFACE CREATOR_PID DESTROYER_PID 435 436 IFACE=`get_iface $1` 437 438 # First thread: create the interface 439 while true; do 440 ifconfig ${IFACE%a} create 2>/dev/null && \ 441 echo -n . >> creator_count.txt 442 done & 443 CREATOR_PID=$! 444 445 # Second thread: destroy the lagg 446 while true; do 447 ifconfig $IFACE destroy 2>/dev/null && \ 448 echo -n . >> destroyer_count.txt 449 done & 450 DESTROYER_PID=$! 451 452 sleep ${TESTLEN} 453 kill $CREATOR_PID 454 kill $DESTROYER_PID 455 echo "Created ${IFACE%a} `stat -f %z creator_count.txt` times." 456 echo "Destroyed it `stat -f %z destroyer_count.txt` times." 457} 458 459# Implement the up stress tests 460# Parameters 461# $1 Interface class, etc "lo" or "tap" 462# $2 "6" to enable IPv6 auto address assignment, anything else otherwise 463# $3 p2p for point to point interfaces, anything else for normal interfaces 464do_up_stress() 465{ 466 local ADDR DSTADDR MASK MEAN_SLEEP_SECONDS MAX_SLEEP_USECS \ 467 IFACE IPV6 P2P SRCDIR LOOP_PID ipv6_cmd up_cmd 468 469 # Configure the interface to use an RFC5737 nonrouteable addresses 470 ADDR="192.0.2.2" 471 DSTADDR="192.0.2.3" 472 MASK="24" 473 # ifconfig takes about 10ms to run. To increase race coverage, 474 # randomly delay the two commands relative to each other by 5ms either 475 # way. 476 MEAN_SLEEP_SECONDS=.005 477 MAX_SLEEP_USECS=10000 478 479 IFACE=`get_iface $1` 480 IPV6=$2 481 P2P=$3 482 483 SRCDIR=$( atf_get_srcdir ) 484 if [ "$IPV6" = 6 ]; then 485 ipv6_cmd="true" 486 else 487 ipv6_cmd="ifconfig $IFACE inet6 ifdisabled" 488 fi 489 if [ "$P2P" = "p2p" ]; then 490 up_cmd="ifconfig $IFACE up ${ADDR}/${MASK} ${DSTADDR}" 491 else 492 up_cmd="ifconfig $IFACE up ${ADDR}/${MASK}" 493 fi 494 while true; do 495 eval "$ipv6_cmd" 496 { sleep ${MEAN_SLEEP_SECONDS} && \ 497 eval "$up_cmd" 2> /dev/null && 498 echo -n . >> up_count.txt ; } & 499 { ${SRCDIR}/randsleep ${MAX_SLEEP_USECS} && \ 500 ifconfig $IFACE destroy && 501 echo -n . >> destroy_count.txt ; } & 502 wait 503 ifconfig ${IFACE%a} create 504 done & 505 LOOP_PID=$! 506 507 sleep ${TESTLEN} 508 kill $LOOP_PID 509 echo "Upped ${IFACE} `stat -f %z up_count.txt` times." 510 echo "Destroyed it `stat -f %z destroy_count.txt` times." 511} 512 513# Creates a new cloned interface, registers it for cleanup, and echoes it 514# params: $1 Interface class name (tap, gif, etc) 515get_iface() 516{ 517 local CLASS DEV N 518 519 CLASS=$1 520 N=0 521 while ! ifconfig ${CLASS}${N} create > /dev/null 2>&1; do 522 if [ "$N" -ge 8 ]; then 523 atf_skip "Could not create a ${CLASS} interface" 524 else 525 N=$(($N + 1)) 526 fi 527 done 528 if [ ${CLASS} = "epair" ]; then 529 DEV=${CLASS}${N}a 530 else 531 DEV=${CLASS}${N} 532 fi 533 # Record the device so we can clean it up later 534 echo ${DEV} >> "devices_to_cleanup" 535 echo ${DEV} 536} 537 538 539cleanup_ifaces() 540{ 541 local DEV 542 543 for DEV in `cat "devices_to_cleanup"`; do 544 ifconfig ${DEV} destroy 545 done 546 true 547} 548