~jdstrand/ufw/ufw-master-import

10 by Jamie Strandboge
* add testing framework
1
#!/bin/sh
2
926 by Jamie Strandboge
move user[6].rules to /etc/ufw
3
#    Copyright 2008-2016 Canonical Ltd.
47 by Jamie Strandboge
adjust files to comply with CopyrightAndLicensing
4
#
5
#    This program is free software: you can redistribute it and/or modify
6
#    it under the terms of the GNU General Public License version 3,
7
#    as published by the Free Software Foundation.
8
#
9
#    This program is distributed in the hope that it will be useful,
10
#    but WITHOUT ANY WARRANTY; without even the implied warranty of
11
#    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12
#    GNU General Public License for more details.
13
#
14
#    You should have received a copy of the GNU General Public License
15
#    along with this program.  If not, see <http://www.gnu.org/licenses/>.
16
612 by Jamie Strandboge
add --force option to enable:
17
export LANG=C
18
10 by Jamie Strandboge
* add testing framework
19
testdir="tests"
800.1.12 by Jamie Strandboge
run_tests.sh: add unit tests
20
tests="unit installation bad bugs good util"
560 by Jamie Strandboge
run_tests.sh: whitespace changes
21
717 by Jamie Strandboge
run_tests.sh: adjust for systems that do not have iptables in PATH. Only the
22
set -e
23
# Some systems may not have iptables in their PATH. Try to account for that.
24
if ! which iptables >/dev/null ; then
25
    export PATH="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"
26
    echo "INFO: 'iptables' not in PATH. Using:"
27
    echo " $PATH"
28
    if ! which iptables >/dev/null; then
29
        echo "ERROR: could not find iptables. Aborting."
30
        exit 1
31
    fi
32
fi
33
set +e
563 by Jamie Strandboge
* update setup.py to use sys.executable
34
ipt_major=`iptables --version | sed 's/.* v//' | cut -d '.' -f 1 | sed 's/\([0-9]\+\).*/\\1/'`
35
ipt_minor=`iptables --version | sed 's/.* v//' | cut -d '.' -f 2 | sed 's/\([0-9]\+\).*/\\1/'`
36
ipt_micro=`iptables --version | sed 's/.* v//' | cut -d '.' -f 3 | sed 's/\([0-9]\+\).*/\\1/'`
37
38
get_result_path() {
39
    d="$1"
40
    f="$d/result"
41
42
    f_micro="$f.$ipt_major.$ipt_minor.$ipt_micro"
43
    f_minor="$f.$ipt_major.$ipt_minor"
44
45
    if [ -f "$f.$ipt_major.$ipt_minor.$ipt_micro" ]; then
46
        f="$f_micro"
47
    elif [ -f "$f.$ipt_major.$ipt_minor" ]; then
48
        f="$f_minor"
49
    fi
50
51
    echo "$f"
52
}
53
10 by Jamie Strandboge
* add testing framework
54
CUR=`pwd`
568 by Jamie Strandboge
run_tests.sh:
55
export TESTPATH="$testdir/testarea"
56
export TESTTMP="$testdir/testarea/tmp"
493 by Jamie Strandboge
update setup.py to install user rules and init script helpers into /lib, rather
57
export TESTSTATE="$TESTPATH/lib/ufw"
926 by Jamie Strandboge
move user[6].rules to /etc/ufw
58
export TESTCONFIG="$TESTPATH/etc/ufw"
10 by Jamie Strandboge
* add testing framework
59
60
STOPONFAIL="no"
61
STOPONSKIP="no"
62
if [ "$1" = "-s" ]; then
560 by Jamie Strandboge
run_tests.sh: whitespace changes
63
    shift
64
    STOPONFAIL="yes"
33 by Jamie Strandboge
ufw:
65
elif [ "$1" = "-S" ]; then
560 by Jamie Strandboge
run_tests.sh: whitespace changes
66
    shift
67
    STOPONFAIL="yes"
68
    STOPONSKIP="yes"
10 by Jamie Strandboge
* add testing framework
69
fi
124 by Jamie Strandboge
fix tests for when ipv6 is blacklisted
70
563 by Jamie Strandboge
* update setup.py to use sys.executable
71
interpreter=""
72
if [ "$1" = "-i" ]; then
73
    shift
74
    if [ -z "$1" ]; then
767 by Jamie Strandboge
run_tests.sh: fix typo
75
        echo "Specified '-i' without an interpreter. Aborting" >&2
563 by Jamie Strandboge
* update setup.py to use sys.executable
76
        exit
77
    fi
78
    interpreter="$1"
79
    shift
80
fi
81
if [ -z "$interpreter" ]; then
1084 by Jamie Strandboge
prefer python3 and fix some comments
82
    for exe in python3 python2 python ; do
