automation-tests/common/libnetwork/resolvconf/resolv_test.go

253 lines
7.5 KiB
Go

package resolvconf
import (
"os"
"path/filepath"
"testing"
"github.com/opencontainers/runtime-spec/specs-go"
"github.com/stretchr/testify/assert"
)
const resolv1 = `nameserver 1.1.1.1
`
const resolv2 = `search example.com
nameserver 1.1.1.1
options edns0
`
func TestNew(t *testing.T) {
tests := []struct {
name string
baseContent string
nameservers []string
options []string
searches []string
ipv6 bool
hostns bool
keepHostServers bool
want string
}{
{
name: "simple resolv.conf",
baseContent: resolv1,
want: resolv1,
},
{
name: "simple resolv.conf with search and options",
baseContent: resolv2,
want: resolv2,
},
{
name: "simple resolv.conf with comments",
baseContent: "#some comment\n" + resolv2,
want: resolv2,
},
{
name: "overwrite default nameservers",
baseContent: resolv2,
nameservers: []string{"1.2.3.4", "5.6.7.8"},
want: "search example.com\nnameserver 1.2.3.4\nnameserver 5.6.7.8\noptions edns0\n",
},
{
name: "overwrite default options",
baseContent: resolv2,
options: []string{"ndots:2"},
want: "search example.com\nnameserver 1.1.1.1\noptions ndots:2\n",
},
{
name: "overwrite default searches",
baseContent: resolv2,
searches: []string{"test.com"},
want: "search test.com\nnameserver 1.1.1.1\noptions edns0\n",
},
{
name: "dot in searches should unset all search domains",
baseContent: resolv2,
searches: []string{"."},
want: "nameserver 1.1.1.1\noptions edns0\n",
},
{
name: "dot in searches should unset all search domains even with keepHostServers",
baseContent: resolv2,
searches: []string{"."},
keepHostServers: true,
want: "nameserver 1.1.1.1\noptions edns0\n",
},
{
name: "overwrite all",
baseContent: resolv2,
nameservers: []string{"1.2.3.4", "5.6.7.8"},
options: []string{"ndots:2"},
searches: []string{"test.com"},
want: "search test.com\nnameserver 1.2.3.4\nnameserver 5.6.7.8\noptions ndots:2\n",
},
{
name: "overwrite all and unset search",
baseContent: resolv2,
nameservers: []string{"1.2.3.4", "5.6.7.8"},
options: []string{"ndots:2"},
searches: []string{"."},
want: "nameserver 1.2.3.4\nnameserver 5.6.7.8\noptions ndots:2\n",
},
{
name: "set all and keep host server",
baseContent: resolv2,
nameservers: []string{"1.2.3.4", "5.6.7.8"},
options: []string{"ndots:2"},
searches: []string{"test.com"},
keepHostServers: true,
want: "search test.com example.com\nnameserver 1.2.3.4\nnameserver 5.6.7.8\nnameserver 1.1.1.1\noptions ndots:2 edns0\n",
},
{
name: "localhost nameservers should be filtered and use defaults instead",
baseContent: "nameserver 127.0.0.1\nnameserver ::1\n",
want: "nameserver 8.8.8.8\nnameserver 8.8.4.4\n",
},
{
name: "localhost nameservers should not be filtered with hostns",
baseContent: "nameserver 127.0.0.1\nnameserver ::1\n",
hostns: true,
want: "nameserver 127.0.0.1\nnameserver ::1\n",
},
{
name: "ipv6 nameservers should be filtered when ipv6 is not set",
baseContent: "nameserver 1.1.1.1\nnameserver fd::1\n",
want: "nameserver 1.1.1.1\n",
},
{
name: "ipv6 nameservers should not be filtered when ipv6 is set",
baseContent: "nameserver 1.1.1.1\nnameserver fd::1\n",
ipv6: true,
want: "nameserver 1.1.1.1\nnameserver fd::1\n",
},
{
name: "ipv6 link local must always be filtered when netns is private",
baseContent: "nameserver 1.1.1.1\nnameserver fe80::1%eth1\nnameserver fd::1\n",
ipv6: true,
want: "nameserver 1.1.1.1\nnameserver fd::1\n",
},
{
name: "ipv6 link local must not be filtered when netns is host",
baseContent: "nameserver 1.1.1.1\nnameserver fe80::1%eth1\nnameserver fd::1\n",
hostns: true,
want: "nameserver 1.1.1.1\nnameserver fe80::1%eth1\nnameserver fd::1\n",
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
base := filepath.Join(t.TempDir(), "resolv.conf")
target := filepath.Join(t.TempDir(), "new-resolv.conf")
err := os.WriteFile(base, []byte(tt.baseContent), 0o644)
assert.NoError(t, err, "write tmp resolv.conf")
var namespaces []specs.LinuxNamespace
if !tt.hostns {
namespaces = []specs.LinuxNamespace{
{Type: specs.NetworkNamespace},
}
}
err = New(&Params{
Path: target,
Nameservers: tt.nameservers,
Searches: tt.searches,
Options: tt.options,
IPv6Enabled: tt.ipv6,
KeepHostServers: tt.keepHostServers,
Namespaces: namespaces,
resolvConfPath: base,
})
assert.NoError(t, err, "New()")
content, err := os.ReadFile(target)
assert.NoError(t, err, "read tmp resolv.conf)")
assert.Equal(t, tt.want, string(content), "expected resolv.conf does not match")
})
}
}
func TestAdd(t *testing.T) {
tests := []struct {
name string
content string
nameservers []string
want string
}{
{
name: "add single nameserver",
content: resolv1,
nameservers: []string{"1.2.3.4"},
want: "nameserver 1.2.3.4\n" + resolv1,
},
{
name: "add single nameserver with search and options",
content: resolv2,
nameservers: []string{"1.2.3.4"},
want: `search example.com
nameserver 1.2.3.4
nameserver 1.1.1.1
options edns0
`,
},
{
name: "add three nameservers",
content: resolv1,
nameservers: []string{"1.2.3.4", "2.3.4.5", "3.4.5.6"},
want: "nameserver 1.2.3.4\nnameserver 2.3.4.5\nnameserver 3.4.5.6\n" + resolv1,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
resolvPath := filepath.Join(t.TempDir(), "resolv.conf")
err := os.WriteFile(resolvPath, []byte(tt.content), 0o644)
assert.NoError(t, err, "write tmp resolv.conf")
err = Add(resolvPath, tt.nameservers)
assert.NoError(t, err, "Add()")
content, err := os.ReadFile(resolvPath)
assert.NoError(t, err, "read tmp resolv.conf)")
assert.Equal(t, tt.want, string(content), "expected resolv.conf does not match")
})
}
}
func TestRemove(t *testing.T) {
tests := []struct {
name string
content string
nameservers []string
want string
}{
{
name: "remove single nameserver",
content: resolv1,
nameservers: []string{"1.1.1.1"},
want: "",
},
{
name: "remove single nameserver with search and options",
content: resolv2,
nameservers: []string{"1.1.1.1"},
want: `search example.com
options edns0
`,
},
{
name: "remove three nameservers",
content: "nameserver 1.2.3.4\nnameserver 2.3.4.5\nnameserver 3.4.5.6\n" + resolv1,
nameservers: []string{"1.2.3.4", "2.3.4.5", "3.4.5.6"},
want: resolv1,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
resolvPath := filepath.Join(t.TempDir(), "resolv.conf")
err := os.WriteFile(resolvPath, []byte(tt.content), 0o644)
assert.NoError(t, err, "write tmp resolv.conf")
err = Remove(resolvPath, tt.nameservers)
assert.NoError(t, err, "Remove()")
content, err := os.ReadFile(resolvPath)
assert.NoError(t, err, "read tmp resolv.conf)")
assert.Equal(t, tt.want, string(content), "expected resolv.conf does not match")
})
}
}