dnsconf_test.go 3.3 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768
  1. package dnsconf
  2. import (
  3. "strings"
  4. "testing"
  5. )
  6. func TestParse(t *testing.T) {
  7. tests := []struct {
  8. name string
  9. value string
  10. wantErr string
  11. wantNil bool
  12. wantCount int
  13. }{
  14. {name: "blank", value: " ", wantNil: true},
  15. {name: "array of strings", value: `["1.1.1.1", "tls://1.0.0.1"]`, wantCount: 2},
  16. {name: "array with object entry", value: `[{"address": "1.1.1.1", "domains": ["geosite:youtube"]}]`, wantCount: 1},
  17. {name: "object with hosts and strategy", value: `{"queryStrategy": "UseIPv4", "hosts": {"example.com": "1.2.3.4"}, "servers": ["https://dns.google/dns-query"]}`, wantCount: 1},
  18. {name: "hosts value list", value: `{"hosts": {"example.com": ["1.2.3.4", "5.6.7.8"]}, "servers": ["1.1.1.1"]}`, wantCount: 1},
  19. {name: "comma separated domains", value: `[{"address": "1.1.1.1", "domains": "geosite:youtube,geosite:netflix"}]`, wantCount: 1},
  20. {name: "client ip set", value: `{"clientIp": "1.2.3.4", "servers": [{"address": "1.1.1.1", "clientIp": "2001:db8::1"}]}`, wantCount: 1},
  21. {name: "malformed JSON", value: `[`, wantErr: "invalid DNS JSON"},
  22. {name: "scalar", value: `42`, wantErr: "must be a JSON object or an array of servers"},
  23. {name: "empty array", value: `[]`, wantErr: `"servers" must list at least one DNS server`},
  24. {name: "object without servers", value: `{"hosts": {"a": "b"}}`, wantErr: `"servers" must list at least one DNS server`},
  25. {name: "misspelled servers key", value: `{"server": ["1.1.1.1"]}`, wantErr: `"servers" must list at least one DNS server`},
  26. {name: "non-string server entry", value: `[53]`, wantErr: "invalid DNS config"},
  27. {name: "server without address", value: `[{"skipFallback": true}]`, wantErr: `needs a non-empty "address"`},
  28. {name: "empty server string", value: `[""]`, wantErr: "is empty"},
  29. {name: "empty server address", value: `[{"address": " "}]`, wantErr: `needs a non-empty "address"`},
  30. {name: "server address wrong type", value: `[{"address": 53}]`, wantErr: "invalid DNS config"},
  31. {name: "hosts wrong type", value: `{"hosts": 5, "servers": ["1.1.1.1"]}`, wantErr: "invalid DNS config"},
  32. {name: "strategy wrong type", value: `{"queryStrategy": 123, "servers": ["1.1.1.1"]}`, wantErr: "invalid DNS config"},
  33. {name: "client ip not an address", value: `{"clientIp": "not-an-ip", "servers": ["1.1.1.1"]}`, wantErr: "clientIp must be an IP address"},
  34. {name: "server client ip not an address", value: `[{"address": "1.1.1.1", "clientIp": "example.com"}]`, wantErr: "clientIp must be an IP address"},
  35. {name: "server port as string", value: `[{"address": "1.1.1.1", "port": "53"}]`, wantErr: "invalid DNS config"},
  36. {name: "server domains wrong type", value: `[{"address": "1.1.1.1", "domains": 5}]`, wantErr: "invalid DNS config"},
  37. }
  38. for _, tc := range tests {
  39. t.Run(tc.name, func(t *testing.T) {
  40. block, err := Parse(tc.value)
  41. if tc.wantErr != "" {
  42. if err == nil || !strings.Contains(err.Error(), tc.wantErr) {
  43. t.Fatalf("err = %v, want %q", err, tc.wantErr)
  44. }
  45. return
  46. }
  47. if err != nil {
  48. t.Fatalf("unexpected error: %v", err)
  49. }
  50. if tc.wantNil {
  51. if block != nil {
  52. t.Fatalf("block = %v, want nil", block)
  53. }
  54. return
  55. }
  56. if block == nil {
  57. t.Fatal("block = nil")
  58. }
  59. servers, _ := block["servers"].([]any)
  60. if len(servers) != tc.wantCount {
  61. t.Fatalf("servers = %v, want %d", servers, tc.wantCount)
  62. }
  63. })
  64. }
  65. }