563 by Jamie Strandboge
* update setup.py to use sys.executable
83
        if which $exe >/dev/null 2>&1; then
84
            interpreter="$exe"
85
            break
86
        fi
87
    done
88
fi
565 by Jamie Strandboge
testsuite:
89
# export the interpreter so the tests can use it too
90
export interpreter="$interpreter"
91
563 by Jamie Strandboge
* update setup.py to use sys.executable
92
echo "Interpreter: $interpreter"
93
echo ""
94
124 by Jamie Strandboge
fix tests for when ipv6 is blacklisted
95
if [ -e "/proc/sys/net/ipv6" ]; then
560 by Jamie Strandboge
run_tests.sh: whitespace changes
96
    tests="$tests ipv6"
124 by Jamie Strandboge
fix tests for when ipv6 is blacklisted
97
fi
98
241 by Jamie Strandboge
update run_tests.sh to use 'class/subclass'
99
subclass=""
33 by Jamie Strandboge
ufw:
100
if [ ! -z "$1" ]; then
560 by Jamie Strandboge
run_tests.sh: whitespace changes
101
    tmp="$1"
102
    if echo "$tmp" | egrep -q '/' ; then
103
        subclass=`basename $tmp`
104
        tests=`dirname $tmp`
105
    else
106
        tests="$tmp"
107
    fi
33 by Jamie Strandboge
ufw:
108
fi
10 by Jamie Strandboge
* add testing framework
109
110
if [ ! -d "$testdir" ]; then
560 by Jamie Strandboge
run_tests.sh: whitespace changes
111
    echo "Couldn't find '$testdir' directory"
112
    exit 1
10 by Jamie Strandboge
* add testing framework
113
fi
114
51 by Jamie Strandboge
use distutils instead of install.py
115
if [ ! -e "./setup.py" ]; then
560 by Jamie Strandboge
run_tests.sh: whitespace changes
116
    echo "Couldn't find setup.py"
117
    exit 1
10 by Jamie Strandboge
* add testing framework
118
fi
119
120
skipped=0
121
errors=0
122
numtests=0
194 by Jamie Strandboge
updated common.py to use --dports and --sports with multiport
123
124
statsdir=`mktemp -d`
125
trap "rm -rf $statsdir" EXIT HUP INT QUIT TERM
126
export statsdir
127
echo "0" > $statsdir/individual
128
800.1.12 by Jamie Strandboge
run_tests.sh: add unit tests
129
# Unit tests
130
for class in $tests
131
do
132
    if [ "$class" != "unit" ]; then
133
        # Functional tests handled separately (see below)
134
        continue
135
    fi
136
137
    if [ ! -z "$subclass" ]; then
138
        if [ ! -f "$testdir/$class/$subclass" ]; then
139
            echo "Could not find '$testdir/$class/$subclass'"
140
            exit 1
141
        fi
142
    fi
800.1.13 by Jamie Strandboge
run_tests.sh: prettify output
143
    echo "= Unit Tests ="
800.1.12 by Jamie Strandboge
run_tests.sh: add unit tests
144
    if ! $interpreter ./tests/unit/runner.py $subclass ; then
145
        echo ""
146
        echo "Found unit test failures. Aborting and skipping functional tests"
809.1.42 by jdstrand
run_tests.sh: copyright and whitespace
147
        exit 1
800.1.12 by Jamie Strandboge
run_tests.sh: add unit tests
148
    fi
149
    # Exit early if only running unit tests
150
    if [ "$tests" = "unit" ]; then
151
        exit 0
152
    fi
800.1.13 by Jamie Strandboge
run_tests.sh: prettify output
153
    echo ""
154
    echo ""
