forked from flannel-io/flannel
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathfunctional-test.sh
executable file
·186 lines (156 loc) · 6.72 KB
/
functional-test.sh
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
#!/bin/bash
ARCH="${ARCH:-amd64}"
ETCD_IMG="${ETCD_IMG:-quay.io/coreos/etcd:v3.2.7}"
# etcd might take a bit to come up - use a known etcd version so we know we have etcdctl available
ETCDCTL_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}"
# Set the proper imagename according to architecture
if [[ ${ARCH} == "ppc64le" ]]; then
ETCD_IMG+="-ppc64le"
ETCDCTL_IMG+="-ppc64le"
elif [[ ${ARCH} == "arm64" ]]; then
ETCD_IMG+="-arm64"
ETCDCTL_IMG+="-arm64"
fi
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
}
teardown_suite() {
# Teardown the etcd server
docker rm -f flannel-e2e-test-etcd >/dev/null
}
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"
# 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"
}
teardown() {
docker rm -f flannel-e2e-test-flannel1 flannel-e2e-test-flannel2 flannel-e2e-test-flannel1-iperf flannel-host1 flannel-host2 > /dev/null 2>&1
}
write_config_etcd() {
local backend=$1
if [ -e "$backend" ]; then
echo "Reading custom conf from $backend"
flannel_conf=`cat "$backend"`
else
flannel_conf="{ \"Network\": \"$FLANNEL_NET\", \"Backend\": { \"Type\": \"${backend}\" } }"
fi
while ! docker run --rm $ETCDCTL_IMG etcdctl --endpoints=$etcd_endpt set /coreos.com/network/config "$flannel_conf" >/dev/null
do
sleep 0.1
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_ping() {
write_config_etcd vxlan
create_ping_dest # creates ping_dest1 and ping_dest2 variables
pings
}
test_udp_ping() {
write_config_etcd udp
create_ping_dest # creates ping_dest1 and ping_dest2 variables
pings
}
test_host-gw_ping() {
write_config_etcd host-gw
create_ping_dest # creates ping_dest1 and ping_dest2 variables
pings
}
pings() {
# ping in both directions
assert "docker exec --privileged flannel-e2e-test-flannel1 /bin/ping -c 3 $ping_dest2" "Host 1 cannot ping host 2"
assert "docker exec --privileged flannel-e2e-test-flannel2 /bin/ping -c 3 $ping_dest1" "Host 2 cannot ping host 1"
}
# These perf tests don't actually assert on anything
test_host-gw-perf() {
write_config_etcd host-gw
create_ping_dest
perf
}
test_vxlan_perf() {
write_config_etcd vxlan
create_ping_dest
perf
}
test_udp_perf() {
write_config_etcd udp
create_ping_dest
perf
}
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 iperf3:latest
docker run --rm --net=container:flannel-e2e-test-flannel2 iperf3:latest -c $ping_dest1
}
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"}}'
while ! docker run --rm $ETCD_IMG etcdctl --endpoints=$etcd_endpt set /vxlan/network/config "$flannel_conf_vxlan" >/dev/null
do
sleep 0.1
done
while ! docker run --rm $ETCD_IMG etcdctl --endpoints=$etcd_endpt set /hostgw/network/config "$flannel_conf_host_gw" >/dev/null
do
sleep 0.1
done
for host in 1 2; do
# 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 -id --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
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 '\
source /vxlan.env &&
ip link add name dummy_vxlan type dummy && \
ip addr add $FLANNEL_SUBNET dev dummy_vxlan && \
ip link set dummy_vxlan up && \
echo $FLANNEL_SUBNET | cut -f 1 -d "/" ')
hostgw_ping_dest=$(docker exec flannel-host1 /bin/sh -c '\
source /hostgw.env &&
ip link add name dummy_hostgw type dummy && \
ip addr add $FLANNEL_SUBNET dev dummy_hostgw && \
ip link set dummy_hostgw up && \
echo $FLANNEL_SUBNET | cut -f 1 -d "/" ')
# 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
assert "docker exec flannel-host2 ping -c 3 $hostgw_ping_dest"
assert "docker exec flannel-host2 ping -c 3 $vxlan_ping_dest"
assert_fails "docker exec flannel-host2 ping -W 1 -c 1 -I flannel.1 $hostgw_ping_dest"
assert_fails "docker exec flannel-host2 ping -W 1 -c 1 -I eth0 $vxlan_ping_dest"
}