Quellcode durchsuchen

Improve functional tests

- Move to using bash_unit
- Test pings in both directions
- Test kubernetes subnet manager
- Test multiple versions of etcd and k8s during a release
Tom Denham vor 7 Jahren
Ursprung
Commit
70bc64db80
4 geänderte Dateien mit 260 neuen und 190 gelöschten Zeilen
  1. 1 1
      .gitignore
  2. 31 3
      Makefile
  3. 121 0
      dist/functional-test-k8s.sh
  4. 107 186
      dist/functional-test.sh

+ 1 - 1
.gitignore

@@ -5,4 +5,4 @@ dist/*.docker
 cover.out
 .editorconfig
 .idea/
-
+bash_unit

+ 31 - 3
Makefile

@@ -46,11 +46,18 @@ dist/flanneld: $(shell find . -type f  -name '*.go')
 	  -ldflags "-s -w -X github.com/coreos/flannel/version.Version=$(TAG)"
 
 test: license-check gofmt
+	# Run the unit tests
 	go test -cover $(TEST_PACKAGES_EXPANDED)
+
+	# Test the docker-opts script
 	cd dist; ./mk-docker-opts_tests.sh
 
-e2e-test: dist/flanneld-$(TAG)-$(ARCH).docker
-	cd dist; ./functional-test.sh $(REGISTRY):$(TAG)-$(ARCH)
+	# Run the functional tests
+	make e2e-test
+
+e2e-test: bash_unit dist/flanneld-$(TAG)-$(ARCH).docker
+	./bash_unit dist/functional-test.sh
+	./bash_unit dist/functional-test-k8s.sh
 
 cover:
 	# A single package must be given - e.g. 'PACKAGES=pkg/ip make cover'
@@ -74,6 +81,10 @@ update-glide:
 	# go get -d -u github.com/sgotti/glide-vc
 	glide vc --only-code --no-tests
 
+bash_unit:
+	wget https://raw.githubusercontent.com/pgrange/bash_unit/v1.6.0/bash_unit
+	chmod +x bash_unit
+
 clean:
 	rm -f dist/flanneld*
 	rm -f dist/*.aci
@@ -161,7 +172,7 @@ tar.gz:
 	tar -tvf dist/flannel-$(TAG)-linux-s390x.tar.gz
 
 ## Make a release after creating a tag
-release: tar.gz
+release: tar.gz release-tests
 	ARCH=amd64 make dist/flanneld-$(TAG)-amd64.aci
 	ARCH=arm make dist/flanneld-$(TAG)-arm.aci
 	ARCH=arm64 make dist/flanneld-$(TAG)-arm64.aci
@@ -171,6 +182,23 @@ release: tar.gz
 	@echo "Add all *.aci, flanneld-* and *.tar.gz files from dist/ to the Github release"
 	@echo "Use make docker-push-all to push the images to a registry"
 
+release-tests: bash_unit
+	# Run the functional tests with different etcd versions.
+	ETCD_IMG="quay.io/coreos/etcd:latest"  ./bash_unit dist/functional-test.sh
+	ETCD_IMG="quay.io/coreos/etcd:v3.2.7"  ./bash_unit dist/functional-test.sh
+	ETCD_IMG="quay.io/coreos/etcd:v3.1.10" ./bash_unit dist/functional-test.sh
+	ETCD_IMG="quay.io/coreos/etcd:v3.0.17" ./bash_unit dist/functional-test.sh
+	# Etcd v2 docker image format is different. Override the etcd binary location so it works.
+	ETCD_IMG="quay.io/coreos/etcd:v2.3.8"  ETCD_LOCATION=" " ./bash_unit dist/functional-test.sh
+
+	# Run the functional tests with different k8s versions. Currently these are the latest point releases.
+	# This list should be updated during the release process.
+	K8S_VERSION="1.7.6"  ./bash_unit dist/functional-test-k8s.sh
+	K8S_VERSION="1.6.10" ./bash_unit dist/functional-test-k8s.sh
+	# K8S_VERSION="1.5.7"  ./bash_unit dist/functional-test-k8s.sh   #kube-flannel.yml is incompatible
+	# K8S_VERSION="1.4.12" ./bash_unit dist/functional-test-k8s.sh   #kube-flannel.yml is incompatible
+	# K8S_VERSION="1.3.10" ./bash_unit dist/functional-test-k8s.sh   #kube-flannel.yml is incompatible
+
 docker-push-all:
 	ARCH=amd64 make docker-push
 	ARCH=arm make docker-push

+ 121 - 0
dist/functional-test-k8s.sh

@@ -0,0 +1,121 @@
+#!/bin/bash
+ETCD_IMG="${ETCD_IMG:-quay.io/coreos/etcd:v3.2.7}"
+ETCD_LOCATION="${ETCD_LOCATION:-etcd}"
+FLANNEL_NET="${FLANNEL_NET:-10.10.0.0/16}"
+TAG=`git describe --tags --dirty`
+FLANNEL_DOCKER_IMAGE="${FLANNEL_DOCKER_IMAGE:-quay.io/coreos/flannel:$TAG}"
+K8S_VERSION="${K8S_VERSION:-1.7.6}"
+
+docker_ip=$(ip -o -f inet addr show docker0 | grep -Po 'inet \K[\d.]+')
+etcd_endpt="http://$docker_ip:2379"
+k8s_endpt="http://$docker_ip:8080"
+
+setup_suite() {
+    # Run etcd, killing any existing one that was running
+
+    # Start etcd
+    docker rm -f flannel-e2e-test-etcd >/dev/null 2>/dev/null
+    docker run --name=flannel-e2e-test-etcd -d -p 2379:2379 $ETCD_IMG etcd --listen-client-urls http://0.0.0.0:2379 --advertise-client-urls $etcd_endpt >/dev/null
+    sleep 1
+
+    # Start a kubernetes API server
+    docker rm -f flannel-e2e-k8s-apiserver >/dev/null 2>/dev/null
+    docker run -d --net=host --name flannel-e2e-k8s-apiserver gcr.io/google_containers/hyperkube-amd64:v$K8S_VERSION \
+      /hyperkube apiserver --etcd-servers=$etcd_endpt \
+      --service-cluster-ip-range=10.101.0.0/16 --insecure-bind-address=0.0.0.0 --allow-privileged >/dev/null
+    sleep 1
+
+    while ! cat <<EOF |  docker run -i --rm --net=host gcr.io/google_containers/hyperkube-amd64:v$K8S_VERSION /hyperkube kubectl create -f - >/dev/null 2>/dev/null
+apiVersion: v1
+kind: Node
+metadata:
+  name: flannel1
+  annotations:
+    dummy: value
+spec:
+  podCIDR: 10.10.1.0/24
+EOF
+do
+    sleep 1
+done
+
+cat <<EOF |  docker run -i --rm --net=host gcr.io/google_containers/hyperkube-amd64:v$K8S_VERSION /hyperkube kubectl create -f - >/dev/null 2>/dev/null
+apiVersion: v1
+kind: Node
+metadata:
+  name: flannel2
+  annotations:
+    dummy: value
+spec:
+  podCIDR: 10.10.2.0/24
+EOF
+}
+
+teardown_suite() {
+    # Teardown the etcd server
+    docker rm -f flannel-e2e-test-etcd >/dev/null
+    docker rm -f flannel-e2e-k8s-apiserver >/dev/null
+}
+
+teardown() {
+	docker rm -f flannel-e2e-test-flannel1 >/dev/null 2>/dev/null
+	docker rm -f flannel-e2e-test-flannel2 >/dev/null 2>/dev/null
+}
+
+start_flannel() {
+    local backend=$1
+
+	flannel_conf="{ \"Network\": \"$FLANNEL_NET\", \"Backend\": { \"Type\": \"${backend}\" } }"
+    for host_num in 1 2; do
+       docker rm -f flannel-e2e-test-flannel$host_num >/dev/null 2>/dev/null
+       docker run -e NODE_NAME=flannel$host_num --privileged --name flannel-e2e-test-flannel$host_num -tid --entrypoint /bin/sh $FLANNEL_DOCKER_IMAGE >/dev/null
+       docker exec flannel-e2e-test-flannel$host_num /bin/sh -c 'mkdir -p /etc/kube-flannel'
+       echo $flannel_conf | docker exec -i flannel-e2e-test-flannel$host_num /bin/sh -c 'cat > /etc/kube-flannel/net-conf.json'
+       docker exec -d flannel-e2e-test-flannel$host_num /opt/bin/flanneld --kube-subnet-mgr --kube-api-url $k8s_endpt
+    done
+}
+
+create_ping_dest() {
+    # add a dummy interface with $FLANNEL_SUBNET so we have a known working IP to ping
+    for host_num in 1 2; do
+       while ! docker exec flannel-e2e-test-flannel$host_num ls /run/flannel/subnet.env >/dev/null 2>&1; do
+         sleep 0.1
+       done
+
+       # Use declare to allow the host_num variable to be part of the ping_dest variable name. -g is needed to make it global
+       declare -g ping_dest$host_num=$(docker "exec" --privileged flannel-e2e-test-flannel$host_num /bin/sh -c '\
+		source /run/flannel/subnet.env && \
+		ip link add name dummy0 type dummy && \
+		ip addr add $FLANNEL_SUBNET dev dummy0 && ip link set dummy0 up && \
+		echo $FLANNEL_SUBNET | cut -f 1 -d "/" ')
+    done
+}
+
+test_vxlan() {
+    start_flannel vxlan
+    create_ping_dest # creates ping_dest1 and ping_dest2 variables
+    pings
+}
+
+test_udp() {
+    start_flannel udp
+    create_ping_dest # creates ping_dest1 and ping_dest2 variables
+    pings
+}
+
+test_host-gw() {
+    start_flannel host-gw
+    create_ping_dest # creates ping_dest1 and ping_dest2 variables
+    pings
+}
+
+pings() {
+    # ping in both directions
+	assert "docker exec -it --privileged flannel-e2e-test-flannel1 /bin/ping -c 5 $ping_dest2" "Host 1 cannot ping host 2"
+	assert "docker exec -it --privileged flannel-e2e-test-flannel2 /bin/ping -c 5 $ping_dest1" "Host 2 cannot ping host 1"
+}
+
+test_manifest() {
+    # This just tests that the API server accepts the manifest, not that it actually acts on it correctly.
+    assert "cat ../Documentation/kube-flannel.yml |  docker run -i --rm --net=host gcr.io/google_containers/hyperkube-amd64:v$K8S_VERSION /hyperkube kubectl create -f -"
+}

+ 107 - 186
dist/functional-test.sh

@@ -1,44 +1,42 @@
 #!/bin/bash
-# Uncomment to see what commands are being executed
-#set -x
-
-ETCD_IMG="quay.io/coreos/etcd:v3.0.3"
-FLANNEL_NET="10.10.0.0/16"
-
-usage() {
-	echo "$0 FLANNEL-DOCKER-IMAGE"
-	echo
-	echo "Run end-to-end tests by bringing up two flannel instances"
-	echo "and having them ping each other"
-	echo
-	echo "NOTE: this script depends on Docker 1.9.0 or higher"
-	exit 1
+ETCD_IMG="${ETCD_IMG:-quay.io/coreos/etcd:v3.2.7}"
+ETCD_LOCATION="${ETCD_LOCATION:-etcd}"
+FLANNEL_NET="${FLANNEL_NET:-10.10.0.0/16}"
+TAG=`git describe --tags --dirty`
+FLANNEL_DOCKER_IMAGE="${FLANNEL_DOCKER_IMAGE:-quay.io/coreos/flannel:$TAG}"
+
+setup_suite() {
+    # Run etcd, killing any existing one that was running
+    docker_ip=$(ip -o -f inet addr show docker0 | grep -Po 'inet \K[\d.]+')
+    etcd_endpt="http://$docker_ip:2379"
+
+    # Start etcd
+    docker rm -f flannel-e2e-test-etcd >/dev/null 2>/dev/null
+    docker run --name=flannel-e2e-test-etcd -d -p 2379:2379 $ETCD_IMG $ETCD_LOCATION --listen-client-urls http://0.0.0.0:2379 --advertise-client-urls $etcd_endpt >/dev/null
 }
 
-version_check() {
-	required=$1
-	actual=$2
-	err_prefix=$3
+teardown_suite() {
+    # Teardown the etcd server
+    docker rm -f flannel-e2e-test-etcd >/dev/null
+}
 
-	req_maj=$(echo $required | cut -d . -f 1)
-	req_min=$(echo $required | cut -d . -f 2)
-	act_maj=$(echo $actual | cut -d . -f 1)
-	act_min=$(echo $actual | cut -d . -f 2)
+setup() {
+	# rm any old flannel container that maybe running, ignore error as it might not exist
+	docker rm -f flannel-e2e-test-flannel1 >/dev/null 2>/dev/null
+	assert "docker run --name=flannel-e2e-test-flannel1 -d --privileged $FLANNEL_DOCKER_IMAGE --etcd-endpoints=$etcd_endpt -v 10 >/dev/null"
 
-	if [ $act_maj -lt $req_maj ] || ( [ $act_maj -eq $req_maj ] && [ $act_min -lt $req_min ] ); then
-		echo "$err_prefix: required=$required, found=$actual"
-		exit 1
-	fi
+	# rm any old flannel container that maybe running, ignore error as it might not exist
+	docker rm -f flannel-e2e-test-flannel2 >/dev/null 2>/dev/null
+	assert "docker run --name=flannel-e2e-test-flannel2 -d --privileged $FLANNEL_DOCKER_IMAGE --etcd-endpoints=$etcd_endpt -v 10 >/dev/null"
 }
 
-docker_version_check() {
-	ver=$(docker version -f '{{.Server.Version}}')
-	version_check "1.9" $ver
+teardown() {
+	docker rm -f flannel-e2e-test-flannel1 >/dev/null 2>/dev/null
+	docker rm -f flannel-e2e-test-flannel2 >/dev/null 2>/dev/null
 }
 
-run_test() {
-	backend=$1
-
+write_config_etcd() {
+    local backend=$1
     if [ -e "$backend" ]; then
         echo "Reading custom conf from $backend"
         flannel_conf=`cat "$backend"`
@@ -46,111 +44,112 @@ run_test() {
 	    flannel_conf="{ \"Network\": \"$FLANNEL_NET\", \"Backend\": { \"Type\": \"${backend}\" } }"
     fi
 
-	# etcd might take a bit to come up
-	while ! docker run --rm -it $ETCD_IMG etcdctl --endpoints=$etcd_endpt set /coreos.com/network/config "$flannel_conf"
+	# etcd might take a bit to come up - use a known etcd version so we know we have etcdctl available
+	while ! docker run --rm -it quay.io/coreos/etcd:v3.2.7 etcdctl --endpoints=$etcd_endpt set /coreos.com/network/config "$flannel_conf" >/dev/null
 	do
-		sleep 1
+		sleep 0.1
 	done
+}
 
-	echo flannel config written
-
-	# rm any old flannel container that maybe running, ignore error as it might not exist
-	docker rm -f flannel-e2e-test-flannel1 2>/dev/null
-	docker run --name=flannel-e2e-test-flannel1 -d --privileged $flannel_img --etcd-endpoints=$etcd_endpt -v 10
-	if [ $? -ne 0 ]; then
-		exit 1
-	fi
-
-	# rm any old flannel container that maybe running, ignore error as it might not exist
-	docker rm -f flannel-e2e-test-flannel2 2>/dev/null
-	docker run --name=flannel-e2e-test-flannel2 -d --privileged $flannel_img --etcd-endpoints=$etcd_endpt -v 10
-	if [ $? -ne 0 ]; then
-		exit 1
-	fi
-
-	echo flannels running
-
-	# wait an arbitrary amount to have flannels come up
-	sleep 5
+create_ping_dest() {
+    # add a dummy interface with $FLANNEL_SUBNET so we have a known working IP to ping
+    for host_num in 1 2; do
+       while ! docker exec flannel-e2e-test-flannel$host_num ls /run/flannel/subnet.env >/dev/null 2>&1; do
+         sleep 0.1
+       done
 
-	# add a dummy interface with $FLANNEL_SUBNET so we have a known working IP to ping
-	ping_dest=$(docker "exec" --privileged flannel-e2e-test-flannel1 /bin/sh -c '\
-		source /run/flannel/subnet.env && 
+       # Use declare to allow the host_num variable to be part of the ping_dest variable name. -g is needed to make it global
+       declare -g ping_dest$host_num=$(docker "exec" --privileged flannel-e2e-test-flannel$host_num /bin/sh -c '\
+		source /run/flannel/subnet.env && \
 		ip link add name dummy0 type dummy && \
-		ip addr add $FLANNEL_SUBNET dev dummy0 && \
-	       	ip link set dummy0 up && \
+		ip addr add $FLANNEL_SUBNET dev dummy0 && ip link set dummy0 up && \
 		echo $FLANNEL_SUBNET | cut -f 1 -d "/" ')
+    done
+}
 
-	docker exec -it --privileged flannel-e2e-test-flannel2 /bin/ping -c 5 $ping_dest
-	exit_code=$?
-
-	# Uncomment to debug (you can nsenter)
-	#if [ $exit_code -eq "1" ]; then
-	#	sleep 10000
-	#fi
+test_vxlan_ping() {
+    write_config_etcd vxlan
+    create_ping_dest # creates ping_dest1 and ping_dest2 variables
+    pings
+}
 
-	echo "Test for backend=$backend: exit=$exit_code"
+test_udp_ping() {
+    write_config_etcd udp
+    create_ping_dest # creates ping_dest1 and ping_dest2 variables
+    pings
+}
 
-	# Perf test - run iperf server on flannel1 and client on flannel2
-	if [ $exit_code -eq 0 ]; then
-        docker rm -f flannel-e2e-test-flannel1-iperf 2>/dev/null
-        docker run -d --name flannel-e2e-test-flannel1-iperf --net=container:flannel-e2e-test-flannel1 mlabbe/iperf3
-        docker run --rm --net=container:flannel-e2e-test-flannel2 mlabbe/iperf3 -c $ping_dest
-    fi
+test_host-gw_ping() {
+    write_config_etcd host-gw
+    create_ping_dest # creates ping_dest1 and ping_dest2 variables
+    pings
+}
 
-	docker stop flannel-e2e-test-flannel1 flannel-e2e-test-flannel2 >/dev/null
+pings() {
+    # ping in both directions
+	assert "docker exec -it --privileged flannel-e2e-test-flannel1 /bin/ping -c 3 $ping_dest2" "Host 1 cannot ping host 2"
+	assert "docker exec -it --privileged flannel-e2e-test-flannel2 /bin/ping -c 3 $ping_dest1" "Host 2 cannot ping host 1"
+}
 
-	if [ $exit_code -ne 0 ]; then
-		# Print flannel logs to help debug
-		echo "------ flannel server (one being pinged) log -------"
-		docker logs flannel-e2e-test-flannel1
-		echo
+# These perf tests don't actually assert on anything
+test_host-gw-perf() {
+    write_config_etcd host-gw
+	create_ping_dest
+	perf
+}
 
-		echo "------ flannel client (one doing the ping) log -------"
-		docker logs flannel-e2e-test-flannel2
-		echo
-	fi
+test_vxlan_perf() {
+    write_config_etcd vxlan
+	create_ping_dest
+    perf
+}
 
-	docker rm flannel-e2e-test-flannel1 flannel-e2e-test-flannel2 >/dev/null
+test_udp_perf() {
+    write_config_etcd udp
+	create_ping_dest
+    perf
+}
 
-	return $exit_code
+perf() {
+    # Perf test - run iperf server on flannel1 and client on flannel2
+    docker rm -f flannel-e2e-test-flannel1-iperf 2>/dev/null
+    docker run -d --name flannel-e2e-test-flannel1-iperf --net=container:flannel-e2e-test-flannel1 mlabbe/iperf3
+    docker run --rm --net=container:flannel-e2e-test-flannel2 mlabbe/iperf3 -c $ping_dest1
 }
 
-multi_test() {
+test_multi() {
 	flannel_conf_vxlan='{"Network": "10.11.0.0/16", "Backend": {"Type": "vxlan"}}'
 	flannel_conf_host_gw='{"Network": "10.12.0.0/16", "Backend": {"Type": "host-gw"}}'
 
-	# etcd might take a bit to come up
-	while ! docker run --rm -it $ETCD_IMG etcdctl --endpoints=$etcd_endpt set /vxlan/network/config "$flannel_conf_vxlan"
+	while ! docker run --rm -it $ETCD_IMG etcdctl --endpoints=$etcd_endpt set /vxlan/network/config "$flannel_conf_vxlan" >/dev/null
 	do
-		sleep 1
+		sleep 0.1
 	done
 
-	while ! docker run --rm -it $ETCD_IMG etcdctl --endpoints=$etcd_endpt set /hostgw/network/config "$flannel_conf_host_gw"
+	while ! docker run --rm -it $ETCD_IMG etcdctl --endpoints=$etcd_endpt set /hostgw/network/config "$flannel_conf_host_gw" >/dev/null
 	do
-		sleep 1
+		sleep 0.1
 	done
 
-	echo flannel config written
-
 	for host in 1 2; do
-    	echo "=== Creating Host: $host ==============================================="
-
-        # rm any old flannel container that maybe running, ignore error as it might not exist
-        docker rm -f flannel-host$host 2>/dev/null
+        # rm any old flannel container, ignore error as it might not exist
+        docker rm -f flannel-host$host 2>/dev/null >/dev/null
 
         # Start the hosts
-        docker run --name=flannel-host$host -d -it --privileged --entrypoint /bin/sh $flannel_img
+        docker run --name=flannel-host$host -d -it --privileged --entrypoint /bin/sh $FLANNEL_DOCKER_IMAGE >/dev/null
 
         # Start two flanneld instances
         docker exec -d flannel-host$host sh -c "/opt/bin/flanneld -v 10 -subnet-file /vxlan.env -etcd-prefix=/vxlan/network --etcd-endpoints=$etcd_endpt 2>vxlan.log"
         docker exec -d flannel-host$host sh -c "/opt/bin/flanneld -v 10 -subnet-file /hostgw.env -etcd-prefix=/hostgw/network --etcd-endpoints=$etcd_endpt 2>hostgw.log"
     done
 
-	echo flannels running
-
-	# wait an arbitrary amount to have flannels come up
-	sleep 1
+    for host in 1 2; do
+        for backend_type in vxlan hostgw; do
+            while ! docker exec flannel-host$host ls /$backend_type.env  >/dev/null 2>&1; do
+              sleep 0.1
+            done
+        done
+    done
 
 	# add dummy interface on host1 only so we have a known working IP to ping then ping it from host2
 	vxlan_ping_dest=$(docker exec flannel-host1 /bin/sh -c '\
@@ -169,86 +168,8 @@ multi_test() {
 
     # Send some pings from host2. Make sure we can send traffic over vxlan or directly.
     # If a particular (wrong) interface is forced then pings should fail
-	docker exec -it flannel-host2 ping -c 3 $hostgw_ping_dest && \
-	docker exec -it flannel-host2 ping -c 3 $vxlan_ping_dest && \
-	! docker exec -it flannel-host2 ping -W 1 -c 1 -I flannel.1 $hostgw_ping_dest && \
-	! docker exec -it flannel-host2 ping -W 1 -c 1 -I eth0 $vxlan_ping_dest
-	exit_code=$?
-
-	# Uncomment to debug (you can nsenter)
-	#if [ $exit_code -eq "1" ]; then
-	#	sleep 10000
-	#fi
-
-	echo "Test for multi-backend: exit=$exit_code"
-
-
-	if [ $exit_code -ne 0 ]; then
-		# Print flannel logs to help debug
-		echo "------ flannel server (one being pinged) log -------"
-		docker exec flannel-host1 sh -c 'cat *.log'
-		echo
-
-		echo "------ flannel client (one doing the ping) log -------"
-		docker exec flannel-host2 sh -c 'cat *.log'
-		echo
-	fi
-
-	docker rm -f flannel-host1 flannel-host2 >/dev/null
-
-	return $exit_code
-}
-
-if [ $# -ne 1 ]; then
-	usage
-fi
-
-flannel_img=$1
-
-# Check that docker is new enough
-docker_version_check
-
-docker0=$(ip -o -f inet addr show docker0 | grep -Po 'inet \K[\d.]+')
-etcd_endpt="http://$docker0:2379"
-
-docker rm -f flannel-e2e-test-etcd 2>/dev/null
-docker run --name=flannel-e2e-test-etcd -d -p 2379:2379 $ETCD_IMG etcd --listen-client-urls http://0.0.0.0:2379 --advertise-client-urls $etcd_endpt
-if [ $? -ne 0 ]; then
-	exit 1
-fi
-
-echo etcd launched
-
-global_exit_code=0
-
-backends=${BACKEND:-"udp vxlan host-gw"}
-for backend in $backends; do
-	echo
-	echo "=== BACKEND: $backend ==============================================="
-
-	if ! run_test $backend; then
-		global_exit_code=1
-	fi
-done
-
-echo "=== MULTI BACKEND ==============================================="
-if ! multi_test; then
-    global_exit_code=1
-fi
-
-docker stop flannel-e2e-test-etcd >/dev/null
-
-if [ $global_exit_code -eq 0 ]; then
-	echo
-	echo "ALL TESTS PASSED"
-else
-	# Print etcd logs to help debug
-	echo "------ etcd log -------"
-	docker logs $etcd
-	echo
-	echo "TEST(S) FAILED"
-fi
-
-docker rm flannel-e2e-test-etcd 2>/dev/null
-
-exit $global_exit_code
+	assert "docker exec -it flannel-host2 ping -c 3 $hostgw_ping_dest"
+	assert "docker exec -it flannel-host2 ping -c 3 $vxlan_ping_dest"
+	assert_fails "docker exec -it flannel-host2 ping -W 1 -c 1 -I flannel.1 $hostgw_ping_dest"
+	assert_fails "docker exec -it flannel-host2 ping -W 1 -c 1 -I eth0 $vxlan_ping_dest"
+}