800.1.12 by Jamie Strandboge
run_tests.sh: add unit tests
155
done
156
800.1.26 by Jamie Strandboge
move 'do_checks' out of backend.py and into common.py. This cleans things up a
157
# clean up before functional tests
158
rm -f "$CUR/src/*.pyc"
159
rm -rf "$CUR/src/__pycache__"
889 by Jamie Strandboge
fixup run_tests.sh -s from previous commits
160
make clean
800.1.26 by Jamie Strandboge
move 'do_checks' out of backend.py and into common.py. This cleans things up a
161
800.1.12 by Jamie Strandboge
run_tests.sh: add unit tests
162
# Functional tests
800.1.13 by Jamie Strandboge
run_tests.sh: prettify output
163
echo "= Functional Tests ="
809.1.41 by jdstrand
run_tests.sh: set ip forwarding sysctl values to predictable state and reset
164
165
# Explicitly disable IP forwarding here, since some tests assume it is
166
# disabled. IP forwarding will be re-enabled in the individual tests
167
# that require it.
809.1.46 by jdstrand
run_tests.sh: grab the correct field from sysctl output
168
orig_ip_forward=`sysctl net.ipv4.ip_forward 2>/dev/null | cut -d ' ' -f 3`
169
orig_ipv6_forwarding_default=`sysctl net.ipv6.conf.default.forwarding 2>/dev/null | cut -d ' ' -f 3`
170
orig_ipv6_forwarding_all=`sysctl net.ipv6.conf.all.forwarding 2>/dev/null | cut -d ' ' -f 3`
809.1.41 by jdstrand
run_tests.sh: set ip forwarding sysctl values to predictable state and reset
171
sysctl -w net.ipv4.ip_forward=0 2>/dev/null || true
172
sysctl -w net.ipv6.conf.default.forwarding=0 2>/dev/null || true
173
sysctl -w net.ipv6.conf.all.forwarding=0 2>/dev/null || true
174
800.1.12 by Jamie Strandboge
run_tests.sh: add unit tests
175
for class in $tests
176
do
177
    if [ "$class" = "unit" ]; then
178
        # Unit tests handled separately (see above)
179
        continue
180
    fi
181
560 by Jamie Strandboge
run_tests.sh: whitespace changes
182
    for d in `ls -d -1 $testdir/$class/* 2>/dev/null`
183
    do
184
        if [ ! -z "$subclass" ]; then
185
            if [ "$d" != "$testdir/$class/$subclass" ]; then
186
                continue
187
            fi
188
        fi
189
190
        if [ $skipped -gt 0 ]; then
191
            if [ "$STOPONSKIP" = "yes" ]; then
192
                echo ""
193
                echo "STOPONSKIP set, exiting on skip"
194
                exit 1
195
            fi
196
        fi
197
        thistest=`basename $d`
198
        echo ""
199
        echo "Performing tests '$class/$thistest'"
200
568 by Jamie Strandboge
run_tests.sh:
201
        if [ ! -x "$testdir/$class/$thistest/runtest.sh" ]; then
560 by Jamie Strandboge
run_tests.sh: whitespace changes
202
            skipped=$(($skipped + 1))
568 by Jamie Strandboge
run_tests.sh:
203
            echo "    WARNING: couldn't find '$testdir/$class/$thistest/runtest.sh' (skipping)"
560 by Jamie Strandboge
run_tests.sh: whitespace changes
204
            continue
205
        fi
206
207
        echo "- installing"
568 by Jamie Strandboge
run_tests.sh:
208
        if [ -d "$TESTPATH" ]; then
209
            rm -rf "$TESTPATH"
560 by Jamie Strandboge
run_tests.sh: whitespace changes
210
        fi
211
        tmpdir=`mktemp -d`
568 by Jamie Strandboge
run_tests.sh:
212
        mv "$tmpdir" "$TESTPATH"
213
214
        mkdir -p "$TESTPATH/usr/sbin" "$TESTPATH/etc" "$TESTPATH/tmp" || exit 1
215
216
        install_dir="$TESTPATH"
800.1.26 by Jamie Strandboge
move 'do_checks' out of backend.py and into common.py. This cleans things up a
217
218
        # this is to allow root to run the tests without error.  I don't
219
        # like building things as root, but some people do...
220
        export UFW_SKIP_CHECKS="1"
221
563 by Jamie Strandboge
* update setup.py to use sys.executable
222
        setup_output=`$interpreter ./setup.py install --home="$install_dir" 2>&1`
560 by Jamie Strandboge
run_tests.sh: whitespace changes
223
        if [ "$?" != "0" ]; then
563 by Jamie Strandboge
* update setup.py to use sys.executable
224
            echo "$setup_output"
560 by Jamie Strandboge
run_tests.sh: whitespace changes
225
            exit 1
226
        fi
227
573 by Jamie Strandboge
run_tests.sh: let scripts have a backup of the original files
228
        # make the installed user rules files available to tests
229
        find "$TESTPATH" -name "user*.rules" -exec cp {} {}.orig \;
230
568 by Jamie Strandboge
run_tests.sh:
231
        cp -rL $testdir/$class/$thistest/orig/* "$TESTPATH/etc" || exit 1
232
        cp -f $testdir/$class/$thistest/runtest.sh "$TESTPATH" || exit 1
560 by Jamie Strandboge
run_tests.sh: whitespace changes
233
741.1.1 by Jamie Strandboge
enable IPv6 by default
234
        # Explicitly disable IPv6 here, since some tests assume it is disabled.
235
        # IPv6 will be re-enabled in the individual tests that require it.
236
        sed -i 's/IPV6=.*/IPV6=no/' $TESTPATH/etc/default/ufw
