import-export_unittest.bash 8.77 KB
Newer Older
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
#!/bin/bash
#

# Copyright (C) 2010 Google Inc.
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful, but
# WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
# General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
# 02110-1301, USA.

set -e
set -o pipefail

export PYTHON=${PYTHON:=python}

26
impexpd="$PYTHON daemons/import-export -d"
27
28
29
30

err() {
  echo "$@"
  echo 'Aborting'
31
  show_output
32
33
34
  exit 1
}

35
show_output() {
36
37
38
39
40
  if [[ -s "$gencert_output" ]]; then
    echo
    echo 'Generating certificates:'
    cat $gencert_output
  fi
41
42
43
44
45
46
47
48
49
50
51
52
  if [[ -s "$dst_output" ]]; then
    echo
    echo 'Import output:'
    cat $dst_output
  fi
  if [[ -s "$src_output" ]]; then
    echo
    echo 'Export output:'
    cat $src_output
  fi
}

53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
checkpids() {
  local result=0

  # Unlike combining the "wait" commands using || or &&, this ensures we
  # actually wait for all PIDs.
  for pid in "$@"; do
    if ! wait $pid; then
      result=1
    fi
  done

  return $result
}

get_testpath() {
  echo "${TOP_SRCDIR:-.}/test"
}

get_testfile() {
  echo "$(get_testpath)/data/$1"
}

75
76
77
78
upto() {
  echo "$(date '+%F %T'):" "$@" '...'
}

79
80
81
statusdir=$(mktemp -d)
trap "rm -rf $statusdir" EXIT

82
83
gencert_output=$statusdir/gencert.output

84
src_statusfile=$statusdir/src.status
85
src_output=$statusdir/src.output
86
87
88
src_x509=$statusdir/src.pem

dst_statusfile=$statusdir/dst.status
89
dst_output=$statusdir/dst.output
90
91
92
93
94
95
dst_x509=$statusdir/dst.pem
dst_portfile=$statusdir/dst.port

other_x509=$statusdir/other.pem

testdata=$statusdir/data1
96
largetestdata=$statusdir/data2
97
98
99

cmd_prefix=
cmd_suffix=
100
101
connect_timeout=10
connect_retries=1
102
compress=gzip
103

104
105
upto 'Command line parameter tests'

106
107
108
109
110
111
112
113
114
115
116
117
$impexpd >/dev/null 2>&1 &&
  err "daemon-util succeeded without parameters"

$impexpd foo bar baz moo boo >/dev/null 2>&1 &&
  err "daemon-util succeeded with wrong parameters"

$impexpd $src_statusfile >/dev/null 2>&1 &&
  err "daemon-util succeeded with insufficient parameters"

$impexpd $src_statusfile invalidmode >/dev/null 2>&1 &&
  err "daemon-util succeeded with invalid mode"

118
119
120
$impexpd $src_statusfile import --compression=rot13 >/dev/null 2>&1 &&
  err "daemon-util succeeded with invalid compression"

121
122
cat $(get_testfile proc_drbd8.txt) $(get_testfile cert1.pem) > $testdata

123
124
125
126
127
128
129
130
131
132
133
# Generate about 7.5 MB of test data
{ tmp="$(<$testdata)"
  for (( i=0; i < 100; ++i )); do
    echo "$tmp $tmp $tmp $tmp $tmp $tmp"
  done
  dd if=/dev/zero bs=1024 count=4096 2>/dev/null
  for (( i=0; i < 100; ++i )); do
    echo "$tmp $tmp $tmp $tmp $tmp $tmp"
  done
} > $largetestdata

134
135
136
137
138
impexpd_helper() {
  $PYTHON $(get_testpath)/import-export_unittest-helper "$@"
}

reset_status() {
139
  rm -f $src_statusfile $dst_output $dst_statusfile $dst_output $dst_portfile
140
  rm -f $gencert_output
141
142
143
}

write_data() {
144
145
  local fname=${1:-$testdata}

146
  # Wait for connection to be established
147
148
149
  impexpd_helper $src_statusfile connected

  # And just to be sure, also wait for destination to report as connected
150
151
  impexpd_helper $dst_statusfile connected

152
  cat $fname
153
154
155
156
157
158
159
160
161
}

do_export() {
  # Wait for listening port
  impexpd_helper $dst_statusfile listen-port > $dst_portfile

  local port=$(< $dst_portfile)

  test -n "$port" || err 'Empty port file'
162
  test "$port" != None || err 'Missing port'
163
164
165
166
167
168
169
170
171
172

  do_export_to_port $port
}

do_export_to_port() {
  local port=$1

  $impexpd $src_statusfile export --bind=127.0.0.1 \
    --host=127.0.0.1 --port=$port \
    --key=$src_x509 --cert=$src_x509 --ca=$dst_x509 \
173
174
    --cmd-prefix="$cmd_prefix" --cmd-suffix="$cmd_suffix" \
    --connect-timeout=$connect_timeout \
175
176
    --connect-retries=$connect_retries \
    --compress=$compress
177
178
179
180
181
182
}

do_import() {
  $impexpd $dst_statusfile import --bind=127.0.0.1 \
    --host=127.0.0.1 \
    --key=$dst_x509 --cert=$dst_x509 --ca=$src_x509 \
183
184
    --cmd-prefix="$cmd_prefix" --cmd-suffix="$cmd_suffix" \
    --connect-timeout=$connect_timeout \
185
186
    --connect-retries=$connect_retries \
    --compress=$compress
187
188
}

