functional-test.sh 7.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249
  1. #!/bin/bash
  2. # Uncomment to see what commands are being executed
  3. #set -x
  4. ETCD_IMG="quay.io/coreos/etcd:v3.0.3"
  5. FLANNEL_NET="10.10.0.0/16"
  6. usage() {
  7. echo "$0 FLANNEL-DOCKER-IMAGE"
  8. echo
  9. echo "Run end-to-end tests by bringing up two flannel instances"
  10. echo "and having them ping each other"
  11. echo
  12. echo "NOTE: this script depends on Docker 1.9.0 or higher"
  13. exit 1
  14. }
  15. version_check() {
  16. required=$1
  17. actual=$2
  18. err_prefix=$3
  19. req_maj=$(echo $required | cut -d . -f 1)
  20. req_min=$(echo $required | cut -d . -f 2)
  21. act_maj=$(echo $actual | cut -d . -f 1)
  22. act_min=$(echo $actual | cut -d . -f 2)
  23. if [ $act_maj -lt $req_maj ] || ( [ $act_maj -eq $req_maj ] && [ $act_min -lt $req_min ] ); then
  24. echo "$err_prefix: required=$required, found=$actual"
  25. exit 1
  26. fi
  27. }
  28. docker_version_check() {
  29. ver=$(docker version -f '{{.Server.Version}}')
  30. version_check "1.9" $ver
  31. }
  32. run_test() {
  33. backend=$1
  34. flannel_conf="{ \"Network\": \"$FLANNEL_NET\", \"Backend\": { \"Type\": \"${backend}\" } }"
  35. # etcd might take a bit to come up
  36. while ! docker run --rm -it $ETCD_IMG etcdctl --endpoints=$etcd_endpt set /coreos.com/network/config "$flannel_conf"
  37. do
  38. sleep 1
  39. done
  40. echo flannel config written
  41. # rm any old flannel container that maybe running, ignore error as it might not exist
  42. docker rm -f flannel-e2e-test-flannel1 2>/dev/null
  43. docker run --name=flannel-e2e-test-flannel1 -d --privileged $flannel_img --etcd-endpoints=$etcd_endpt
  44. if [ $? -ne 0 ]; then
  45. exit 1
  46. fi
  47. # rm any old flannel container that maybe running, ignore error as it might not exist
  48. docker rm -f flannel-e2e-test-flannel2 2>/dev/null
  49. docker run --name=flannel-e2e-test-flannel2 -d --privileged $flannel_img --etcd-endpoints=$etcd_endpt
  50. if [ $? -ne 0 ]; then
  51. exit 1
  52. fi
  53. echo flannels running
  54. # wait an arbitrary amount to have flannels come up
  55. sleep 5
  56. # add a dummy interface with $FLANNEL_SUBNET so we have a known working IP to ping
  57. ping_dest=$(docker "exec" --privileged flannel-e2e-test-flannel1 /bin/sh -c '\
  58. source /run/flannel/subnet.env &&
  59. ip link add name dummy0 type dummy && \
  60. ip addr add $FLANNEL_SUBNET dev dummy0 && \
  61. ip link set dummy0 up && \
  62. echo $FLANNEL_SUBNET | cut -f 1 -d "/" ')
  63. docker exec -it --privileged flannel-e2e-test-flannel2 /bin/ping -c 5 $ping_dest
  64. exit_code=$?
  65. # Uncomment to debug (you can nsenter)
  66. #if [ $exit_code -eq "1" ]; then
  67. # sleep 10000
  68. #fi
  69. echo "Test for backend=$backend: exit=$exit_code"
  70. # Perf test - run iperf server on flannel1 and client on flannel2
  71. if [ $exit_code -eq 0 ]; then
  72. docker rm -f flannel-e2e-test-flannel1-iperf 2>/dev/null
  73. docker run -d --name flannel-e2e-test-flannel1-iperf --net=container:flannel-e2e-test-flannel1 mlabbe/iperf3
  74. docker run --rm --net=container:flannel-e2e-test-flannel2 mlabbe/iperf3 -c $ping_dest
  75. fi
  76. docker stop flannel-e2e-test-flannel1 flannel-e2e-test-flannel2 >/dev/null
  77. if [ $exit_code -ne 0 ]; then
  78. # Print flannel logs to help debug
  79. echo "------ flannel server (one being pinged) log -------"
  80. docker logs flannel-e2e-test-flannel1
  81. echo
  82. echo "------ flannel client (one doing the ping) log -------"
  83. docker logs flannel-e2e-test-flannel2
  84. echo
  85. fi
  86. docker rm flannel-e2e-test-flannel1 flannel-e2e-test-flannel2 >/dev/null
  87. return $exit_code
  88. }
  89. multi_test() {
  90. flannel_conf_vxlan='{"Network": "10.11.0.0/16", "Backend": {"Type": "vxlan"}}'
  91. flannel_conf_host_gw='{"Network": "10.12.0.0/16", "Backend": {"Type": "host-gw"}}'
  92. # etcd might take a bit to come up
  93. while ! docker run --rm -it $ETCD_IMG etcdctl --endpoints=$etcd_endpt set /vxlan/network/config "$flannel_conf_vxlan"
  94. do
  95. sleep 1
  96. done
  97. while ! docker run --rm -it $ETCD_IMG etcdctl --endpoints=$etcd_endpt set /hostgw/network/config "$flannel_conf_host_gw"
  98. do
  99. sleep 1
  100. done
  101. echo flannel config written
  102. for host in 1 2; do
  103. echo "=== Creating Host: $host ==============================================="
  104. # rm any old flannel container that maybe running, ignore error as it might not exist
  105. docker rm -f flannel-host$host 2>/dev/null
  106. # Start the hosts
  107. docker run --name=flannel-host$host -d -it --privileged --entrypoint /bin/sh $flannel_img
  108. # Start two flanneld instances
  109. docker exec -d flannel-host$host sh -c "/opt/bin/flanneld -subnet-file /vxlan.env -etcd-prefix=/vxlan/network --etcd-endpoints=$etcd_endpt 2>vxlan.log"
  110. docker exec -d flannel-host$host sh -c "/opt/bin/flanneld -subnet-file /hostgw.env -etcd-prefix=/hostgw/network --etcd-endpoints=$etcd_endpt 2>hostgw.log"
  111. done
  112. echo flannels running
  113. # wait an arbitrary amount to have flannels come up
  114. sleep 1
  115. # add dummy interface on host1 only so we have a known working IP to ping then ping it from host2
  116. vxlan_ping_dest=$(docker exec flannel-host1 /bin/sh -c '\
  117. source /vxlan.env &&
  118. ip link add name dummy_vxlan type dummy && \
  119. ip addr add $FLANNEL_SUBNET dev dummy_vxlan && \
  120. ip link set dummy_vxlan up && \
  121. echo $FLANNEL_SUBNET | cut -f 1 -d "/" ')
  122. hostgw_ping_dest=$(docker exec flannel-host1 /bin/sh -c '\
  123. source /hostgw.env &&
  124. ip link add name dummy_hostgw type dummy && \
  125. ip addr add $FLANNEL_SUBNET dev dummy_hostgw && \
  126. ip link set dummy_hostgw up && \
  127. echo $FLANNEL_SUBNET | cut -f 1 -d "/" ')
  128. # Send some pings from host2. Make sure we can send traffic over vxlan or directly.
  129. # If a particular (wrong) interface is forced then pings should fail
  130. docker exec -it flannel-host2 ping -c 3 $hostgw_ping_dest && \
  131. docker exec -it flannel-host2 ping -c 3 $vxlan_ping_dest && \
  132. ! docker exec -it flannel-host2 ping -W 1 -c 1 -I flannel.1 $hostgw_ping_dest && \
  133. ! docker exec -it flannel-host2 ping -W 1 -c 1 -I eth0 $vxlan_ping_dest
  134. exit_code=$?
  135. # Uncomment to debug (you can nsenter)
  136. #if [ $exit_code -eq "1" ]; then
  137. # sleep 10000
  138. #fi
  139. echo "Test for multi-backend: exit=$exit_code"
  140. if [ $exit_code -ne 0 ]; then
  141. # Print flannel logs to help debug
  142. echo "------ flannel server (one being pinged) log -------"
  143. docker exec flannel-host1 sh -c 'cat *.log'
  144. echo
  145. echo "------ flannel client (one doing the ping) log -------"
  146. docker exec flannel-host2 sh -c 'cat *.log'
  147. echo
  148. fi
  149. docker rm -f flannel-host1 flannel-host2 >/dev/null
  150. return $exit_code
  151. }
  152. if [ $# -ne 1 ]; then
  153. usage
  154. fi
  155. flannel_img=$1
  156. # Check that docker is new enough
  157. docker_version_check
  158. docker0=$(ip -o -f inet addr show docker0 | grep -Po 'inet \K[\d.]+')
  159. etcd_endpt="http://$docker0:2379"
  160. docker rm -f flannel-e2e-test-etcd 2>/dev/null
  161. 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
  162. if [ $? -ne 0 ]; then
  163. exit 1
  164. fi
  165. echo etcd launched
  166. global_exit_code=0
  167. backends=${BACKEND:-"udp vxlan host-gw"}
  168. for backend in $backends; do
  169. echo
  170. echo "=== BACKEND: $backend ==============================================="
  171. if ! run_test $backend; then
  172. global_exit_code=1
  173. fi
  174. done
  175. echo "=== MULTI BACKEND ==============================================="
  176. if ! multi_test; then
  177. global_exit_code=1
  178. fi
  179. docker stop flannel-e2e-test-etcd >/dev/null
  180. if [ $global_exit_code -eq 0 ]; then
  181. echo
  182. echo "ALL TESTS PASSED"
  183. else
  184. # Print etcd logs to help debug
  185. echo "------ etcd log -------"
  186. docker logs $etcd
  187. echo
  188. echo "TEST(S) FAILED"
  189. fi
  190. docker rm flannel-e2e-test-etcd 2>/dev/null
  191. exit $global_exit_code