Skip to content

Commit

Permalink
aghnet: cover with tests
Browse files Browse the repository at this point in the history
  • Loading branch information
EugeneOne1 committed Jan 21, 2022
1 parent f7ff02f commit 28d8e64
Show file tree
Hide file tree
Showing 8 changed files with 226 additions and 109 deletions.
3 changes: 2 additions & 1 deletion internal/aghnet/dhcp_unix.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,8 @@ import (
"github.com/insomniacslk/dhcp/iana"
)

// defaultDiscoverTime is the
// defaultDiscoverTime is the default timeout of checking another DHCP server
// response.
const defaultDiscoverTime = 3 * time.Second

func checkOtherDHCP(ifaceName string) (ok4, ok6 bool, err4, err6 error) {
Expand Down
11 changes: 11 additions & 0 deletions internal/aghnet/dhcp_unix_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
//go:build aix || darwin || dragonfly || freebsd || linux || netbsd || openbsd || solaris
// +build aix darwin dragonfly freebsd linux netbsd openbsd solaris

package aghnet

import (
"testing"
)

func TestCheckOtherDHCP(t *testing.T) {
}
26 changes: 17 additions & 9 deletions internal/aghnet/hostscontainer_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -344,6 +344,8 @@ func TestHostsContainer(t *testing.T) {
testdata := os.DirFS("./testdata")

nRewrites := func(t *testing.T, res *urlfilter.DNSResult, n int) (rws []*rules.DNSRewrite) {
require.NotNil(t, res)

rewrites := res.DNSRewrites()
require.Len(t, rewrites, n)

Expand Down Expand Up @@ -408,7 +410,7 @@ func TestHostsContainer(t *testing.T) {
DNSType: dns.TypeA,
},
testTail: func(t *testing.T, res *urlfilter.DNSResult) {
assert.Empty(t, res.DNSRewrites())
nRewrites(t, res, 0)
},
}, {
name: "hello_alias_subdomain",
Expand All @@ -417,7 +419,7 @@ func TestHostsContainer(t *testing.T) {
DNSType: dns.TypeA,
},
testTail: func(t *testing.T, res *urlfilter.DNSResult) {
assert.Empty(t, res.DNSRewrites())
nRewrites(t, res, 0)
},
}, {
name: "lots_of_aliases",
Expand All @@ -435,10 +437,10 @@ func TestHostsContainer(t *testing.T) {
DNSType: dns.TypePTR,
},
testTail: func(t *testing.T, res *urlfilter.DNSResult) {
rws := nRewrites(t, res, 1)
rw := nRewrites(t, res, 1)[0]

assert.Equal(t, dns.TypePTR, rws[0].RRType)
assert.Equal(t, "simplehost.", rws[0].Value)
assert.Equal(t, dns.TypePTR, rw.RRType)
assert.Equal(t, "simplehost.", rw.Value)
},
}, {
name: "non-existing",
Expand All @@ -447,9 +449,16 @@ func TestHostsContainer(t *testing.T) {
DNSType: dns.TypeA,
},
testTail: func(t *testing.T, res *urlfilter.DNSResult) {
require.NotNil(t, res)

assert.Nil(t, res.DNSRewrites())
nRewrites(t, res, 0)
},
}, {
name: "bad_type",
req: urlfilter.DNSRequest{
Hostname: "1.0.0.1.in-addr.arpa",
DNSType: dns.TypeSRV,
},
testTail: func(t *testing.T, res *urlfilter.DNSResult) {
assert.Nil(t, res)
},
}}

Expand All @@ -466,7 +475,6 @@ func TestHostsContainer(t *testing.T) {
t.Run(tc.name, func(t *testing.T) {
res, ok := hc.MatchRequest(tc.req)
require.False(t, ok)
require.NotNil(t, res)

tc.testTail(t, res)
})
Expand Down
36 changes: 19 additions & 17 deletions internal/aghnet/interfaces.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,13 @@ type NetIface interface {

// IfaceIPAddrs returns the interface's IP addresses.
func IfaceIPAddrs(iface NetIface, ipv IPVersion) (ips []net.IP, err error) {
switch ipv {
case IPVersion4, IPVersion6:
// Go on.
default:
return nil, fmt.Errorf("invalid ip version %d", ipv)
}

addrs, err := iface.Addrs()
if err != nil {
return nil, err
Expand All @@ -41,20 +48,15 @@ func IfaceIPAddrs(iface NetIface, ipv IPVersion) (ips []net.IP, err error) {
continue
}

// Assume that net.(*Interface).Addrs can only return valid IPv4
// and IPv6 addresses. Thus, if it isn't an IPv4 address, it
// must be an IPv6 one.
switch ipv {
case IPVersion4:
if ip4 := ip.To4(); ip4 != nil {
// Assume that net.(*Interface).Addrs can only return valid IPv4 and
// IPv6 addresses. Thus, if it isn't an IPv4 address, it must be an
// IPv6 one.
if ip4 := ip.To4(); ipv == IPVersion4 {
if ip4 != nil {
ips = append(ips, ip4)
}
case IPVersion6:
if ip6 := ip.To4(); ip6 == nil {
ips = append(ips, ip)
}
default:
return nil, fmt.Errorf("invalid ip version %d", ipv)
} else if ip4 == nil {
ips = append(ips, ip)
}
}

Expand Down Expand Up @@ -96,16 +98,16 @@ func IfaceDNSIPAddrs(

switch len(addrs) {
case 0:
// Don't return errors in case the users want to try and enable
// the DHCP server later.
// Don't return errors in case the users want to try and enable the DHCP
// server later.
t := time.Duration(n) * backoff
log.Error("dhcpv%d: no ip for iface after %d attempts and %s", ipv, n, t)

return nil, nil
case 1:
// Some Android devices use 8.8.8.8 if there is not a secondary
// DNS server. Fix that by setting the secondary DNS address to
// the same address.
// Some Android devices use 8.8.8.8 if there is not a secondary DNS
// server. Fix that by setting the secondary DNS address to the same
// address.
//
// See https://github.com/AdguardTeam/AdGuardHome/issues/1708.
log.Debug("dhcpv%d: setting secondary dns ip to itself", ipv)
Expand Down
125 changes: 82 additions & 43 deletions internal/aghnet/interfaces_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,15 @@ import (
"testing"

"github.com/AdguardTeam/golibs/errors"
"github.com/AdguardTeam/golibs/testutil"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)

// fakeIface is a stub implementation of aghnet.NetIface to simplify testing.
type fakeIface struct {
addrs []net.Addr
err error
addrs []net.Addr
}

// Addrs implements the NetIface interface for *fakeIface.
Expand All @@ -33,53 +35,78 @@ func TestIfaceIPAddrs(t *testing.T) {
addr6 := &net.IPNet{IP: ip6}

testCases := []struct {
name string
iface NetIface
ipv IPVersion
want []net.IP
wantErr error
iface NetIface
name string
wantErrMsg string
want []net.IP
ipv IPVersion
}{{
name: "ipv4_success",
iface: &fakeIface{addrs: []net.Addr{addr4}, err: nil},
ipv: IPVersion4,
want: []net.IP{ip4},
wantErr: nil,
iface: &fakeIface{addrs: []net.Addr{addr4}, err: nil},
name: "ipv4_success",
wantErrMsg: "",
want: []net.IP{ip4},
ipv: IPVersion4,
}, {
name: "ipv4_success_with_ipv6",
iface: &fakeIface{addrs: []net.Addr{addr6, addr4}, err: nil},
ipv: IPVersion4,
want: []net.IP{ip4},
wantErr: nil,
iface: &fakeIface{addrs: []net.Addr{addr6, addr4}, err: nil},
name: "ipv4_success_with_ipv6",
wantErrMsg: "",
want: []net.IP{ip4},
ipv: IPVersion4,
}, {
name: "ipv4_error",
iface: &fakeIface{addrs: []net.Addr{addr4}, err: errTest},
ipv: IPVersion4,
want: nil,
wantErr: errTest,
iface: &fakeIface{addrs: []net.Addr{addr4}, err: errTest},
name: "ipv4_error",
wantErrMsg: errTest.Error(),
want: nil,
ipv: IPVersion4,
}, {
name: "ipv6_success",
iface: &fakeIface{addrs: []net.Addr{addr6}, err: nil},
ipv: IPVersion6,
want: []net.IP{ip6},
wantErr: nil,
iface: &fakeIface{addrs: []net.Addr{addr6}, err: nil},
name: "ipv6_success",
wantErrMsg: "",
want: []net.IP{ip6},
ipv: IPVersion6,
}, {
name: "ipv6_success_with_ipv4",
iface: &fakeIface{addrs: []net.Addr{addr6, addr4}, err: nil},
ipv: IPVersion6,
want: []net.IP{ip6},
wantErr: nil,
iface: &fakeIface{addrs: []net.Addr{addr6, addr4}, err: nil},
name: "ipv6_success_with_ipv4",
wantErrMsg: "",
want: []net.IP{ip6},
ipv: IPVersion6,
}, {
name: "ipv6_error",
iface: &fakeIface{addrs: []net.Addr{addr6}, err: errTest},
ipv: IPVersion6,
want: nil,
wantErr: errTest,
iface: &fakeIface{addrs: []net.Addr{addr6}, err: errTest},
name: "ipv6_error",
wantErrMsg: errTest.Error(),
want: nil,
ipv: IPVersion6,
}, {
iface: &fakeIface{addrs: nil, err: nil},
name: "bad_proto",
wantErrMsg: "invalid ip version 10",
want: nil,
ipv: IPVersion6 + IPVersion4,
}, {
iface: &fakeIface{addrs: []net.Addr{&net.IPAddr{IP: ip4}}, err: nil},
name: "ipaddr_v4",
wantErrMsg: "",
want: []net.IP{ip4},
ipv: IPVersion4,
}, {
iface: &fakeIface{addrs: []net.Addr{&net.IPAddr{IP: ip6, Zone: ""}}, err: nil},
name: "ipaddr_v6",
wantErrMsg: "",
want: []net.IP{ip6},
ipv: IPVersion6,
}, {
iface: &fakeIface{addrs: []net.Addr{&net.UnixAddr{}}, err: nil},
name: "non-ipv4",
wantErrMsg: "",
want: nil,
ipv: IPVersion4,
}}

for _, tc := range testCases {
t.Run(tc.name, func(t *testing.T) {
got, gotErr := IfaceIPAddrs(tc.iface, tc.ipv)
require.True(t, errors.Is(gotErr, tc.wantErr))
got, err := IfaceIPAddrs(tc.iface, tc.ipv)
testutil.AssertErrorMsg(t, tc.wantErrMsg, err)

assert.Equal(t, tc.want, got)
})
}
Expand Down Expand Up @@ -116,11 +143,11 @@ func TestIfaceDNSIPAddrs(t *testing.T) {
addr6 := &net.IPNet{IP: ip6}

testCases := []struct {
name string
iface NetIface
ipv IPVersion
want []net.IP
wantErr error
name string
want []net.IP
ipv IPVersion
}{{
name: "ipv4_success",
iface: &fakeIface{addrs: []net.Addr{addr4}, err: nil},
Expand Down Expand Up @@ -169,12 +196,24 @@ func TestIfaceDNSIPAddrs(t *testing.T) {
ipv: IPVersion6,
want: []net.IP{ip6, ip6},
wantErr: nil,
}, {
name: "empty",
iface: &fakeIface{addrs: nil, err: nil},
ipv: IPVersion4,
want: nil,
wantErr: nil,
}, {
name: "many",
iface: &fakeIface{addrs: []net.Addr{addr4, addr4}},
ipv: IPVersion4,
want: []net.IP{ip4, ip4},
wantErr: nil,
}}

for _, tc := range testCases {
t.Run(tc.name, func(t *testing.T) {
got, gotErr := IfaceDNSIPAddrs(tc.iface, tc.ipv, 2, 0)
require.True(t, errors.Is(gotErr, tc.wantErr))
got, err := IfaceDNSIPAddrs(tc.iface, tc.ipv, 2, 0)
require.True(t, errors.Is(err, tc.wantErr))
assert.Equal(t, tc.want, got)
})
}
Expand Down
44 changes: 44 additions & 0 deletions internal/aghnet/ipmut_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
package aghnet

import (
"net"
"testing"

"github.com/AdguardTeam/golibs/netutil"
"github.com/stretchr/testify/assert"
)

func TestIPMut(t *testing.T) {
testIPs := []net.IP{{
127, 0, 0, 1,
}, {
192, 168, 0, 1,
}, {
8, 8, 8, 8,
}}

t.Run("nil", func(t *testing.T) {
ipmut := NewIPMut(nil)

ips := netutil.CloneIPs(testIPs)
for i := range ips {
ipmut.Load()(ips[i])
assert.True(t, ips[i].Equal(testIPs[i]))
}
})

t.Run("not_nil", func(t *testing.T) {
ipmut := NewIPMut(func(ip net.IP) {
for i := range ip {
ip[i] = 0
}
})
want := netutil.IPv4Zero()

ips := netutil.CloneIPs(testIPs)
for i := range ips {
ipmut.Load()(ips[i])
assert.True(t, ips[i].Equal(want))
}
})
}
Loading

0 comments on commit 28d8e64

Please sign in to comment.