github.com/kaisenlinux/docker.io@v0.0.0-20230510090727-ea55db55fac7/libnetwork/resolvconf/resolvconf_test.go (about)

     1  package resolvconf
     2  
     3  import (
     4  	"bytes"
     5  	"io/ioutil"
     6  	"os"
     7  	"testing"
     8  
     9  	"github.com/docker/docker/pkg/ioutils"
    10  	_ "github.com/docker/libnetwork/testutils"
    11  	"github.com/docker/libnetwork/types"
    12  )
    13  
    14  func TestGet(t *testing.T) {
    15  	resolvConfUtils, err := Get()
    16  	if err != nil {
    17  		t.Fatal(err)
    18  	}
    19  	resolvConfSystem, err := ioutil.ReadFile("/etc/resolv.conf")
    20  	if err != nil {
    21  		t.Fatal(err)
    22  	}
    23  	if string(resolvConfUtils.Content) != string(resolvConfSystem) {
    24  		t.Fatalf("/etc/resolv.conf and GetResolvConf have different content.")
    25  	}
    26  	hashSystem, err := ioutils.HashData(bytes.NewReader(resolvConfSystem))
    27  	if err != nil {
    28  		t.Fatal(err)
    29  	}
    30  	if resolvConfUtils.Hash != hashSystem {
    31  		t.Fatalf("/etc/resolv.conf and GetResolvConf have different hashes.")
    32  	}
    33  }
    34  
    35  func TestGetNameservers(t *testing.T) {
    36  	for resolv, result := range map[string][]string{`
    37  nameserver 1.2.3.4
    38  nameserver 40.3.200.10
    39  search example.com`: {"1.2.3.4", "40.3.200.10"},
    40  		`search example.com`: {},
    41  		`nameserver 1.2.3.4
    42  search example.com
    43  nameserver 4.30.20.100`: {"1.2.3.4", "4.30.20.100"},
    44  		``:                        {},
    45  		`  nameserver 1.2.3.4   `: {"1.2.3.4"},
    46  		`search example.com
    47  nameserver 1.2.3.4
    48  #nameserver 4.3.2.1`: {"1.2.3.4"},
    49  		`search example.com
    50  nameserver 1.2.3.4 # not 4.3.2.1`: {"1.2.3.4"},
    51  	} {
    52  		test := GetNameservers([]byte(resolv), types.IP)
    53  		if !strSlicesEqual(test, result) {
    54  			t.Fatalf("Wrong nameserver string {%s} should be %v. Input: %s", test, result, resolv)
    55  		}
    56  	}
    57  }
    58  
    59  func TestGetNameserversAsCIDR(t *testing.T) {
    60  	for resolv, result := range map[string][]string{`
    61  nameserver 1.2.3.4
    62  nameserver 40.3.200.10
    63  search example.com`: {"1.2.3.4/32", "40.3.200.10/32"},
    64  		`search example.com`: {},
    65  		`nameserver 1.2.3.4
    66  search example.com
    67  nameserver 4.30.20.100`: {"1.2.3.4/32", "4.30.20.100/32"},
    68  		``:                        {},
    69  		`  nameserver 1.2.3.4   `: {"1.2.3.4/32"},
    70  		`search example.com
    71  nameserver 1.2.3.4
    72  #nameserver 4.3.2.1`: {"1.2.3.4/32"},
    73  		`search example.com
    74  nameserver 1.2.3.4 # not 4.3.2.1`: {"1.2.3.4/32"},
    75  	} {
    76  		test := GetNameserversAsCIDR([]byte(resolv))
    77  		if !strSlicesEqual(test, result) {
    78  			t.Fatalf("Wrong nameserver string {%s} should be %v. Input: %s", test, result, resolv)
    79  		}
    80  	}
    81  }
    82  
    83  func TestGetSearchDomains(t *testing.T) {
    84  	for resolv, result := range map[string][]string{
    85  		`search example.com`:           {"example.com"},
    86  		`search example.com # ignored`: {"example.com"},
    87  		`	  search	 example.com	  `: {"example.com"},
    88  		`	  search	 example.com	  # ignored`: {"example.com"},
    89  		`search foo.example.com example.com`: {"foo.example.com", "example.com"},
    90  		`	   search	   foo.example.com	 example.com	`: {"foo.example.com", "example.com"},
    91  		`	   search	   foo.example.com	 example.com	# ignored`: {"foo.example.com", "example.com"},
    92  		``:          {},
    93  		`# ignored`: {},
    94  		`nameserver 1.2.3.4
    95  search foo.example.com example.com`: {"foo.example.com", "example.com"},
    96  		`nameserver 1.2.3.4
    97  search dup1.example.com dup2.example.com
    98  search foo.example.com example.com`: {"foo.example.com", "example.com"},
    99  		`nameserver 1.2.3.4
   100  search foo.example.com example.com
   101  nameserver 4.30.20.100`: {"foo.example.com", "example.com"},
   102  	} {
   103  		test := GetSearchDomains([]byte(resolv))
   104  		if !strSlicesEqual(test, result) {
   105  			t.Fatalf("Wrong search domain string {%s} should be %v. Input: %s", test, result, resolv)
   106  		}
   107  	}
   108  }
   109  
   110  func TestGetOptions(t *testing.T) {
   111  	for resolv, result := range map[string][]string{
   112  		`options opt1`:           {"opt1"},
   113  		`options opt1 # ignored`: {"opt1"},
   114  		`	  options	 opt1	  `: {"opt1"},
   115  		`	  options	 opt1	  # ignored`: {"opt1"},
   116  		`options opt1 opt2 opt3`:           {"opt1", "opt2", "opt3"},
   117  		`options opt1 opt2 opt3 # ignored`: {"opt1", "opt2", "opt3"},
   118  		`	   options	 opt1	 opt2	 opt3	`: {"opt1", "opt2", "opt3"},
   119  		`	   options	 opt1	 opt2	 opt3	# ignored`: {"opt1", "opt2", "opt3"},
   120  		``:                   {},
   121  		`# ignored`:          {},
   122  		`nameserver 1.2.3.4`: {},
   123  		`nameserver 1.2.3.4
   124  options opt1 opt2 opt3`: {"opt1", "opt2", "opt3"},
   125  		`nameserver 1.2.3.4
   126  options opt1 opt2
   127  options opt3 opt4`: {"opt3", "opt4"},
   128  	} {
   129  		test := GetOptions([]byte(resolv))
   130  		if !strSlicesEqual(test, result) {
   131  			t.Fatalf("Wrong options string {%s} should be %v. Input: %s", test, result, resolv)
   132  		}
   133  	}
   134  }
   135  
   136  func strSlicesEqual(a, b []string) bool {
   137  	if len(a) != len(b) {
   138  		return false
   139  	}
   140  
   141  	for i, v := range a {
   142  		if v != b[i] {
   143  			return false
   144  		}
   145  	}
   146  
   147  	return true
   148  }
   149  
   150  func TestBuild(t *testing.T) {
   151  	file, err := ioutil.TempFile("", "")
   152  	if err != nil {
   153  		t.Fatal(err)
   154  	}
   155  	defer os.Remove(file.Name())
   156  
   157  	_, err = Build(file.Name(), []string{"ns1", "ns2", "ns3"}, []string{"search1"}, []string{"opt1"})
   158  	if err != nil {
   159  		t.Fatal(err)
   160  	}
   161  
   162  	content, err := ioutil.ReadFile(file.Name())
   163  	if err != nil {
   164  		t.Fatal(err)
   165  	}
   166  
   167  	if expected := "search search1\nnameserver ns1\nnameserver ns2\nnameserver ns3\noptions opt1\n"; !bytes.Contains(content, []byte(expected)) {
   168  		t.Fatalf("Expected to find '%s' got '%s'", expected, content)
   169  	}
   170  }
   171  
   172  func TestBuildWithZeroLengthDomainSearch(t *testing.T) {
   173  	file, err := ioutil.TempFile("", "")
   174  	if err != nil {
   175  		t.Fatal(err)
   176  	}
   177  	defer os.Remove(file.Name())
   178  
   179  	_, err = Build(file.Name(), []string{"ns1", "ns2", "ns3"}, []string{"."}, []string{"opt1"})
   180  	if err != nil {
   181  		t.Fatal(err)
   182  	}
   183  
   184  	content, err := ioutil.ReadFile(file.Name())
   185  	if err != nil {
   186  		t.Fatal(err)
   187  	}
   188  
   189  	if expected := "nameserver ns1\nnameserver ns2\nnameserver ns3\noptions opt1\n"; !bytes.Contains(content, []byte(expected)) {
   190  		t.Fatalf("Expected to find '%s' got '%s'", expected, content)
   191  	}
   192  	if notExpected := "search ."; bytes.Contains(content, []byte(notExpected)) {
   193  		t.Fatalf("Expected to not find '%s' got '%s'", notExpected, content)
   194  	}
   195  }
   196  
   197  func TestBuildWithNoOptions(t *testing.T) {
   198  	file, err := ioutil.TempFile("", "")
   199  	if err != nil {
   200  		t.Fatal(err)
   201  	}
   202  	defer os.Remove(file.Name())
   203  
   204  	_, err = Build(file.Name(), []string{"ns1", "ns2", "ns3"}, []string{"search1"}, []string{})
   205  	if err != nil {
   206  		t.Fatal(err)
   207  	}
   208  
   209  	content, err := ioutil.ReadFile(file.Name())
   210  	if err != nil {
   211  		t.Fatal(err)
   212  	}
   213  
   214  	if expected := "search search1\nnameserver ns1\nnameserver ns2\nnameserver ns3\n"; !bytes.Contains(content, []byte(expected)) {
   215  		t.Fatalf("Expected to find '%s' got '%s'", expected, content)
   216  	}
   217  	if notExpected := "search ."; bytes.Contains(content, []byte(notExpected)) {
   218  		t.Fatalf("Expected to not find '%s' got '%s'", notExpected, content)
   219  	}
   220  }
   221  
   222  func TestFilterResolvDns(t *testing.T) {
   223  	ns0 := "nameserver 10.16.60.14\nnameserver 10.16.60.21\n"
   224  
   225  	if result, _ := FilterResolvDNS([]byte(ns0), false); result != nil {
   226  		if ns0 != string(result.Content) {
   227  			t.Fatalf("Failed No Localhost: expected \n<%s> got \n<%s>", ns0, string(result.Content))
   228  		}
   229  	}
   230  
   231  	ns1 := "nameserver 10.16.60.14\nnameserver 10.16.60.21\nnameserver 127.0.0.1\n"
   232  	if result, _ := FilterResolvDNS([]byte(ns1), false); result != nil {
   233  		if ns0 != string(result.Content) {
   234  			t.Fatalf("Failed Localhost: expected \n<%s> got \n<%s>", ns0, string(result.Content))
   235  		}
   236  	}
   237  
   238  	ns1 = "nameserver 10.16.60.14\nnameserver 127.0.0.1\nnameserver 10.16.60.21\n"
   239  	if result, _ := FilterResolvDNS([]byte(ns1), false); result != nil {
   240  		if ns0 != string(result.Content) {
   241  			t.Fatalf("Failed Localhost: expected \n<%s> got \n<%s>", ns0, string(result.Content))
   242  		}
   243  	}
   244  
   245  	ns1 = "nameserver 127.0.1.1\nnameserver 10.16.60.14\nnameserver 10.16.60.21\n"
   246  	if result, _ := FilterResolvDNS([]byte(ns1), false); result != nil {
   247  		if ns0 != string(result.Content) {
   248  			t.Fatalf("Failed Localhost: expected \n<%s> got \n<%s>", ns0, string(result.Content))
   249  		}
   250  	}
   251  
   252  	ns1 = "nameserver ::1\nnameserver 10.16.60.14\nnameserver 127.0.2.1\nnameserver 10.16.60.21\n"
   253  	if result, _ := FilterResolvDNS([]byte(ns1), false); result != nil {
   254  		if ns0 != string(result.Content) {
   255  			t.Fatalf("Failed Localhost: expected \n<%s> got \n<%s>", ns0, string(result.Content))
   256  		}
   257  	}
   258  
   259  	ns1 = "nameserver 10.16.60.14\nnameserver ::1\nnameserver 10.16.60.21\nnameserver ::1"
   260  	if result, _ := FilterResolvDNS([]byte(ns1), false); result != nil {
   261  		if ns0 != string(result.Content) {
   262  			t.Fatalf("Failed Localhost: expected \n<%s> got \n<%s>", ns0, string(result.Content))
   263  		}
   264  	}
   265  
   266  	// with IPv6 disabled (false param), the IPv6 nameserver should be removed
   267  	ns1 = "nameserver 10.16.60.14\nnameserver 2002:dead:beef::1\nnameserver 10.16.60.21\nnameserver ::1"
   268  	if result, _ := FilterResolvDNS([]byte(ns1), false); result != nil {
   269  		if ns0 != string(result.Content) {
   270  			t.Fatalf("Failed Localhost+IPv6 off: expected \n<%s> got \n<%s>", ns0, string(result.Content))
   271  		}
   272  	}
   273  
   274  	// with IPv6 disabled (false param), the IPv6 link-local nameserver with zone ID should be removed
   275  	ns1 = "nameserver 10.16.60.14\nnameserver FE80::BB1%1\nnameserver FE80::BB1%eth0\nnameserver 10.16.60.21\n"
   276  	if result, _ := FilterResolvDNS([]byte(ns1), false); result != nil {
   277  		if ns0 != string(result.Content) {
   278  			t.Fatalf("Failed Localhost+IPv6 off: expected \n<%s> got \n<%s>", ns0, string(result.Content))
   279  		}
   280  	}
   281  
   282  	// with IPv6 enabled, the IPv6 nameserver should be preserved
   283  	ns0 = "nameserver 10.16.60.14\nnameserver 2002:dead:beef::1\nnameserver 10.16.60.21\n"
   284  	ns1 = "nameserver 10.16.60.14\nnameserver 2002:dead:beef::1\nnameserver 10.16.60.21\nnameserver ::1"
   285  	if result, _ := FilterResolvDNS([]byte(ns1), true); result != nil {
   286  		if ns0 != string(result.Content) {
   287  			t.Fatalf("Failed Localhost+IPv6 on: expected \n<%s> got \n<%s>", ns0, string(result.Content))
   288  		}
   289  	}
   290  
   291  	// with IPv6 enabled, and no non-localhost servers, Google defaults (both IPv4+IPv6) should be added
   292  	ns0 = "\nnameserver 8.8.8.8\nnameserver 8.8.4.4\nnameserver 2001:4860:4860::8888\nnameserver 2001:4860:4860::8844"
   293  	ns1 = "nameserver 127.0.0.1\nnameserver ::1\nnameserver 127.0.2.1"
   294  	if result, _ := FilterResolvDNS([]byte(ns1), true); result != nil {
   295  		if ns0 != string(result.Content) {
   296  			t.Fatalf("Failed no Localhost+IPv6 enabled: expected \n<%s> got \n<%s>", ns0, string(result.Content))
   297  		}
   298  	}
   299  
   300  	// with IPv6 disabled, and no non-localhost servers, Google defaults (only IPv4) should be added
   301  	ns0 = "\nnameserver 8.8.8.8\nnameserver 8.8.4.4"
   302  	ns1 = "nameserver 127.0.0.1\nnameserver ::1\nnameserver 127.0.2.1"
   303  	if result, _ := FilterResolvDNS([]byte(ns1), false); result != nil {
   304  		if ns0 != string(result.Content) {
   305  			t.Fatalf("Failed no Localhost+IPv6 enabled: expected \n<%s> got \n<%s>", ns0, string(result.Content))
   306  		}
   307  	}
   308  }