#!/bin/sh -e

rm -rf tests/
mkdir tests
cat >tests/testcase.1 <<EOF
# RUN: -a
auto eth0 eth1 eth2 eth3
iface eth0 inet static
  address 1.2.3.4
  netmask 255.255.255.0
  broadcast 1.2.3.255
  up echo hi
  post-up echo hello

iface eth1 inet static
  address 1.2.3.4/14
  broadcast 1.3.255.255
  up echo hi
  post-up echo hello

iface eth2 inet static
  address 1.2.3.4/14
  netmask 255.255.255.128
  broadcast 1.2.3.127
  up echo hi
  post-up echo hello

iface eth3 inet static
  address 1.2.3.4/24
  broadcast -
  up true

iface eth3 inet static
  address 1.2.3.4/30
  broadcast -
  up true

iface eth3 inet static
  address 1.2.3.4/31
  up true

iface eth3 inet static
  address 1.2.3.4/31
  broadcast -
  up true
EOF
cat >tests/up.1 <<EOF
====stdout====
====stderr====
run-parts --exit-on-error --verbose /etc/network/if-pre-up.d
Configuring interface eth0=eth0 (inet)
run-parts --exit-on-error --verbose /etc/network/if-pre-up.d
ip addr add 1.2.3.4/255.255.255.0 broadcast 1.2.3.255 	  dev eth0 label eth0
ip link set dev eth0   up

echo hi
echo hello
run-parts --exit-on-error --verbose /etc/network/if-up.d
Configuring interface eth1=eth1 (inet)
run-parts --exit-on-error --verbose /etc/network/if-pre-up.d
ip addr add 1.2.3.4/255.252.0.0 broadcast 1.3.255.255 	  dev eth1 label eth1
ip link set dev eth1   up

echo hi
echo hello
run-parts --exit-on-error --verbose /etc/network/if-up.d
Configuring interface eth2=eth2 (inet)
run-parts --exit-on-error --verbose /etc/network/if-pre-up.d
ip addr add 1.2.3.4/255.255.255.128 broadcast 1.2.3.127 	  dev eth2 label eth2
ip link set dev eth2   up

echo hi
echo hello
run-parts --exit-on-error --verbose /etc/network/if-up.d
Configuring interface eth3=eth3 (inet)
run-parts --exit-on-error --verbose /etc/network/if-pre-up.d
ip addr add 1.2.3.4/255.255.255.0 broadcast 1.2.3.0 	  dev eth3 label eth3
ip link set dev eth3   up

true
run-parts --exit-on-error --verbose /etc/network/if-up.d
Configuring interface eth3=eth3 (inet)
run-parts --exit-on-error --verbose /etc/network/if-pre-up.d
ip addr add 1.2.3.4/255.255.255.252 broadcast 1.2.3.4 	  dev eth3 label eth3
ip link set dev eth3   up

true
run-parts --exit-on-error --verbose /etc/network/if-up.d
Configuring interface eth3=eth3 (inet)
run-parts --exit-on-error --verbose /etc/network/if-pre-up.d
ip addr add 1.2.3.4/255.255.255.254 broadcast 255.255.255.255 	  dev eth3 label eth3
ip link set dev eth3   up

true
run-parts --exit-on-error --verbose /etc/network/if-up.d
Configuring interface eth3=eth3 (inet)
run-parts --exit-on-error --verbose /etc/network/if-pre-up.d
ip addr add 1.2.3.4/255.255.255.254 broadcast 0.0.0.0 	  dev eth3 label eth3
ip link set dev eth3   up

true
run-parts --exit-on-error --verbose /etc/network/if-up.d
run-parts --exit-on-error --verbose /etc/network/if-up.d
EOF

cat >tests/testcase.2 <<EOF
# RUN: -a
auto eth0 eth1 eth2
auto eth3 eth4 eth5
allow-hotplug eth6
iface eth0 inet static
  address 1.2.3.4
  netmask 255.255.255.0
iface eth1 inet static
  address 1.3.4.5
  netmask 255.255.255.0
iface eth2 inet static
  address 1.4.5.6
  netmask 255.255.255.0
iface eth3 inet static
  address 1.5.6.7
  netmask 255.255.255.0
iface eth4 inet static
  address 1.7.8.9
  netmask 255.255.255.0
iface eth5 inet static
  address 1.8.9.10
  netmask 255.255.255.0