237
560 by Jamie Strandboge
run_tests.sh: whitespace changes
238
        echo "- result: "
239
        numtests=$(($numtests + 1))
240
        # now run the test
568 by Jamie Strandboge
run_tests.sh:
241
        PYTHONPATH="$PYTHONPATH:$install_dir/lib/python" "$TESTPATH/runtest.sh"
560 by Jamie Strandboge
run_tests.sh: whitespace changes
242
        if [ "$?" != "0" ];then
243
            echo "    ** FAIL **"
244
            errors=$(($errors + 1))
245
        else
246
            if [ ! -f "$TESTTMP/result" ]; then
247
                skipped=$(($skipped + 1))
248
                echo "    WARNING: couldn't find '$TESTTMP/result' (skipping)"
249
                continue
250
            else
251
                # fix discrepencies between python versions
252
                sed -i 's/^usage:/Usage:/' $TESTTMP/result
253
                sed -i 's/^options:/Options:/' $TESTTMP/result
254
            fi
255
            if [ ! -f "$testdir/$class/$thistest/result" ]; then
256
                skipped=$(($skipped + 1))
257
                echo "    WARNING: couldn't find '$testdir/$class/$thistest/result' (skipping)"
258
                continue
259
            fi
563 by Jamie Strandboge
* update setup.py to use sys.executable
260
261
            result_file=`get_result_path $testdir/$class/$thistest`
262
            diffs=`diff -w $result_file $TESTTMP/result`
560 by Jamie Strandboge
run_tests.sh: whitespace changes
263
            if [ -z "$diffs" ]; then
264
                echo "    PASS"
265
            else
266
                errors=$(($errors + 1))
267
                echo "    FAIL:"
268
                echo "$diffs"
269
            fi
270
        fi
568 by Jamie Strandboge
run_tests.sh:
271
        chmod 755 "$TESTPATH"
560 by Jamie Strandboge
run_tests.sh: whitespace changes
272
        if [ $errors -gt 0 ]; then
273
            if [ "$STOPONFAIL" = "yes" ]; then
274
                echo ""
675 by Jamie Strandboge
run_tests.sh: add a little more output for easier debugging
275
                echo "FAILED $testdir/$class/$thistest -- result found in $TESTTMP/result"
276
                echo "For more information, see:"
277
                echo "diff -Naur $testdir/$class/$thistest/result $TESTTMP/result"
560 by Jamie Strandboge
run_tests.sh: whitespace changes
278
                exit 1
279
            fi
280
        fi
281
    done
10 by Jamie Strandboge
* add testing framework
282
done
283
809.1.41 by jdstrand
run_tests.sh: set ip forwarding sysctl values to predictable state and reset
284
# Restore IP forwarding
285
test -n "$orig_ip_forward" && \
286
    sysctl -w net.ipv4.ip_forward="$orig_ip_forward" 2>/dev/null || true
287
test -n "$orig_ipv6_forwarding_default" && \
288
    sysctl -w net.ipv6.conf.default.forwarding="$orig_ipv6_forwarding_default" 2>/dev/null || true
289
test -n "$orig_ipv6_forwarding_all" && \
290
    sysctl -w net.ipv6.conf.all.forwarding="$orig_ipv6_forwarding_all" 2>/dev/null || true
291
568 by Jamie Strandboge
run_tests.sh:
292
if [ -d "$TESTPATH" ]; then
293
    rm -rf "$TESTPATH"
10 by Jamie Strandboge
* add testing framework
294
fi
295
194 by Jamie Strandboge
updated common.py to use --dports and --sports with multiport
296
individual=$(cat $statsdir/individual)
297
10 by Jamie Strandboge
* add testing framework
298
echo ""
800.1.12 by Jamie Strandboge
run_tests.sh: add unit tests
299
echo "------------------------"
300
echo "Functional tests summary"
301
echo "------------------------"
197 by Jamie Strandboge
updated test output
302
echo "Attempted:           $numtests ($individual individual tests)"
303
echo "Skipped:             $skipped"
304
echo "Errors:              $errors"
10 by Jamie Strandboge
* add testing framework
305
306
if [ "$errors" != "0" ]; then
560 by Jamie Strandboge
run_tests.sh: whitespace changes
307
    exit 1
10 by Jamie Strandboge
* add testing framework
308
fi
485 by Jamie Strandboge
update frontend.py to insert multi-rule application rules properly.
309
310
# cleanup
311
rm -rf $statsdir
312
646 by Jamie Strandboge
run_tests.sh: revert temporarily disable 'skipped' check
313
if [ "$skipped" != "0" ]; then
314
    exit 2
315
fi
10 by Jamie Strandboge
* add testing framework
316
317
exit 0
318