diff mbox series

[ovs-dev,v7,3/5] tests: Eliminate most "sleep" calls.

Message ID 20201119051308.27913-4-blp@ovn.org
State New
Headers show
Series Add DDlog implementation of ovn-northd | expand

Commit Message

Ben Pfaff Nov. 19, 2020, 5:13 a.m. UTC
Many of these could be replaced by "ovn-nbctl sync".  Some weren't
really needed at all because they were adjacent to something that itself
called sync or otherwise used --wait.  Some were more appropriately
done with explicit waits for what was really needed.

I left some "sleep"s.  Some were because they were "negative" sleeps:
they were giving time for something to happen that should *not* happen
(in other words, if you wait for it to happen, you'll wait forever,
unless there's a bug).  Some were because I didn't know how to properly
wait for what they were waiting for, or because I didn't understand
the circumstances deeply enough.

Signed-off-by: Ben Pfaff <blp@ovn.org>
---
 tests/ovn-macros.at |  15 +++
 tests/ovn-northd.at |  11 +-
 tests/ovn.at        | 259 ++++++++++++++++++++++----------------------
 3 files changed, 155 insertions(+), 130 deletions(-)
diff mbox series

Patch

diff --git a/tests/ovn-macros.at b/tests/ovn-macros.at
index 44c0e20cfdc5..b4dc387e54a4 100644
--- a/tests/ovn-macros.at
+++ b/tests/ovn-macros.at
@@ -437,6 +437,21 @@  wait_column() {
       echo "$column in $db table $table has value $found, from the following rows:"
       ovn-${db}ctl list $table])
 }
+
+# wait_for_ports_up [PORT...]
+#
+# With arguments, waits for specified Logical_Switch_Ports to come up.
+# Without arguments, waits for all Logical_Switch_Ports (except
+# localnet, localport, and virtual ports) to come up.
+wait_for_ports_up() {
+    if test $# = 0; then
+        wait_row_count nb:Logical_Switch_Port 0 up!=true type!=localnet type!=localport type!=virtual
+    else
+        for port; do
+            wait_row_count nb:Logical_Switch_Port 1 up=true name=$port
+        done
+    fi
+}
 OVS_END_SHELL_HELPERS
 
 m4_define([OVN_POPULATE_ARP], [AT_CHECK(ovn_populate_arp__, [0], [ignore])])
diff --git a/tests/ovn-northd.at b/tests/ovn-northd.at
index 949a8eee054e..78b1ff728af3 100644
--- a/tests/ovn-northd.at
+++ b/tests/ovn-northd.at
@@ -878,7 +878,7 @@  uuid=$(fetch_column Port_Binding _uuid logical_port=cr-DR-S1)
 echo "CR-LRP UUID is: " $uuid
 
 check ovn-nbctl set Logical_Router $cr_uuid options:chassis=gw1
-check ovn-nbctl --wait=hv sync
+check ovn-nbctl --wait=sb sync
 
 ovn-nbctl create Address_Set name=allowed_range addresses=\"1.1.1.1\"
 ovn-nbctl create Address_Set name=disallowed_range addresses=\"2.2.2.2\"
@@ -1120,6 +1120,7 @@  ovn-nbctl --wait=sb -- --id=@hc create \
 Load_Balancer_Health_Check vip="10.0.0.10\:80" -- add Load_Balancer . \
 health_check @hc
 wait_row_count Service_Monitor 2
