router7/integration/radvd/radvd_test.go
Michael Stapelberg 5a07d6696d split integration tests into multiple packages
This makes them complete more quickly (because they are run in parallel) and
invalidates only the cache for the integration test I’m working on, not for all
of them.
2018-06-24 11:46:49 +02:00

80 lines
2.4 KiB
Go

package integration_test
import (
"io/ioutil"
"net"
"os"
"os/exec"
"router7/internal/radvd"
"testing"
)
func TestRouterAdvertisement(t *testing.T) {
const ns = "ns2" // name of the network namespace to use for this test
if err := exec.Command("ip", "netns", "add", ns).Run(); err != nil {
t.Fatalf("ip netns add %s: %v", ns, err)
}
defer exec.Command("ip", "netns", "delete", ns).Run()
nsSetup := []*exec.Cmd{
exec.Command("ip", "link", "add", "veth2a", "type", "veth", "peer", "name", "veth2b", "netns", ns),
// Disable Duplicate Address Detection: until DAD completes, the link-local
// address remains in state “tentative”, resulting in any attempts to
// bind(2) to the address to fail with -EADDRNOTAVAIL.
exec.Command("/bin/sh", "-c", "echo 0 > /proc/sys/net/ipv6/conf/veth2a/accept_dad"),
exec.Command("ip", "netns", "exec", ns, "/bin/sh", "-c", "echo 0 > /proc/sys/net/ipv6/conf/veth2b/accept_dad"),
exec.Command("ip", "link", "set", "veth2a", "up"),
exec.Command("ip", "netns", "exec", ns, "ip", "addr", "add", "192.168.23.1/24", "dev", "veth2b"),
exec.Command("ip", "netns", "exec", ns, "ip", "link", "set", "veth2b", "up"),
exec.Command("ip", "netns", "exec", ns, "ip", "link", "set", "veth2b"),
exec.Command("/bin/sh", "-c", "echo 1 > /proc/sys/net/ipv6/conf/veth2a/forwarding"),
}
for _, cmd := range nsSetup {
if err := cmd.Run(); err != nil {
t.Fatalf("%v: %v", cmd.Args, err)
}
}
ready, err := ioutil.TempFile("", "router7")
if err != nil {
t.Fatal(err)
}
ready.Close() // dnsmasq will re-create the file anyway
defer os.Remove(ready.Name()) // dnsmasq does not clean up its pid file
srv, err := radvd.NewServer()
if err != nil {
t.Fatal(err)
}
srv.SetPrefixes([]net.IPNet{
net.IPNet{IP: net.ParseIP("2a02:168:4a00::"), Mask: net.CIDRMask(64, 128)},
})
conn, err := net.ListenIP("ip6:ipv6-icmp", &net.IPAddr{net.IPv6unspecified, ""})
if err != nil {
t.Fatal(err)
}
go func() {
if err := srv.Serve("veth2a", conn); err != nil {
t.Fatal(err)
}
}()
//time.Sleep(5 * time.Second)
rdisc6 := exec.Command("ip", "netns", "exec", ns, "rdisc6",
"--single", // exit after first router advertisement
"--retry", "1", // retry only once
"--wait", "1000", // wait 1s
"veth2b")
rdisc6.Stderr = os.Stderr
b, err := rdisc6.Output()
if err != nil {
t.Fatalf("%v: %v (output: %v)", rdisc6.Args, err, string(b))
}
t.Logf("b = %s", string(b))
}