189
upto 'Generate X509 certificates and keys'
190
191
192
193
194
impexpd_helper $src_x509 gencert 2>$gencert_output & srccertpid=$!
impexpd_helper $dst_x509 gencert 2>$gencert_output & dstcertpid=$!
impexpd_helper $other_x509 gencert 2>$gencert_output & othercertpid=$!
checkpids $srccertpid $dstcertpid $othercertpid || \
  err 'Failed to generate certificates'
195

196
upto 'Normal case'
197
reset_status
198
199
do_import > $statusdir/recv1 2>$dst_output & imppid=$!
{ write_data | do_export; } &>$src_output & exppid=$!
200
201
202
checkpids $exppid $imppid || err 'An error occurred'
cmp $testdata $statusdir/recv1 || err 'Received data does not match input'

203
upto 'Export using wrong CA'
204
reset_status
205
206
207
# Setting lower timeout to not wait for too long
connect_timeout=1 do_import &>$dst_output & imppid=$!
: | dst_x509=$other_x509 do_export &>$src_output & exppid=$!
208
209
checkpids $exppid $imppid && err 'Export did not fail when using wrong CA'

210
upto 'Import using wrong CA'
211
reset_status
212
213
214
# Setting lower timeout to not wait for too long
src_x509=$other_x509 connect_timeout=1 do_import &>$dst_output & imppid=$!
: | do_export &>$src_output & exppid=$!
215
216
checkpids $exppid $imppid && err 'Import did not fail when using wrong CA'

217
upto 'Suffix command on import'
218
reset_status
219
220
cmd_suffix="| cksum > $statusdir/recv2" do_import &>$dst_output & imppid=$!
{ write_data | do_export; } &>$src_output & exppid=$!
221
222
223
224
checkpids $exppid $imppid || err 'Testing additional commands failed'
cmp $statusdir/recv2 <(cksum < $testdata) || \
  err 'Checksum of received data does not match'

225
upto 'Prefix command on export'
226
reset_status
227
228
do_import > $statusdir/recv3 2>$dst_output & imppid=$!
{ write_data | cmd_prefix="cksum |" do_export; } &>$src_output & exppid=$!
229
230
231
232
checkpids $exppid $imppid || err 'Testing additional commands failed'
cmp $statusdir/recv3 <(cksum < $testdata) || \
  err 'Received checksum does not match'

233
upto 'Failing prefix command on export'
234
reset_status
235
: | cmd_prefix='exit 1;' do_export_to_port 0 &>$src_output & exppid=$!
236
237
checkpids $exppid && err 'Prefix command on export did not fail when it should'

238
upto 'Failing suffix command on export'
239
reset_status
240
241
do_import >&$src_output & imppid=$!
: | cmd_suffix='| exit 1' do_export &>$dst_output & exppid=$!
242
243
244
checkpids $imppid $exppid && \
  err 'Suffix command on export did not fail when it should'

245
upto 'Failing prefix command on import'
246
reset_status
247
cmd_prefix='exit 1;' do_import &>$dst_output & imppid=$!
248
249
checkpids $imppid && err 'Prefix command on import did not fail when it should'

250
upto 'Failing suffix command on import'
251
reset_status
252
253
cmd_suffix='| exit 1' do_import &>$dst_output & imppid=$!
: | do_export &>$src_output & exppid=$!
254
255
256
checkpids $imppid $exppid && \
  err 'Suffix command on import did not fail when it should'

257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
upto 'Listen timeout A'
reset_status
# Setting lower timeout to not wait too long (there won't be anything trying to
# connect)
connect_timeout=1 do_import &>$dst_output & imppid=$!
checkpids $imppid && \
  err 'Listening with timeout did not fail when it should'

upto 'Listen timeout B'
reset_status
do_import &>$dst_output & imppid=$!
{ sleep 1; : | do_export; } &>$src_output & exppid=$!
checkpids $exppid $imppid || \
  err 'Listening with timeout failed when it should not'

272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
upto 'No compression'
reset_status
compress=none do_import > $statusdir/recv-nocompr 2>$dst_output & imppid=$!
{ write_data | compress=none do_export; } &>$src_output & exppid=$!
checkpids $exppid $imppid || err 'An error occurred'
cmp $testdata $statusdir/recv-nocompr || \
  err 'Received data does not match input'

upto 'Compression mismatch A'
reset_status
compress=none do_import > $statusdir/recv-miscompr 2>$dst_output & imppid=$!
{ write_data | compress=gzip do_export; } &>$src_output & exppid=$!
checkpids $exppid $imppid || err 'An error occurred'
cmp -s $testdata $statusdir/recv-miscompr && \
  err 'Received data matches input when it should not'

upto 'Compression mismatch B'
reset_status
compress=gzip do_import > $statusdir/recv-miscompr2 2>$dst_output & imppid=$!
{ write_data | compress=none do_export; } &>$src_output & exppid=$!
checkpids $exppid $imppid && err 'Did not fail when it should'
cmp -s $testdata $statusdir/recv-miscompr2 && \
  err 'Received data matches input when it should not'

296
297
298
299
300
301
302
303
upto 'Large transfer'
reset_status
do_import > $statusdir/recv-large 2>$dst_output & imppid=$!
{ write_data $largetestdata | do_export; } &>$src_output & exppid=$!
checkpids $exppid $imppid || err 'An error occurred'
cmp $largetestdata $statusdir/recv-large || \
  err 'Received data does not match input'

304
exit 0