diff --git a/tests/ovn-controller-vtep.at b/tests/ovn-controller-vtep.at
index 8b4c180b1669..8e7c1eefd805 100644
--- a/tests/ovn-controller-vtep.at
+++ b/tests/ovn-controller-vtep.at
@@ -177,22 +177,22 @@ AT_CLEANUP
 AT_SETUP([ovn-controller-vtep - binding 1])
 OVN_CONTROLLER_VTEP_START
 
-# adds logical switch 'lswitch0' and vlan_bindings.
+AS_BOX([add logical switch 'lswitch0' and vlan_bindings])
 AT_CHECK([vtep-ctl add-ls lswitch0 -- bind-ls br-vtep p0 100 lswitch0 -- bind-ls br-vtep p1 300 lswitch0])
 # adds logical switch port in ovn-nb database, and sets the type and options.
 OVN_NB_ADD_VTEP_PORT([br-test], [br-vtep_lswitch0], [br-vtep], [lswitch0])
-check ovn-sbctl wait-until Port_Binding br-vtep_lswitch0 chassis!='[[]]'
+wait_row_count Port_Binding 1 logical_port=br-vtep_lswitch0 chassis!='[[]]'
 # should see one binding, associated to chassis of 'br-vtep'.
 chassis_uuid=$(ovn-sbctl --columns=_uuid list Chassis br-vtep | cut -d ':' -f2 | tr -d ' ')
 AT_CHECK_UNQUOTED([ovn-sbctl --columns=chassis list Port_Binding br-vtep_lswitch0 | cut -d ':' -f2 | tr -d ' '], [0], [dnl
 ${chassis_uuid}
 ])
 
-# adds another logical switch 'lswitch1' and vlan_bindings.
+AS_BOX([add another logical switch 'lswitch1' and vlan_bindings])
 AT_CHECK([vtep-ctl add-ls lswitch1 -- bind-ls br-vtep p0 200 lswitch1])
 # adds logical switch port in ovn-nb database for lswitch1.
 OVN_NB_ADD_VTEP_PORT([br-test], [br-vtep_lswitch1], [br-vtep], [lswitch1])
-check ovn-sbctl wait-until Port_Binding br-vtep_lswitch1 chassis!='[[]]'
+wait_row_count Port_Binding 1 logical_port=br-vtep_lswitch1 chassis!='[[]]'
 # This is allowed, but not recommended, to have two vlan_bindings (to different vtep logical switches)
 # from one vtep gateway physical port in one ovn-nb logical swithch.
 AT_CHECK_UNQUOTED([ovn-sbctl --columns=chassis list Port_Binding | cut -d ':' -f2 | tr -d ' ' | sort], [0], [dnl
@@ -201,9 +201,9 @@ ${chassis_uuid}
 ${chassis_uuid}
 ])
 
-# adds another logical switch port in ovn-nb database for lswitch0.
+AS_BOX([add another logical switch port in ovn-nb database for lswitch0])
 OVN_NB_ADD_VTEP_PORT([br-test], [br-vtep_lswitch0_dup], [br-vtep], [lswitch0])
-check ovn-sbctl wait-until Port_Binding br-vtep_lswitch0_dup chassis!='[[]]'
+wait_row_count Port_Binding 1 logical_port=br-vtep_lswitch0_dup chassis!='[[]]'
 # it is not allowed to have more than one ovn-nb logical port for the same
 # vtep logical switch on a vtep gateway chassis, so should still see only
 # two port_binding entries bound.
@@ -214,12 +214,13 @@ AT_CHECK_UNQUOTED([ovn-sbctl --columns=chassis list Port_Binding | cut -d ':' -f
 ${chassis_uuid}
 ${chassis_uuid}
 ])
-# confirms the warning log.
+
+AS_BOX([confirm warning log])
 AT_CHECK([sed -n 's/^.*\(|WARN|.*\)$/\1/p' ovn-controller-vtep.log | sed 's/([[-_0-9a-z]][[-_0-9a-z]]*)/()/g' | uniq], [0], [dnl
 |WARN|logical switch (), on vtep gateway chassis () has already been associated with logical port (), ignore logical port ()
 ])
 
-# deletes physical ports from vtep.
+AS_BOX([delete physical ports from vtep])
 AT_CHECK([ovs-vsctl del-port p0 -- del-port p1])
 OVS_WAIT_UNTIL([test -z "`ovn-sbctl list Chassis | grep -- br-vtep_lswitch`"])
 OVS_WAIT_UNTIL([test -z "`vtep-ctl list physical_port p0`"])
diff --git a/tests/ovn-northd.at b/tests/ovn-northd.at
index 04f4e9d0cebd..9069cace0896 100644
--- a/tests/ovn-northd.at
+++ b/tests/ovn-northd.at
@@ -650,8 +650,9 @@ get_northd_status() {
     as northd-backup ovn-appctl -t NORTHD_TYPE status
 }
 
-# Pause the backup, to force the main northd to become active (otherwise
-# there's no guarantee, ovn_start is racy).
+AS_BOX([Pause the backup])
+# This forces the main northd to become active (otherwise there's no
+# guarantee, ovn_start is racy).
 check as northd-backup ovs-appctl -t NORTHD_TYPE pause
 OVS_WAIT_FOR_OUTPUT([get_northd_status], [0], [false
 Status: active
@@ -659,7 +660,7 @@ true
 Status: paused
 ])
 
-# Resume the backup.
+AS_BOX([Resume the backup])
 check as northd-backup ovs-appctl -t NORTHD_TYPE resume
 OVS_WAIT_FOR_OUTPUT([get_northd_status], [0], [false
 Status: active
@@ -667,6 +668,7 @@ false
 Status: standby
 ])
 
+AS_BOX([Check that ovn-northd is active])
 # Check that ovn-northd is active, by verifying that it creates and
 # destroys southbound datapaths as one would expect.
 check_row_count Datapath_Binding 0
@@ -675,7 +677,7 @@ check_row_count Datapath_Binding 1
 check ovn-nbctl --wait=sb ls-del sw0
 check_row_count Datapath_Binding 0
 
-# Now pause the ovn-northd
+AS_BOX([Pause the main northd])
 check as northd ovs-appctl -t NORTHD_TYPE pause
 check as northd-backup ovs-appctl -t NORTHD_TYPE pause
 AT_CHECK([get_northd_status], [0], [true
@@ -684,12 +686,13 @@ true
 Status: paused
 ])
 
+AS_BOX([Verify that ovn-northd is paused])
 # Now ovn-northd won't respond by adding a datapath, because it's paused.
 check ovn-nbctl ls-add sw0
-sleep 5
+check sleep 5
 check_row_count Datapath_Binding 0
 