iface eth6 inet static
  address 1.11.12.13
  netmask 255.255.255.0
iface eth7 inet static
  address 1.14.15.16
  netmask 255.255.255.0
EOF
cat >tests/up.2 <<EOF
====stdout====
====stderr====
run-parts --exit-on-error --verbose /etc/network/if-pre-up.d
Configuring interface eth0=eth0 (inet)
run-parts --exit-on-error --verbose /etc/network/if-pre-up.d
ip addr add 1.2.3.4/255.255.255.0 broadcast 1.2.3.255 	  dev eth0 label eth0
ip link set dev eth0   up

run-parts --exit-on-error --verbose /etc/network/if-up.d
Configuring interface eth1=eth1 (inet)
run-parts --exit-on-error --verbose /etc/network/if-pre-up.d
ip addr add 1.3.4.5/255.255.255.0 broadcast 1.3.4.255 	  dev eth1 label eth1
ip link set dev eth1   up

run-parts --exit-on-error --verbose /etc/network/if-up.d
Configuring interface eth2=eth2 (inet)
run-parts --exit-on-error --verbose /etc/network/if-pre-up.d
ip addr add 1.4.5.6/255.255.255.0 broadcast 1.4.5.255 	  dev eth2 label eth2
ip link set dev eth2   up

run-parts --exit-on-error --verbose /etc/network/if-up.d
Configuring interface eth3=eth3 (inet)
run-parts --exit-on-error --verbose /etc/network/if-pre-up.d
ip addr add 1.5.6.7/255.255.255.0 broadcast 1.5.6.255 	  dev eth3 label eth3
ip link set dev eth3   up

run-parts --exit-on-error --verbose /etc/network/if-up.d
Configuring interface eth4=eth4 (inet)
run-parts --exit-on-error --verbose /etc/network/if-pre-up.d
ip addr add 1.7.8.9/255.255.255.0 broadcast 1.7.8.255 	  dev eth4 label eth4
ip link set dev eth4   up

run-parts --exit-on-error --verbose /etc/network/if-up.d
Configuring interface eth5=eth5 (inet)
run-parts --exit-on-error --verbose /etc/network/if-pre-up.d
ip addr add 1.8.9.10/255.255.255.0 broadcast 1.8.9.255 	  dev eth5 label eth5
ip link set dev eth5   up

run-parts --exit-on-error --verbose /etc/network/if-up.d
run-parts --exit-on-error --verbose /etc/network/if-up.d
EOF

cat >tests/testcase.3 <<EOF
# RUN: -a
auto eth0
iface eth0 inet static
  address 1.2.3.4
  netmask 255.255.255.0
iface eth0 inet6 static
  address 3ffe:ffff:100:f101::1
  netmask 64
  dad-attempts 0
iface eth0 inet6 static
  address 3ffe:ffff:100:f101::2/64
  dad-attempts 0
iface eth0 inet6 static
  address 3ffe:ffff:100:f101::3/64
  netmask 64
  dad-attempts 0
iface eth0 inet6 static
  address 3ffe:ffff:100:f101::4/
  dad-attempts 0
iface eth0 inet6 static
  address 3ffe:ffff:100:f101::5/64
  netmask 128
  dad-attempts 0
iface eth0 inet6 static
  address /64
  dad-attempts 0
iface eth0 inet6 static
  address /
  dad-attempts 0
EOF
cat >tests/up.3 <<EOF
====stdout====
Failed to bring up eth0.
====stderr====
run-parts --exit-on-error --verbose /etc/network/if-pre-up.d
Configuring interface eth0=eth0 (inet)
run-parts --exit-on-error --verbose /etc/network/if-pre-up.d
ip addr add 1.2.3.4/255.255.255.0 broadcast 1.2.3.255 	  dev eth0 label eth0
ip link set dev eth0   up

run-parts --exit-on-error --verbose /etc/network/if-up.d
Configuring interface eth0=eth0 (inet6)
run-parts --exit-on-error --verbose /etc/network/if-pre-up.d
modprobe -q net-pf-10 > /dev/null 2>&1 || true # ignore failure.


sysctl -q -e -w net.ipv6.conf.eth0.autoconf=0
ip link set dev eth0   up
ip -6 addr add 3ffe:ffff:100:f101::1/64  dev eth0 