+check ovn-nbctl --wait=sb sync
 
 ovn-sbctl dump-flows sw0 | grep ct_lb | grep priority=120 > lflows.txt
 AT_CHECK([cat lflows.txt | sed 's/table=..//'], [0], [dnl
@@ -1139,6 +1140,7 @@  OVS_WAIT_FOR_OUTPUT(
 # Set the service monitor for sw1-p1 to offline
 check ovn-sbctl set service_monitor sw1-p1 status=offline
 wait_row_count Service_Monitor 1 logical_port=sw1-p1 status=offline
+check ovn-nbctl --wait=sb sync
 
 AT_CAPTURE_FILE([sbflows4])
 OVS_WAIT_FOR_OUTPUT(
@@ -1150,6 +1152,7 @@  OVS_WAIT_FOR_OUTPUT(
 ovn-sbctl set service_monitor $sm_sw0_p1 status=offline
 
 wait_row_count Service_Monitor 1 logical_port=sw0-p1 status=offline
+check ovn-nbctl --wait=sb sync
 
 AT_CAPTURE_FILE([sbflows5])
 OVS_WAIT_FOR_OUTPUT(
@@ -1166,6 +1169,7 @@  ovn-sbctl set service_monitor $sm_sw0_p1 status=online
 ovn-sbctl set service_monitor $sm_sw1_p1 status=online
 
 wait_row_count Service_Monitor 1 logical_port=sw1-p1 status=online
+check ovn-nbctl --wait=sb sync
 
 AT_CAPTURE_FILE([sbflows7])
 OVS_WAIT_FOR_OUTPUT(
@@ -1176,6 +1180,7 @@  OVS_WAIT_FOR_OUTPUT(
 # Set the service monitor for sw1-p1 to error
 ovn-sbctl set service_monitor $sm_sw1_p1 status=error
 wait_row_count Service_Monitor 1 logical_port=sw1-p1 status=error
+check ovn-nbctl --wait=sb sync
 
 ovn-sbctl dump-flows sw0 | grep "ip4.dst == 10.0.0.10 && tcp.dst == 80" \
 | grep priority=120 > lflows.txt
@@ -1214,6 +1219,7 @@  OVS_WAIT_FOR_OUTPUT(
 check ovn-sbctl set service_monitor sw1-p1 status=online
 
 wait_row_count Service_Monitor 1 logical_port=sw1-p1 status=online
+check ovn-nbctl --wait=sb sync
 
 AT_CAPTURE_FILE([sbflows10])
 OVS_WAIT_FOR_OUTPUT(
@@ -1244,6 +1250,7 @@  AT_CHECK([ovn-nbctl -- --id=@hc create Load_Balancer_Health_Check vip="10.0.0.10
 
 check ovn-nbctl ls-lb-add sw0 lb2
 check ovn-nbctl ls-lb-add sw1 lb2
+check ovn-nbctl --wait=sb sync
 
 wait_row_count Service_Monitor 5
 
@@ -1756,7 +1763,7 @@  check ovn-nbctl pg-add pg0 sw0-p1 sw1-p1
 check ovn-nbctl acl-add pg0 from-lport 1002 "inport == @pg0 && ip4 && tcp && tcp.dst == 80" reject
 check ovn-nbctl acl-add pg0 to-lport 1003 "outport == @pg0 && ip6 && udp" reject
 
-check ovn-nbctl --wait=hv sync
+check ovn-nbctl --wait=sb sync
 
 AS_BOX([1])
 
diff --git a/tests/ovn.at b/tests/ovn.at
index 2f295dd6ee98..6a81ec6f07a5 100644
--- a/tests/ovn.at
+++ b/tests/ovn.at
@@ -1792,16 +1792,13 @@  get_lsp_uuid () {
 ovn-nbctl create Port_Group name=pg1 ports=`get_lsp_uuid lp22`,`get_lsp_uuid lp33`
 ovn-nbctl acl-add lsw0 to-lport 1000 'eth.type == 0x1238 && outport == @pg1' drop
 check ovn-nbctl --wait=hv sync
+wait_for_ports_up
 
 # Pre-populate the hypervisors' ARP tables so that we don't lose any
 # packets for ARP resolution (native tunneling doesn't queue packets
 # for ARP resolution).
 OVN_POPULATE_ARP
 
-# Allow some time for ovn-northd and ovn-controller to catch up.
-# XXX This should be more systematic.
-sleep 1
-
 # Make sure there is no attempt to adding duplicated flows by ovn-controller
 AT_FAIL_IF([test -n "`grep duplicate hv1/ovn-controller.log`"])
 AT_FAIL_IF([test -n "`grep duplicate hv2/ovn-controller.log`"])
@@ -1996,11 +1993,7 @@  done
 
 # set address for lp13 with invalid characters.
 # lp13 should be configured with only 192.168.0.13.
-ovn-nbctl lsp-set-addresses lp13 "f0:00:00:00:00:13 192.168.0.13 invalid 192.169.0.13"
-
-# Allow some time for ovn-northd and ovn-controller to catch up.
-# XXX This should be more systematic.
-sleep 1
+ovn-nbctl --wait=hv lsp-set-addresses lp13 "f0:00:00:00:00:13 192.168.0.13 invalid 192.169.0.13"
 
 sip=`ip_to_hex 192 168 0 11`
 tip=`ip_to_hex 192 168 0 13`
@@ -2075,7 +2068,11 @@  for i in 1 2; do
     done
 done
 
-sleep 1
+# Wait for bindings to take effect.
+wait_row_count Port_Binding 1 logical_port=lp11 'encap!=[[]]'
+wait_row_count Port_Binding 1 logical_port=lp12 'encap!=[[]]'
+wait_row_count Port_Binding 1 logical_port=lp21 'encap!=[[]]'
+wait_row_count Port_Binding 1 logical_port=lp22 'encap!=[[]]'
 
 # dump port bindings; since we have vxlan and geneve tunnels, we expect the
 # ports to be bound to geneve tunnels.
@@ -2095,9 +2092,8 @@  check_row_count Port_Binding 1 logical_port=lp22 encap=$encap_rec
 # for ARP resolution).
 OVN_POPULATE_ARP
 
-# Allow some time for ovn-northd and ovn-controller to catch up.
-# XXX This should be more systematic.
-sleep 1
+wait_for_ports_up
+check ovn-nbctl --wait=hv sync
 
 # Make sure there is no attempt to adding duplicated flows by ovn-controller
 AT_FAIL_IF([test -n "`grep duplicate hv1/ovn-controller.log`"])
@@ -2491,6 +2487,7 @@  for i in 1 2; do
         OVS_WAIT_UNTIL([test x`ovn-nbctl lsp-get-up $lsp_name` = xup])
     done
 done
+wait_for_ports_up
 ovn-nbctl --wait=sb sync
 ovn-sbctl dump-flows > sbflows
 AT_CAPTURE_FILE([sbflows])
@@ -2659,6 +2656,7 @@  for hv in 1 2; do
 done
 
 
+wait_for_ports_up
 ovn-nbctl --wait=sb sync
 
 ovn-sbctl dump-flows > sbflows
@@ -2794,6 +2792,7 @@  for hv in 1 2; do
 done
 
 
+wait_for_ports_up
 ovn-nbctl --wait=sb sync
 ovn-nbctl show
 ovn-sbctl dump-flows > sbflows
@@ -2933,6 +2932,7 @@  for i in 1 2; do
     OVS_WAIT_UNTIL([test x`ovn-nbctl lsp-get-up $lsp_name` = xup])
 done
 
+wait_for_ports_up
 ovn-nbctl --wait=sb sync
 ovn-nbctl show
 ovn-sbctl dump-flows > sbflows
@@ -3149,6 +3149,7 @@  for tag in 10 20; do
         OVS_WAIT_UNTIL([test x`ovn-nbctl lsp-get-up $lsp_name` = xup])
     done
 done
+wait_for_ports_up
 ovn-nbctl --wait=sb sync
 ovn-sbctl dump-flows
 
@@ -3309,9 +3310,8 @@  ovs-vsctl add-port br-phys vif3 -- set Interface vif3 options:tx_pcap=hv3/vif3-t
 # for ARP resolution).
 OVN_POPULATE_ARP
 
-# Allow some time for ovn-northd and ovn-controller to catch up.
-# XXX This should be more systematic.
-sleep 1
+wait_for_ports_up
+check ovn-nbctl --wait=hv sync
 
 # test_packet INPORT DST SRC ETHTYPE OUTPORT...
 #
@@ -3477,9 +3477,8 @@  ovs-vsctl add-port br-phys vif3 -- set Interface vif3 options:tx_pcap=hv3/vif3-t
 # for ARP resolution).
 OVN_POPULATE_ARP
 
-# Allow some time for ovn-northd and ovn-controller to catch up.
-# XXX This should be more systematic.
-sleep 1
+wait_for_ports_up
+check ovn-nbctl --wait=hv sync
 
 # test_packet INPORT DST SRC ETHTYPE OUTPORT...
 #
@@ -3670,6 +3669,7 @@  for i in 1 2 3; do
     done
 done
 
+wait_for_ports_up
 check ovn-nbctl --wait=hv sync
 
 # Pre-populate the hypervisors' ARP tables so that we don't lose any
@@ -3677,8 +3677,7 @@  check ovn-nbctl --wait=hv sync
 # for ARP resolution).
 OVN_POPULATE_ARP
 
-# Allow some time for ovn-northd and ovn-controller to catch up.
-# XXX This should be more systematic.
+check ovn-nbctl --wait=hv sync
 
 # test_ip INPORT SRC_MAC DST_MAC SRC_IP DST_IP OUTPORT...
 #
@@ -4078,8 +4077,8 @@  done
 OVN_POPULATE_ARP
 
 # Allow some time for ovn-northd and ovn-controller to catch up.
-# XXX This should be more systematic.
-sleep 1
+wait_for_ports_up
+check ovn-nbctl --wait=hv sync
 
 # test_ip INPORT SRC_MAC DST_MAC SRC_IP DST_IP OUTPORT...
 #
@@ -4253,8 +4252,8 @@  done
 OVN_POPULATE_ARP
 
 # Allow some time for ovn-northd and ovn-controller to catch up.
-# XXX This should be more systematic.
-sleep 1
+wait_for_ports_up
+check ovn-nbctl --wait=hv sync
 
 # Given the name of a logical port, prints the name of the hypervisor
 # on which it is located.
@@ -4688,8 +4687,8 @@  ovs-vsctl -- add-port br-int hv2-vif1 -- \
 OVN_POPULATE_ARP
 
 # Allow some time for ovn-northd and ovn-controller to catch up.
-# XXX This should be more systematic.
-sleep 1
+wait_for_ports_up
+check ovn-nbctl --wait=hv sync
 
 # Packet to send.
 packet="inport==\"ls1-lp1\" && eth.src==$ls1_lp1_mac && eth.dst==$rp_ls1_mac &&
@@ -4800,9 +4799,8 @@  ovs-vsctl -- add-port br-int vif2 -- \
     ofport-request=1
 
 
-# Allow some time for ovn-northd and ovn-controller to catch up.
-# XXX This should be more systematic.
-sleep 1
+wait_for_ports_up
+check ovn-nbctl --wait=hv sync
 
 # Send ip packets between the two ports.
 
@@ -4834,11 +4832,7 @@  as hv1 ovs-ofctl dump-flows br-int
 
 
 #Disable router R1
-ovn-nbctl set Logical_Router R1 enabled=false
-
-# Allow some time for ovn-northd and ovn-controller to catch up.
-# XXX This should be more systematic.
-sleep 1
+ovn-nbctl --wait=hv set Logical_Router R1 enabled=false
 
 echo "---------SB dump-----"
 ovn-sbctl list datapath_binding
@@ -4914,10 +4908,9 @@  ovs-vsctl -- add-port br-int vif2 -- \
     options:rxq_pcap=hv1/vif2-rx.pcap \
     ofport-request=1
 
+wait_for_ports_up
+check ovn-nbctl --wait=hv sync
 
-# Allow some time for ovn-northd and ovn-controller to catch up.
-# XXX This should be more systematic.
-sleep 1
 
 # Send ip packets between the two ports.
 
@@ -4948,7 +4941,7 @@  echo "------ hv1 dump ----------"
 as hv1 ovs-ofctl dump-flows br-int
 
 #Disable router R1
-ovn-nbctl set Logical_Router R1 enabled=false
+ovn-nbctl --wait=hv set Logical_Router R1 enabled=false
 
 echo "---------SB dump-----"
 ovn-sbctl list datapath_binding
@@ -4959,9 +4952,6 @@  echo "---------------------"
 echo "------ hv1 dump ----------"
 as hv1 ovs-ofctl dump-flows br-int
 
-# Allow some time for the disabling of logical router R1 to propagate.
-# XXX This should be more systematic.
-sleep 1
 
 as hv1 ovs-appctl netdev-dummy/receive vif1 $packet
 
@@ -5066,8 +5056,8 @@  ovs-vsctl -- add-port br-int hv2-vif1 -- \
 OVN_POPULATE_ARP
 
 # Allow some time for ovn-northd and ovn-controller to catch up.
-# XXX This should be more systematic.
-sleep 1
+wait_for_ports_up
+check ovn-nbctl --wait=hv sync
 
 # Send ip packets between foo1 and alice1
 src_mac="f00000010203"
@@ -5289,8 +5279,8 @@  ovs-vsctl -- add-port br-int hv2-vif1 -- \
 OVN_POPULATE_ARP
 
 # Allow some time for ovn-northd and ovn-controller to catch up.
-# XXX This should be more systematic.
-sleep 1
+wait_for_ports_up
+check ovn-nbctl --wait=hv sync
 
 # Send ip packets between foo1 and alice1
 src_mac="f00000010203"
@@ -5427,7 +5417,8 @@  as hv1 ovs-appctl vlog/set dbg
 
 OVN_POPULATE_ARP
 
-sleep 2
+wait_for_ports_up
+check ovn-nbctl --wait=hv sync
 
 as hv1 ovs-vsctl show
 
@@ -6092,7 +6083,8 @@  ovs-vsctl -- add-port br-int hv1-vif5 -- \
 
 OVN_POPULATE_ARP
 
-sleep 2
+wait_for_ports_up
+check ovn-nbctl --wait=hv sync
 
 trim_zeros() {
     sed 's/\(00\)\{1,\}$//'
@@ -6374,10 +6366,8 @@  ovn-nbctl lsp-add foo foo1 \
 ovn-nbctl lsp-add alice alice1 \
 -- lsp-set-addresses alice1 "f0:00:00:01:02:04 172.16.1.2"
 
-
-# Allow some time for ovn-northd and ovn-controller to catch up.
-# XXX This should be more systematic.
-sleep 2
+wait_for_ports_up
+check ovn-nbctl --wait=hv sync
 
 # Send ip packets between foo1 and alice1
 src_mac="f00000010203"
@@ -6440,7 +6430,8 @@  ip_prefix=192.168.1.0/24 nexthop=20.0.0.1 -- add Logical_Router \
 R2 static_routes @lrt
 
 # Wait for ovn-controller to catch up.
-sleep 1
+wait_for_ports_up
+check ovn-nbctl --wait=hv sync
 
 # Send the packet again.
 as hv1 ovs-appctl netdev-dummy/receive hv1-vif1 $packet
@@ -6512,10 +6503,9 @@  ovs-vsctl -- add-port br-int vif2 -- \
     options:rxq_pcap=hv1/vif2-rx.pcap \
     ofport-request=1
 
-
 # Allow some time for ovn-northd and ovn-controller to catch up.
-# XXX This should be more systematic.
-sleep 1
+wait_for_ports_up
+check ovn-nbctl --wait=hv sync
 
 
 for i in 1 2; do
@@ -6673,10 +6663,6 @@  ovs-vsctl -- add-port br-int vif3 -- \
     options:rxq_pcap=pbr-hv/vif3-rx.pcap \
     ofport-request=1
 
-# Allow some time for ovn-northd and ovn-controller to catch up.
-# XXX This should be more systematic.
-sleep 1
-
 ls1_ro_mac=00:00:00:01:02:f1
 ls1_ro_ip=192.168.1.1
 
@@ -6863,10 +6849,6 @@  ovs-vsctl -- add-port br-int vif3 -- \
     options:rxq_pcap=pbr-hv/vif3-rx.pcap \
     ofport-request=1
 
-# Allow some time for ovn-northd and ovn-controller to catch up.
-# XXX This should be more systematic.
-sleep 1
-
 ls1_ro_mac=00:00:00:01:02:f1
 ls1_ro_ip=2001::1
 
@@ -7073,6 +7055,7 @@  ovn-nbctl lsp-del lp1
 ovn-nbctl ls-del ls1
 
 # wait for earlier changes to take effect
+wait_for_ports_up
 check ovn-nbctl --wait=sb sync
 
 # ensure OF rules are no longer present. There used to be a bug here.
@@ -7121,14 +7104,12 @@  ovn-nbctl acl-add lsw0 to-lport 1002 'outport == "lp1" && ip6 && icmp6'  allow-r
 ovn-nbctl acl-add lsw0 to-lport 1002 'outport == "lp2" && ip6 && icmp6'  allow-related
 
 # Allow some time for ovn-northd and ovn-controller to catch up.
-# XXX This should be more systematic.
+# XXX The "sleep" here seems to be essential for ovn-northd-ddlog,
+# which may indicate that it needs improvement.
+wait_for_ports_up
+check ovn-nbctl --wait=hv sync
 sleep 1
 
-# Given the name of a logical port, prints the name of the hypervisor
-# on which it is located.
-vif_to_hv() {
-    echo hv1${1%?}
-}
 for i in 1 2; do
     : > $i.expected
 done
@@ -7169,9 +7150,7 @@  ovn_attach n1 br-phys 192.168.0.1
 
 row=`ovn-nbctl create Address_Set name=set1 addresses=\"1.1.1.1\"`
 ovn-nbctl set Address_Set $row name=set1 addresses=\"1.1.1.1,1.1.1.2\"
-ovn-nbctl destroy Address_Set $row
-
-sleep 1
+ovn-nbctl --wait=hv destroy Address_Set $row
 
 # A bug previously existed in the address set support code
 # that caused ovn-controller to crash after an address set
@@ -7559,8 +7538,8 @@  ovs-vsctl -- add-port br-int hv1-vif3 -- \
     ofport-request=3
 
 # Allow some time for ovn-northd and ovn-controller to catch up.
-# XXX This should be more systematic.
-sleep 1
+wait_for_ports_up
+check ovn-nbctl --wait=hv sync
 
 # Send ip packets between foo1 and foo2
 src_mac="0a0000a80103"
@@ -7771,8 +7750,8 @@  ovs-vsctl -- add-port br-int hv1-ls2lp2 -- \
     ofport-request=2
 
 # Allow some time for ovn-northd and ovn-controller to catch up.
-# XXX This should be more systematic.
-sleep 1
+wait_for_ports_up
+check ovn-nbctl --wait=hv sync
 
 echo "---------NB dump-----"
 ovn-nbctl show
@@ -8255,6 +8234,7 @@  ovn-nbctl --wait=sb lsp-add lsw0 lp2
 ovn-nbctl lsp-set-addresses lp1 $lp1_mac
 ovn-nbctl lsp-set-addresses lp2 $lp2_mac
 ovn-nbctl --wait=sb sync
+wait_for_ports_up
 
 ovn-nbctl acl-add lsw0 to-lport 1000 'tcp.dst==80' drop
 ovn-nbctl --log --severity=alert --name=drop-flow acl-add lsw0 to-lport 1000 'tcp.dst==81' drop
@@ -8362,6 +8342,7 @@  ovn-nbctl --wait=sb lsp-add lsw0 lp2
 ovn-nbctl lsp-set-addresses lp1 $lp1_mac
 ovn-nbctl lsp-set-addresses lp2 $lp2_mac
 ovn-nbctl --wait=sb sync
+wait_for_ports_up
 
 
 # Add an ACL that rate-limits logs at 10 per second.
@@ -8453,6 +8434,7 @@  ovn-nbctl --wait=sb lsp-add lsw0 lp2
 ovn-nbctl lsp-set-addresses lp1 $lp1_mac
 ovn-nbctl lsp-set-addresses lp2 $lp2_mac
 ovn-nbctl --wait=sb sync
+wait_for_ports_up
 
 ovn-appctl -t ovn-controller vlog/set file:dbg
 
@@ -8501,6 +8483,7 @@  check ovs-vsctl add-br br-phys
 ovn_attach n1 br-phys 192.168.0.1
 check ovs-vsctl add-port br-int vif1 -- set Interface vif1 external-ids:iface-id=lp1 options:tx_pcap=vif1-tx.pcap options:rxq_pcap=vif1-rx.pcap ofport-request=1
 check ovs-vsctl add-port br-int vif2 -- set Interface vif2 external-ids:iface-id=lp2 options:tx_pcap=vif2-tx.pcap options:rxq_pcap=vif2-rx.pcap ofport-request=2
+wait_for_ports_up lp1 lp2
 
 AT_CAPTURE_FILE([trace])
 ovn_trace () {
@@ -8901,8 +8884,8 @@  ovs-vsctl -- add-port br-int vm2 -- \
 OVN_POPULATE_ARP
 
 # Allow some time for ovn-northd and ovn-controller to catch up.
-# XXX This should be more systematic.
-sleep 1
+wait_for_ports_up
+check ovn-nbctl --wait=hv sync
 
 # Test that ovn-controllers create ct-zone entry for container ports.
 foo1_zoneid=$(as hv1 ovs-vsctl get bridge br-int external_ids:ct-zone-foo1)
@@ -8929,6 +8912,7 @@  AT_CHECK([test  -z $bar2_zoneid])
 # Add back bar2
 ovn-nbctl lsp-add bar bar2 vm2 1 \
 -- lsp-set-addresses bar2 "f0:00:00:01:02:08 192.168.2.3"
+wait_for_ports_up
 ovn-nbctl --wait=hv sync
 
 bar2_zoneid=$(as hv2 ovs-vsctl get bridge br-int external_ids:ct-zone-bar2)
@@ -9210,8 +9194,8 @@  ovn-nbctl --wait=hv lsp-add bob bob1 \
 OVN_POPULATE_ARP
 
 # Allow some time for ovn-northd and ovn-controller to catch up.
-# XXX This should be more systematic.
-sleep 1
+wait_for_ports_up
+check ovn-nbctl --wait=hv sync
 
 trim_zeros() {
     sed 's/\(00\)\{1,\}$//'
@@ -9320,7 +9304,8 @@  ovs-vsctl -- add-port br-int hv1-vif2 -- \
     ofport-request=2
 
 OVN_POPULATE_ARP
-sleep 2
+wait_for_ports_up
+check ovn-nbctl --wait=hv sync
 as hv1 ovs-vsctl show
 
 echo "*************************"
@@ -9815,6 +9800,7 @@  check as gw1 ovs-vsctl set open . external-ids:ovn-bridge-mappings=phys:br-phys
 check as gw2 ovs-vsctl set open . external-ids:ovn-bridge-mappings=phys:br-phys
 check as ext1 ovs-vsctl set open . external-ids:ovn-bridge-mappings=phys:br-phys
 
+wait_for_ports_up
 AT_CHECK([ovn-nbctl --wait=sb sync], [0], [ignore])
 
 ovn-sbctl dump-flows > sbflows
@@ -9882,13 +9868,9 @@  test_ip_packet()
     fi
     as ext1 reset_pcap_file ext1-vif1 ext1/vif1
 
-    sleep 1
-
     # Resend packet from foo1 to outside1
     check as hv1 ovs-appctl netdev-dummy/receive hv1-vif1 $packet
 
-    sleep 1
-
     AT_CAPTURE_FILE([exp])
     AT_CAPTURE_FILE([rcv])
     check_packets() {
@@ -10080,6 +10062,7 @@  as gw1 ovs-vsctl set open . external-ids:ovn-bridge-mappings=phys:br-phys
 as gw2 ovs-vsctl set open . external-ids:ovn-bridge-mappings=phys:br-phys
 as ext1 ovs-vsctl set open . external-ids:ovn-bridge-mappings=phys:br-phys
 
+wait_for_ports_up
 check ovn-nbctl --wait=sb sync
 
 ovn-sbctl dump-flows > sbflows
@@ -10092,8 +10075,7 @@  hv1_ch_uuid=$(fetch_column Chassis _uuid name=hv1)
 wait_column "$hv1_ch_uuid" HA_Chassis_Group ref_chassis
 
 # Allow some time for ovn-northd and ovn-controller to catch up.
-# XXX This should be more systematic.
-sleep 2
+check ovn-nbctl --wait=hv sync
 
 reset_pcap_file() {
     local iface=$1
@@ -10293,6 +10275,7 @@  check as hv3 ovs-vsctl set open . external-ids:ovn-bridge-mappings=phys:br-phys
 
 
 dnl Allow some time for ovn-northd and ovn-controller to catch up.
+wait_for_ports_up
 ovn-nbctl --wait=hv sync
 
 (echo "---------NB dump-----"
@@ -10412,6 +10395,7 @@  OVS_WAIT_UNTIL([test 1 = `as hv2 ovs-vsctl show | \
 grep "Port patch-br-int-to-ln-alice" | wc -l`])
 
 dnl Allow some time for ovn-controller to catch up.
+wait_for_ports_up
 ovn-nbctl --wait=hv sync
 
 # ARP for router IP address from outside1
@@ -10485,8 +10469,8 @@  ovn-nbctl lsp-add foo foo2 \
 -- lsp-set-addresses foo2 "f0:00:00:01:02:06 192.168.1.3"
 
 # Allow some time for ovn-northd and ovn-controller to catch up.
-# XXX This should be more systematic.
-sleep 1
+wait_for_ports_up
+check ovn-nbctl --wait=hv sync
 
 : > hv1-vif2.expected
 
@@ -10577,10 +10561,6 @@  AT_CHECK([ovn-nbctl lsp-set-addresses ln_port unknown])
 AT_CHECK([ovn-nbctl lsp-set-type ln_port localnet])
 AT_CHECK([ovn-nbctl --wait=hv lsp-set-options ln_port network_name=physnet1])
 
-# Allow some time for ovn-northd and ovn-controller to catch up.
-# XXX This should be more systematic.
-sleep 2
-
 # Expect no packets when hv2 bridge-mapping is not present
 : > packets
 OVN_CHECK_PACKETS([hv1/snoopvif-tx.pcap], [packets])
@@ -10802,16 +10782,16 @@  ovn-nbctl lsp-set-addresses ln-outside unknown
 ovn-nbctl lsp-set-type ln-outside localnet
 ovn-nbctl lsp-set-options ln-outside network_name=phys
 
-# Allow some time for ovn-northd and ovn-controller to catch up.
-check ovn-nbctl --wait=hv sync
-
 # Check that there is a logical flow in logical switch foo's pipeline
 # to set the outport to rp-foo (which is expected).
 OVS_WAIT_UNTIL([test 1 = `ovn-sbctl dump-flows foo | grep ls_in_l2_lkup | \
 grep rp-foo | grep -v is_chassis_resident | grep priority=50 -c`])
 
 # Set the option 'reside-on-redirect-chassis' for foo
-check ovn-nbctl --wait=hv set logical_router_port foo options:reside-on-redirect-chassis=true
+check ovn-nbctl set logical_router_port foo options:reside-on-redirect-chassis=true
+wait_for_ports_up
+check ovn-nbctl --wait=hv sync
+
 # Check that there is a logical flow in logical switch foo's pipeline
 # to set the outport to rp-foo with the condition is_chassis_redirect.
 ovn-sbctl dump-flows foo
@@ -11040,8 +11020,8 @@  ovs-vsctl -- add-port br-int hv1-vif3 -- \
     ofport-request=3
 
 # Allow some time for ovn-northd and ovn-controller to catch up.
-# XXX This should be more systematic.
-sleep 1
+wait_for_ports_up
+check ovn-nbctl --wait=hv sync
 
 reset_pcap_file() {
     local iface=$1
@@ -11296,8 +11276,8 @@  ovs-vsctl -- add-port br-int hv2-vif1 -- \
 OVN_POPULATE_ARP
 
 # Allow some time for ovn-northd and ovn-controller to catch up.
-# XXX This should be more systematic.
-sleep 1
+wait_for_ports_up
+check ovn-nbctl --wait=hv sync
 
 # Send ip packets between foo1 and alice1
 src_mac="f00000010203"
@@ -11363,6 +11343,7 @@  for i in 1 2; do
         OVS_WAIT_UNTIL([test x`ovn-nbctl lsp-get-up lp${i}1` = xup])
 done
 
+wait_for_ports_up
 ovn-nbctl --wait=sb sync
 ovn-sbctl dump-flows
 
@@ -11516,6 +11497,7 @@  ovn-nbctl lsp-set-type ln-outside localnet
 ovn-nbctl lsp-set-options ln-outside network_name=phys
 
 # Allow some time for ovn-northd and ovn-controller to catch up.
+wait_for_ports_up
 check ovn-nbctl --wait=hv sync
 
 echo "---------NB dump-----"
@@ -11639,6 +11621,7 @@  ovn-nbctl --id=@gc0 create Gateway_Chassis \
           set Logical_Router_Port outside 'gateway_chassis=[@gc0,@gc1]'
 
 
+wait_for_ports_up
 check ovn-nbctl --wait=hv sync
 
 # we make sure that the hypervisors noticed, and inverted the slave ports
@@ -12006,6 +11989,7 @@  AT_CHECK([ovn-nbctl lsp-set-type ln_port localnet])
 AT_CHECK([ovn-nbctl lsp-set-options ln_port network_name=physnet1])
 
 # wait for earlier changes to take effect
+wait_for_ports_up
 check ovn-nbctl --wait=hv sync
 
 reset_pcap_file() {
@@ -12208,6 +12192,7 @@  ovn-nbctl lsp-set-type ln-outside localnet
 ovn-nbctl lsp-set-options ln-outside network_name=phys
 
 # Allow some time for ovn-northd and ovn-controller to catch up.
+wait_for_ports_up
 check ovn-nbctl --wait=hv sync
 
 # currently when ovn-controller is restarted, the old entry is deleted
@@ -12881,8 +12866,6 @@  for i in 1 2 3; do
 done
 
 OVN_POPULATE_ARP
-# allow some time for ovn-northd and ovn-controller to catch up.
-sleep 1
 
 for i in 1 2 3; do
     : > vif${i}1.expected
@@ -12893,6 +12876,7 @@  check ovn-nbctl --log acl-add sw0 from-lport 1000 "inport == \"sw0-p11\"" reject
 check ovn-nbctl --log acl-add sw0 from-lport 1000 "inport == \"sw0-p21\"" reject
 
 # Allow some time for ovn-northd and ovn-controller to catch up.
+wait_for_ports_up
 check ovn-nbctl --wait=hv sync
 
 ovn-sbctl dump-flows > sbflows
@@ -13041,8 +13025,8 @@  done
 OVN_POPULATE_ARP
 
 # Allow some time for ovn-northd and ovn-controller to catch up.
-# XXX This should be more systematic.
-sleep 1
+wait_for_ports_up
+check ovn-nbctl --wait=hv sync
 
 # test_ip INPORT SRC_MAC DST_MAC SRC_IP DST_IP OUTPORT...
 #
@@ -13121,10 +13105,6 @@  for is in 1 2 3; do
   done
 done
 
-# Allow some time for packet forwarding.
-# XXX This can be improved.
-sleep 1
-
 # Now check the packets actually received against the ones expected.
 for i in 1 2 3; do
     for j in 1 2 3; do
@@ -13265,8 +13245,8 @@  done
 OVN_POPULATE_ARP
 
 # Allow some time for ovn-northd and ovn-controller to catch up.
-# XXX This should be more systematic.
-sleep 1
+wait_for_ports_up
+check ovn-nbctl --wait=hv sync
 
 lsp_to_mac() {
     echo f0:00:00:00:0${1:0:1}:${1:1:2}
@@ -13372,10 +13352,6 @@  for is in 1 2 3; do
   done
 done
 
-# Allow some time for packet forwarding.
-# XXX This can be improved.
-sleep 1
-
 # Now check the packets actually received against the ones expected.
 for i in 1 2 3; do
     for j in 1 2 3; do
@@ -13691,6 +13667,7 @@  grep conjunction.*conjunction.*conjunction | wc -l`])
 ovn-nbctl acl-del ls1 to-lport 1001 \
 'ip4 && ip4.src == $set1 && ip4.dst == $set1'
 
+wait_for_ports_up
 ovn-nbctl --wait=hv sync
 # priority=2001,ip,metadata=0x1,nw_dst=10.0.0.10 actions=conjunction(10,1/2)
 # priority=2001,ip,metadata=0x1,nw_dst=10.0.0.8 actions=conjunction(11,1/2)
@@ -13775,6 +13752,7 @@  ovn-nbctl acl-add ls1 to-lport 2 'arp' allow
 ovn-nbctl acl-add ls1 to-lport 1 'ip4' drop
 ovn-nbctl acl-add ls1 to-lport 3 '(ip4.src==10.0.0.1 || ip4.src==10.0.0.2) && (ip4.dst == 10.0.0.3 || ip4.dst == 10.0.0.4)' allow
 ovn-nbctl acl-add ls1 to-lport 3 '(ip4.src==10.0.0.1 || ip4.src==10.0.0.42) && (ip4.dst == 10.0.0.3 || ip4.dst == 10.0.0.4)' allow
+wait_for_ports_up
 ovn-nbctl --wait=hv sync
 
 # Traffic 10.0.0.1, 10.0.0.2 -> 10.0.0.3, 10.0.0.4 should be allowed.
@@ -13847,8 +13825,6 @@  reset_pcap_file hv1-vif2 hv1/vif2
 rm -f 2.packets
 > 2.expected
 
-#sleep infinity
-
 # Remove the first less restrictive allow ACL.
 ovn-nbctl acl-del ls1 to-lport 3 'ip4.src==10.0.0.1 || ip4.src==10.0.0.1'
 ovn-nbctl --wait=hv sync
@@ -13974,8 +13950,8 @@  ovn-nbctl create Address_Set name=set1 addresses=\"f0:00:00:00:00:11\",\"f0:00:0
 OVN_POPULATE_ARP
 
 # Allow some time for ovn-northd and ovn-controller to catch up.
-# XXX This should be more systematic.
-sleep 1
+wait_for_ports_up
+check ovn-nbctl --wait=hv sync
 
 # Make sure there is no attempt to adding duplicated flows by ovn-controller
 AT_FAIL_IF([test -n "`grep duplicate hv1/ovn-controller.log`"])
@@ -14217,6 +14193,7 @@  done
 
 OVN_POPULATE_ARP
 # allow some time for ovn-northd and ovn-controller to catch up.
+wait_for_ports_up
 ovn-nbctl --wait=hv sync
 
 test_ip_packet 1 1 000000000001 00000000ff01 $(ip_to_hex 192 168 1 1) $(ip_to_hex 192 168 2 1) $(ip_to_hex 192 168 1 254) 0000 f87c ea96
@@ -14360,6 +14337,7 @@  done
 
 OVN_POPULATE_ARP
 # allow some time for ovn-northd and ovn-controller to catch up.
+wait_for_ports_up
 ovn-nbctl --wait=hv sync
 
 test_ip_packet 1 1 000000000001 00000000ff01 $(ip_to_hex 192 168 1 1) $(ip_to_hex 192 168 1 254) 11 0000 f87c f485 0303
@@ -14436,7 +14414,8 @@  ovs-vsctl -- add-port br-int hv2-vif1 -- \
 
 OVN_POPULATE_ARP
 
-sleep 1
+wait_for_ports_up
+check ovn-nbctl --wait=hv sync
 
 packet="inport==\"sw1-p1\" && eth.src==$sw1_p1_mac && eth.dst==$sw1_ro_mac &&
        ip4 && ip.ttl==64 && ip4.src==$sw1_p1_ip && ip4.dst==$sw2_p1_ip &&
@@ -15360,7 +15339,8 @@  ovs-vsctl -- add-port br-int hv2-vif1 -- \
 
 OVN_POPULATE_ARP
 
-sleep 1
+wait_for_ports_up
+check ovn-nbctl --wait=hv sync
 
 packet="inport==\"sw1-p1\" && eth.src==$sw1_p1_mac && eth.dst==$sw1_ro_mac &&
        ip4 && ip.ttl==64 && ip4.src==$sw1_p1_ip && ip4.dst==$sw2_p1_ip &&
@@ -15645,6 +15625,7 @@  test_ip6_packet_larger() {
     fi
 }
 
+wait_for_ports_up
 ovn-nbctl --wait=hv sync
 
 ovn-nbctl show > nbdump
@@ -15806,6 +15787,7 @@  ovn-nbctl lr-nat-add lr0 snat 172.16.1.1 192.168.1.0/24
 ovn-nbctl lr-nat-add lr0 snat 2002::1 2001::/64
 
 OVN_POPULATE_ARP
+wait_for_ports_up
 ovn-nbctl --wait=hv sync
 
 ovn-sbctl dump-flows > sbflows
@@ -16033,6 +16015,7 @@  for i in 1 2 3 4 5; do
 done
 
 dnl Wait for the changes to be propagated
+wait_for_ports_up
 check ovn-nbctl --wait=hv sync
 
 dnl Assert that each Chassis has a tunnel formed to every other Chassis
@@ -16314,6 +16297,7 @@  ovn-nbctl lrp-add router router-to-ls2 00:00:01:01:02:05 192.168.2.3/24
 ovn-nbctl lsp-add ls1 ls1-to-router -- set Logical_Switch_Port ls1-to-router type=router options:router-port=router-to-ls1 -- lsp-set-addresses ls1-to-router router
 ovn-nbctl lsp-add ls2 ls2-to-router -- set Logical_Switch_Port ls2-to-router type=router options:router-port=router-to-ls2 -- lsp-set-addresses ls2-to-router router
 
+wait_for_ports_up
 ovn-nbctl --wait=sb sync
 #ovn-sbctl dump-flows
 
@@ -16492,6 +16476,7 @@  ovn-nbctl lsp-set-type sw0-vir virtual
 ovn-nbctl set logical_switch_port sw0-vir options:virtual-ip=10.0.0.10
 ovn-nbctl set logical_switch_port sw0-vir options:virtual-parents=sw0-p1,sw0-p2,sw0-p3
 
+wait_for_ports_up
 ovn-nbctl --wait=hv sync
 
 # Check that logical flows are added for sw0-vir in lsp_in_arp_rsp pipeline
@@ -16819,6 +16804,7 @@  uuid_lb2=$(ovn-nbctl --bare --columns=_uuid find load_balancer name=lb2)
 ovn-nbctl --wait=hv meter-add event-elb drop 100 pktps 10
 
 OVN_POPULATE_ARP
+wait_for_ports_up
 check ovn-nbctl --wait=hv sync
 ovn-sbctl lflow-list > sbflows
 AT_CAPTURE_FILE([sbflows])
@@ -17790,6 +17776,7 @@  check ovs-vsctl -- add-port br-int hv2-vif4 -- \
     ofport-request=1
 check ovs-vsctl set open . external-ids:ovn-bridge-mappings=phys:br-phys
 
+wait_for_ports_up
 check ovn-nbctl --wait=hv sync
 
 AT_CAPTURE_FILE([sbflows])
@@ -18472,6 +18459,7 @@  m4_define([DVR_N_S_ARP_HANDLING],
 
    # Set a hypervisor as gateway chassis, for router port 172.31.0.1
    ovn-nbctl lrp-set-gateway-chassis router-to-underlay hv3
+   wait_for_ports_up
    ovn-nbctl --wait=sb sync
 
    wait_row_count Port_Binding 1 logical_port=cr-router-to-underlay
@@ -18691,6 +18679,7 @@  m4_define([DVR_N_S_PING],
    ovn-nbctl lrp-set-gateway-chassis router-to-underlay hv3
    ovn-nbctl lrp-set-redirect-type router-to-underlay bridged
 
+   wait_for_ports_up
    ovn-nbctl --wait=sb sync
 
 
@@ -18922,6 +18911,7 @@  ovn-nbctl lsp-set-addresses sw1-lr0 00:00:00:00:ff:02
 ovn-nbctl lsp-set-options sw1-lr0 router-port=lr0-sw1
 
 OVN_POPULATE_ARP
+wait_for_ports_up
 ovn-nbctl --wait=hv sync
 
 as hv1 ovs-appctl -t ovn-controller vlog/set dbg
@@ -19105,8 +19095,7 @@  ovn-nbctl lsp-add ls1 lp11
 ovn-nbctl lsp-set-addresses lp11 "f0:00:00:00:00:11"
 ovn-nbctl lsp-set-port-security lp11 f0:00:00:00:00:11
 
-OVS_WAIT_UNTIL([test x`ovn-nbctl lsp-get-up lp11` = xup])
-
+wait_for_ports_up
 ovn-nbctl --wait=sb sync
 
 ovn-nbctl show
@@ -19277,6 +19266,7 @@  ovn-nbctl lrp-set-gateway-chassis router-to-underlay hv3
 ovn-nbctl --stateless lr-nat-add router dnat_and_snat 172.31.0.100 192.168.1.1
 ovn-nbctl lrp-set-redirect-type router-to-underlay bridged
 
+wait_for_ports_up
 ovn-nbctl --wait=sb sync
 
 
@@ -19543,6 +19533,7 @@  check ovn-nbctl lsp-set-options ln-public network_name=public
 check ovn-nbctl --wait=hv lrp-set-gateway-chassis lr0-public hv1 20
 
 OVN_POPULATE_ARP
+wait_for_ports_up
 check ovn-nbctl --wait=hv sync
 
 wait_row_count Service_Monitor 2
@@ -19733,6 +19724,7 @@  ovn-nbctl lsp-set-options ln-public network_name=public
 ovn-nbctl --wait=hv lrp-set-gateway-chassis lr0-public hv1 20
 
 OVN_POPULATE_ARP
+wait_for_ports_up
 ovn-nbctl --wait=hv sync
 
 # And now for the anticlimax. We need to ensure that there is no
@@ -19874,6 +19866,7 @@  check ovs-vsctl -- add-port br-int hv1-vif2 -- \
     ofport-request=3
 
 OVN_POPULATE_ARP
+wait_for_ports_up
 check ovn-nbctl --wait=hv sync
 
 ovn-sbctl dump-flows > sbflows
@@ -20231,6 +20224,7 @@  ovn-nbctl lsp-add lsw0 lp1
 ovn-nbctl lsp-set-addresses lp1 "f0:00:00:00:00:01 10.0.0.1"
 ovn-nbctl acl-add lsw0 from-lport 1000 'eth.type == 0x1234' drop
 
+wait_for_ports_up
 check ovn-nbctl --wait=hv sync
 
 # Trace with --ovs should see ovs flow related to the ACL
@@ -20327,6 +20321,7 @@  for az in `seq 1 $n_az`; do
     done
     check ovn-nbctl --wait=hv sync
     ovn-sbctl list Port_Binding > az$az.ports
+    wait_for_ports_up
 done
 
 # Pre-populate the hypervisors' ARP tables so that we don't lose any
@@ -20503,6 +20498,7 @@  ovs-vsctl -- add-port br-int hv1-vif3 -- \
 
 # wait for earlier changes to take effect
 check ovn-nbctl --wait=hv sync
+wait_for_ports_up
 
 ovn-sbctl dump-flows > sbflows
 AT_CAPTURE_FILE([sbflows])
@@ -20765,6 +20761,7 @@  ovn-nbctl lsp-add sw sw-rtr                       \
     -- lsp-set-options sw-rtr router-port=rtr-sw
 
 ovn-nbctl --wait=hv sync
+wait_for_ports_up
 
 # Inject IPv4 TCP packet from lsp.
 > expected
@@ -20966,6 +20963,7 @@  check ovn-nbctl lsp-set-options ln-public network_name=public
 check ovn-nbctl lrp-set-gateway-chassis lr0-public hv1 20
 check ovn-nbctl lr-nat-add lr0 snat 172.168.0.100 10.0.0.0/24
 check ovn-nbctl --wait=hv sync
+wait_for_ports_up
 
 wait_row_count datapath_binding 1 external-ids:name=lr0
 lr0_dp_uuid=$(ovn-sbctl --bare --columns _uuid list datapath_binding lr0)
@@ -21769,6 +21767,7 @@  check ovn-nbctl --policy="src-ip" lr-route-add DR 10.0.0.0/24 20.0.0.2
 check ovn-nbctl --ecmp-symmetric-reply --policy="src-ip" lr-route-add GW 10.0.0.0/24 172.16.0.2
 check ovn-nbctl --ecmp-symmetric-reply --policy="src-ip" lr-route-add GW 10.0.0.0/24 172.16.0.3
 
+wait_for_ports_up
 check ovn-nbctl --wait=hv sync
 
 # Ensure ECMP symmetric reply flows are not present on any hypervisor.
@@ -21904,6 +21903,7 @@  ovs-vsctl -- add-port br-int hv2-vif1 -- \
 # for ARP resolution).
 OVN_POPULATE_ARP
 
+wait_for_ports_up
 ovn-nbctl --wait=hv sync
 
 AT_CHECK([ovn-sbctl lflow-list | grep lr_in_arp_resolve | grep 10.0.0.1], [1], [])
@@ -21984,10 +21984,7 @@  ovs-vsctl -- add-port br-int hv1-vif4 -- \
     options:rxq_pcap=hv1/vif4-rx.pcap \
     ofport-request=4
 
-OVS_WAIT_UNTIL([test x$(ovn-nbctl lsp-get-up sw0-p1) = xup])
-OVS_WAIT_UNTIL([test x$(ovn-nbctl lsp-get-up sw0-p2) = xup])
-OVS_WAIT_UNTIL([test x$(ovn-nbctl lsp-get-up sw0-p3) = xup])
-OVS_WAIT_UNTIL([test x$(ovn-nbctl lsp-get-up sw0-p4) = xup])
+wait_for_ports_up
 
 ovn-nbctl pg-add pg0 sw0-p1 sw0-p2
 ovn-nbctl acl-add pg0 to-lport 1002 "outport == @pg0 && ip4 && tcp.dst >= 80 && tcp.dst <= 82" allow
@@ -22147,6 +22144,7 @@  ovs-vsctl -- add-port br-int hv1-vif1 -- \
 # for ARP resolution).
 OVN_POPULATE_ARP
 
+wait_for_ports_up
 ovn-nbctl --wait=hv sync
 
 sw_key=$(ovn-sbctl --bare --columns tunnel_key list datapath_binding r1)
@@ -22265,6 +22263,7 @@  check test "$hvt2" -gt 0
 # Then wait for 9 out of 10
 sleep 1
 check as hv3 ovn-appctl -t ovn-controller exit --restart
+wait_for_ports_up
 ovn-nbctl --wait=sb sync
 wait_row_count Chassis_Private 9 name!=hv3 nb_cfg=2
 check_row_count Chassis_Private 1 name=hv3 nb_cfg=1
@@ -22440,6 +22439,7 @@  ovn-nbctl set logical_router gw_router options:chassis=hv3
 ovn-nbctl lr-nat-add gw_router snat 172.16.0.200 30.0.0.0/24
 ovn-nbctl lr-nat-add gw_router snat 172.16.0.201 30.0.0.3
 
+wait_for_ports_up
 ovn-nbctl --wait=hv sync
 
 # Create an interface in br-phys in hv2 and send ARP request for 172.16.0.100
@@ -22631,6 +22631,7 @@  check ovn-nbctl acl-add ls1 to-lport 1001 \
 check ovn-nbctl acl-add ls1 to-lport 1001 \
     'outport == "lsp1" && ip4 && ip4.src == {10.0.0.2, 10.0.0.3}' allow
 
+wait_for_ports_up
 check ovn-nbctl --wait=hv sync
 
 sip=`ip_to_hex 10 0 0 2`
@@ -22801,6 +22802,7 @@  ovs-vsctl -- add-port br-int hv1-vif1 -- \
     options:rxq_pcap=hv1/vif1-rx.pcap \
     ofport-request=1
 
+wait_for_ports_up
 ovn-nbctl --wait=hv sync
 
 # Expected conjunction flows:
@@ -22860,6 +22862,7 @@  as hv1 ovs-vsctl \
 ovn-nbctl --wait=hv sync
 
 # hv1 ovn-controller should not bind sw0-p2.
+wait_for_ports_up sw0-p1
 check_row_count Port_Binding 0 logical_port=sw0-p2 chassis=$c
 
 # Trigger recompute and sw0-p2 should not be claimed.