-# Now resume ovn-northd!
+AS_BOX([Resume the main northd])
 check as northd ovs-appctl -t NORTHD_TYPE resume
 check as northd-backup ovs-appctl -t NORTHD_TYPE resume
 OVS_WAIT_FOR_OUTPUT([get_northd_status], [0], [false
@@ -1078,7 +1081,7 @@ health_check @hc | uuidfilt], [0], [<0>
 
 wait_row_count Service_Monitor 0
 
-# create logical switches and ports
+AS_BOX([create logical switches and ports])
 ovn-nbctl ls-add sw0
 ovn-nbctl --wait=sb lsp-add sw0 sw0-p1 -- lsp-set-addresses sw0-p1 \
 "00:00:00:00:00:03 10.0.0.3"
@@ -1105,7 +1108,7 @@ OVS_WAIT_FOR_OUTPUT(
   (ls_in_stateful     ), priority=120  , match=(ct.new && ip4.dst == 10.0.0.10 && tcp.dst == 80), action=(ct_lb(backends=10.0.0.3:80,20.0.0.3:80);)
 ])
 
-# Delete the Load_Balancer_Health_Check
+AS_BOX([Delete the Load_Balancer_Health_Check])
 ovn-nbctl --wait=sb clear load_balancer . health_check
 wait_row_count Service_Monitor 0
 
@@ -1115,7 +1118,7 @@ OVS_WAIT_FOR_OUTPUT(
 [  (ls_in_stateful     ), priority=120  , match=(ct.new && ip4.dst == 10.0.0.10 && tcp.dst == 80), action=(ct_lb(backends=10.0.0.3:80,20.0.0.3:80);)
 ])
 
-# Create the Load_Balancer_Health_Check again.
+AS_BOX([Create the Load_Balancer_Health_Check again.])
 ovn-nbctl --wait=sb -- --id=@hc create \
 Load_Balancer_Health_Check vip="10.0.0.10\:80" -- add Load_Balancer . \
 health_check @hc
@@ -1127,7 +1130,7 @@ AT_CHECK([cat lflows.txt | sed 's/table=..//'], [0], [dnl
   (ls_in_stateful     ), priority=120  , match=(ct.new && ip4.dst == 10.0.0.10 && tcp.dst == 80), action=(ct_lb(backends=10.0.0.3:80,20.0.0.3:80);)
 ])
 
-# Get the uuid of both the service_monitor
+AS_BOX([Get the uuid of both the service_monitor])
 sm_sw0_p1=$(fetch_column Service_Monitor _uuid logical_port=sw0-p1)
 sm_sw1_p1=$(fetch_column Service_Monitor _uuid logical_port=sw1-p1)
 
@@ -1137,7 +1140,7 @@ OVS_WAIT_FOR_OUTPUT(
 [  (ls_in_stateful     ), priority=120  , match=(ct.new && ip4.dst == 10.0.0.10 && tcp.dst == 80), action=(ct_lb(backends=10.0.0.3:80,20.0.0.3:80);)
 ])
 
-# Set the service monitor for sw1-p1 to offline
+AS_BOX([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
@@ -1148,7 +1151,7 @@ OVS_WAIT_FOR_OUTPUT(
 [  (ls_in_stateful     ), priority=120  , match=(ct.new && ip4.dst == 10.0.0.10 && tcp.dst == 80), action=(ct_lb(backends=10.0.0.3:80);)
 ])
 
-# Set the service monitor for sw0-p1 to offline
+AS_BOX([Set the service monitor for sw0-p1 to offline])
 ovn-sbctl set service_monitor $sm_sw0_p1 status=offline
 
 wait_row_count Service_Monitor 1 logical_port=sw0-p1 status=offline
@@ -1164,7 +1167,7 @@ OVS_WAIT_FOR_OUTPUT(
   (ls_in_stateful     ), priority=120  , match=(ct.new && ip4.dst == 10.0.0.10 && tcp.dst == 80), action=(drop;)
 ])
 
-# Set the service monitor for sw0-p1 and sw1-p1 to online
+AS_BOX([Set the service monitor for sw0-p1 and sw1-p1 to online])
 ovn-sbctl set service_monitor $sm_sw0_p1 status=online
 ovn-sbctl set service_monitor $sm_sw1_p1 status=online
 
@@ -1177,7 +1180,7 @@ OVS_WAIT_FOR_OUTPUT(
 [  (ls_in_stateful     ), priority=120  , match=(ct.new && ip4.dst == 10.0.0.10 && tcp.dst == 80), action=(ct_lb(backends=10.0.0.3:80,20.0.0.3:80);)
 ])
 
-# Set the service monitor for sw1-p1 to error
+AS_BOX([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
@@ -1188,10 +1191,10 @@ AT_CHECK([cat lflows.txt | sed 's/table=..//'], [0], [dnl
   (ls_in_stateful     ), priority=120  , match=(ct.new && ip4.dst == 10.0.0.10 && tcp.dst == 80), action=(ct_lb(backends=10.0.0.3:80);)
 ])
 
-# Add one more vip to lb1
+AS_BOX([Add one more vip to lb1])
 check ovn-nbctl set load_balancer . vip:10.0.0.40\\:1000=10.0.0.3:1000,20.0.0.3:80
 
-# create health_check for new vip - 10.0.0.40
+AS_BOX([create health_check for new vip - 10.0.0.40])
 AT_CHECK(
   [ovn-nbctl --wait=sb \
           -- --id=@hc create Load_Balancer_Health_Check vip=10.0.0.40\\:1000 \
@@ -1215,7 +1218,7 @@ OVS_WAIT_FOR_OUTPUT(
   (ls_in_stateful     ), priority=120  , match=(ct.new && ip4.dst == 10.0.0.40 && tcp.dst == 1000), action=(ct_lb(backends=10.0.0.3:1000);)
 ])
 
-# Set the service monitor for sw1-p1 to online
+AS_BOX([Set the service monitor for sw1-p1 to online])
 check ovn-sbctl set service_monitor sw1-p1 status=online
 
 wait_row_count Service_Monitor 1 logical_port=sw1-p1 status=online
@@ -1229,7 +1232,7 @@ OVS_WAIT_FOR_OUTPUT(
   (ls_in_stateful     ), priority=120  , match=(ct.new && ip4.dst == 10.0.0.40 && tcp.dst == 1000), action=(ct_lb(backends=10.0.0.3:1000,20.0.0.3:80);)
 ])
 
-# Associate lb1 to sw1
+AS_BOX([Associate lb1 to sw1])
 check ovn-nbctl --wait=sb ls-lb-add sw1 lb1
 AT_CAPTURE_FILE([sbflows11])
 OVS_WAIT_FOR_OUTPUT(
@@ -1239,7 +1242,7 @@ OVS_WAIT_FOR_OUTPUT(
   (ls_in_stateful     ), priority=120  , match=(ct.new && ip4.dst == 10.0.0.40 && tcp.dst == 1000), action=(ct_lb(backends=10.0.0.3:1000,20.0.0.3:80);)
 ])
 
-# Now create lb2 same as lb1 but udp protocol.
+AS_BOX([Now create lb2 same as lb1 but udp protocol.])
 check ovn-nbctl lb-add lb2 10.0.0.10:80 10.0.0.3:80,20.0.0.3:80 udp
 check ovn-nbctl --wait=sb set load_balancer lb2 ip_port_mappings:10.0.0.3=sw0-p1:10.0.0.2
 check ovn-nbctl --wait=sb set load_balancer lb2 ip_port_mappings:20.0.0.3=sw1-p1:20.0.0.2
@@ -1254,12 +1257,13 @@ check ovn-nbctl --wait=sb sync
 
 wait_row_count Service_Monitor 5
 
-# Change the svc_monitor_mac. This should get reflected in service_monitor table rows.
+AS_BOX([Change the svc_monitor_mac.])
+# This should get reflected in service_monitor table rows.
 check ovn-nbctl set NB_Global . options:svc_monitor_mac="fe:a0:65:a2:01:03"
 
 wait_row_count Service_Monitor 5 src_mac='"fe:a0:65:a2:01:03"'
 
-# Change the source ip for 10.0.0.3 backend ip in lb2
+AS_BOX([Change the source ip for 10.0.0.3 backend ip in lb2])
 check ovn-nbctl --wait=sb set load_balancer lb2 ip_port_mappings:10.0.0.3=sw0-p1:10.0.0.100
 
 wait_row_count Service_Monitor 1 logical_port=sw0-p1 src_ip=10.0.0.100
@@ -1772,28 +1776,12 @@ AT_CAPTURE_FILE([sw0flows])
 ovn-sbctl dump-flows sw1 > sw1flows
 AT_CAPTURE_FILE([sw1flows])
 
-AT_CHECK([grep "ls_in_acl" sw0flows | grep pg0 | sort], [0], [dnl
-  table=7 (ls_in_acl          ), priority=2002 , dnl
-match=(inport == @pg0 && ip4 && tcp && tcp.dst == 80), dnl
-action=(reg0 = 0; reject { /* eth.dst <-> eth.src; ip.dst <-> ip.src; is implicit. */ outport <-> inport; next(pipeline=egress,table=6); };)
-])
-
-AT_CHECK([grep "ls_in_acl" sw1flows | grep pg0 | sort], [0], [dnl
-  table=7 (ls_in_acl          ), priority=2002 , dnl
-match=(inport == @pg0 && ip4 && tcp && tcp.dst == 80), dnl
-action=(reg0 = 0; reject { /* eth.dst <-> eth.src; ip.dst <-> ip.src; is implicit. */ outport <-> inport; next(pipeline=egress,table=6); };)
-])
-
-AT_CHECK([grep "ls_out_acl" sw0flows | grep pg0 | sort], [0], [dnl
-  table=5 (ls_out_acl         ), priority=2003 , dnl
-match=(outport == @pg0 && ip6 && udp), dnl
-action=(reg0 = 0; reject { /* eth.dst <-> eth.src; ip.dst <-> ip.src; is implicit. */ outport <-> inport; next(pipeline=ingress,table=21); };)
-])
-
-AT_CHECK([grep "ls_out_acl" sw1flows | grep pg0 | sort], [0], [dnl
-  table=5 (ls_out_acl         ), priority=2003 , dnl
-match=(outport == @pg0 && ip6 && udp), dnl
-action=(reg0 = 0; reject { /* eth.dst <-> eth.src; ip.dst <-> ip.src; is implicit. */ outport <-> inport; next(pipeline=ingress,table=21); };)
+AT_CHECK(
+  [grep -E 'ls_(in|out)_acl' sw0flows sw1flows | grep pg0 | sort], [0], [dnl
+sw0flows:  table=5 (ls_out_acl         ), priority=2003 , match=(outport == @pg0 && ip6 && udp), action=(reg0 = 0; reject { /* eth.dst <-> eth.src; ip.dst <-> ip.src; is implicit. */ outport <-> inport; next(pipeline=ingress,table=21); };)
+sw0flows:  table=7 (ls_in_acl          ), priority=2002 , match=(inport == @pg0 && ip4 && tcp && tcp.dst == 80), action=(reg0 = 0; reject { /* eth.dst <-> eth.src; ip.dst <-> ip.src; is implicit. */ outport <-> inport; next(pipeline=egress,table=6); };)
+sw1flows:  table=5 (ls_out_acl         ), priority=2003 , match=(outport == @pg0 && ip6 && udp), action=(reg0 = 0; reject { /* eth.dst <-> eth.src; ip.dst <-> ip.src; is implicit. */ outport <-> inport; next(pipeline=ingress,table=21); };)
+sw1flows:  table=7 (ls_in_acl          ), priority=2002 , match=(inport == @pg0 && ip4 && tcp && tcp.dst == 80), action=(reg0 = 0; reject { /* eth.dst <-> eth.src; ip.dst <-> ip.src; is implicit. */ outport <-> inport; next(pipeline=egress,table=6); };)
 ])
 
 AS_BOX([2])
@@ -1805,22 +1793,11 @@ AT_CAPTURE_FILE([sw0flows2])
 ovn-sbctl dump-flows sw1 > sw1flows2
 AT_CAPTURE_FILE([sw1flows2])
 
-AT_CHECK([grep "ls_out_acl" sw0flows2 | grep pg0 | sort], [0], [dnl
-  table=5 (ls_out_acl         ), priority=2002 , dnl
-match=(outport == @pg0 && ip4 && udp), dnl
-action=(reg0 = 0; reject { /* eth.dst <-> eth.src; ip.dst <-> ip.src; is implicit. */ outport <-> inport; next(pipeline=ingress,table=21); };)
-  table=5 (ls_out_acl         ), priority=2003 , dnl
-match=(outport == @pg0 && ip6 && udp), dnl
-action=(reg0 = 0; reject { /* eth.dst <-> eth.src; ip.dst <-> ip.src; is implicit. */ outport <-> inport; next(pipeline=ingress,table=21); };)
-])
-
-AT_CHECK([grep "ls_out_acl" sw1flows2 | grep pg0 | sort], [0], [dnl
-  table=5 (ls_out_acl         ), priority=2002 , dnl
-match=(outport == @pg0 && ip4 && udp), dnl
-action=(reg0 = 0; reject { /* eth.dst <-> eth.src; ip.dst <-> ip.src; is implicit. */ outport <-> inport; next(pipeline=ingress,table=21); };)
-  table=5 (ls_out_acl         ), priority=2003 , dnl
-match=(outport == @pg0 && ip6 && udp), dnl
-action=(reg0 = 0; reject { /* eth.dst <-> eth.src; ip.dst <-> ip.src; is implicit. */ outport <-> inport; next(pipeline=ingress,table=21); };)
+AT_CHECK([grep "ls_out_acl" sw0flows2 sw1flows2 | grep pg0 | sort], [0], [dnl
+sw0flows2:  table=5 (ls_out_acl         ), priority=2002 , match=(outport == @pg0 && ip4 && udp), action=(reg0 = 0; reject { /* eth.dst <-> eth.src; ip.dst <-> ip.src; is implicit. */ outport <-> inport; next(pipeline=ingress,table=21); };)
+sw0flows2:  table=5 (ls_out_acl         ), priority=2003 , match=(outport == @pg0 && ip6 && udp), action=(reg0 = 0; reject { /* eth.dst <-> eth.src; ip.dst <-> ip.src; is implicit. */ outport <-> inport; next(pipeline=ingress,table=21); };)
+sw1flows2:  table=5 (ls_out_acl         ), priority=2002 , match=(outport == @pg0 && ip4 && udp), action=(reg0 = 0; reject { /* eth.dst <-> eth.src; ip.dst <-> ip.src; is implicit. */ outport <-> inport; next(pipeline=ingress,table=21); };)
+sw1flows2:  table=5 (ls_out_acl         ), priority=2003 , match=(outport == @pg0 && ip6 && udp), action=(reg0 = 0; reject { /* eth.dst <-> eth.src; ip.dst <-> ip.src; is implicit. */ outport <-> inport; next(pipeline=ingress,table=21); };)
 ])
 
 AS_BOX([3])
@@ -1832,42 +1809,19 @@ AT_CAPTURE_FILE([sw0flows3])
 ovn-sbctl dump-flows sw1 > sw1flows3
 AT_CAPTURE_FILE([sw1flows3])
 
-AT_CHECK([grep "ls_out_acl" sw0flows3 | grep pg0 | sort], [0], [dnl
-  table=5 (ls_out_acl         ), priority=2001 , dnl
-match=(reg0[[7]] == 1 && (outport == @pg0 && ip)), action=(reg0[[1]] = 1; next;)
-  table=5 (ls_out_acl         ), priority=2001 , dnl
-match=(reg0[[8]] == 1 && (outport == @pg0 && ip)), action=(next;)
-  table=5 (ls_out_acl         ), priority=2002 , dnl
-match=((reg0[[10]] == 1) && outport == @pg0 && ip4 && udp), dnl
-action=(ct_commit { ct_label.blocked = 1; };  reg0 = 0; reject { /* eth.dst <-> eth.src; ip.dst <-> ip.src; is implicit. */ outport <-> inport; next(pipeline=ingress,table=21); };)
-  table=5 (ls_out_acl         ), priority=2002 , dnl
-match=((reg0[[9]] == 1) && outport == @pg0 && ip4 && udp), dnl
-action=(reg0 = 0; reject { /* eth.dst <-> eth.src; ip.dst <-> ip.src; is implicit. */ outport <-> inport; next(pipeline=ingress,table=21); };)
-  table=5 (ls_out_acl         ), priority=2003 , dnl
-match=((reg0[[10]] == 1) && outport == @pg0 && ip6 && udp), dnl
-action=(ct_commit { ct_label.blocked = 1; };  reg0 = 0; reject { /* eth.dst <-> eth.src; ip.dst <-> ip.src; is implicit. */ outport <-> inport; next(pipeline=ingress,table=21); };)
-  table=5 (ls_out_acl         ), priority=2003 , dnl
-match=((reg0[[9]] == 1) && outport == @pg0 && ip6 && udp), dnl
-action=(reg0 = 0; reject { /* eth.dst <-> eth.src; ip.dst <-> ip.src; is implicit. */ outport <-> inport; next(pipeline=ingress,table=21); };)
-])
-
-AT_CHECK([grep "ls_out_acl" sw1flows3 | grep pg0 | sort], [0], [dnl
-  table=5 (ls_out_acl         ), priority=2001 , dnl
-match=(reg0[[7]] == 1 && (outport == @pg0 && ip)), action=(reg0[[1]] = 1; next;)
-  table=5 (ls_out_acl         ), priority=2001 , dnl
-match=(reg0[[8]] == 1 && (outport == @pg0 && ip)), action=(next;)
-  table=5 (ls_out_acl         ), priority=2002 , dnl
-match=((reg0[[10]] == 1) && outport == @pg0 && ip4 && udp), dnl
-action=(ct_commit { ct_label.blocked = 1; };  reg0 = 0; reject { /* eth.dst <-> eth.src; ip.dst <-> ip.src; is implicit. */ outport <-> inport; next(pipeline=ingress,table=21); };)
-  table=5 (ls_out_acl         ), priority=2002 , dnl
-match=((reg0[[9]] == 1) && outport == @pg0 && ip4 && udp), dnl
-action=(reg0 = 0; reject { /* eth.dst <-> eth.src; ip.dst <-> ip.src; is implicit. */ outport <-> inport; next(pipeline=ingress,table=21); };)
-  table=5 (ls_out_acl         ), priority=2003 , dnl
-match=((reg0[[10]] == 1) && outport == @pg0 && ip6 && udp), dnl
-action=(ct_commit { ct_label.blocked = 1; };  reg0 = 0; reject { /* eth.dst <-> eth.src; ip.dst <-> ip.src; is implicit. */ outport <-> inport; next(pipeline=ingress,table=21); };)
-  table=5 (ls_out_acl         ), priority=2003 , dnl
-match=((reg0[[9]] == 1) && outport == @pg0 && ip6 && udp), dnl
-action=(reg0 = 0; reject { /* eth.dst <-> eth.src; ip.dst <-> ip.src; is implicit. */ outport <-> inport; next(pipeline=ingress,table=21); };)
+AT_CHECK([grep "ls_out_acl" sw0flows3 sw1flows3 | grep pg0 | sort], [0], [dnl
+sw0flows3:  table=5 (ls_out_acl         ), priority=2001 , match=(reg0[[7]] == 1 && (outport == @pg0 && ip)), action=(reg0[[1]] = 1; next;)
+sw0flows3:  table=5 (ls_out_acl         ), priority=2001 , match=(reg0[[8]] == 1 && (outport == @pg0 && ip)), action=(next;)
+sw0flows3:  table=5 (ls_out_acl         ), priority=2002 , match=((reg0[[10]] == 1) && outport == @pg0 && ip4 && udp), action=(ct_commit { ct_label.blocked = 1; };  reg0 = 0; reject { /* eth.dst <-> eth.src; ip.dst <-> ip.src; is implicit. */ outport <-> inport; next(pipeline=ingress,table=21); };)
+sw0flows3:  table=5 (ls_out_acl         ), priority=2002 , match=((reg0[[9]] == 1) && outport == @pg0 && ip4 && udp), action=(reg0 = 0; reject { /* eth.dst <-> eth.src; ip.dst <-> ip.src; is implicit. */ outport <-> inport; next(pipeline=ingress,table=21); };)
+sw0flows3:  table=5 (ls_out_acl         ), priority=2003 , match=((reg0[[10]] == 1) && outport == @pg0 && ip6 && udp), action=(ct_commit { ct_label.blocked = 1; };  reg0 = 0; reject { /* eth.dst <-> eth.src; ip.dst <-> ip.src; is implicit. */ outport <-> inport; next(pipeline=ingress,table=21); };)
+sw0flows3:  table=5 (ls_out_acl         ), priority=2003 , match=((reg0[[9]] == 1) && outport == @pg0 && ip6 && udp), action=(reg0 = 0; reject { /* eth.dst <-> eth.src; ip.dst <-> ip.src; is implicit. */ outport <-> inport; next(pipeline=ingress,table=21); };)
+sw1flows3:  table=5 (ls_out_acl         ), priority=2001 , match=(reg0[[7]] == 1 && (outport == @pg0 && ip)), action=(reg0[[1]] = 1; next;)
+sw1flows3:  table=5 (ls_out_acl         ), priority=2001 , match=(reg0[[8]] == 1 && (outport == @pg0 && ip)), action=(next;)
+sw1flows3:  table=5 (ls_out_acl         ), priority=2002 , match=((reg0[[10]] == 1) && outport == @pg0 && ip4 && udp), action=(ct_commit { ct_label.blocked = 1; };  reg0 = 0; reject { /* eth.dst <-> eth.src; ip.dst <-> ip.src; is implicit. */ outport <-> inport; next(pipeline=ingress,table=21); };)
+sw1flows3:  table=5 (ls_out_acl         ), priority=2002 , match=((reg0[[9]] == 1) && outport == @pg0 && ip4 && udp), action=(reg0 = 0; reject { /* eth.dst <-> eth.src; ip.dst <-> ip.src; is implicit. */ outport <-> inport; next(pipeline=ingress,table=21); };)
+sw1flows3:  table=5 (ls_out_acl         ), priority=2003 , match=((reg0[[10]] == 1) && outport == @pg0 && ip6 && udp), action=(ct_commit { ct_label.blocked = 1; };  reg0 = 0; reject { /* eth.dst <-> eth.src; ip.dst <-> ip.src; is implicit. */ outport <-> inport; next(pipeline=ingress,table=21); };)
+sw1flows3:  table=5 (ls_out_acl         ), priority=2003 , match=((reg0[[9]] == 1) && outport == @pg0 && ip6 && udp), action=(reg0 = 0; reject { /* eth.dst <-> eth.src; ip.dst <-> ip.src; is implicit. */ outport <-> inport; next(pipeline=ingress,table=21); };)
 ])
 AT_CLEANUP
 ])
diff --git a/tests/ovn.at b/tests/ovn.at
index 5f439342dcf2..a6f2bf8ad2b5 100644
--- a/tests/ovn.at
+++ b/tests/ovn.at
@@ -4994,6 +4994,8 @@ ovs-vsctl -- add-port br-int vif2 -- \
 wait_for_ports_up
 check ovn-nbctl --wait=hv sync
 
+ovs-sbctl dump-flows > sbflows
+AT_CAPTURE_FILE([sbflows])
 
 # Send ip packets between the two ports.
 
@@ -5005,36 +5007,11 @@ dst_ip=`ip_to_hex 172 16 1 2`
 packet=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
 as hv1 ovs-appctl netdev-dummy/receive vif1 $packet
 
-
-echo "---------NB dump-----"
-ovn-nbctl show
-echo "---------------------"
-ovn-nbctl list logical_router
-echo "---------------------"
-ovn-nbctl list logical_router_port
-echo "---------------------"
-
-echo "---------SB dump-----"
-ovn-sbctl list datapath_binding
-echo "---------------------"
-ovn-sbctl list logical_flow
-echo "---------------------"
-
-echo "------ hv1 dump ----------"
-as hv1 ovs-ofctl dump-flows br-int
-
 #Disable router R1
 ovn-nbctl --wait=hv set Logical_Router R1 enabled=false
 
-echo "---------SB dump-----"
-ovn-sbctl list datapath_binding
-echo "---------------------"
-ovn-sbctl list logical_flow
-echo "---------------------"
-
-echo "------ hv1 dump ----------"
-as hv1 ovs-ofctl dump-flows br-int
-
+ovs-sbctl dump-flows > sbflows2
+AT_CAPTURE_FILE([sbflows2])
 
 as hv1 ovs-appctl netdev-dummy/receive vif1 $packet
 
@@ -5142,6 +5119,9 @@ OVN_POPULATE_ARP
 wait_for_ports_up
 check ovn-nbctl --wait=hv sync
 
+ovn-sbctl dump-flows > sbflows
+AT_CAPTURE_FILE([sbflows])
+
 # Send ip packets between foo1 and alice1
 src_mac="f00000010203"
 dst_mac="000000010203"
@@ -5158,25 +5138,6 @@ dst_ip=`ip_to_hex 172 16 2 2`
 packet=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
 as hv1 ovs-appctl netdev-dummy/receive hv1-vif1 $packet
 
-echo "---------NB dump-----"
-ovn-nbctl show
-echo "---------------------"
-ovn-nbctl list logical_router
-echo "---------------------"
-ovn-nbctl list logical_router_port
-echo "---------------------"
-
-echo "---------SB dump-----"
-ovn-sbctl list datapath_binding
-echo "---------------------"
-ovn-sbctl list port_binding
-echo "---------------------"
-
-echo "------ hv1 dump ----------"
-as hv1 ovs-ofctl dump-flows br-int
-echo "------ hv2 dump ----------"
-as hv2 ovs-ofctl dump-flows br-int
-
 # Packet to Expect at bob1
 src_mac="000000010205"
 dst_mac="f00000010205"
@@ -6646,7 +6607,8 @@ ovs-vsctl -- add-port br-int vif2 -- \
 # Allow some time for ovn-northd and ovn-controller to catch up.
 wait_for_ports_up
 check ovn-nbctl --wait=hv sync
-
+ovn-nbctl dump-flows > sbflows
+AT_CAPTURE_FILE([sbflows])
 
 for i in 1 2; do
     : > vif$i.expected
@@ -7250,6 +7212,9 @@ wait_for_ports_up
 check ovn-nbctl --wait=hv sync
 sleep 1
 
+ovn-nbctl dump-flows > sbflows
+AT_CAPTURE_FILE([sbflows])
+
 for i in 1 2; do
     : > $i.expected
 done
@@ -7263,11 +7228,6 @@ na_packet=fa163e940598fa163ea1f9ae86dd6000000000203afffd81ce49a9480000f8163efffe
 as hv1 ovs-appctl netdev-dummy/receive vif1 $ns_packet
 echo $na_packet >> 1.expected
 
-echo "------ hv1 dump ------"
-as hv1 ovs-vsctl show
-as hv1 ovs-ofctl -O OpenFlow13 show br-int
-as hv1 ovs-ofctl -O OpenFlow13 dump-flows br-int
-
 for i in 1 2; do
     OVN_CHECK_PACKETS([hv1/vif$i-tx.pcap], [$i.expected])
 done
@@ -7893,29 +7853,8 @@ ovs-vsctl -- add-port br-int hv1-ls2lp2 -- \
 wait_for_ports_up
 check ovn-nbctl --wait=hv sync
 
-echo "---------NB dump-----"
-ovn-nbctl show
-echo "---------------------"
-ovn-nbctl list logical_router
-echo "---------------------"
-ovn-nbctl list logical_router_port
-echo "---------------------"
-
-echo "---------SB dump-----"
-ovn-sbctl list datapath_binding
-echo "---------------------"
-ovn-sbctl list port_binding
-echo "---------------------"
-ovn-sbctl dump-flows
-echo "---------------------"
-ovn-sbctl list chassis
-ovn-sbctl list encap
-echo "---------------------"
-
-echo "------Flows dump-----"
-as hv1
-ovs-ofctl dump-flows
-echo "---------------------"
+ovn-sbctl dump-flows > sbflows
+AT_CAPTURE_FILE([sbflows])
 
 src_mac="f00000000003"
 dst_mac="f00000000001"
@@ -10934,38 +10873,42 @@ 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
-OVS_WAIT_UNTIL([test 1 = `ovn-sbctl dump-flows foo | grep ls_in_l2_lkup | \
+ovn-sbctl dump-flows foo > sbflows
+AT_CAPTURE_FILE([sbflows])
+OVS_WAIT_UNTIL([test 1 = `grep ls_in_l2_lkup sbflows | \
 grep rp-foo | grep is_chassis_resident | grep priority=50 -c`])
 
-echo "---------NB dump-----"
-ovn-nbctl show
-echo "---------------------"
-ovn-nbctl list logical_router
-echo "---------------------"
-ovn-nbctl list nat
-echo "---------------------"
-ovn-nbctl list logical_router_port
-echo "---------------------"
+(echo "---------NB dump-----"
+ ovn-nbctl show
+ echo "---------------------"
+ ovn-nbctl list logical_router
+ echo "---------------------"
+ ovn-nbctl list nat
+ echo "---------------------"
+ ovn-nbctl list logical_router_port
+ echo "---------------------") > nbdump
+AT_CAPTURE_FILE([nbdump])
 
-echo "---------SB dump-----"
-ovn-sbctl list datapath_binding
-echo "---------------------"
-ovn-sbctl list port_binding
-echo "---------------------"
-ovn-sbctl dump-flows
-echo "---------------------"
-ovn-sbctl list chassis
-echo "---------------------"
+(echo "---------SB dump-----"
+ ovn-sbctl list datapath_binding
+ echo "---------------------"
+ ovn-sbctl list port_binding
+ echo "---------------------"
+ ovn-sbctl list chassis
+ echo "---------------------") > sbdump
+AT_CAPTURE_FILE([sbdump])
 
 for chassis in hv1 hv2 hv3; do
-    as $chassis
-    echo "------ $chassis dump ----------"
-    ovs-vsctl show br-int
-    ovs-ofctl show br-int
-    ovs-ofctl dump-flows br-int
-    echo "--------------------------"
+    (as $chassis
+     echo "------ $chassis dump ----------"
+     ovs-vsctl show
+     ovs-ofctl show br-int
+     ovs-ofctl dump-flows br-int
+     echo "--------------------------") > ${chassis}dump
 done
+AT_CAPTURE_FILE([hv1dump])
+AT_CAPTURE_FILE([hv2dump])
+AT_CAPTURE_FILE([hv3dump])
 
 foo1_ip=$(ip_to_hex 192 168 1 2)
 gw_ip=$(ip_to_hex 172 16 1 6)
@@ -11419,6 +11362,9 @@ OVN_POPULATE_ARP
 wait_for_ports_up
 check ovn-nbctl --wait=hv sync
 
+ovn-sbctl dump-flows > sbflows
+AT_CAPTURE_FILE([sbflows])
+
 # Send ip packets between foo1 and alice1
 src_mac="f00000010203"
 dst_mac="000000010203"
@@ -13831,27 +13777,30 @@ OVN_FOR_EACH_NORTHD([
 AT_SETUP([ovn -- Superseding ACLs with conjunction])
 ovn_start
 
-ovn-nbctl ls-add ls1
+check ovn-nbctl set nb_global . options:svc_monitor_mac=66:66:66:66:66:66
+check ovn-nbctl ls-add ls1
 
-ovn-nbctl lsp-add ls1 ls1-lp1 \
--- lsp-set-addresses ls1-lp1 "f0:00:00:00:00:01"
+check ovn-nbctl lsp-add ls1 ls1-lp1 \
+-- lsp-set-addresses ls1-lp1 "f0:00:00:00:00:01" \
+-- set logical_switch_port ls1-lp1 options:requested-tnl-key=1
 
-ovn-nbctl lsp-add ls1 ls1-lp2 \
--- lsp-set-addresses ls1-lp2 "f0:00:00:00:00:02"
+check ovn-nbctl lsp-add ls1 ls1-lp2 \
+-- lsp-set-addresses ls1-lp2 "f0:00:00:00:00:02" \
+-- set logical_switch_port ls1-lp1 options:requested-tnl-key=2
 
 net_add n1
 sim_add hv1
 
 as hv1
-ovs-vsctl add-br br-phys
+check ovs-vsctl add-br br-phys
 ovn_attach n1 br-phys 192.168.0.1
-ovs-vsctl -- add-port br-int hv1-vif1 -- \
+check ovs-vsctl -- add-port br-int hv1-vif1 -- \
     set interface hv1-vif1 external-ids:iface-id=ls1-lp1 \
     options:tx_pcap=hv1/vif1-tx.pcap \
     options:rxq_pcap=hv1/vif1-rx.pcap \
     ofport-request=1
 
-ovs-vsctl -- add-port br-int hv1-vif2 -- \
+check ovs-vsctl -- add-port br-int hv1-vif2 -- \
     set interface hv1-vif2 external-ids:iface-id=ls1-lp2 \
     options:tx_pcap=hv1/vif2-tx.pcap \
     options:rxq_pcap=hv1/vif2-rx.pcap \
@@ -13871,7 +13820,8 @@ test_ip() {
     local packet=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}\
 ${dst_ip}0035111100080000
     shift; shift; shift; shift; shift
-    as hv1 ovs-appctl netdev-dummy/receive hv1-vif1 $packet
+    check as hv1 ovs-appctl netdev-dummy/receive hv1-vif1 $packet
+    ovs-appctl ofproto/trace br-int in_port=hv1-vif1 "$packet" > trace
     for outport; do
         echo $packet >> $outport.expected
     done
@@ -13880,20 +13830,23 @@ ${dst_ip}0035111100080000
 reset_pcap_file() {
     local iface=$1
     local pcap_file=$2
-    ovs-vsctl -- set Interface $iface options:tx_pcap=dummy-tx.pcap \
+    check ovs-vsctl -- set Interface $iface options:tx_pcap=dummy-tx.pcap \
 options:rxq_pcap=dummy-rx.pcap
     rm -f ${pcap_file}*.pcap
-    ovs-vsctl -- set Interface $iface options:tx_pcap=${pcap_file}-tx.pcap \
+    check ovs-vsctl -- set Interface $iface options:tx_pcap=${pcap_file}-tx.pcap \
 options:rxq_pcap=${pcap_file}-rx.pcap
 }
 
 # Add a default deny ACL and an allow ACL for specific IP traffic.
-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
+check ovn-nbctl acl-add ls1 to-lport 2 'arp' allow
+check ovn-nbctl acl-add ls1 to-lport 1 'ip4' drop
+check 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
+check 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
+check ovn-nbctl --wait=hv sync
+
+ovn-sbctl dump-flows > sbflows
+AT_CAPTURE_FILE([sbflows])
 
 # Traffic 10.0.0.1, 10.0.0.2 -> 10.0.0.3, 10.0.0.4 should be allowed.
 for src in `seq 1 2`; do
@@ -13921,9 +13874,9 @@ rm -f 2.packets
 > 2.expected
 
 # Add two less restrictive allow ACLs for src IP 10.0.0.1.
-ovn-nbctl acl-add ls1 to-lport 3 'ip4.src==10.0.0.1 || ip4.src==10.0.0.1' allow
-ovn-nbctl acl-add ls1 to-lport 3 'ip4.src==10.0.0.1' allow
-ovn-nbctl --wait=hv sync
+check ovn-nbctl acl-add ls1 to-lport 3 'ip4.src==10.0.0.1 || ip4.src==10.0.0.1' allow
+check ovn-nbctl acl-add ls1 to-lport 3 'ip4.src==10.0.0.1' allow
+check ovn-nbctl --wait=hv sync
 
 # Check OVS flows, the less restrictive flows should have been installed.
 AT_CHECK([as hv1 ovs-ofctl dump-flows br-int table=45 | \
@@ -13966,8 +13919,8 @@ rm -f 2.packets
 > 2.expected
 
 # 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
+check ovn-nbctl acl-del ls1 to-lport 3 'ip4.src==10.0.0.1 || ip4.src==10.0.0.1'
+check ovn-nbctl --wait=hv sync
 
 # Check OVS flows, the second less restrictive allow ACL should have been installed.
 AT_CHECK([as hv1 ovs-ofctl dump-flows br-int table=45 | \
@@ -13983,8 +13936,8 @@ priority=1003,ip,metadata=0x1,nw_src=10.0.0.42 actions=conjunction()
 ])
 
 # Remove the less restrictive allow ACL.
-ovn-nbctl acl-del ls1 to-lport 3 'ip4.src==10.0.0.1'
-ovn-nbctl --wait=hv sync
+check ovn-nbctl acl-del ls1 to-lport 3 'ip4.src==10.0.0.1'
+check ovn-nbctl --wait=hv sync
 
 # Check OVS flows, the 10.0.0.1 conjunction should have been reinstalled.
 AT_CHECK([as hv1 ovs-ofctl dump-flows br-int table=45 | \
@@ -14022,8 +13975,8 @@ $PYTHON "$ovs_srcdir/utilities/ovs-pcap.in" hv1/vif2-tx.pcap > 2.packets
 AT_CHECK([cat 2.packets], [0], [expout])
 
 # Re-add the less restrictive allow ACL for src IP 10.0.0.1
-ovn-nbctl acl-add ls1 to-lport 3 'ip4.src==10.0.0.1' allow
-ovn-nbctl --wait=hv sync
+check ovn-nbctl acl-add ls1 to-lport 3 'ip4.src==10.0.0.1' allow
+check ovn-nbctl --wait=hv sync
 
 # Check OVS flows, the less restrictive flows should have been installed.
 AT_CHECK([as hv1 ovs-ofctl dump-flows br-int table=45 | \
@@ -16672,12 +16625,9 @@ spa=$(ip_to_hex 10 0 0 10)
 tpa=$(ip_to_hex 10 0 0 10)
 send_garp 1 1 $eth_src $eth_dst $spa $tpa
 
-OVS_WAIT_UNTIL([test x$(ovn-sbctl --bare --columns chassis find port_binding \
-logical_port=sw0-vir) = x$hv1_ch_uuid], [0], [])
-
-AT_CHECK([test x$(ovn-sbctl --bare --columns virtual_parent find port_binding \
-logical_port=sw0-vir) = xsw0-p1])
-
+wait_row_count Port_Binding 1 logical_port=sw0-vir chassis=$hv1_ch_uuid
+check_row_count Port_Binding 1 logical_port=sw0-vir virtual_parent=sw0-p1
+check ovn-nbctl --wait=hv sync
 
 # There should be an arp resolve flow to resolve the virtual_ip with the
 # sw0-p1's MAC.
@@ -17283,6 +17233,7 @@ AT_CAPTURE_FILE([sbflows3])
 cp ovn-sb/ovn-sb.db ovn-sb3.db
 ovn-sbctl dump-flows > sbflows3
 
+AS_BOX([IGMP traffic test 1])
 # Send traffic and make sure it gets forwarded only on the two ports that
 # joined.
 > expected
@@ -17331,6 +17282,7 @@ send_igmp_v3_report hv1-vif1 hv1 \
 wait_row_count IGMP_Group 1 address=239.0.1.68
 check ovn-nbctl --wait=hv sync
 
+AS_BOX([IGMP traffic test 2])
 # Send traffic and make sure it gets forwarded only on the port that joined.
 as hv1 reset_pcap_file hv1-vif1 hv1/vif1
 as hv2 reset_pcap_file hv2-vif1 hv2/vif1
@@ -17370,6 +17322,7 @@ send_igmp_v3_report hv1-vif1 hv1 \
 # Check that the IGMP Group is learned.
 wait_row_count IGMP_Group 1 address=224.0.0.42
 
+AS_BOX([IGMP traffic test 3])
 # Send traffic and make sure it gets flooded to all ports.
 as hv1 reset_pcap_file hv1-vif1 hv1/vif1
 as hv1 reset_pcap_file hv1-vif2 hv1/vif2
@@ -17399,6 +17352,7 @@ check ovn-nbctl set Logical_Switch sw2 \
     other_config:mcast_eth_src="00:00:00:00:02:fe" \
     other_config:mcast_ip4_src="20.0.0.254"
 
+AS_BOX([IGMP traffic test 4])
 # Wait for 1 query interval (1 sec) and check that two queries are generated.
 > expected
 store_igmp_v3_query 0000000002fe $(ip_to_hex 20 0 0 254) 84dd expected
@@ -17420,6 +17374,7 @@ check ovn-nbctl set Logical_Switch sw3       \
 
 check ovn-nbctl --wait=hv sync
 
+AS_BOX([IGMP traffic test 5])
 # Send traffic from sw3 and make sure rtr doesn't relay it.
 > expected_empty
 
@@ -17469,6 +17424,7 @@ send_igmp_v3_report hv2-vif3 hv2 \
 wait_row_count IGMP_Group 2 address=239.0.1.68
 check ovn-nbctl --wait=hv sync
 
+AS_BOX([IGMP traffic test 6])
 # Send traffic from sw3 and make sure it is relayed by rtr.
 # to ports that joined.
 > expected_routed_sw1
@@ -17518,6 +17474,7 @@ send_igmp_v3_report hv1-vif4 hv1 \
 wait_row_count IGMP_Group 3 address=239.0.1.68
 check ovn-nbctl --wait=hv sync
 
+AS_BOX([IGMP traffic test 7])
 # Send traffic from sw3 and make sure it is relayed by rtr
 # to ports that joined.
 > expected_routed_sw1
@@ -17617,6 +17574,7 @@ send_igmp_v3_report hv1-vif2 hv1 \
 wait_row_count IGMP_Group 1 address=239.0.1.68
 check ovn-nbctl --wait=hv sync
 
+AS_BOX([IGMP traffic test 8])
 # Send traffic from sw1-p21
 send_ip_multicast_pkt hv2-vif1 hv2 \
     000000000001 01005e000144 \
@@ -21938,26 +21896,25 @@ ovn-nbctl set Logical_Router $gw_uuid options:chassis=hv1
 ovn-nbctl --wait=hv sync
 
 # And ensure that ECMP symmetric reply flows are present only on hv1
-AT_CHECK([
-    test 1 -eq $(as hv1 ovs-ofctl dump-flows br-int table=15 | \
-    grep "priority=100" | \
-    grep "ct(commit,zone=NXM_NX_REG11\\[[0..15\\]],exec(move:NXM_OF_ETH_SRC\\[[\\]]->NXM_NX_CT_LABEL\\[[32..79\\]],load:0x[[0-9]]->NXM_NX_CT_LABEL\\[[80..95\\]]))" -c)
-])
-AT_CHECK([
-    test 1 -eq $(as hv1 ovs-ofctl dump-flows br-int table=21 | \
-    grep "priority=200" | \
-    grep "actions=move:NXM_NX_CT_LABEL\\[[32..79\\]]->NXM_OF_ETH_DST\\[[\\]]" -c)
-])
+as hv1 ovs-ofctl dump-flows br-int > hv1flows
+AT_CAPTURE_FILE([hv1flows])
+as hv2 ovs-ofctl dump-flows br-int > hv2flows
+AT_CAPTURE_FILE([hv2flows])
 
 AT_CHECK([
-    test 0 -eq $(as hv2 ovs-ofctl dump-flows br-int table=15 | \
-    grep "priority=100" | \
-    grep "ct(commit,zone=NXM_NX_REG11\\[[0..15\\]],exec(move:NXM_OF_ETH_SRC\\[[\\]]->NXM_NX_CT_LABEL\\[[32..79\\]],load:0x[[0-9]]->NXM_NX_CT_LABEL\\[[80..95\\]]))" -c)
-])
-AT_CHECK([
-    test 0 -eq $(as hv2 ovs-ofctl dump-flows br-int table=21 | \
-    grep "priority=200" | \
-    grep "actions=move:NXM_NX_CT_LABEL\\[[32..79\\]]->NXM_OF_ETH_DST\\[[\\]]" -c)
+    for hv in 1 2; do
+        grep table=15 hv${hv}flows | \
+        grep "priority=100" | \
+        grep -c "ct(commit,zone=NXM_NX_REG11\\[[0..15\\]],exec(move:NXM_OF_ETH_SRC\\[[\\]]->NXM_NX_CT_LABEL\\[[32..79\\]],load:0x[[0-9]]->NXM_NX_CT_LABEL\\[[80..95\\]]))"
+
+        grep table=21 hv${hv}flows | \
+        grep "priority=200" | \
+        grep -c "actions=move:NXM_NX_CT_LABEL\\[[32..79\\]]->NXM_OF_ETH_DST\\[[\\]]"
+    done; :], [0], [dnl
+1
+1
+0
+0
 ])
 
 OVN_CLEANUP([hv1], [hv2])
@@ -22085,22 +22042,22 @@ as hv1
 ovs-vsctl add-br br-phys
 ovn_attach n1 br-phys 192.168.0.1
 
-ovn-nbctl ls-add sw0
-ovn-nbctl lsp-add sw0 sw0-p1
-ovn-nbctl lsp-set-addresses sw0-p1 "10:14:00:00:00:03 10.0.0.3"
-ovn-nbctl lsp-set-port-security sw0-p1 "10:14:00:00:00:03 10.0.0.3"
+check ovn-nbctl ls-add sw0
+check ovn-nbctl lsp-add sw0 sw0-p1
+check ovn-nbctl lsp-set-addresses sw0-p1 "10:14:00:00:00:03 10.0.0.3"
+check ovn-nbctl lsp-set-port-security sw0-p1 "10:14:00:00:00:03 10.0.0.3"
 
-ovn-nbctl lsp-add sw0 sw0-p2
-ovn-nbctl lsp-set-addresses sw0-p2 "10:14:00:00:00:04 10.0.0.4"
-ovn-nbctl lsp-set-port-security sw0-p2 "10:14:00:00:00:04 10.0.0.4"
+check ovn-nbctl lsp-add sw0 sw0-p2
+check ovn-nbctl lsp-set-addresses sw0-p2 "10:14:00:00:00:04 10.0.0.4"
+check ovn-nbctl lsp-set-port-security sw0-p2 "10:14:00:00:00:04 10.0.0.4"
 
-ovn-nbctl lsp-add sw0 sw0-p3
-ovn-nbctl lsp-set-addresses sw0-p3 "10:14:00:00:00:05 10.0.0.5"
-ovn-nbctl lsp-set-port-security sw0-p3 "10:14:00:00:00:05 10.0.0.5"
+check ovn-nbctl lsp-add sw0 sw0-p3
+check ovn-nbctl lsp-set-addresses sw0-p3 "10:14:00:00:00:05 10.0.0.5"
+check ovn-nbctl lsp-set-port-security sw0-p3 "10:14:00:00:00:05 10.0.0.5"
 
-ovn-nbctl lsp-add sw0 sw0-p4
-ovn-nbctl lsp-set-addresses sw0-p4 "10:14:00:00:00:06 10.0.0.6"
-ovn-nbctl lsp-set-port-security sw0-p4 "10:14:00:00:00:06 10.0.0.6"
+check ovn-nbctl lsp-add sw0 sw0-p4
+check ovn-nbctl lsp-set-addresses sw0-p4 "10:14:00:00:00:06 10.0.0.6"
+check ovn-nbctl lsp-set-port-security sw0-p4 "10:14:00:00:00:06 10.0.0.6"
 
 as hv1
 ovs-vsctl -- add-port br-int hv1-vif1 -- \
@@ -22126,83 +22083,99 @@ ovs-vsctl -- add-port br-int hv1-vif4 -- \
 
 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
-ovn-nbctl --wait=hv sync
+check ovn-nbctl pg-add pg0 sw0-p1 sw0-p2
+check ovn-nbctl acl-add pg0 to-lport 1002 "outport == @pg0 && ip4 && tcp.dst >= 80 && tcp.dst <= 82" allow
+check ovn-nbctl --wait=hv sync
 
-OVS_WAIT_UNTIL([test 1 = $(as hv1 ovs-ofctl dump-flows br-int table=45 | grep -c "conj_id=2")])
+# wait_conj_id_count COUNT ["ID COUNT [MATCH]"]...
+#
+# Waits until COUNT flows matching against conj_id appear in the
+# table 45 on hv1's br-int bridge.  Makes the flows available in
+# "hv1flows", which will be logged on error.
+#
+# In addition, for each quoted "ID COUNT" or "ID COUNT MATCH",
+# verifies that there are COUNT flows in table 45 that match
+# aginst conj_id=ID and (if MATCH) is nonempty, match MATCH.
+wait_conj_id_count() {
+  AT_CAPTURE_FILE([hv1flows])
+  local retval
+  case $1 in
+      (0) retval=1 ;;
+      (*) retval=0 ;;
+  esac
+
+  echo "waiting for $1 conj_id flows..."
+  OVS_WAIT_FOR_OUTPUT_UNQUOTED(
+    [ovs-ofctl dump-flows br-int > hv1flows
+     grep table=45 hv1flows | grep -c conj_id],
+    [$retval], [$1
+])
+
+  shift
+  for arg; do
+    set -- $arg; id=$1 count=$2 match=$3
+    echo "checking that there are $count ${match:+$match }flows with conj_id=$id..."
+    AT_CHECK_UNQUOTED(
+      [grep table=45 hv1flows | grep "$match" | grep -c conj_id=$id],
+      [0], [$count
+])
+  done
+}
 
-# Add sw0-p3 to the port group pg0. The conj_id should be 2.
-ovn-nbctl pg-set-ports pg0 sw0-p1 sw0-p2 sw0-p3
-OVS_WAIT_UNTIL([test 1 = $(as hv1 ovs-ofctl dump-flows br-int table=45 | grep -c "conj_id")])
-AT_CHECK([test 1 = $(as hv1 ovs-ofctl dump-flows br-int table=45 | grep -c "conj_id=2")])
+AS_BOX([Add sw0-p3 to the port group pg0. The conj_id should be 2.])
+check ovn-nbctl --wait=hv pg-set-ports pg0 sw0-p1 sw0-p2 sw0-p3
+wait_conj_id_count 1 "2 1"
 
-# Add sw0p4 to the port group pg0. The conj_id should be 2.
-ovn-nbctl pg-set-ports pg0 sw0-p1 sw0-p2 sw0-p3 sw0-p4
-OVS_WAIT_UNTIL([test 1 = $(as hv1 ovs-ofctl dump-flows br-int table=45 | grep -c "conj_id")])
-AT_CHECK([test 1 = $(as hv1 ovs-ofctl dump-flows br-int table=45 | grep -c "conj_id=2")])
+AS_BOX([Add sw0p4 to the port group pg0. The conj_id should be 2.])
+check ovn-nbctl --wait=hv pg-set-ports pg0 sw0-p1 sw0-p2 sw0-p3 sw0-p4
+wait_conj_id_count 1 "2 1"
 
-# Add another ACL with conjunction.
-ovn-nbctl acl-add pg0 to-lport 1002 "outport == @pg0 && ip4 && udp.dst >= 80 && udp.dst <= 82" allow
-OVS_WAIT_UNTIL([test 2 = $(as hv1 ovs-ofctl dump-flows br-int table=45 | grep -c "conj_id")])
-AT_CHECK([test 1 = $(as hv1 ovs-ofctl dump-flows br-int table=45 | grep tcp | grep -c "conj_id=2")])
-AT_CHECK([test 1 = $(as hv1 ovs-ofctl dump-flows br-int table=45 | grep udp | grep -c "conj_id=3")])
+AS_BOX([Add another ACL with conjunction.])
+check ovn-nbctl --wait=hv acl-add pg0 to-lport 1002 "outport == @pg0 && ip4 && udp.dst >= 80 && udp.dst <= 82" allow
+wait_conj_id_count 2 "2 1 tcp" "3 1 udp"
 
-# Delete tcp ACL.
-ovn-nbctl acl-del pg0 to-lport 1002 "outport == @pg0 && ip4 && tcp.dst >= 80 && tcp.dst <= 82"
-OVS_WAIT_UNTIL([test 1 = $(as hv1 ovs-ofctl dump-flows br-int table=45 | grep -c "conj_id")])
-AT_CHECK([test 1 = $(as hv1 ovs-ofctl dump-flows br-int table=45 | grep udp | grep -c "conj_id=3")])
+AS_BOX([Delete tcp ACL.])
+check ovn-nbctl --wait=hv acl-del pg0 to-lport 1002 "outport == @pg0 && ip4 && tcp.dst >= 80 && tcp.dst <= 82"
+wait_conj_id_count 1 "3 1 udp"
 
-# Add back the tcp ACL.
-ovn-nbctl acl-add pg0 to-lport 1002 "outport == @pg0 && ip4 && tcp.dst >= 80 && tcp.dst <= 82" allow
-OVS_WAIT_UNTIL([test 2 = $(as hv1 ovs-ofctl dump-flows br-int table=45 | grep -c "conj_id")])
+AS_BOX([Add back the tcp ACL.])
+check ovn-nbctl --wait=hv acl-add pg0 to-lport 1002 "outport == @pg0 && ip4 && tcp.dst >= 80 && tcp.dst <= 82" allow
+wait_conj_id_count 2 "3 1 udp" "4 1 tcp"
 AT_CHECK([test 1 = $(as hv1 ovs-ofctl dump-flows br-int table=45 | grep udp | grep -c "conj_id=3")])
 AT_CHECK([test 1 = $(as hv1 ovs-ofctl dump-flows br-int table=45 | grep tcp | grep -c "conj_id=4")])
 
-ovn-nbctl acl-add pg0 to-lport 1002 "outport == @pg0 && inport == @pg0 && ip4 && tcp.dst >= 84 && tcp.dst <= 86" allow
-OVS_WAIT_UNTIL([test 3 = $(as hv1 ovs-ofctl dump-flows br-int table=45 | grep -c "conj_id")])
-AT_CHECK([test 1 = $(as hv1 ovs-ofctl dump-flows br-int table=45 | grep udp | grep -c "conj_id=3")])
-AT_CHECK([test 1 = $(as hv1 ovs-ofctl dump-flows br-int table=45 | grep tcp | grep -c "conj_id=4")])
-AT_CHECK([test 1 = $(as hv1 ovs-ofctl dump-flows br-int table=45 | grep tcp | grep -c "conj_id=5")])
+AS_BOX([Add another tcp ACL.])
+check ovn-nbctl --wait=hv acl-add pg0 to-lport 1002 "outport == @pg0 && inport == @pg0 && ip4 && tcp.dst >= 84 && tcp.dst <= 86" allow
+wait_conj_id_count 3 "3 1 udp" "4 1 tcp" "5 1 tcp"
 
-ovn-nbctl clear port_group pg0 acls
-OVS_WAIT_UNTIL([test 0 = $(as hv1 ovs-ofctl dump-flows br-int table=45 | grep -c "conj_id")])
+AS_BOX([Clear ACLs.])
+check ovn-nbctl --wait=hv clear port_group pg0 acls
+wait_conj_id_count 0
 
-ovn-nbctl --wait=hv acl-add pg0 to-lport 1002 "outport == @pg0 && ip4 && tcp.dst >= 80 && tcp.dst <= 82" allow
-ovn-nbctl --wait=hv acl-add pg0 to-lport 1002 "outport == @pg0 && ip4 && udp.dst >= 80 && udp.dst <= 82" allow
-OVS_WAIT_UNTIL([test 2 = $(as hv1 ovs-ofctl dump-flows br-int table=45 | grep -c "conj_id")])
-AT_CHECK([test 1 = $(as hv1 ovs-ofctl dump-flows br-int table=45 | grep tcp | grep -c "conj_id=6")])
-AT_CHECK([test 1 = $(as hv1 ovs-ofctl dump-flows br-int table=45 | grep udp | grep -c "conj_id=7")])
+AS_BOX([Add TCP ACL.])
+check ovn-nbctl --wait=hv acl-add pg0 to-lport 1002 "outport == @pg0 && ip4 && tcp.dst >= 80 && tcp.dst <= 82" allow
+check ovn-nbctl acl-add pg0 to-lport 1002 "outport == @pg0 && ip4 && udp.dst >= 80 && udp.dst <= 82" allow
+wait_conj_id_count 2 "6 1 tcp" "7 1 udp"
 
-# Flush the lflow cache.
+AS_BOX([Flush lflow cache.])
 as hv1 ovn-appctl -t ovn-controller flush-lflow-cache
-OVS_WAIT_UNTIL([test 2 = $(as hv1 ovs-ofctl dump-flows br-int table=45 | grep -c "conj_id")])
-AT_CHECK([test 1 = $(as hv1 ovs-ofctl dump-flows br-int table=45 | grep -c "conj_id=2")])
-AT_CHECK([test 1 = $(as hv1 ovs-ofctl dump-flows br-int table=45 | grep -c "conj_id=3")])
-
-# Disable lflow caching.
+wait_conj_id_count 2 "2 1" "3 1"
 
+AS_BOX([Disable lflow caching.])
 as hv1 ovs-vsctl set open . external_ids:ovn-enable-lflow-cache=false
 
-# Wait until ovn-enble-lflow-cache is processed by ovn-controller.
-OVS_WAIT_UNTIL([
-    test $(ovn-sbctl get chassis hv1 other_config:ovn-enable-lflow-cache) = '"false"'
-])
-
-AT_CHECK([test 1 = $(as hv1 ovs-ofctl dump-flows br-int table=45 | grep -c "conj_id=2")])
-AT_CHECK([test 1 = $(as hv1 ovs-ofctl dump-flows br-int table=45 | grep -c "conj_id=3")])
+AS_BOX([Wait until ovn-enble-lflow-cache is processed by ovn-controller.])
+wait_row_count Chassis 1 name=hv1 other_config:ovn-enable-lflow-cache=false
+wait_conj_id_count 2 "2 1" "3 1"
 
-# Remove port sw0-p4 from port group.
-ovn-nbctl pg-set-ports pg0 sw0-p1 sw0-p2 sw0-p3
-OVS_WAIT_UNTIL([test 2 = $(as hv1 ovs-ofctl dump-flows br-int table=45 | grep -c "conj_id")])
-AT_CHECK([test 1 = $(as hv1 ovs-ofctl dump-flows br-int table=45 | grep -c "conj_id=4")])
-AT_CHECK([test 1 = $(as hv1 ovs-ofctl dump-flows br-int table=45 | grep -c "conj_id=5")])
+AS_BOX([Remove port sw0-p4 from port group.])
+check ovn-nbctl --wait=hv pg-set-ports pg0 sw0-p1 sw0-p2 sw0-p3
+wait_conj_id_count 2 "4 1" "5 1"
 
+AS_BOX([Recompute.])
 as hv1 ovn-appctl -t ovn-controller recompute
 
-OVS_WAIT_UNTIL([test 2 = $(as hv1 ovs-ofctl dump-flows br-int table=45 | grep -c "conj_id")])
-OVS_WAIT_UNTIL([test 1 = $(as hv1 ovs-ofctl dump-flows br-int table=45 | grep -c "conj_id=2")])
-AT_CHECK([test 1 = $(as hv1 ovs-ofctl dump-flows br-int table=45 | grep -c "conj_id=3")])
+wait_conj_id_count 2 "2 1" "3 1"
 
 OVN_CLEANUP([hv1])
 
diff --git a/tests/ovs-macros.at b/tests/ovs-macros.at
index d859750f4df6..2c5c55c5871d 100644
--- a/tests/ovs-macros.at
+++ b/tests/ovs-macros.at
@@ -272,14 +272,16 @@ m4_define([OVS_WAIT_UNTIL],
   [OVS_WAIT([$1], [$2], [AT_LINE], [until $1])])
 
 dnl OVS_WAIT_FOR_OUTPUT(COMMAND, EXIT-STATUS, STDOUT, STDERR)
+dnl OVS_WAIT_FOR_OUTPUT_UNQUOTED(COMMAND, EXIT-STATUS, STDOUT, STDERR)
 dnl
 dnl Executes shell COMMAND in a loop until it exits with status EXIT-STATUS,
 dnl prints STDOUT on stdout, and prints STDERR on stderr.  If this doesn't
 dnl happen within a reasonable time limit, then the test fails.
-m4_define([OVS_WAIT_FOR_OUTPUT], [dnl
+dnl
+dnl The UNQUOTED version expands shell $variables, $(command)s, and so on.
+dnl The plain version does not
+m4_define([OVS_WAIT_FOR_OUTPUT__], [dnl
 wait_expected_status=m4_if([$2], [], [0], [$2])
-AT_DATA([wait-expected-stdout], [$3])
-AT_DATA([wait-expected-stderr], [$4])
 ovs_wait_command() {
     $1
 }
@@ -299,6 +301,18 @@ ovs_wait_failed () {
 }
 ovs_wait "AS_ESCAPE([AT_LINE])" "for output from AS_ESCAPE([$1])"
 ])
+m4_define([OVS_WAIT_FOR_OUTPUT], [dnl
+AT_DATA([wait-expected-stdout], [$3])
+AT_DATA([wait-expected-stderr], [$4])
+OVS_WAIT_FOR_OUTPUT__([$1], [$2])
+])
+m4_define([OVS_WAIT_FOR_OUTPUT_UNQUOTED], [dnl
+cat > wait-expected-stdout <<EOF
+$3[]EOF
+cat > wait-expected-stderr <<EOF
+$4[]EOF
+OVS_WAIT_FOR_OUTPUT__([$1], [$2])
+])
     
 dnl OVS_WAIT_WHILE(COMMAND[, IF-FAILED])
 dnl
