blocky/config/config_test.go

190 lines
5.9 KiB
Go

package config
import (
"io/ioutil"
"net"
"os"
. "github.com/0xERR0R/blocky/log"
. "github.com/onsi/ginkgo"
. "github.com/onsi/ginkgo/extensions/table"
. "github.com/onsi/gomega"
)
var _ = Describe("Config", func() {
Describe("Creation of Config", func() {
When("Test config file will be parsed", func() {
It("should return a valid config struct", func() {
err := os.Chdir("../testdata")
Expect(err).Should(Succeed())
LoadConfig("config.yml", true)
Expect(config.Port).Should(Equal("55555"))
Expect(config.Upstream.ExternalResolvers["default"]).Should(HaveLen(3))
Expect(config.Upstream.ExternalResolvers["default"][0].Host).Should(Equal("8.8.8.8"))
Expect(config.Upstream.ExternalResolvers["default"][1].Host).Should(Equal("8.8.4.4"))
Expect(config.Upstream.ExternalResolvers["default"][2].Host).Should(Equal("1.1.1.1"))
Expect(config.CustomDNS.Mapping.HostIPs).Should(HaveLen(2))
Expect(config.CustomDNS.Mapping.HostIPs["my.duckdns.org"][0]).Should(Equal(net.ParseIP("192.168.178.3")))
Expect(config.CustomDNS.Mapping.HostIPs["multiple.ips"][0]).Should(Equal(net.ParseIP("192.168.178.3")))
Expect(config.CustomDNS.Mapping.HostIPs["multiple.ips"][1]).Should(Equal(net.ParseIP("192.168.178.4")))
Expect(config.CustomDNS.Mapping.HostIPs["multiple.ips"][2]).Should(Equal(
net.ParseIP("2001:0db8:85a3:08d3:1319:8a2e:0370:7344")))
Expect(config.Conditional.Mapping.Upstreams).Should(HaveLen(2))
Expect(config.Conditional.Mapping.Upstreams["fritz.box"]).Should(HaveLen(1))
Expect(config.Conditional.Mapping.Upstreams["multiple.resolvers"]).Should(HaveLen(2))
Expect(config.ClientLookup.Upstream.Host).Should(Equal("192.168.178.1"))
Expect(config.ClientLookup.SingleNameOrder).Should(Equal([]uint{2, 1}))
Expect(config.Blocking.BlackLists).Should(HaveLen(2))
Expect(config.Blocking.WhiteLists).Should(HaveLen(1))
Expect(config.Blocking.ClientGroupsBlock).Should(HaveLen(2))
Expect(config.Caching.MaxCachingTime).Should(Equal(0))
Expect(config.Caching.MinCachingTime).Should(Equal(0))
})
})
When("config file is malformed", func() {
It("should log with fatal and exit", func() {
dir, err := ioutil.TempDir("", "blocky")
defer os.Remove(dir)
Expect(err).Should(Succeed())
err = os.Chdir(dir)
Expect(err).Should(Succeed())
err = ioutil.WriteFile("config.yml", []byte("malformed_config"), 0600)
Expect(err).Should(Succeed())
defer func() { Log().ExitFunc = nil }()
var fatal bool
Log().ExitFunc = func(int) { fatal = true }
LoadConfig("config.yml", true)
Expect(fatal).Should(BeTrue())
})
})
When("config directory does not exist", func() {
It("should log with fatal and exit if config is mandatory", func() {
err := os.Chdir("../..")
Expect(err).Should(Succeed())
defer func() { Log().ExitFunc = nil }()
var fatal bool
Log().ExitFunc = func(int) { fatal = true }
LoadConfig("config.yml", true)
Expect(fatal).Should(BeTrue())
})
It("should use default config if config is not mandatory", func() {
err := os.Chdir("../..")
Expect(err).Should(Succeed())
LoadConfig("config.yml", false)
Expect(config.LogLevel).Should(Equal("info"))
})
})
})
DescribeTable("parse upstream string",
func(in string, wantResult Upstream, wantErr bool) {
result, err := ParseUpstream(in)
if wantErr {
Expect(err).Should(HaveOccurred())
} else {
Expect(err).Should(Succeed())
}
Expect(result).Should(Equal(wantResult))
},
Entry("udp with port",
"udp:4.4.4.4:531",
Upstream{Net: "tcp+udp", Host: "4.4.4.4", Port: 531},
false),
Entry("udp without port, use default",
"udp:4.4.4.4",
Upstream{Net: "tcp+udp", Host: "4.4.4.4", Port: 53},
false),
Entry("tcp with port",
"tcp:4.4.4.4:4711",
Upstream{Net: "tcp+udp", Host: "4.4.4.4", Port: 4711},
false),
Entry("tcp without port, use default",
"tcp:4.4.4.4",
Upstream{Net: "tcp+udp", Host: "4.4.4.4", Port: 53},
false),
Entry("tcp-tls without port, use default",
"tcp-tls:4.4.4.4",
Upstream{Net: "tcp-tls", Host: "4.4.4.4", Port: 853},
false),
Entry("DoH without port, use default",
"https:4.4.4.4",
Upstream{Net: "https", Host: "4.4.4.4", Port: 443},
false),
Entry("DoH with port",
"https:4.4.4.4:888",
Upstream{Net: "https", Host: "4.4.4.4", Port: 888},
false),
Entry("DoH named",
"https://dns.google/dns-query",
Upstream{Net: "https", Host: "dns.google", Port: 443, Path: "/dns-query"},
false),
Entry("DoH named, path with multiple slashes",
"https://dns.google/dns-query/a/b",
Upstream{Net: "https", Host: "dns.google", Port: 443, Path: "/dns-query/a/b"},
false),
Entry("DoH named with port",
"https://dns.google:888/dns-query",
Upstream{Net: "https", Host: "dns.google", Port: 888, Path: "/dns-query"},
false),
Entry("empty",
"",
Upstream{Net: ""},
false),
Entry("udpIpv6WithPort",
"udp:[fd00::6cd4:d7e0:d99d:2952]:53",
Upstream{Net: "tcp+udp", Host: "fd00::6cd4:d7e0:d99d:2952", Port: 53},
false),
Entry("udpIpv6WithPort2",
"udp://[2001:4860:4860::8888]:53",
Upstream{Net: "tcp+udp", Host: "2001:4860:4860::8888", Port: 53},
false),
Entry("default net, default port",
"1.1.1.1",
Upstream{Net: "tcp+udp", Host: "1.1.1.1", Port: 53},
false),
Entry("default net with port",
"1.1.1.1:153",
Upstream{Net: "tcp+udp", Host: "1.1.1.1", Port: 153},
false),
Entry("with negative port",
"tcp:4.4.4.4:-1",
nil,
true),
Entry("with invalid port",
"tcp:4.4.4.4:65536",
nil,
true),
Entry("with not numeric port",
"tcp:4.4.4.4:A636",
nil,
true),
Entry("with wrong protocol",
"bla:4.4.4.4:53",
nil,
true),
Entry("tcp+udp",
"tcp+udp:1.1.1.1:53",
Upstream{Net: "tcp+udp", Host: "1.1.1.1", Port: 53},
false),
Entry("tcp+udp default port",
"tcp+udp:1.1.1.1",
Upstream{Net: "tcp+udp", Host: "1.1.1.1", Port: 53},
false),
)
})