run-parts --exit-on-error --verbose /etc/network/if-up.d
Configuring interface eth0=eth0 (inet6)
run-parts --exit-on-error --verbose /etc/network/if-pre-up.d
modprobe -q net-pf-10 > /dev/null 2>&1 || true # ignore failure.


sysctl -q -e -w net.ipv6.conf.eth0.autoconf=0
ip link set dev eth0   up
ip -6 addr add 3ffe:ffff:100:f101::2/64  dev eth0 

run-parts --exit-on-error --verbose /etc/network/if-up.d
Configuring interface eth0=eth0 (inet6)
run-parts --exit-on-error --verbose /etc/network/if-pre-up.d
modprobe -q net-pf-10 > /dev/null 2>&1 || true # ignore failure.


sysctl -q -e -w net.ipv6.conf.eth0.autoconf=0
ip link set dev eth0   up
ip -6 addr add 3ffe:ffff:100:f101::3/64  dev eth0 

run-parts --exit-on-error --verbose /etc/network/if-up.d
Configuring interface eth0=eth0 (inet6)
run-parts --exit-on-error --verbose /etc/network/if-pre-up.d
modprobe -q net-pf-10 > /dev/null 2>&1 || true # ignore failure.


sysctl -q -e -w net.ipv6.conf.eth0.autoconf=0
ip link set dev eth0   up
ip -6 addr add 3ffe:ffff:100:f101::4  dev eth0 

run-parts --exit-on-error --verbose /etc/network/if-up.d
Configuring interface eth0=eth0 (inet6)
run-parts --exit-on-error --verbose /etc/network/if-pre-up.d
modprobe -q net-pf-10 > /dev/null 2>&1 || true # ignore failure.


sysctl -q -e -w net.ipv6.conf.eth0.autoconf=0
ip link set dev eth0   up
ip -6 addr add 3ffe:ffff:100:f101::5/128  dev eth0 

run-parts --exit-on-error --verbose /etc/network/if-up.d
Configuring interface eth0=eth0 (inet6)
run-parts --exit-on-error --verbose /etc/network/if-pre-up.d
modprobe -q net-pf-10 > /dev/null 2>&1 || true # ignore failure.


sysctl -q -e -w net.ipv6.conf.eth0.autoconf=0
ip link set dev eth0   up
ip -6 addr add 64  dev eth0 

run-parts --exit-on-error --verbose /etc/network/if-up.d
Configuring interface eth0=eth0 (inet6)
Missing required variable: address
Missing required configuration variables for interface eth0/inet6.
run-parts --exit-on-error --verbose /etc/network/if-up.d
EOF

cat >tests/testcase.4 <<EOF
# RUN: eth0=work
mapping eth0
  script tests/map.eth0.work
iface work inet static
  address 1.2.3.4
  netmask 255.255.255.0
  up echo hi
  post-up echo hello
EOF
cat >tests/up.4 <<EOF
====stdout====
====stderr====
Configuring interface eth0=work (inet)
run-parts --exit-on-error --verbose /etc/network/if-pre-up.d
ip addr add 1.2.3.4/255.255.255.0 broadcast 1.2.3.255 	  dev eth0 label eth0
ip link set dev eth0   up

echo hi
echo hello
run-parts --exit-on-error --verbose /etc/network/if-up.d
EOF

cat >tests/testcase.5 <<EOF
# RUN: -a
auto eth0
iface eth0 inet static
  address 1.2.3.4
  netmask 255.255.255.0
  hwaddress ether 00:DE:AD:00:BE:AF
EOF
cat >tests/up.5 <<EOF
====stdout====
====stderr====
run-parts --exit-on-error --verbose /etc/network/if-pre-up.d
Configuring interface eth0=eth0 (inet)
run-parts --exit-on-error --verbose /etc/network/if-pre-up.d
ip addr add 1.2.3.4/255.255.255.0 broadcast 1.2.3.255 	  dev eth0 label eth0
ip link set dev eth0  address 00:DE:AD:00:BE:AF up

run-parts --exit-on-error --verbose /etc/network/if-up.d
run-parts --exit-on-error --verbose /etc/network/if-up.d
EOF

cat >tests/testcase.6 <<EOF
# RUN: -a
auto eth0
iface eth0 inet static
  address 1.2.3.4
  netmask 255.255.255.0
  hwaddress 00:DE:AD:00:BE:AF
