functional-test.sh 7.4 KB

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