diff --git a/tests/system-ovn.at b/tests/system-ovn.at
index 2d21fb262..456bb0599 100644
--- a/tests/system-ovn.at
+++ b/tests/system-ovn.at
@@ -1449,45 +1449,72 @@ OVS_START_L7([bar2], [http])
 OVS_START_L7([bar3], [http])
 
 dnl Should work with the virtual IP 30.0.0.1 address through NAT
-for i in `seq 1 20`; do
-    echo Request $i
-    NS_CHECK_EXEC([foo1], [wget 30.0.0.1 -t 5 -T 1 --retry-connrefused -v -o wget$i.log])
-done
-
 dnl Each server should have at least one connection.
-AT_CHECK([ovs-appctl dpctl/dump-conntrack | FORMAT_CT(30.0.0.1) | \
-sed -e 's/zone=[[0-9]]*/zone=<cleared>/'], [0], [dnl
-tcp,orig=(src=192.168.1.2,dst=30.0.0.1,sport=<cleared>,dport=<cleared>),reply=(src=172.16.1.2,dst=192.168.1.2,sport=<cleared>,dport=<cleared>),zone=<cleared>,labels=0x2,protoinfo=(state=<cleared>)
-tcp,orig=(src=192.168.1.2,dst=30.0.0.1,sport=<cleared>,dport=<cleared>),reply=(src=172.16.1.3,dst=192.168.1.2,sport=<cleared>,dport=<cleared>),zone=<cleared>,labels=0x2,protoinfo=(state=<cleared>)
-tcp,orig=(src=192.168.1.2,dst=30.0.0.1,sport=<cleared>,dport=<cleared>),reply=(src=172.16.1.4,dst=192.168.1.2,sport=<cleared>,dport=<cleared>),zone=<cleared>,labels=0x2,protoinfo=(state=<cleared>)
+dnl With 20 requests, one server might not receive any connection
+dnl in 0.3% of cases, so run a few times.
+
+OVS_WAIT_UNTIL([
+    for i in `seq 1 20`; do
+        echo Request $i;
+        ip netns exec foo1 wget 30.0.0.1 -t 5 -T 1 --retry-connrefused -v -o wget$i.log;
+    done
+    ct1=$(ovs-appctl dpctl/dump-conntrack | FORMAT_CT(30.0.0.1) | \
+      sed -e 's/zone=[[0-9]]*/zone=<cleared>/'| \
+      grep "tcp,orig=(src=192.168.1.2,dst=30.0.0.1,sport=<cleared>,dport=<cleared>),reply=(src=172.16.1.2,dst=192.168.1.2,sport=<cleared>,dport=<cleared>),zone=<cleared>,labels=0x2,protoinfo=(state=<cleared>)" -c)
+    ct2=$(ovs-appctl dpctl/dump-conntrack | FORMAT_CT(30.0.0.1) | \
+      sed -e 's/zone=[[0-9]]*/zone=<cleared>/'| \
+      grep "tcp,orig=(src=192.168.1.2,dst=30.0.0.1,sport=<cleared>,dport=<cleared>),reply=(src=172.16.1.3,dst=192.168.1.2,sport=<cleared>,dport=<cleared>),zone=<cleared>,labels=0x2,protoinfo=(state=<cleared>)" -c)
+    ct3=$(ovs-appctl dpctl/dump-conntrack | FORMAT_CT(30.0.0.1) | \
+      sed -e 's/zone=[[0-9]]*/zone=<cleared>/'| \
+      grep "tcp,orig=(src=192.168.1.2,dst=30.0.0.1,sport=<cleared>,dport=<cleared>),reply=(src=172.16.1.4,dst=192.168.1.2,sport=<cleared>,dport=<cleared>),zone=<cleared>,labels=0x2,protoinfo=(state=<cleared>)" -c)
+    test $ct1 -gt 0 && echo "There are flows for 172.16.1.2"
+    test $ct2 -gt 0 && echo "There are flows for 172.16.1.3"
+    test $ct3 -gt 0 && echo "There are flows for 172.16.1.4"
+    test $ct1 -gt 0 && test $ct2 -gt 0 && test $ct3 -gt 0
 ])
 
 dnl Should work with the virtual IP 30.0.0.3 address through NAT
-for i in `seq 1 20`; do
-    echo Request $i
-    NS_CHECK_EXEC([foo1], [wget 30.0.0.3 -t 5 -T 1 --retry-connrefused -v -o wget$i.log])
-done
-
 dnl Each server should have at least one connection.
-AT_CHECK([ovs-appctl dpctl/dump-conntrack | FORMAT_CT(30.0.0.3) | \
-sed -e 's/zone=[[0-9]]*/zone=<cleared>/'], [0], [dnl
-tcp,orig=(src=192.168.1.2,dst=30.0.0.3,sport=<cleared>,dport=<cleared>),reply=(src=172.16.1.2,dst=192.168.1.2,sport=<cleared>,dport=<cleared>),zone=<cleared>,labels=0x2,protoinfo=(state=<cleared>)
-tcp,orig=(src=192.168.1.2,dst=30.0.0.3,sport=<cleared>,dport=<cleared>),reply=(src=172.16.1.3,dst=192.168.1.2,sport=<cleared>,dport=<cleared>),zone=<cleared>,labels=0x2,protoinfo=(state=<cleared>)
-tcp,orig=(src=192.168.1.2,dst=30.0.0.3,sport=<cleared>,dport=<cleared>),reply=(src=172.16.1.4,dst=192.168.1.2,sport=<cleared>,dport=<cleared>),zone=<cleared>,labels=0x2,protoinfo=(state=<cleared>)
+OVS_WAIT_UNTIL([
+    for i in `seq 1 20`; do
+        echo Request $i;
+        ip netns exec foo1 wget 30.0.0.3 -t 5 -T 1 --retry-connrefused -v -o wget$i.log;
+    done
+    ct1=$(ovs-appctl dpctl/dump-conntrack | FORMAT_CT(30.0.0.3) | \
+      sed -e 's/zone=[[0-9]]*/zone=<cleared>/'| \
+      grep "tcp,orig=(src=192.168.1.2,dst=30.0.0.3,sport=<cleared>,dport=<cleared>),reply=(src=172.16.1.2,dst=192.168.1.2,sport=<cleared>,dport=<cleared>),zone=<cleared>,labels=0x2,protoinfo=(state=<cleared>)" -c)
+    ct2=$(ovs-appctl dpctl/dump-conntrack | FORMAT_CT(30.0.0.3) | \
+      sed -e 's/zone=[[0-9]]*/zone=<cleared>/'| \
+      grep "tcp,orig=(src=192.168.1.2,dst=30.0.0.3,sport=<cleared>,dport=<cleared>),reply=(src=172.16.1.3,dst=192.168.1.2,sport=<cleared>,dport=<cleared>),zone=<cleared>,labels=0x2,protoinfo=(state=<cleared>)" -c)
+    ct3=$(ovs-appctl dpctl/dump-conntrack | FORMAT_CT(30.0.0.3) | \
+      sed -e 's/zone=[[0-9]]*/zone=<cleared>/'| \
+      grep "tcp,orig=(src=192.168.1.2,dst=30.0.0.3,sport=<cleared>,dport=<cleared>),reply=(src=172.16.1.4,dst=192.168.1.2,sport=<cleared>,dport=<cleared>),zone=<cleared>,labels=0x2,protoinfo=(state=<cleared>)" -c)
+    test $ct1 -gt 0 && echo "There are flows for 172.16.1.2"
+    test $ct2 -gt 0 && echo "There are flows for 172.16.1.3"
+    test $ct3 -gt 0 && echo "There are flows for 172.16.1.4"
+    test $ct1 -gt 0 && test $ct2 -gt 0 && test $ct3 -gt 0
 ])
 
 dnl Test load-balancing that includes L4 ports in NAT.
-for i in `seq 1 20`; do
-    echo Request $i
-    NS_CHECK_EXEC([foo1], [wget 30.0.0.2:8000 -t 5 -T 1 --retry-connrefused -v -o wget$i.log])
-done
-
 dnl Each server should have at least one connection.
-AT_CHECK([ovs-appctl dpctl/dump-conntrack | FORMAT_CT(30.0.0.2) | \
-sed -e 's/zone=[[0-9]]*/zone=<cleared>/'], [0], [dnl
-tcp,orig=(src=192.168.1.2,dst=30.0.0.2,sport=<cleared>,dport=<cleared>),reply=(src=172.16.1.2,dst=192.168.1.2,sport=<cleared>,dport=<cleared>),zone=<cleared>,labels=0x2,protoinfo=(state=<cleared>)
-tcp,orig=(src=192.168.1.2,dst=30.0.0.2,sport=<cleared>,dport=<cleared>),reply=(src=172.16.1.3,dst=192.168.1.2,sport=<cleared>,dport=<cleared>),zone=<cleared>,labels=0x2,protoinfo=(state=<cleared>)
-tcp,orig=(src=192.168.1.2,dst=30.0.0.2,sport=<cleared>,dport=<cleared>),reply=(src=172.16.1.4,dst=192.168.1.2,sport=<cleared>,dport=<cleared>),zone=<cleared>,labels=0x2,protoinfo=(state=<cleared>)
+OVS_WAIT_UNTIL([
+    for i in `seq 1 20`; do
+        echo Request $i;
+        ip netns exec foo1 wget 30.0.0.2:8000 -t 5 -T 1 --retry-connrefused -v -o wget$i.log;
+    done
+    ct1=$(ovs-appctl dpctl/dump-conntrack | FORMAT_CT(30.0.0.2) | \
+      sed -e 's/zone=[[0-9]]*/zone=<cleared>/'| \
+      grep "tcp,orig=(src=192.168.1.2,dst=30.0.0.2,sport=<cleared>,dport=<cleared>),reply=(src=172.16.1.2,dst=192.168.1.2,sport=<cleared>,dport=<cleared>),zone=<cleared>,labels=0x2,protoinfo=(state=<cleared>)" -c)
+    ct2=$(ovs-appctl dpctl/dump-conntrack | FORMAT_CT(30.0.0.2) | \
+      sed -e 's/zone=[[0-9]]*/zone=<cleared>/'| \
+      grep "tcp,orig=(src=192.168.1.2,dst=30.0.0.2,sport=<cleared>,dport=<cleared>),reply=(src=172.16.1.3,dst=192.168.1.2,sport=<cleared>,dport=<cleared>),zone=<cleared>,labels=0x2,protoinfo=(state=<cleared>)" -c)
+    ct3=$(ovs-appctl dpctl/dump-conntrack | FORMAT_CT(30.0.0.2) | \
+      sed -e 's/zone=[[0-9]]*/zone=<cleared>/'| \
+      grep "tcp,orig=(src=192.168.1.2,dst=30.0.0.2,sport=<cleared>,dport=<cleared>),reply=(src=172.16.1.4,dst=192.168.1.2,sport=<cleared>,dport=<cleared>),zone=<cleared>,labels=0x2,protoinfo=(state=<cleared>)" -c)
+    test $ct1 -gt 0 && echo "There are flows for 172.16.1.2"
+    test $ct2 -gt 0 && echo "There are flows for 172.16.1.3"
+    test $ct3 -gt 0 && echo "There are flows for 172.16.1.4"
+    test $ct1 -gt 0 && test $ct2 -gt 0 && test $ct3 -gt 0
 ])
 
 # Configure selection_fields.
@@ -1500,17 +1527,25 @@ OVS_WAIT_UNTIL([
 AT_CHECK([ovs-appctl dpctl/flush-conntrack])
 
 dnl Test load-balancing that includes L4 ports in NAT.
-for i in `seq 1 20`; do
-    echo Request $i
-    NS_CHECK_EXEC([foo1], [wget 30.0.0.2:8000 -t 5 -T 1 --retry-connrefused -v -o wget$i.log])
-done
-
 dnl Each server should have at least one connection.
-AT_CHECK([ovs-appctl dpctl/dump-conntrack | FORMAT_CT(30.0.0.2) | \
-sed -e 's/zone=[[0-9]]*/zone=<cleared>/'], [0], [dnl
-tcp,orig=(src=192.168.1.2,dst=30.0.0.2,sport=<cleared>,dport=<cleared>),reply=(src=172.16.1.2,dst=192.168.1.2,sport=<cleared>,dport=<cleared>),zone=<cleared>,labels=0x2,protoinfo=(state=<cleared>)
-tcp,orig=(src=192.168.1.2,dst=30.0.0.2,sport=<cleared>,dport=<cleared>),reply=(src=172.16.1.3,dst=192.168.1.2,sport=<cleared>,dport=<cleared>),zone=<cleared>,labels=0x2,protoinfo=(state=<cleared>)
-tcp,orig=(src=192.168.1.2,dst=30.0.0.2,sport=<cleared>,dport=<cleared>),reply=(src=172.16.1.4,dst=192.168.1.2,sport=<cleared>,dport=<cleared>),zone=<cleared>,labels=0x2,protoinfo=(state=<cleared>)
+OVS_WAIT_UNTIL([
+    for i in `seq 1 20`; do
+        echo Request $i;
+        ip netns exec foo1 wget 30.0.0.2:8000 -t 5 -T 1 --retry-connrefused -v -o wget$i.log;
+    done
+    ct1=$(ovs-appctl dpctl/dump-conntrack | FORMAT_CT(30.0.0.2) | \
+      sed -e 's/zone=[[0-9]]*/zone=<cleared>/'| \
+      grep "tcp,orig=(src=192.168.1.2,dst=30.0.0.2,sport=<cleared>,dport=<cleared>),reply=(src=172.16.1.2,dst=192.168.1.2,sport=<cleared>,dport=<cleared>),zone=<cleared>,labels=0x2,protoinfo=(state=<cleared>)" -c)
+    ct2=$(ovs-appctl dpctl/dump-conntrack | FORMAT_CT(30.0.0.2) | \
+      sed -e 's/zone=[[0-9]]*/zone=<cleared>/'| \
+      grep "tcp,orig=(src=192.168.1.2,dst=30.0.0.2,sport=<cleared>,dport=<cleared>),reply=(src=172.16.1.3,dst=192.168.1.2,sport=<cleared>,dport=<cleared>),zone=<cleared>,labels=0x2,protoinfo=(state=<cleared>)" -c)
+    ct3=$(ovs-appctl dpctl/dump-conntrack | FORMAT_CT(30.0.0.2) | \
+      sed -e 's/zone=[[0-9]]*/zone=<cleared>/'| \
+      grep "tcp,orig=(src=192.168.1.2,dst=30.0.0.2,sport=<cleared>,dport=<cleared>),reply=(src=172.16.1.4,dst=192.168.1.2,sport=<cleared>,dport=<cleared>),zone=<cleared>,labels=0x2,protoinfo=(state=<cleared>)" -c)
+    test $ct1 -gt 0 && echo "There are flows for 172.16.1.2"
+    test $ct2 -gt 0 && echo "There are flows for 172.16.1.3"
+    test $ct3 -gt 0 && echo "There are flows for 172.16.1.4"
+    test $ct1 -gt 0 && test $ct2 -gt 0 && test $ct3 -gt 0
 ])
 
 AT_CHECK([ovs-appctl dpctl/flush-conntrack])