EOF
cat >tests/up.6 <<EOF
====stdout====
====stderr====
run-parts --exit-on-error --verbose /etc/network/if-pre-up.d
Configuring interface eth0=eth0 (inet)
run-parts --exit-on-error --verbose /etc/network/if-pre-up.d
ip addr add 1.2.3.4/255.255.255.0 broadcast 1.2.3.255 	  dev eth0 label eth0
ip link set dev eth0  address 00:DE:AD:00:BE:AF up

run-parts --exit-on-error --verbose /etc/network/if-up.d
run-parts --exit-on-error --verbose /etc/network/if-up.d
EOF

cat >tests/testcase.7 <<EOF
# RUN: -a
auto eth0 eth0.1 eth0.0201 br0.0201 br0.0202 tunnel
iface eth0 inet static
  address 1.2.3.4
  netmask 255.255.255.0
iface eth0 inet6 static
  address 3ffe:ffff:100:f101::1
  netmask 64
  privext 2
  accept_ra 0
  dad-attempts 0
iface eth0.1 inet6 static
  address 3ffe:ffff:120:f101::1
  netmask 64
  dad-attempts 0
iface eth0.0201 inet static
  address 192.168.0.1/25
iface br0.0201 inet manual
  bridge_ports eth0.0201
iface br0.0202 inet manual
iface tunnel inet6 6to4
  local 1.2.3.4
EOF
cat >tests/up.7 <<EOF
====stdout====
====stderr====
run-parts --exit-on-error --verbose /etc/network/if-pre-up.d
Configuring interface eth0=eth0 (inet)
run-parts --exit-on-error --verbose /etc/network/if-pre-up.d
ip addr add 1.2.3.4/255.255.255.0 broadcast 1.2.3.255 	  dev eth0 label eth0
ip link set dev eth0   up

run-parts --exit-on-error --verbose /etc/network/if-up.d
Configuring interface eth0=eth0 (inet6)
run-parts --exit-on-error --verbose /etc/network/if-pre-up.d
modprobe -q net-pf-10 > /dev/null 2>&1 || true # ignore failure.
sysctl -q -e -w net.ipv6.conf.eth0.use_tempaddr=2
sysctl -q -e -w net.ipv6.conf.eth0.accept_ra=0
sysctl -q -e -w net.ipv6.conf.eth0.autoconf=0
ip link set dev eth0   up
ip -6 addr add 3ffe:ffff:100:f101::1/64 dev eth0

run-parts --exit-on-error --verbose /etc/network/if-up.d
Configuring interface eth0.1=eth0.1 (inet6)
run-parts --exit-on-error --verbose /etc/network/if-pre-up.d
modprobe -q net-pf-10 > /dev/null 2>&1 || true # ignore failure.


sysctl -q -e -w net.ipv6.conf.eth0/1.autoconf=0
ip link set dev eth0.1   up
ip -6 addr add 3ffe:ffff:120:f101::1/64 dev eth0.1

run-parts --exit-on-error --verbose /etc/network/if-up.d
Configuring interface eth0.0201=eth0.0201 (inet)
run-parts --exit-on-error --verbose /etc/network/if-pre-up.d
ip addr add 192.168.0.1/255.255.255.128 broadcast 192.168.0.127 	  dev eth0.0201 label eth0.0201
ip link set dev eth0.0201   up

run-parts --exit-on-error --verbose /etc/network/if-up.d
Configuring interface br0.0201=br0.0201 (inet)
run-parts --exit-on-error --verbose /etc/network/if-pre-up.d
ip link set dev br0.0201   up
run-parts --exit-on-error --verbose /etc/network/if-up.d
Configuring interface br0.0202=br0.0202 (inet)
run-parts --exit-on-error --verbose /etc/network/if-pre-up.d
ip link set dev br0.0202   up
run-parts --exit-on-error --verbose /etc/network/if-up.d
Configuring interface tunnel=tunnel (inet6)
run-parts --exit-on-error --verbose /etc/network/if-pre-up.d
modprobe -q net-pf-10 > /dev/null 2>&1 || true # ignore failure.
ip tunnel add tunnel mode sit remote any local 1.2.3.4        
ip link set tunnel up 
ip addr add 2002:0102:0304::1/16 dev tunnel
ip route add 2000::/3 via ::192.88.99.1 dev tunnel
run-parts --exit-on-error --verbose /etc/network/if-up.d
run-parts --exit-on-error --verbose /etc/network/if-up.d
EOF

