github.com/rumpl/bof@v23.0.0-rc.2+incompatible/libnetwork/resolvconf/resolvconf_linux_test.go (about)

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