mirror of
https://passt.top/passt
synced 2025-02-22 02:42:22 +00:00
test: Add migration tests
PCAP=1 ./run migrate/bidirectional gives an overview of how the whole thing is working. Add 12 tests in total, checking basic functionality with and without flows in both directions, with and without sockets in half-closed states (both inbound and outbound), migration behaviour under traffic flood, under traffic flood with > 253 flows, and strict checking of sequences under flood with ramp patterns in both directions. These tests need preparation and teardown for each case, as we need to restore the source guest in its own context and pane before we can test again. Eventually, we could consider alternating source and target so that we don't need to restart from scratch every time, but that's beyond the scope of this initial test implementation. Trick: './run migrate/*' runs all the tests with preparation and teardown steps. Co-authored-by: David Gibson <david@gibson.dropbear.id.au> Reviewed-by: David Gibson <david@gibson.dropbear.id.au> Signed-off-by: Stefano Brivio <sbrivio@redhat.com>
This commit is contained in:
parent
89ecf2fd40
commit
a1e48a02ff
@ -135,7 +135,7 @@ layout_two_guests() {
|
||||
get_info_cols
|
||||
|
||||
pane_watch_contexts ${PANE_GUEST_1} "guest #1 in namespace #1" qemu_1 guest_1
|
||||
pane_watch_contexts ${PANE_GUEST_2} "guest #2 in namespace #2" qemu_2 guest_2
|
||||
pane_watch_contexts ${PANE_GUEST_2} "guest #2 in namespace #1" qemu_2 guest_2
|
||||
|
||||
tmux send-keys -l -t ${PANE_INFO} 'while cat '"$STATEBASE/log_pipe"'; do :; done'
|
||||
tmux send-keys -t ${PANE_INFO} -N 100 C-m
|
||||
@ -143,13 +143,66 @@ layout_two_guests() {
|
||||
|
||||
pane_watch_contexts ${PANE_HOST} host host
|
||||
pane_watch_contexts ${PANE_PASST_1} "passt #1 in namespace #1" pasta_1 passt_1
|
||||
pane_watch_contexts ${PANE_PASST_2} "passt #2 in namespace #2" pasta_2 passt_2
|
||||
pane_watch_contexts ${PANE_PASST_2} "passt #2 in namespace #1" pasta_1 passt_2
|
||||
|
||||
info_layout "two guests, two passt instances, in namespaces"
|
||||
|
||||
sleep 1
|
||||
}
|
||||
|
||||
# layout_migrate() - Two guest panes, two passt panes, two passt-repair panes,
|
||||
# plus host and log
|
||||
layout_migrate() {
|
||||
sleep 1
|
||||
|
||||
tmux kill-pane -a -t 0
|
||||
cmd_write 0 clear
|
||||
|
||||
tmux split-window -v -t passt_test
|
||||
tmux split-window -h -l '33%'
|
||||
tmux split-window -h -t passt_test:1.1
|
||||
|
||||
tmux split-window -h -l '35%' -t passt_test:1.0
|
||||
tmux split-window -v -t passt_test:1.0
|
||||
|
||||
tmux split-window -v -t passt_test:1.4
|
||||
tmux split-window -v -t passt_test:1.6
|
||||
|
||||
tmux split-window -v -t passt_test:1.3
|
||||
|
||||
PANE_GUEST_1=0
|
||||
PANE_GUEST_2=1
|
||||
PANE_INFO=2
|
||||
PANE_MON=3
|
||||
PANE_HOST=4
|
||||
PANE_PASST_REPAIR_1=5
|
||||
PANE_PASST_1=6
|
||||
PANE_PASST_REPAIR_2=7
|
||||
PANE_PASST_2=8
|
||||
|
||||
get_info_cols
|
||||
|
||||
pane_watch_contexts ${PANE_GUEST_1} "guest #1 in namespace #1" qemu_1 guest_1
|
||||
pane_watch_contexts ${PANE_GUEST_2} "guest #2 in namespace #2" qemu_2 guest_2
|
||||
|
||||
tmux send-keys -l -t ${PANE_INFO} 'while cat '"$STATEBASE/log_pipe"'; do :; done'
|
||||
tmux send-keys -t ${PANE_INFO} -N 100 C-m
|
||||
tmux select-pane -t ${PANE_INFO} -T "test log"
|
||||
|
||||
pane_watch_contexts ${PANE_MON} "QEMU monitor" mon mon
|
||||
|
||||
pane_watch_contexts ${PANE_HOST} host host
|
||||
pane_watch_contexts ${PANE_PASST_REPAIR_1} "passt-repair #1 in namespace #1" repair_1 passt_repair_1
|
||||
pane_watch_contexts ${PANE_PASST_1} "passt #1 in namespace #1" pasta_1 passt_1
|
||||
|
||||
pane_watch_contexts ${PANE_PASST_REPAIR_2} "passt-repair #2 in namespace #2" repair_2 passt_repair_2
|
||||
pane_watch_contexts ${PANE_PASST_2} "passt #2 in namespace #2" pasta_2 passt_2
|
||||
|
||||
info_layout "two guests, two passt + passt-repair instances, in namespaces"
|
||||
|
||||
sleep 1
|
||||
}
|
||||
|
||||
# layout_demo_pasta() - Four panes for pasta demo
|
||||
layout_demo_pasta() {
|
||||
sleep 1
|
||||
|
138
test/lib/setup
138
test/lib/setup
@ -305,6 +305,117 @@ setup_two_guests() {
|
||||
context_setup_guest guest_2 ${GUEST_2_CID}
|
||||
}
|
||||
|
||||
# setup_migrate() - Set up two namespace, run qemu, passt/passt-repair in both
|
||||
setup_migrate() {
|
||||
context_setup_host host
|
||||
context_setup_host mon
|
||||
context_setup_host pasta_1
|
||||
context_setup_host pasta_2
|
||||
|
||||
layout_migrate
|
||||
|
||||
# Ports:
|
||||
#
|
||||
# guest #1 | guest #2 | ns #1 | host
|
||||
# --------- |-----------|-----------|------------
|
||||
# 10001 as server | | to guest | to ns #1
|
||||
# 10002 | | as server | to ns #1
|
||||
# 10003 | | to init | as server
|
||||
# 10004 | as server | to guest | to ns #1
|
||||
|
||||
__opts=
|
||||
[ ${PCAP} -eq 1 ] && __opts="${__opts} -p ${LOGDIR}/pasta_1.pcap"
|
||||
[ ${DEBUG} -eq 1 ] && __opts="${__opts} -d"
|
||||
[ ${TRACE} -eq 1 ] && __opts="${__opts} --trace"
|
||||
|
||||
__map_host4=192.0.2.1
|
||||
__map_host6=2001:db8:9a55::1
|
||||
__map_ns4=192.0.2.2
|
||||
__map_ns6=2001:db8:9a55::2
|
||||
|
||||
# Option 1: send stuff via spliced path in pasta
|
||||
# context_run_bg pasta_1 "./pasta ${__opts} -P ${STATESETUP}/pasta_1.pid -t 10001,10002 -T 10003 -u 10001,10002 -U 10003 --config-net ${NSTOOL} hold ${STATESETUP}/ns1.hold"
|
||||
# Option 2: send stuff via tap (--map-guest-addr) instead (useful to see capture of full migration)
|
||||
context_run_bg pasta_1 "./pasta ${__opts} -P ${STATESETUP}/pasta_1.pid -t 10001,10002,10004 -T 10003 -u 10001,10002,10004 -U 10003 --map-guest-addr ${__map_host4} --map-guest-addr ${__map_host6} --config-net ${NSTOOL} hold ${STATESETUP}/ns1.hold"
|
||||
context_setup_nstool passt_1 ${STATESETUP}/ns1.hold
|
||||
context_setup_nstool passt_repair_1 ${STATESETUP}/ns1.hold
|
||||
|
||||
context_setup_nstool passt_2 ${STATESETUP}/ns1.hold
|
||||
context_setup_nstool passt_repair_2 ${STATESETUP}/ns1.hold
|
||||
|
||||
context_setup_nstool qemu_1 ${STATESETUP}/ns1.hold
|
||||
context_setup_nstool qemu_2 ${STATESETUP}/ns1.hold
|
||||
|
||||
__ifname="$(context_run qemu_1 "ip -j link show | jq -rM '.[] | select(.link_type == \"ether\").ifname'")"
|
||||
|
||||
sleep 1
|
||||
|
||||
__opts="--vhost-user"
|
||||
[ ${PCAP} -eq 1 ] && __opts="${__opts} -p ${LOGDIR}/passt_1.pcap"
|
||||
[ ${DEBUG} -eq 1 ] && __opts="${__opts} -d"
|
||||
[ ${TRACE} -eq 1 ] && __opts="${__opts} --trace"
|
||||
|
||||
context_run_bg passt_1 "./passt -s ${STATESETUP}/passt_1.socket -P ${STATESETUP}/passt_1.pid -f ${__opts} -t 10001 -u 10001"
|
||||
wait_for [ -f "${STATESETUP}/passt_1.pid" ]
|
||||
|
||||
context_run_bg passt_repair_1 "./passt-repair ${STATESETUP}/passt_1.socket.repair"
|
||||
|
||||
__opts="--vhost-user"
|
||||
[ ${PCAP} -eq 1 ] && __opts="${__opts} -p ${LOGDIR}/passt_2.pcap"
|
||||
[ ${DEBUG} -eq 1 ] && __opts="${__opts} -d"
|
||||
[ ${TRACE} -eq 1 ] && __opts="${__opts} --trace"
|
||||
|
||||
context_run_bg passt_2 "./passt -s ${STATESETUP}/passt_2.socket -P ${STATESETUP}/passt_2.pid -f ${__opts} -t 10004 -u 10004"
|
||||
wait_for [ -f "${STATESETUP}/passt_2.pid" ]
|
||||
|
||||
context_run_bg passt_repair_2 "./passt-repair ${STATESETUP}/passt_2.socket.repair"
|
||||
|
||||
__vmem="512M" # Keep migration fast
|
||||
__qemu_netdev1=" \
|
||||
-chardev socket,id=c,path=${STATESETUP}/passt_1.socket \
|
||||
-netdev vhost-user,id=v,chardev=c \
|
||||
-device virtio-net,netdev=v \
|
||||
-object memory-backend-memfd,id=m,share=on,size=${__vmem} \
|
||||
-numa node,memdev=m"
|
||||
__qemu_netdev2=" \
|
||||
-chardev socket,id=c,path=${STATESETUP}/passt_2.socket \
|
||||
-netdev vhost-user,id=v,chardev=c \
|
||||
-device virtio-net,netdev=v \
|
||||
-object memory-backend-memfd,id=m,share=on,size=${__vmem} \
|
||||
-numa node,memdev=m"
|
||||
|
||||
GUEST_1_CID=94557
|
||||
context_run_bg qemu_1 'qemu-system-'"${QEMU_ARCH}" \
|
||||
' -M accel=kvm:tcg' \
|
||||
' -m '${__vmem}' -cpu host -smp '${VCPUS} \
|
||||
' -kernel '"${KERNEL}" \
|
||||
' -initrd '${INITRAMFS}' -nographic -serial stdio' \
|
||||
' -nodefaults' \
|
||||
' -append "console=ttyS0 mitigations=off apparmor=0" ' \
|
||||
" ${__qemu_netdev1}" \
|
||||
" -pidfile ${STATESETUP}/qemu_1.pid" \
|
||||
" -device vhost-vsock-pci,guest-cid=$GUEST_1_CID" \
|
||||
" -monitor unix:${STATESETUP}/qemu_1_mon.sock,server,nowait"
|
||||
|
||||
GUEST_2_CID=94558
|
||||
context_run_bg qemu_2 'qemu-system-'"${QEMU_ARCH}" \
|
||||
' -M accel=kvm:tcg' \
|
||||
' -m '${__vmem}' -cpu host -smp '${VCPUS} \
|
||||
' -kernel '"${KERNEL}" \
|
||||
' -initrd '${INITRAMFS}' -nographic -serial stdio' \
|
||||
' -nodefaults' \
|
||||
' -append "console=ttyS0 mitigations=off apparmor=0" ' \
|
||||
" ${__qemu_netdev2}" \
|
||||
" -pidfile ${STATESETUP}/qemu_2.pid" \
|
||||
" -device vhost-vsock-pci,guest-cid=$GUEST_2_CID" \
|
||||
" -monitor unix:${STATESETUP}/qemu_2_mon.sock,server,nowait" \
|
||||
" -incoming tcp:0:20005"
|
||||
|
||||
context_setup_guest guest_1 ${GUEST_1_CID}
|
||||
# Only available after migration:
|
||||
( context_setup_guest guest_2 ${GUEST_2_CID} & )
|
||||
}
|
||||
|
||||
# teardown_context_watch() - Remove contexts and stop panes watching them
|
||||
# $1: Pane number watching
|
||||
# $@: Context names
|
||||
@ -375,7 +486,8 @@ teardown_two_guests() {
|
||||
context_wait pasta_1
|
||||
context_wait pasta_2
|
||||
|
||||
rm -f "${STATESETUP}/passt__[12].pid" "${STATESETUP}/pasta_[12].pid"
|
||||
rm "${STATESETUP}/passt_1.pid" "${STATESETUP}/passt_2.pid"
|
||||
rm "${STATESETUP}/pasta_1.pid" "${STATESETUP}/pasta_2.pid"
|
||||
|
||||
teardown_context_watch ${PANE_HOST} host
|
||||
teardown_context_watch ${PANE_GUEST_1} qemu_1 guest_1
|
||||
@ -384,6 +496,30 @@ teardown_two_guests() {
|
||||
teardown_context_watch ${PANE_PASST_2} pasta_2 passt_2
|
||||
}
|
||||
|
||||
# teardown_migrate() - Exit namespaces, kill qemu processes, passt and pasta
|
||||
teardown_migrate() {
|
||||
${NSTOOL} exec ${STATESETUP}/ns1.hold -- kill $(cat "${STATESETUP}/qemu_1.pid")
|
||||
${NSTOOL} exec ${STATESETUP}/ns1.hold -- kill $(cat "${STATESETUP}/qemu_2.pid")
|
||||
context_wait qemu_1
|
||||
context_wait qemu_2
|
||||
|
||||
${NSTOOL} exec ${STATESETUP}/ns1.hold -- kill $(cat "${STATESETUP}/passt_2.pid")
|
||||
context_wait passt_1
|
||||
context_wait passt_2
|
||||
${NSTOOL} stop "${STATESETUP}/ns1.hold"
|
||||
context_wait pasta_1
|
||||
|
||||
rm -f "${STATESETUP}/passt_1.pid" "${STATESETUP}/passt_2.pid"
|
||||
rm -f "${STATESETUP}/pasta_1.pid" "${STATESETUP}/pasta_2.pid"
|
||||
|
||||
teardown_context_watch ${PANE_HOST} host
|
||||
|
||||
teardown_context_watch ${PANE_GUEST_1} qemu_1 guest_1
|
||||
teardown_context_watch ${PANE_GUEST_2} qemu_2 guest_2
|
||||
teardown_context_watch ${PANE_PASST_1} pasta_1 passt_1
|
||||
teardown_context_watch ${PANE_PASST_2} pasta_1 passt_2
|
||||
}
|
||||
|
||||
# teardown_demo_passt() - Exit namespace, kill qemu, passt and pasta
|
||||
teardown_demo_passt() {
|
||||
tmux send-keys -t ${PANE_GUEST} "C-c"
|
||||
|
@ -68,6 +68,45 @@ test_iperf3() {
|
||||
TEST_ONE_subs="$(list_add_pair "${TEST_ONE_subs}" "__${__var}__" "${__bw}" )"
|
||||
}
|
||||
|
||||
# test_iperf3m() - Ugly helper for iperf3 directive, guest migration variant
|
||||
# $1: Variable name: to put the measure bandwidth into
|
||||
# $2: Initial source/client context
|
||||
# $3: Second source/client context the guest is moving to
|
||||
# $4: Destination name or address for client
|
||||
# $5: Port number, ${i} is translated to process index
|
||||
# $6: Run time, in seconds
|
||||
# $7: Client options
|
||||
test_iperf3m() {
|
||||
__var="${1}"; shift
|
||||
__cctx="${1}"; shift
|
||||
__cctx2="${1}"; shift
|
||||
__dest="${1}"; shift
|
||||
__port="${1}"; shift
|
||||
__time="${1}"; shift
|
||||
|
||||
pane_or_context_run "${__cctx}" 'rm -f c.json'
|
||||
|
||||
# A 1s wait for connection on what's basically a local link
|
||||
# indicates something is pretty wrong
|
||||
__timeout=1000
|
||||
pane_or_context_run_bg "${__cctx}" \
|
||||
'iperf3 -J -c '${__dest}' -p '${__port} \
|
||||
' --connect-timeout '${__timeout} \
|
||||
' -t'${__time}' -i0 '"${@}"' > c.json' \
|
||||
|
||||
__jval=".end.sum_received.bits_per_second"
|
||||
|
||||
sleep $((${__time} + 3))
|
||||
|
||||
pane_or_context_output "${__cctx2}" \
|
||||
'cat c.json'
|
||||
|
||||
__bw=$(pane_or_context_output "${__cctx2}" \
|
||||
'cat c.json | jq -rMs "map('${__jval}') | add"')
|
||||
|
||||
TEST_ONE_subs="$(list_add_pair "${TEST_ONE_subs}" "__${__var}__" "${__bw}" )"
|
||||
}
|
||||
|
||||
test_one_line() {
|
||||
__line="${1}"
|
||||
|
||||
@ -177,6 +216,12 @@ test_one_line() {
|
||||
"guest2w")
|
||||
pane_or_context_wait guest_2 || TEST_ONE_nok=1
|
||||
;;
|
||||
"mon")
|
||||
pane_or_context_run mon "${__arg}" || TEST_ONE_nok=1
|
||||
;;
|
||||
"monb")
|
||||
pane_or_context_run_bg mon "${__arg}"
|
||||
;;
|
||||
"ns")
|
||||
pane_or_context_run ns "${__arg}" || TEST_ONE_nok=1
|
||||
;;
|
||||
@ -292,6 +337,9 @@ test_one_line() {
|
||||
"iperf3")
|
||||
test_iperf3 ${__arg}
|
||||
;;
|
||||
"iperf3m")
|
||||
test_iperf3m ${__arg}
|
||||
;;
|
||||
"set")
|
||||
TEST_ONE_subs="$(list_add_pair "${TEST_ONE_subs}" "__${__arg%% *}__" "${__arg#* }")"
|
||||
;;
|
||||
|
59
test/migrate/basic
Normal file
59
test/migrate/basic
Normal file
@ -0,0 +1,59 @@
|
||||
# SPDX-License-Identifier: GPL-2.0-or-later
|
||||
#
|
||||
# PASST - Plug A Simple Socket Transport
|
||||
# for qemu/UNIX domain socket mode
|
||||
#
|
||||
# PASTA - Pack A Subtle Tap Abstraction
|
||||
# for network namespace/tap device mode
|
||||
#
|
||||
# test/migrate/basic - Check basic migration functionality
|
||||
#
|
||||
# Copyright (c) 2025 Red Hat GmbH
|
||||
# Author: Stefano Brivio <sbrivio@redhat.com>
|
||||
|
||||
g1tools ip jq dhclient socat cat
|
||||
htools ip jq
|
||||
|
||||
set MAP_HOST4 192.0.2.1
|
||||
set MAP_HOST6 2001:db8:9a55::1
|
||||
set MAP_NS4 192.0.2.2
|
||||
set MAP_NS6 2001:db8:9a55::2
|
||||
|
||||
test Interface name
|
||||
g1out IFNAME1 ip -j link show | jq -rM '.[] | select(.link_type == "ether").ifname'
|
||||
hout HOST_IFNAME ip -j -4 route show|jq -rM '[.[] | select(.dst == "default").dev] | .[0]'
|
||||
hout HOST_IFNAME6 ip -j -6 route show|jq -rM '[.[] | select(.dst == "default").dev] | .[0]'
|
||||
check [ -n "__IFNAME1__" ]
|
||||
|
||||
test DHCP: address
|
||||
guest1 ip link set dev __IFNAME1__ up
|
||||
guest1 /sbin/dhclient -4 __IFNAME1__
|
||||
g1out ADDR1 ip -j -4 addr show|jq -rM '.[] | select(.ifname == "__IFNAME1__").addr_info[0].local'
|
||||
hout HOST_ADDR ip -j -4 addr show|jq -rM '.[] | select(.ifname == "__HOST_IFNAME__").addr_info[0].local'
|
||||
check [ "__ADDR1__" = "__HOST_ADDR__" ]
|
||||
|
||||
test DHCPv6: address
|
||||
# Link is up now, wait for DAD to complete
|
||||
guest1 while ip -j -6 addr show tentative | jq -e '.[].addr_info'; do sleep 0.1; done
|
||||
guest1 /sbin/dhclient -6 __IFNAME1__
|
||||
# Wait for DAD to complete on the DHCP address
|
||||
guest1 while ip -j -6 addr show tentative | jq -e '.[].addr_info'; do sleep 0.1; done
|
||||
g1out ADDR1_6 ip -j -6 addr show|jq -rM '[.[] | select(.ifname == "__IFNAME1__").addr_info[] | select(.prefixlen == 128).local] | .[0]'
|
||||
hout HOST_ADDR6 ip -j -6 addr show|jq -rM '[.[] | select(.ifname == "__HOST_IFNAME6__").addr_info[] | select(.scope == "global" and .deprecated != true).local] | .[0]'
|
||||
check [ "__ADDR1_6__" = "__HOST_ADDR6__" ]
|
||||
|
||||
test TCP/IPv4: guest1/guest2 > host
|
||||
g1out GW1 ip -j -4 route show|jq -rM '.[] | select(.dst == "default").gateway'
|
||||
hostb socat -u TCP4-LISTEN:10006 OPEN:__STATESETUP__/msg,create,trunc
|
||||
sleep 1
|
||||
# Option 1: via spliced path in pasta, namespace to host
|
||||
# guest1b { printf "Hello from guest 1"; sleep 10; printf " and from guest 2\n"; } | socat -u STDIN TCP4:__GW1__:10003
|
||||
# Option 2: via --map-guest-addr (tap) in pasta, namespace to host
|
||||
guest1b { printf "Hello from guest 1"; sleep 3; printf " and from guest 2\n"; } | socat -u STDIN TCP4:__MAP_HOST4__:10006
|
||||
sleep 1
|
||||
|
||||
mon echo "migrate tcp:0:20005" | socat -u STDIN UNIX:__STATESETUP__/qemu_1_mon.sock
|
||||
|
||||
hostw
|
||||
hout MSG cat __STATESETUP__/msg
|
||||
check [ "__MSG__" = "Hello from guest 1 and from guest 2" ]
|
62
test/migrate/basic_fin
Normal file
62
test/migrate/basic_fin
Normal file
@ -0,0 +1,62 @@
|
||||
# SPDX-License-Identifier: GPL-2.0-or-later
|
||||
#
|
||||
# PASST - Plug A Simple Socket Transport
|
||||
# for qemu/UNIX domain socket mode
|
||||
#
|
||||
# PASTA - Pack A Subtle Tap Abstraction
|
||||
# for network namespace/tap device mode
|
||||
#
|
||||
# test/migrate/basic_fin - Outbound traffic across migration, half-closed socket
|
||||
#
|
||||
# Copyright (c) 2025 Red Hat GmbH
|
||||
# Author: Stefano Brivio <sbrivio@redhat.com>
|
||||
|
||||
g1tools ip jq dhclient socat cat
|
||||
htools ip jq
|
||||
|
||||
set MAP_HOST4 192.0.2.1
|
||||
set MAP_HOST6 2001:db8:9a55::1
|
||||
set MAP_NS4 192.0.2.2
|
||||
set MAP_NS6 2001:db8:9a55::2
|
||||
|
||||
test Interface name
|
||||
g1out IFNAME1 ip -j link show | jq -rM '.[] | select(.link_type == "ether").ifname'
|
||||
hout HOST_IFNAME ip -j -4 route show|jq -rM '[.[] | select(.dst == "default").dev] | .[0]'
|
||||
hout HOST_IFNAME6 ip -j -6 route show|jq -rM '[.[] | select(.dst == "default").dev] | .[0]'
|
||||
check [ -n "__IFNAME1__" ]
|
||||
|
||||
test DHCP: address
|
||||
guest1 ip link set dev __IFNAME1__ up
|
||||
guest1 /sbin/dhclient -4 __IFNAME1__
|
||||
g1out ADDR1 ip -j -4 addr show|jq -rM '.[] | select(.ifname == "__IFNAME1__").addr_info[0].local'
|
||||
hout HOST_ADDR ip -j -4 addr show|jq -rM '.[] | select(.ifname == "__HOST_IFNAME__").addr_info[0].local'
|
||||
check [ "__ADDR1__" = "__HOST_ADDR__" ]
|
||||
|
||||
test DHCPv6: address
|
||||
# Link is up now, wait for DAD to complete
|
||||
guest1 while ip -j -6 addr show tentative | jq -e '.[].addr_info'; do sleep 0.1; done
|
||||
guest1 /sbin/dhclient -6 __IFNAME1__
|
||||
# Wait for DAD to complete on the DHCP address
|
||||
guest1 while ip -j -6 addr show tentative | jq -e '.[].addr_info'; do sleep 0.1; done
|
||||
g1out ADDR1_6 ip -j -6 addr show|jq -rM '[.[] | select(.ifname == "__IFNAME1__").addr_info[] | select(.prefixlen == 128).local] | .[0]'
|
||||
hout HOST_ADDR6 ip -j -6 addr show|jq -rM '[.[] | select(.ifname == "__HOST_IFNAME6__").addr_info[] | select(.scope == "global" and .deprecated != true).local] | .[0]'
|
||||
check [ "__ADDR1_6__" = "__HOST_ADDR6__" ]
|
||||
|
||||
test TCP/IPv4: guest1, half-close, guest2 > host
|
||||
g1out GW1 ip -j -4 route show|jq -rM '.[] | select(.dst == "default").gateway'
|
||||
|
||||
hostb echo FIN | socat TCP4-LISTEN:10006,shut-down STDIO,ignoreeof > __STATESETUP__/msg
|
||||
#hostb socat -u TCP4-LISTEN:10006 OPEN:__STATESETUP__/msg,create,trunc
|
||||
|
||||
#sleep 20
|
||||
# Option 1: via spliced path in pasta, namespace to host
|
||||
# guest1b { printf "Hello from guest 1"; sleep 10; printf " and from guest 2\n"; } | socat -u STDIN TCP4:__GW1__:10003
|
||||
# Option 2: via --map-guest-addr (tap) in pasta, namespace to host
|
||||
guest1b { printf "Hello from guest 1"; sleep 3; printf " and from guest 2\n"; } | socat -u STDIN TCP4:__MAP_HOST4__:10006
|
||||
sleep 1
|
||||
|
||||
mon echo "migrate tcp:0:20005" | socat -u STDIN UNIX:__STATESETUP__/qemu_1_mon.sock
|
||||
|
||||
hostw
|
||||
hout MSG cat __STATESETUP__/msg
|
||||
check [ "__MSG__" = "Hello from guest 1 and from guest 2" ]
|
64
test/migrate/bidirectional
Normal file
64
test/migrate/bidirectional
Normal file
@ -0,0 +1,64 @@
|
||||
# SPDX-License-Identifier: GPL-2.0-or-later
|
||||
#
|
||||
# PASST - Plug A Simple Socket Transport
|
||||
# for qemu/UNIX domain socket mode
|
||||
#
|
||||
# PASTA - Pack A Subtle Tap Abstraction
|
||||
# for network namespace/tap device mode
|
||||
#
|
||||
# test/migrate/bidirectional - Check migration with messages in both directions
|
||||
#
|
||||
# Copyright (c) 2025 Red Hat GmbH
|
||||
# Author: Stefano Brivio <sbrivio@redhat.com>
|
||||
|
||||
g1tools ip jq dhclient socat cat
|
||||
htools ip jq
|
||||
|
||||
set MAP_HOST4 192.0.2.1
|
||||
set MAP_HOST6 2001:db8:9a55::1
|
||||
set MAP_NS4 192.0.2.2
|
||||
set MAP_NS6 2001:db8:9a55::2
|
||||
|
||||
test Interface name
|
||||
g1out IFNAME1 ip -j link show | jq -rM '.[] | select(.link_type == "ether").ifname'
|
||||
hout HOST_IFNAME ip -j -4 route show|jq -rM '[.[] | select(.dst == "default").dev] | .[0]'
|
||||
hout HOST_IFNAME6 ip -j -6 route show|jq -rM '[.[] | select(.dst == "default").dev] | .[0]'
|
||||
check [ -n "__IFNAME1__" ]
|
||||
|
||||
test DHCP: address
|
||||
guest1 ip link set dev __IFNAME1__ up
|
||||
guest1 /sbin/dhclient -4 __IFNAME1__
|
||||
g1out ADDR1 ip -j -4 addr show|jq -rM '.[] | select(.ifname == "__IFNAME1__").addr_info[0].local'
|
||||
hout HOST_ADDR ip -j -4 addr show|jq -rM '.[] | select(.ifname == "__HOST_IFNAME__").addr_info[0].local'
|
||||
check [ "__ADDR1__" = "__HOST_ADDR__" ]
|
||||
|
||||
test TCP/IPv4: guest1/guest2 > host, host > guest1/guest2
|
||||
g1out GW1 ip -j -4 route show|jq -rM '.[] | select(.dst == "default").gateway'
|
||||
|
||||
hostb socat -u TCP4-LISTEN:10006 OPEN:__STATESETUP__/msg,create,trunc
|
||||
guest1b socat -u TCP4-LISTEN:10001 OPEN:msg,create,trunc
|
||||
sleep 1
|
||||
|
||||
guest1b socat -u UNIX-RECV:proxy.sock,null-eof TCP4:__MAP_HOST4__:10006
|
||||
hostb socat -u UNIX-RECV:__STATESETUP__/proxy.sock,null-eof TCP4:__ADDR1__:10001
|
||||
sleep 1
|
||||
guest1 printf "Hello from guest 1" | socat -u STDIN UNIX:proxy.sock
|
||||
host printf "Dear guest 1," | socat -u STDIN UNIX:__STATESETUP__/proxy.sock
|
||||
sleep 1
|
||||
|
||||
mon echo "migrate tcp:0:20005" | socat -u STDIN UNIX:__STATESETUP__/qemu_1_mon.sock
|
||||
|
||||
sleep 2
|
||||
guest2 printf " and from guest 2" | socat -u STDIN UNIX:proxy.sock,shut-null
|
||||
host printf " you are now guest 2" | socat -u STDIN UNIX:__STATESETUP__/proxy.sock,shut-null
|
||||
|
||||
hostw
|
||||
# FIXME: guest2w doesn't work here because shell jobs are (also) from guest #1,
|
||||
# use sleep 1 for the moment
|
||||
sleep 1
|
||||
|
||||
hout MSG cat __STATESETUP__/msg
|
||||
check [ "__MSG__" = "Hello from guest 1 and from guest 2" ]
|
||||
|
||||
g2out MSG cat msg
|
||||
check [ "__MSG__" = "Dear guest 1, you are now guest 2" ]
|
64
test/migrate/bidirectional_fin
Normal file
64
test/migrate/bidirectional_fin
Normal file
@ -0,0 +1,64 @@
|
||||
# SPDX-License-Identifier: GPL-2.0-or-later
|
||||
#
|
||||
# PASST - Plug A Simple Socket Transport
|
||||
# for qemu/UNIX domain socket mode
|
||||
#
|
||||
# PASTA - Pack A Subtle Tap Abstraction
|
||||
# for network namespace/tap device mode
|
||||
#
|
||||
# test/migrate/bidirectional_fin - Both directions, half-closed sockets
|
||||
#
|
||||
# Copyright (c) 2025 Red Hat GmbH
|
||||
# Author: Stefano Brivio <sbrivio@redhat.com>
|
||||
|
||||
g1tools ip jq dhclient socat cat
|
||||
htools ip jq
|
||||
|
||||
set MAP_HOST4 192.0.2.1
|
||||
set MAP_HOST6 2001:db8:9a55::1
|
||||
set MAP_NS4 192.0.2.2
|
||||
set MAP_NS6 2001:db8:9a55::2
|
||||
|
||||
test Interface name
|
||||
g1out IFNAME1 ip -j link show | jq -rM '.[] | select(.link_type == "ether").ifname'
|
||||
hout HOST_IFNAME ip -j -4 route show|jq -rM '[.[] | select(.dst == "default").dev] | .[0]'
|
||||
hout HOST_IFNAME6 ip -j -6 route show|jq -rM '[.[] | select(.dst == "default").dev] | .[0]'
|
||||
check [ -n "__IFNAME1__" ]
|
||||
|
||||
test DHCP: address
|
||||
guest1 ip link set dev __IFNAME1__ up
|
||||
guest1 /sbin/dhclient -4 __IFNAME1__
|
||||
g1out ADDR1 ip -j -4 addr show|jq -rM '.[] | select(.ifname == "__IFNAME1__").addr_info[0].local'
|
||||
hout HOST_ADDR ip -j -4 addr show|jq -rM '.[] | select(.ifname == "__HOST_IFNAME__").addr_info[0].local'
|
||||
check [ "__ADDR1__" = "__HOST_ADDR__" ]
|
||||
|
||||
test TCP/IPv4: guest1/guest2 <- (half closed) -> host
|
||||
g1out GW1 ip -j -4 route show|jq -rM '.[] | select(.dst == "default").gateway'
|
||||
|
||||
hostb echo FIN | socat TCP4-LISTEN:10006,shut-down STDIO,ignoreeof > __STATESETUP__/msg
|
||||
guest1b echo FIN | socat TCP4-LISTEN:10001,shut-down STDIO,ignoreeof > msg
|
||||
sleep 1
|
||||
|
||||
guest1b socat -u UNIX-RECV:proxy.sock,null-eof TCP4:__MAP_HOST4__:10006
|
||||
hostb socat -u UNIX-RECV:__STATESETUP__/proxy.sock,null-eof TCP4:__ADDR1__:10001
|
||||
sleep 1
|
||||
guest1 printf "Hello from guest 1" | socat -u STDIN UNIX:proxy.sock
|
||||
host printf "Dear guest 1," | socat -u STDIN UNIX:__STATESETUP__/proxy.sock
|
||||
sleep 1
|
||||
|
||||
mon echo "migrate tcp:0:20005" | socat -u STDIN UNIX:__STATESETUP__/qemu_1_mon.sock
|
||||
|
||||
sleep 2
|
||||
guest2 printf " and from guest 2" | socat -u STDIN UNIX:proxy.sock,shut-null
|
||||
host printf " you are now guest 2" | socat -u STDIN UNIX:__STATESETUP__/proxy.sock,shut-null
|
||||
|
||||
hostw
|
||||
# FIXME: guest2w doesn't work here because shell jobs are (also) from guest #1,
|
||||
# use sleep 1 for the moment
|
||||
sleep 1
|
||||
|
||||
hout MSG cat __STATESETUP__/msg
|
||||
check [ "__MSG__" = "Hello from guest 1 and from guest 2" ]
|
||||
|
||||
g2out MSG cat msg
|
||||
check [ "__MSG__" = "Dear guest 1, you are now guest 2" ]
|
58
test/migrate/iperf3_bidir6
Normal file
58
test/migrate/iperf3_bidir6
Normal file
@ -0,0 +1,58 @@
|
||||
# SPDX-License-Identifier: GPL-2.0-or-later
|
||||
#
|
||||
# PASST - Plug A Simple Socket Transport
|
||||
# for qemu/UNIX domain socket mode
|
||||
#
|
||||
# PASTA - Pack A Subtle Tap Abstraction
|
||||
# for network namespace/tap device mode
|
||||
#
|
||||
# test/migrate/iperf3_bidir6 - Migration behaviour with many bidirectional flows
|
||||
#
|
||||
# Copyright (c) 2025 Red Hat GmbH
|
||||
# Author: Stefano Brivio <sbrivio@redhat.com>
|
||||
|
||||
g1tools ip jq dhclient socat cat
|
||||
htools ip jq
|
||||
|
||||
set MAP_HOST4 192.0.2.1
|
||||
set MAP_HOST6 2001:db8:9a55::1
|
||||
set MAP_NS4 192.0.2.2
|
||||
set MAP_NS6 2001:db8:9a55::2
|
||||
|
||||
set THREADS 128
|
||||
set TIME 3
|
||||
set OMIT 0.1
|
||||
set OPTS -Z -P __THREADS__ -O__OMIT__ -N --bidir
|
||||
|
||||
test Interface name
|
||||
g1out IFNAME1 ip -j link show | jq -rM '.[] | select(.link_type == "ether").ifname'
|
||||
hout HOST_IFNAME ip -j -4 route show|jq -rM '[.[] | select(.dst == "default").dev] | .[0]'
|
||||
hout HOST_IFNAME6 ip -j -6 route show|jq -rM '[.[] | select(.dst == "default").dev] | .[0]'
|
||||
check [ -n "__IFNAME1__" ]
|
||||
|
||||
test DHCP: address
|
||||
guest1 ip link set dev __IFNAME1__ up
|
||||
guest1 /sbin/dhclient -4 __IFNAME1__
|
||||
g1out ADDR1 ip -j -4 addr show|jq -rM '.[] | select(.ifname == "__IFNAME1__").addr_info[0].local'
|
||||
hout HOST_ADDR ip -j -4 addr show|jq -rM '.[] | select(.ifname == "__HOST_IFNAME__").addr_info[0].local'
|
||||
check [ "__ADDR1__" = "__HOST_ADDR__" ]
|
||||
|
||||
test DHCPv6: address
|
||||
# Link is up now, wait for DAD to complete
|
||||
guest1 while ip -j -6 addr show tentative | jq -e '.[].addr_info'; do sleep 0.1; done
|
||||
guest1 /sbin/dhclient -6 __IFNAME1__
|
||||
# Wait for DAD to complete on the DHCP address
|
||||
guest1 while ip -j -6 addr show tentative | jq -e '.[].addr_info'; do sleep 0.1; done
|
||||
g1out ADDR1_6 ip -j -6 addr show|jq -rM '[.[] | select(.ifname == "__IFNAME1__").addr_info[] | select(.prefixlen == 128).local] | .[0]'
|
||||
hout HOST_ADDR6 ip -j -6 addr show|jq -rM '[.[] | select(.ifname == "__HOST_IFNAME6__").addr_info[] | select(.scope == "global" and .deprecated != true).local] | .[0]'
|
||||
check [ "__ADDR1_6__" = "__HOST_ADDR6__" ]
|
||||
|
||||
test TCP/IPv6 host <-> guest flood, many flows, during migration
|
||||
|
||||
monb sleep 1; echo "migrate tcp:0:20005" | socat -u STDIN UNIX:__STATESETUP__/qemu_1_mon.sock
|
||||
|
||||
iperf3s host 10006
|
||||
iperf3m BW guest_1 guest_2 __MAP_HOST6__ 10006 __TIME__ __OPTS__
|
||||
bw __BW__ 1 2
|
||||
|
||||
iperf3k host
|
50
test/migrate/iperf3_in4
Normal file
50
test/migrate/iperf3_in4
Normal file
@ -0,0 +1,50 @@
|
||||
# SPDX-License-Identifier: GPL-2.0-or-later
|
||||
#
|
||||
# PASST - Plug A Simple Socket Transport
|
||||
# for qemu/UNIX domain socket mode
|
||||
#
|
||||
# PASTA - Pack A Subtle Tap Abstraction
|
||||
# for network namespace/tap device mode
|
||||
#
|
||||
# test/migrate/iperf3_in4 - Migration behaviour under inbound IPv4 flood
|
||||
#
|
||||
# Copyright (c) 2025 Red Hat GmbH
|
||||
# Author: Stefano Brivio <sbrivio@redhat.com>
|
||||
|
||||
g1tools ip jq dhclient socat cat
|
||||
htools ip jq
|
||||
|
||||
set MAP_HOST4 192.0.2.1
|
||||
set MAP_HOST6 2001:db8:9a55::1
|
||||
set MAP_NS4 192.0.2.2
|
||||
set MAP_NS6 2001:db8:9a55::2
|
||||
|
||||
guest1 /sbin/sysctl -w net.core.rmem_max=33554432
|
||||
guest1 /sbin/sysctl -w net.core.wmem_max=33554432
|
||||
|
||||
set THREADS 1
|
||||
set TIME 4
|
||||
set OMIT 0.1
|
||||
set OPTS -Z -P __THREADS__ -O__OMIT__ -N -R
|
||||
|
||||
test Interface name
|
||||
g1out IFNAME1 ip -j link show | jq -rM '.[] | select(.link_type == "ether").ifname'
|
||||
hout HOST_IFNAME ip -j -4 route show|jq -rM '[.[] | select(.dst == "default").dev] | .[0]'
|
||||
check [ -n "__IFNAME1__" ]
|
||||
|
||||
test DHCP: address
|
||||
guest1 ip link set dev __IFNAME1__ up
|
||||
guest1 /sbin/dhclient -4 __IFNAME1__
|
||||
g1out ADDR1 ip -j -4 addr show|jq -rM '.[] | select(.ifname == "__IFNAME1__").addr_info[0].local'
|
||||
hout HOST_ADDR ip -j -4 addr show|jq -rM '.[] | select(.ifname == "__HOST_IFNAME__").addr_info[0].local'
|
||||
check [ "__ADDR1__" = "__HOST_ADDR__" ]
|
||||
|
||||
test TCP/IPv4 host to guest throughput during migration
|
||||
|
||||
monb sleep 1; echo "migrate tcp:0:20005" | socat -u STDIN UNIX:__STATESETUP__/qemu_1_mon.sock
|
||||
|
||||
iperf3s host 10006
|
||||
iperf3m BW guest_1 guest_2 __MAP_HOST4__ 10006 __TIME__ __OPTS__
|
||||
bw __BW__ 1 2
|
||||
|
||||
iperf3k host
|
58
test/migrate/iperf3_in6
Normal file
58
test/migrate/iperf3_in6
Normal file
@ -0,0 +1,58 @@
|
||||
# SPDX-License-Identifier: GPL-2.0-or-later
|
||||
#
|
||||
# PASST - Plug A Simple Socket Transport
|
||||
# for qemu/UNIX domain socket mode
|
||||
#
|
||||
# PASTA - Pack A Subtle Tap Abstraction
|
||||
# for network namespace/tap device mode
|
||||
#
|
||||
# test/migrate/iperf3_in6 - Migration behaviour under inbound IPv6 flood
|
||||
#
|
||||
# Copyright (c) 2025 Red Hat GmbH
|
||||
# Author: Stefano Brivio <sbrivio@redhat.com>
|
||||
|
||||
g1tools ip jq dhclient socat cat
|
||||
htools ip jq
|
||||
|
||||
set MAP_HOST4 192.0.2.1
|
||||
set MAP_HOST6 2001:db8:9a55::1
|
||||
set MAP_NS4 192.0.2.2
|
||||
set MAP_NS6 2001:db8:9a55::2
|
||||
|
||||
set THREADS 4
|
||||
set TIME 3
|
||||
set OMIT 0.1
|
||||
set OPTS -Z -P __THREADS__ -O__OMIT__ -N -R
|
||||
|
||||
test Interface name
|
||||
g1out IFNAME1 ip -j link show | jq -rM '.[] | select(.link_type == "ether").ifname'
|
||||
hout HOST_IFNAME ip -j -4 route show|jq -rM '[.[] | select(.dst == "default").dev] | .[0]'
|
||||
hout HOST_IFNAME6 ip -j -6 route show|jq -rM '[.[] | select(.dst == "default").dev] | .[0]'
|
||||
check [ -n "__IFNAME1__" ]
|
||||
|
||||
test DHCP: address
|
||||
guest1 ip link set dev __IFNAME1__ up
|
||||
guest1 /sbin/dhclient -4 __IFNAME1__
|
||||
g1out ADDR1 ip -j -4 addr show|jq -rM '.[] | select(.ifname == "__IFNAME1__").addr_info[0].local'
|
||||
hout HOST_ADDR ip -j -4 addr show|jq -rM '.[] | select(.ifname == "__HOST_IFNAME__").addr_info[0].local'
|
||||
check [ "__ADDR1__" = "__HOST_ADDR__" ]
|
||||
|
||||
test DHCPv6: address
|
||||
# Link is up now, wait for DAD to complete
|
||||
guest1 while ip -j -6 addr show tentative | jq -e '.[].addr_info'; do sleep 0.1; done
|
||||
guest1 /sbin/dhclient -6 __IFNAME1__
|
||||
# Wait for DAD to complete on the DHCP address
|
||||
guest1 while ip -j -6 addr show tentative | jq -e '.[].addr_info'; do sleep 0.1; done
|
||||
g1out ADDR1_6 ip -j -6 addr show|jq -rM '[.[] | select(.ifname == "__IFNAME1__").addr_info[] | select(.prefixlen == 128).local] | .[0]'
|
||||
hout HOST_ADDR6 ip -j -6 addr show|jq -rM '[.[] | select(.ifname == "__HOST_IFNAME6__").addr_info[] | select(.scope == "global" and .deprecated != true).local] | .[0]'
|
||||
check [ "__ADDR1_6__" = "__HOST_ADDR6__" ]
|
||||
|
||||
test TCP/IPv6 host to guest throughput during migration
|
||||
|
||||
monb sleep 1; echo "migrate tcp:0:20005" | socat -u STDIN UNIX:__STATESETUP__/qemu_1_mon.sock
|
||||
|
||||
iperf3s host 10006
|
||||
iperf3m BW guest_1 guest_2 __MAP_HOST6__ 10006 __TIME__ __OPTS__
|
||||
bw __BW__ 1 2
|
||||
|
||||
iperf3k host
|
60
test/migrate/iperf3_many_out6
Normal file
60
test/migrate/iperf3_many_out6
Normal file
@ -0,0 +1,60 @@
|
||||
# SPDX-License-Identifier: GPL-2.0-or-later
|
||||
#
|
||||
# PASST - Plug A Simple Socket Transport
|
||||
# for qemu/UNIX domain socket mode
|
||||
#
|
||||
# PASTA - Pack A Subtle Tap Abstraction
|
||||
# for network namespace/tap device mode
|
||||
#
|
||||
# test/migrate/iperf3_many_out6 - Migration behaviour with many outbound flows
|
||||
#
|
||||
# Copyright (c) 2025 Red Hat GmbH
|
||||
# Author: Stefano Brivio <sbrivio@redhat.com>
|
||||
|
||||
g1tools ip jq dhclient socat cat
|
||||
htools ip jq
|
||||
|
||||
set MAP_HOST4 192.0.2.1
|
||||
set MAP_HOST6 2001:db8:9a55::1
|
||||
set MAP_NS4 192.0.2.2
|
||||
set MAP_NS6 2001:db8:9a55::2
|
||||
|
||||
set THREADS 16
|
||||
set TIME 3
|
||||
set OMIT 0.1
|
||||
set OPTS -Z -P __THREADS__ -O__OMIT__ -N -l 1M
|
||||
|
||||
test Interface name
|
||||
g1out IFNAME1 ip -j link show | jq -rM '.[] | select(.link_type == "ether").ifname'
|
||||
hout HOST_IFNAME ip -j -4 route show|jq -rM '[.[] | select(.dst == "default").dev] | .[0]'
|
||||
hout HOST_IFNAME6 ip -j -6 route show|jq -rM '[.[] | select(.dst == "default").dev] | .[0]'
|
||||
check [ -n "__IFNAME1__" ]
|
||||
|
||||
test DHCP: address
|
||||
guest1 ip link set dev __IFNAME1__ up
|
||||
guest1 /sbin/dhclient -4 __IFNAME1__
|
||||
g1out ADDR1 ip -j -4 addr show|jq -rM '.[] | select(.ifname == "__IFNAME1__").addr_info[0].local'
|
||||
hout HOST_ADDR ip -j -4 addr show|jq -rM '.[] | select(.ifname == "__HOST_IFNAME__").addr_info[0].local'
|
||||
check [ "__ADDR1__" = "__HOST_ADDR__" ]
|
||||
|
||||
test DHCPv6: address
|
||||
# Link is up now, wait for DAD to complete
|
||||
guest1 while ip -j -6 addr show tentative | jq -e '.[].addr_info'; do sleep 0.1; done
|
||||
guest1 /sbin/dhclient -6 __IFNAME1__
|
||||
# Wait for DAD to complete on the DHCP address
|
||||
guest1 while ip -j -6 addr show tentative | jq -e '.[].addr_info'; do sleep 0.1; done
|
||||
g1out ADDR1_6 ip -j -6 addr show|jq -rM '[.[] | select(.ifname == "__IFNAME1__").addr_info[] | select(.prefixlen == 128).local] | .[0]'
|
||||
hout HOST_ADDR6 ip -j -6 addr show|jq -rM '[.[] | select(.ifname == "__HOST_IFNAME6__").addr_info[] | select(.scope == "global" and .deprecated != true).local] | .[0]'
|
||||
check [ "__ADDR1_6__" = "__HOST_ADDR6__" ]
|
||||
|
||||
test TCP/IPv6 guest to host flood, many flows, during migration
|
||||
|
||||
test TCP/IPv6 host to guest throughput during migration
|
||||
|
||||
monb sleep 1; echo "migrate tcp:0:20005" | socat -u STDIN UNIX:__STATESETUP__/qemu_1_mon.sock
|
||||
|
||||
iperf3s host 10006
|
||||
iperf3m BW guest_1 guest_2 __MAP_HOST6__ 10006 __TIME__ __OPTS__
|
||||
bw __BW__ 1 2
|
||||
|
||||
iperf3k host
|
47
test/migrate/iperf3_out4
Normal file
47
test/migrate/iperf3_out4
Normal file
@ -0,0 +1,47 @@
|
||||
# SPDX-License-Identifier: GPL-2.0-or-later
|
||||
#
|
||||
# PASST - Plug A Simple Socket Transport
|
||||
# for qemu/UNIX domain socket mode
|
||||
#
|
||||
# PASTA - Pack A Subtle Tap Abstraction
|
||||
# for network namespace/tap device mode
|
||||
#
|
||||
# test/migrate/iperf3_out4 - Migration behaviour under outbound IPv4 flood
|
||||
#
|
||||
# Copyright (c) 2025 Red Hat GmbH
|
||||
# Author: Stefano Brivio <sbrivio@redhat.com>
|
||||
|
||||
g1tools ip jq dhclient socat cat
|
||||
htools ip jq
|
||||
|
||||
set MAP_HOST4 192.0.2.1
|
||||
set MAP_HOST6 2001:db8:9a55::1
|
||||
set MAP_NS4 192.0.2.2
|
||||
set MAP_NS6 2001:db8:9a55::2
|
||||
|
||||
set THREADS 6
|
||||
set TIME 2
|
||||
set OMIT 0.1
|
||||
set OPTS -P __THREADS__ -O__OMIT__ -Z -N -l 1M
|
||||
|
||||
test Interface name
|
||||
g1out IFNAME1 ip -j link show | jq -rM '.[] | select(.link_type == "ether").ifname'
|
||||
hout HOST_IFNAME ip -j -4 route show|jq -rM '[.[] | select(.dst == "default").dev] | .[0]'
|
||||
check [ -n "__IFNAME1__" ]
|
||||
|
||||
test DHCP: address
|
||||
guest1 ip link set dev __IFNAME1__ up
|
||||
guest1 /sbin/dhclient -4 __IFNAME1__
|
||||
g1out ADDR1 ip -j -4 addr show|jq -rM '.[] | select(.ifname == "__IFNAME1__").addr_info[0].local'
|
||||
hout HOST_ADDR ip -j -4 addr show|jq -rM '.[] | select(.ifname == "__HOST_IFNAME__").addr_info[0].local'
|
||||
check [ "__ADDR1__" = "__HOST_ADDR__" ]
|
||||
|
||||
test TCP/IPv4 guest to host throughput during migration
|
||||
|
||||
monb sleep 1; echo "migrate tcp:0:20005" | socat -u STDIN UNIX:__STATESETUP__/qemu_1_mon.sock
|
||||
|
||||
iperf3s host 10006
|
||||
iperf3m BW guest_1 guest_2 __MAP_HOST4__ 10006 __TIME__ __OPTS__
|
||||
bw __BW__ 1 2
|
||||
|
||||
iperf3k host
|
58
test/migrate/iperf3_out6
Normal file
58
test/migrate/iperf3_out6
Normal file
@ -0,0 +1,58 @@
|
||||
# SPDX-License-Identifier: GPL-2.0-or-later
|
||||
#
|
||||
# PASST - Plug A Simple Socket Transport
|
||||
# for qemu/UNIX domain socket mode
|
||||
#
|
||||
# PASTA - Pack A Subtle Tap Abstraction
|
||||
# for network namespace/tap device mode
|
||||
#
|
||||
# test/migrate/iperf3_out6 - Migration behaviour under outbound IPv6 flood
|
||||
#
|
||||
# Copyright (c) 2025 Red Hat GmbH
|
||||
# Author: Stefano Brivio <sbrivio@redhat.com>
|
||||
|
||||
g1tools ip jq dhclient socat cat
|
||||
htools ip jq
|
||||
|
||||
set MAP_HOST4 192.0.2.1
|
||||
set MAP_HOST6 2001:db8:9a55::1
|
||||
set MAP_NS4 192.0.2.2
|
||||
set MAP_NS6 2001:db8:9a55::2
|
||||
|
||||
set THREADS 6
|
||||
set TIME 2
|
||||
set OMIT 0.1
|
||||
set OPTS -P __THREADS__ -O__OMIT__ -Z -N -l 1M
|
||||
|
||||
test Interface name
|
||||
g1out IFNAME1 ip -j link show | jq -rM '.[] | select(.link_type == "ether").ifname'
|
||||
hout HOST_IFNAME ip -j -4 route show|jq -rM '[.[] | select(.dst == "default").dev] | .[0]'
|
||||
hout HOST_IFNAME6 ip -j -6 route show|jq -rM '[.[] | select(.dst == "default").dev] | .[0]'
|
||||
check [ -n "__IFNAME1__" ]
|
||||
|
||||
test DHCP: address
|
||||
guest1 ip link set dev __IFNAME1__ up
|
||||
guest1 /sbin/dhclient -4 __IFNAME1__
|
||||
g1out ADDR1 ip -j -4 addr show|jq -rM '.[] | select(.ifname == "__IFNAME1__").addr_info[0].local'
|
||||
hout HOST_ADDR ip -j -4 addr show|jq -rM '.[] | select(.ifname == "__HOST_IFNAME__").addr_info[0].local'
|
||||
check [ "__ADDR1__" = "__HOST_ADDR__" ]
|
||||
|
||||
test DHCPv6: address
|
||||
# Link is up now, wait for DAD to complete
|
||||
guest1 while ip -j -6 addr show tentative | jq -e '.[].addr_info'; do sleep 0.1; done
|
||||
guest1 /sbin/dhclient -6 __IFNAME1__
|
||||
# Wait for DAD to complete on the DHCP address
|
||||
guest1 while ip -j -6 addr show tentative | jq -e '.[].addr_info'; do sleep 0.1; done
|
||||
g1out ADDR1_6 ip -j -6 addr show|jq -rM '[.[] | select(.ifname == "__IFNAME1__").addr_info[] | select(.prefixlen == 128).local] | .[0]'
|
||||
hout HOST_ADDR6 ip -j -6 addr show|jq -rM '[.[] | select(.ifname == "__HOST_IFNAME6__").addr_info[] | select(.scope == "global" and .deprecated != true).local] | .[0]'
|
||||
check [ "__ADDR1_6__" = "__HOST_ADDR6__" ]
|
||||
|
||||
test TCP/IPv6 guest to host throughput during migration
|
||||
|
||||
monb sleep 1; echo "migrate tcp:0:20005" | socat -u STDIN UNIX:__STATESETUP__/qemu_1_mon.sock
|
||||
|
||||
iperf3s host 10006
|
||||
iperf3m BW guest_1 guest_2 __MAP_HOST6__ 10006 __TIME__ __OPTS__
|
||||
bw __BW__ 1 2
|
||||
|
||||
iperf3k host
|
@ -6,10 +6,10 @@
|
||||
# PASTA - Pack A Subtle Tap Abstraction
|
||||
# for network namespace/tap device mode
|
||||
#
|
||||
# test/migrate/basic - Check basic migration functionality
|
||||
# test/migrate/rampstream_in - Check sequence correctness with inbound ramp
|
||||
#
|
||||
# Copyright (c) 2025 Red Hat GmbH
|
||||
# Author: Stefano Brivio <sbrivio@redhat.com>
|
||||
# Copyright (c) 2025 Red Hat
|
||||
# Author: David Gibson <david@gibson.dropbear.id.au>
|
||||
|
||||
g1tools ip jq dhclient socat cat
|
||||
htools ip jq
|
||||
@ -43,15 +43,15 @@ g1out ADDR1_6 ip -j -6 addr show|jq -rM '[.[] | select(.ifname == "__IFNAME1__")
|
||||
hout HOST_ADDR6 ip -j -6 addr show|jq -rM '[.[] | select(.ifname == "__HOST_IFNAME6__").addr_info[] | select(.scope == "global" and .deprecated != true).local] | .[0]'
|
||||
check [ "__ADDR1_6__" = "__HOST_ADDR6__" ]
|
||||
|
||||
test TCP/IPv4: host > guest
|
||||
test TCP/IPv4: sequence check, ramps, inbound
|
||||
g1out GW1 ip -j -4 route show|jq -rM '.[] | select(.dst == "default").gateway'
|
||||
guest1b socat -u TCP4-LISTEN:10001 EXEC:"rampstream-check.sh __RAMPS__"
|
||||
sleep 1
|
||||
hostb socat -u EXEC:"test/rampstream send __RAMPS__" TCP4:__ADDR1__:10001
|
||||
|
||||
sleep 1
|
||||
sleep 1
|
||||
|
||||
#mon echo "migrate tcp:0:20005" | socat -u STDIN UNIX:__STATESETUP__/qemu_1_mon.sock
|
||||
monb echo "migrate tcp:0:20005" | socat -u STDIN UNIX:__STATESETUP__/qemu_1_mon.sock
|
||||
|
||||
hostw
|
||||
|
||||
|
@ -6,10 +6,10 @@
|
||||
# PASTA - Pack A Subtle Tap Abstraction
|
||||
# for network namespace/tap device mode
|
||||
#
|
||||
# test/migrate/basic - Check basic migration functionality
|
||||
# test/migrate/rampstream_out - Check sequence correctness with outbound ramp
|
||||
#
|
||||
# Copyright (c) 2025 Red Hat GmbH
|
||||
# Author: Stefano Brivio <sbrivio@redhat.com>
|
||||
# Copyright (c) 2025 Red Hat
|
||||
# Author: David Gibson <david@gibson.dropbear.id.au>
|
||||
|
||||
g1tools ip jq dhclient socat cat
|
||||
htools ip jq
|
||||
@ -43,7 +43,7 @@ g1out ADDR1_6 ip -j -6 addr show|jq -rM '[.[] | select(.ifname == "__IFNAME1__")
|
||||
hout HOST_ADDR6 ip -j -6 addr show|jq -rM '[.[] | select(.ifname == "__HOST_IFNAME6__").addr_info[] | select(.scope == "global" and .deprecated != true).local] | .[0]'
|
||||
check [ "__ADDR1_6__" = "__HOST_ADDR6__" ]
|
||||
|
||||
test TCP/IPv4: guest > host
|
||||
test TCP/IPv4: sequence check, ramps, outbound
|
||||
g1out GW1 ip -j -4 route show|jq -rM '.[] | select(.dst == "default").gateway'
|
||||
hostb socat -u TCP4-LISTEN:10006 EXEC:"test/rampstream check __RAMPS__"
|
||||
sleep 1
|
||||
|
42
test/run
42
test/run
@ -130,6 +130,43 @@ run() {
|
||||
test two_guests_vu/basic
|
||||
teardown two_guests
|
||||
|
||||
setup migrate
|
||||
test migrate/basic
|
||||
teardown migrate
|
||||
setup migrate
|
||||
test migrate/basic_fin
|
||||
teardown migrate
|
||||
setup migrate
|
||||
test migrate/bidirectional
|
||||
teardown migrate
|
||||
setup migrate
|
||||
test migrate/bidirectional_fin
|
||||
teardown migrate
|
||||
setup migrate
|
||||
test migrate/iperf3_out4
|
||||
teardown migrate
|
||||
setup migrate
|
||||
test migrate/iperf3_out6
|
||||
teardown migrate
|
||||
setup migrate
|
||||
test migrate/iperf3_in4
|
||||
teardown migrate
|
||||
setup migrate
|
||||
test migrate/iperf3_in6
|
||||
teardown migrate
|
||||
setup migrate
|
||||
test migrate/iperf3_bidir6
|
||||
teardown migrate
|
||||
setup migrate
|
||||
test migrate/iperf3_many_out6
|
||||
teardown migrate
|
||||
setup migrate
|
||||
test migrate/rampstream_in
|
||||
teardown migrate
|
||||
setup migrate
|
||||
test migrate/rampstream_out
|
||||
teardown migrate
|
||||
|
||||
VALGRIND=0
|
||||
VHOST_USER=0
|
||||
setup passt_in_ns
|
||||
@ -186,7 +223,10 @@ run_selected() {
|
||||
|
||||
__setup=
|
||||
for __test; do
|
||||
if [ "${__test%%/*}" != "${__setup}" ]; then
|
||||
# HACK: the migrate tests need the setup repeated for
|
||||
# each test
|
||||
if [ "${__test%%/*}" != "${__setup}" -o \
|
||||
"${__test%%/*}" = "migrate" ]; then
|
||||
[ -n "${__setup}" ] && teardown "${__setup}"
|
||||
__setup="${__test%%/*}"
|
||||
setup "${__setup}"
|
||||
|
Loading…
x
Reference in New Issue
Block a user