github.com/juju/juju@v0.0.0-20240430160146-1752b71fcf00/core/network/dns_test.go (about)

     1  // Copyright 2021 Canonical Ltd.
     2  // Licensed under the AGPLv3, see LICENCE file for details.
     3  
     4  package network_test
     5  
     6  import (
     7  	"fmt"
     8  	"os"
     9  	"path/filepath"
    10  
    11  	"github.com/juju/testing"
    12  	jc "github.com/juju/testing/checkers"
    13  	gc "gopkg.in/check.v1"
    14  
    15  	"github.com/juju/juju/core/network"
    16  )
    17  
    18  type dnsSuite struct {
    19  	testing.IsolationSuite
    20  }
    21  
    22  var _ = gc.Suite(&dnsSuite{})
    23  
    24  func (*dnsSuite) TestParseResolvConfEmptyOrMissingPath(c *gc.C) {
    25  	emptyPath := ""
    26  	missingPath := filepath.Join(c.MkDir(), "missing")
    27  
    28  	for _, path := range []string{emptyPath, missingPath} {
    29  		result, err := network.ParseResolvConf(path)
    30  		c.Check(err, jc.ErrorIsNil)
    31  		c.Check(result, gc.IsNil)
    32  	}
    33  }
    34  
    35  func (*dnsSuite) TestParseResolvConfNotReadablePath(c *gc.C) {
    36  	unreadableConf := makeResolvConf(c, "#empty", 0000)
    37  	result, err := network.ParseResolvConf(unreadableConf)
    38  	expected := fmt.Sprintf("open %s: permission denied", unreadableConf)
    39  	c.Check(err, gc.ErrorMatches, expected)
    40  	c.Check(result, gc.IsNil)
    41  }
    42  
    43  func makeResolvConf(c *gc.C, content string, perms os.FileMode) string {
    44  	fakeConfPath := filepath.Join(c.MkDir(), "fake")
    45  	err := os.WriteFile(fakeConfPath, []byte(content), perms)
    46  	c.Check(err, jc.ErrorIsNil)
    47  	return fakeConfPath
    48  }
    49  
    50  func (*dnsSuite) TestParseResolvConfEmptyFile(c *gc.C) {
    51  	emptyConf := makeResolvConf(c, "", 0644)
    52  	result, err := network.ParseResolvConf(emptyConf)
    53  	c.Check(err, jc.ErrorIsNil)
    54  	// Expected non-nil, but empty result.
    55  	c.Check(result, jc.DeepEquals, &network.DNSConfig{})
    56  }
    57  
    58  func (*dnsSuite) TestParseResolvConfCommentsAndWhitespaceHandling(c *gc.C) {
    59  	const exampleConf = `
    60    ;; comment
    61  # also comment
    62  ;# ditto
    63    #nameserver ;still comment
    64  
    65    search    foo example.com       bar.     ;comment, leading/trailing ignored
    66  nameserver 8.8.8.8 #comment #still the same comment
    67  `
    68  	fakeConf := makeResolvConf(c, exampleConf, 0644)
    69  	result, err := network.ParseResolvConf(fakeConf)
    70  	c.Check(err, jc.ErrorIsNil)
    71  	c.Check(result, jc.DeepEquals, &network.DNSConfig{
    72  		Nameservers:   network.NewMachineAddresses([]string{"8.8.8.8"}).AsProviderAddresses(),
    73  		SearchDomains: []string{"foo", "example.com", "bar."},
    74  	})
    75  }
    76  
    77  func (*dnsSuite) TestParseResolvConfSearchWithoutValue(c *gc.C) {
    78  	badConf := makeResolvConf(c, "search # no value\n", 0644)
    79  	result, err := network.ParseResolvConf(badConf)
    80  	c.Check(err, gc.ErrorMatches, `parsing ".*", line 1: "search": required value\(s\) missing`)
    81  	c.Check(result, gc.IsNil)
    82  }
    83  
    84  func (*dnsSuite) TestParseResolvConfNameserverWithoutValue(c *gc.C) {
    85  	badConf := makeResolvConf(c, "nameserver", 0644)
    86  	result, err := network.ParseResolvConf(badConf)
    87  	c.Check(err, gc.ErrorMatches, `parsing ".*", line 1: "nameserver": required value\(s\) missing`)
    88  	c.Check(result, gc.IsNil)
    89  }
    90  
    91  func (*dnsSuite) TestParseResolvConfValueFollowedByCommentWithoutWhitespace(c *gc.C) {
    92  	badConf := makeResolvConf(c, "search foo bar#bad rest;is#ignored: still part of the comment", 0644)
    93  	result, err := network.ParseResolvConf(badConf)
    94  	c.Check(err, gc.ErrorMatches, `parsing ".*", line 1: "search": invalid value "bar#bad"`)
    95  	c.Check(result, gc.IsNil)
    96  }
    97  
    98  func (*dnsSuite) TestParseResolvConfNameserverWithMultipleValues(c *gc.C) {
    99  	badConf := makeResolvConf(c, "nameserver one two 42 ;;; comment still-inside-comment\n", 0644)
   100  	result, err := network.ParseResolvConf(badConf)
   101  	c.Check(err, gc.ErrorMatches, `parsing ".*", line 1: one value expected for "nameserver", got 3`)
   102  	c.Check(result, gc.IsNil)
   103  }
   104  
   105  func (*dnsSuite) TestParseResolvConfLastSearchWins(c *gc.C) {
   106  	const multiSearchConf = `
   107  search zero five
   108  search one
   109  # this below overrides all of the above
   110  search two three #comment ;also-comment still-comment
   111  `
   112  	fakeConf := makeResolvConf(c, multiSearchConf, 0644)
   113  	result, err := network.ParseResolvConf(fakeConf)
   114  	c.Check(err, jc.ErrorIsNil)
   115  	c.Check(result, jc.DeepEquals, &network.DNSConfig{
   116  		SearchDomains: []string{"two", "three"},
   117  	})
   118  }