netconfig_test: better diffs, refactor for clarity/brevity

This commit is contained in:
Michael Stapelberg 2018-11-26 08:46:59 +01:00
parent 127bdc466e
commit b6a5227d49

View File

@ -26,6 +26,7 @@ import (
"github.com/rtr7/router7/internal/netconfig" "github.com/rtr7/router7/internal/netconfig"
"github.com/andreyvit/diff"
"github.com/google/go-cmp/cmp" "github.com/google/go-cmp/cmp"
"github.com/google/nftables" "github.com/google/nftables"
) )
@ -47,42 +48,26 @@ const goldenInterfaces = `
} }
` `
const goldenPortForwardings = ` func goldenPortForwardings(additionalForwarding bool) string {
{ add := ""
"forwardings":[ if additionalForwarding {
{ add = `
"port": "8080",
"dest_addr": "192.168.42.23",
"dest_port": "9999"
},
{
"port": "8040-8060",
"dest_addr": "192.168.42.99",
"dest_port": "8040-8060"
},
{
"proto": "udp",
"port": "53",
"dest_addr": "192.168.42.99",
"dest_port": "53"
}
]
}
`
const additionalPortForwardings = `
{
"forwardings":[
{
"port": "8080",
"dest_addr": "192.168.42.23",
"dest_port": "9999"
},
{ {
"port": "8045", "port": "8045",
"dest_addr": "192.168.42.22", "dest_addr": "192.168.42.22",
"dest_port": "8045" "dest_port": "8045"
}, },
`
}
return `
{
"forwardings":[
{
"port": "8080",
"dest_addr": "192.168.42.23",
"dest_port": "9999"
},
` + add + `
{ {
"port": "8040-8060", "port": "8040-8060",
"dest_addr": "192.168.42.99", "dest_addr": "192.168.42.99",
@ -97,6 +82,50 @@ const additionalPortForwardings = `
] ]
} }
` `
}
func goldenNftablesRules(additionalForwarding bool) string {
add := ""
if additionalForwarding {
add = `
iifname "uplink0" tcp dport 8045 dnat to 192.168.42.22:8045`
}
return `table ip nat {
chain prerouting {
type nat hook prerouting priority 0; policy accept;
iifname "uplink0" udp dport domain dnat to 192.168.42.99:domain
iifname "uplink0" tcp dport 8040-8060 dnat to 192.168.42.99:8040-8060` + add + `
iifname "uplink0" tcp dport http-alt dnat to 192.168.42.23:9999
}
chain postrouting {
type nat hook postrouting priority 100; policy accept;
oifname "uplink0" masquerade
}
}
table ip filter {
counter fwded {
packets 23 bytes 42
}
chain forward {
type filter hook forward priority 0; policy accept;
counter name "fwded"
oifname "uplink0" tcp flags syn tcp option maxseg size set rt mtu
}
}
table ip6 filter {
counter fwded {
packets 23 bytes 42
}
chain forward {
type filter hook forward priority 0; policy accept;
counter name "fwded"
oifname "uplink0" tcp flags syn tcp option maxseg size set rt mtu
}
}`
}
const goldenDhcp4 = ` const goldenDhcp4 = `
{ {
@ -132,10 +161,7 @@ func TestNetconfig(t *testing.T) {
} }
defer os.RemoveAll(tmp) defer os.RemoveAll(tmp)
pf := goldenPortForwardings pf := goldenPortForwardings(os.Getenv("ADDITIONAL_PORT_FORWARDINGS") == "1")
if os.Getenv("ADDITIONAL_PORT_FORWARDINGS") == "1" {
pf = additionalPortForwardings
}
for _, golden := range []struct { for _, golden := range []struct {
filename, content string filename, content string
}{ }{
@ -213,6 +239,7 @@ func TestNetconfig(t *testing.T) {
t.Fatal(err) t.Fatal(err)
} }
t.Run("VerifyAddresses", func(t *testing.T) {
link, err := exec.Command("ip", "-netns", ns, "link", "show", "dev", "lan0").Output() link, err := exec.Command("ip", "-netns", ns, "link", "show", "dev", "lan0").Output()
if err != nil { if err != nil {
t.Fatal(err) t.Fatal(err)
@ -254,63 +281,28 @@ func TestNetconfig(t *testing.T) {
if diff := cmp.Diff(routes, wantRoutes); diff != "" { if diff := cmp.Diff(routes, wantRoutes); diff != "" {
t.Fatalf("routes: diff (-got +want):\n%s", diff) t.Fatalf("routes: diff (-got +want):\n%s", diff)
} }
})
rules, err := ipLines("netns", "exec", ns, "nft", "list", "ruleset")
if err != nil {
t.Fatal(err)
}
for n, rule := range rules {
t.Logf("rule %d: %s", n, rule)
}
if len(rules) < 2 {
t.Fatalf("nftables rules not found")
}
wantRules := []string{
`table ip nat {`,
` chain prerouting {`,
` type nat hook prerouting priority 0; policy accept;`,
` iifname "uplink0" udp dport domain dnat to 192.168.42.99:domain`,
` iifname "uplink0" tcp dport 8040-8060 dnat to 192.168.42.99:8040-8060`,
` iifname "uplink0" tcp dport http-alt dnat to 192.168.42.23:9999`,
` }`,
``,
` chain postrouting {`,
` type nat hook postrouting priority 100; policy accept;`,
` oifname "uplink0" masquerade`,
` }`,
`}`,
`table ip filter {`,
` counter fwded {`,
` packets 23 bytes 42`,
` }`,
``,
` chain forward {`,
` type filter hook forward priority 0; policy accept;`,
` counter name "fwded"`,
` oifname "uplink0" tcp flags syn tcp option maxseg size set rt mtu`,
` }`,
`}`,
`table ip6 filter {`,
` counter fwded {`,
` packets 23 bytes 42`,
` }`,
``,
` chain forward {`,
` type filter hook forward priority 0; policy accept;`,
` counter name "fwded"`,
` oifname "uplink0" tcp flags syn tcp option maxseg size set rt mtu`,
` }`,
`}`,
}
opts := []cmp.Option{ opts := []cmp.Option{
cmp.Transformer("formatting", func(line string) string { cmp.Transformer("formatting", func(line string) string {
return strings.TrimSpace(strings.Replace(line, "dnat to", "dnat", -1)) return strings.TrimSpace(strings.Replace(line, "dnat to", "dnat", -1))
}), }),
} }
if diff := cmp.Diff(rules, wantRules, opts...); diff != "" { t.Run("VerifyNftables", func(t *testing.T) {
rules, err := ipLines("netns", "exec", ns, "nft", "list", "ruleset")
if err != nil {
t.Fatal(err)
}
if len(rules) < 2 {
t.Fatalf("nftables rules not found")
}
got := strings.Join(rules, "\n")
if diff := cmp.Diff(got, goldenNftablesRules(false), opts...); diff != "" {
t.Fatalf("unexpected nftables rules: diff (-got +want):\n%s", diff) t.Fatalf("unexpected nftables rules: diff (-got +want):\n%s", diff)
} }
})
cmd = exec.Command("ip", "netns", "exec", ns, os.Args[0], "-test.run=^TestNetconfig$") cmd = exec.Command("ip", "netns", "exec", ns, os.Args[0], "-test.run=^TestNetconfig$")
cmd.Env = append(os.Environ(), "HELPER_PROCESS=1", "ADDITIONAL_PORT_FORWARDINGS=1") cmd.Env = append(os.Environ(), "HELPER_PROCESS=1", "ADDITIONAL_PORT_FORWARDINGS=1")
@ -320,58 +312,19 @@ func TestNetconfig(t *testing.T) {
t.Fatal(err) t.Fatal(err)
} }
rules, err = ipLines("netns", "exec", ns, "nft", "list", "ruleset") t.Run("VerifyAdditionalNftables", func(t *testing.T) {
rules, err := ipLines("netns", "exec", ns, "nft", "list", "ruleset")
if err != nil { if err != nil {
t.Fatal(err) t.Fatal(err)
} }
for n, rule := range rules {
t.Logf("rule %d: %s", n, rule)
}
if len(rules) < 2 { if len(rules) < 2 {
t.Fatalf("nftables rules not found") t.Fatalf("nftables rules not found")
} }
wantRules = []string{ if got, want := strings.Join(rules, "\n"), goldenNftablesRules(true); got != want {
`table ip nat {`, t.Fatalf("unexpected nftables rules: diff (-want +got):\n%s", diff.LineDiff(want, got))
` chain prerouting {`,
` type nat hook prerouting priority 0; policy accept;`,
` iifname "uplink0" udp dport domain dnat to 192.168.42.99:domain`,
` iifname "uplink0" tcp dport 8040-8060 dnat to 192.168.42.99:8040-8060`,
` iifname "uplink0" tcp dport 8045 dnat to 192.168.42.22:8045`,
` iifname "uplink0" tcp dport http-alt dnat to 192.168.42.23:9999`,
` }`,
``,
` chain postrouting {`,
` type nat hook postrouting priority 100; policy accept;`,
` oifname "uplink0" masquerade`,
` }`,
`}`,
`table ip filter {`,
` counter fwded {`,
` packets 23 bytes 42`,
` }`,
``,
` chain forward {`,
` type filter hook forward priority 0; policy accept;`,
` counter name "fwded"`,
` oifname "uplink0" tcp flags syn tcp option maxseg size set rt mtu`,
` }`,
`}`,
`table ip6 filter {`,
` counter fwded {`,
` packets 23 bytes 42`,
` }`,
``,
` chain forward {`,
` type filter hook forward priority 0; policy accept;`,
` counter name "fwded"`,
` oifname "uplink0" tcp flags syn tcp option maxseg size set rt mtu`,
` }`,
`}`,
}
if diff := cmp.Diff(rules, wantRules, opts...); diff != "" {
t.Fatalf("unexpected nftables rules: diff (-got +want):\n%s", diff)
} }
})
} }
func ipLines(args ...string) ([]string, error) { func ipLines(args ...string) ([]string, error) {