cat >tests/testcase.8 <<EOF
# RUN: -a
auto eth1 eth1:1 eth2.2 eth2.2:3
iface eth1 inet static
  address 1.2.3.4
  netmask 255.255.255.0
  up echo hi
  post-up echo hello

iface eth1:1 inet static
  address 1.5.3.4
  netmask 255.255.255.0
  up echo hihi
  post-up echo hellolo

iface eth2.2 inet static
  address 2.3.4.5/24

iface eth2.2:3 inet static
  address 3.4.5.6/23
EOF
cat >tests/up.8 <<EOF
====stdout====
====stderr====
run-parts --exit-on-error --verbose /etc/network/if-pre-up.d
Configuring interface eth1=eth1 (inet)
run-parts --exit-on-error --verbose /etc/network/if-pre-up.d
ip addr add 1.2.3.4/255.255.255.0 broadcast 1.2.3.255 	  dev eth1 label eth1
ip link set dev eth1   up

echo hi
echo hello
run-parts --exit-on-error --verbose /etc/network/if-up.d
Configuring interface eth1:1=eth1:1 (inet)
run-parts --exit-on-error --verbose /etc/network/if-pre-up.d
ip addr add 1.5.3.4/255.255.255.0 broadcast 1.5.3.255 	  dev eth1:1 label eth1:1
ip link set dev eth1:1   up

echo hihi
echo hellolo
run-parts --exit-on-error --verbose /etc/network/if-up.d
Configuring interface eth2.2=eth2.2 (inet)
run-parts --exit-on-error --verbose /etc/network/if-pre-up.d
ip addr add 2.3.4.5/255.255.255.0 broadcast 2.3.4.255 	  dev eth2.2 label eth2.2
ip link set dev eth2.2   up

run-parts --exit-on-error --verbose /etc/network/if-up.d
Configuring interface eth2.2:3=eth2.2:3 (inet)
run-parts --exit-on-error --verbose /etc/network/if-pre-up.d
ip addr add 3.4.5.6/255.255.254.0 broadcast 3.4.5.255 	  dev eth2.2:3 label eth2.2:3
ip link set dev eth2.2:3   up

run-parts --exit-on-error --verbose /etc/network/if-up.d
run-parts --exit-on-error --verbose /etc/network/if-up.d
EOF

cat >tests/testcase.9 <<EOF
# RUN: tunnel -o local=2.3.4.5
iface tunnel inet6 6to4
  local 1.2.3.4
EOF
cat >tests/up.9 <<EOF
====stdout====
====stderr====
Configuring interface tunnel=tunnel (inet6)
run-parts --exit-on-error --verbose /etc/network/if-pre-up.d
modprobe -q net-pf-10 > /dev/null 2>&1 || true # ignore failure.
ip tunnel add tunnel mode sit remote any local 2.3.4.5        
ip link set tunnel up 
ip addr add 2002:0203:0405::1/16 dev tunnel
ip route add 2000::/3 via ::192.88.99.1 dev tunnel
run-parts --exit-on-error --verbose /etc/network/if-up.d
EOF

cat >tests/testcase.10 <<EOF
# RUN: -a
source /dev/null
source null
EOF
cat >tests/up.10 <<EOF
====stdout====
====stderr====
Parsing file /dev/null
Parsing file tests/null
run-parts --exit-on-error --verbose /etc/network/if-pre-up.d
run-parts --exit-on-error --verbose /etc/network/if-up.d
EOF


result=true
for test in 1 2 3 4 5 6 7 8 9 10; do
        args="$(cat tests/testcase.$test | sed -n 's/^# RUN: //p')"
        ./ifup --no-loopback -nv --force -i tests/testcase.$test $args \
                >tests/up-res-out.$test 2>tests/up-res-err.$test || 
                true
        (echo "====stdout===="; cat tests/up-res-out.$test
         echo "====stderr===="; cat tests/up-res-err.$test) > tests/up-res.$test

        echo "Testcase $test: $args"
        
        if diff -ub tests/up.$test tests/up-res.$test; then
                echo "(okay)"
        else
                echo "(failed)"
                result=false
        fi
        echo "=========="
done

if $result; then
        echo "(okay overall)"
        exit 0
else
        echo "(failed overall)"
        exit 1
fi
