mirror of
https://github.com/StackExchange/dnscontrol.git
synced 2024-11-13 03:34:32 +08:00
153 lines
4.2 KiB
Go
153 lines
4.2 KiB
Go
package js
|
|
|
|
import (
|
|
"bytes"
|
|
"encoding/json"
|
|
"fmt"
|
|
"os"
|
|
"path/filepath"
|
|
"testing"
|
|
"unicode"
|
|
|
|
"github.com/StackExchange/dnscontrol/v4/pkg/normalize"
|
|
"github.com/StackExchange/dnscontrol/v4/pkg/prettyzone"
|
|
"github.com/StackExchange/dnscontrol/v4/providers"
|
|
_ "github.com/StackExchange/dnscontrol/v4/providers/_all"
|
|
testifyrequire "github.com/stretchr/testify/require"
|
|
)
|
|
|
|
const (
|
|
testDir = "pkg/js/parse_tests"
|
|
errorDir = "pkg/js/error_tests"
|
|
)
|
|
|
|
func init() {
|
|
os.Chdir("../..") // go up a directory so we helpers.js is in a consistent place.
|
|
}
|
|
|
|
func TestParsedFiles(t *testing.T) {
|
|
files, err := os.ReadDir(testDir)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
for _, f := range files {
|
|
name := f.Name()
|
|
|
|
// run all js files that start with a number. Skip others.
|
|
if filepath.Ext(name) != ".js" || !unicode.IsNumber(rune(name[0])) {
|
|
continue
|
|
}
|
|
t.Run(name, func(t *testing.T) {
|
|
var err error
|
|
|
|
// Compile the .js file:
|
|
conf, err := ExecuteJavaScript(string(filepath.Join(testDir, name)), true, nil)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
// for _, dc := range conf.Domains {
|
|
// normalize.UpdateNameSplitHorizon(dc)
|
|
// }
|
|
|
|
// Initialize any DNS providers mentioned.
|
|
for _, dProv := range conf.DNSProviders {
|
|
var pcfg = map[string]string{}
|
|
|
|
if dProv.Type == "-" {
|
|
// Pretend any "look up provider type in creds.json" results
|
|
// in a provider type that actually exists.
|
|
dProv.Type = "CLOUDFLAREAPI"
|
|
}
|
|
|
|
// Fake out any provider's validation tests.
|
|
switch dProv.Type {
|
|
case "CLOUDFLAREAPI":
|
|
pcfg["apitoken"] = "fake"
|
|
default:
|
|
}
|
|
_, err := providers.CreateDNSProvider(dProv.Type, pcfg, nil)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
}
|
|
|
|
// Test the JS compiled as expected (compare to the .json file)
|
|
actualJSON, err := json.MarshalIndent(conf, "", " ")
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
testName := name[:len(name)-3]
|
|
expectedFile := filepath.Join(testDir, testName+".json")
|
|
expectedJSON, err := os.ReadFile(expectedFile)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
es := string(expectedJSON)
|
|
as := string(actualJSON)
|
|
_, _ = es, as
|
|
// When debugging, leave behind the actual result:
|
|
os.WriteFile(expectedFile+".ACTUAL", []byte(as), 0644) // Leave behind the actual result:
|
|
testifyrequire.JSONEqf(t, es, as, "EXPECTING %q = \n```\n%s\n```", expectedFile, as)
|
|
|
|
// For each domain, if there is a zone file, test against it:
|
|
|
|
errs := normalize.ValidateAndNormalizeConfig(conf)
|
|
if len(errs) != 0 {
|
|
t.Fatal(errs[0])
|
|
}
|
|
|
|
var dCount int
|
|
for _, dc := range conf.Domains {
|
|
zoneFile := filepath.Join(testDir, testName, dc.Name+".zone")
|
|
expectedZone, err := os.ReadFile(zoneFile)
|
|
if err != nil {
|
|
continue
|
|
}
|
|
dCount++
|
|
|
|
// Generate the zonefile
|
|
var buf bytes.Buffer
|
|
err = prettyzone.WriteZoneFileRC(&buf, dc.Records, dc.Name, 300, nil)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
actualZone := buf.String()
|
|
|
|
es := string(expectedZone)
|
|
as := actualZone
|
|
if es != as {
|
|
// On failure, leave behind the .ACTUAL file.
|
|
os.WriteFile(zoneFile+".ACTUAL", []byte(actualZone), 0644)
|
|
}
|
|
testifyrequire.Equal(t, es, as, "EXPECTING %q =\n```\n%s```", zoneFile, as)
|
|
}
|
|
if dCount > 0 && (len(conf.Domains) != dCount) {
|
|
t.Fatal(fmt.Errorf("only %d of %d domains in %q have zonefiles", dCount, len(conf.Domains), name))
|
|
}
|
|
|
|
})
|
|
|
|
}
|
|
}
|
|
|
|
func TestErrors(t *testing.T) {
|
|
tests := []struct{ desc, text string }{
|
|
{"old dsp style", `D("foo.com","reg","dsp")`},
|
|
{"MX no priority", `D("foo.com","reg",MX("@","test."))`},
|
|
{"MX reversed", `D("foo.com","reg",MX("@","test.", 5))`},
|
|
{"CF_REDIRECT With comma", `D("foo.com","reg",CF_REDIRECT("foo.com,","baaa"))`},
|
|
{"CF_TEMP_REDIRECT With comma", `D("foo.com","reg",CF_TEMP_REDIRECT("foo.com","baa,a"))`},
|
|
{"CF_WORKER_ROUTE With comma", `D("foo.com","reg",CF_WORKER_ROUTE("foo.com","baa,a"))`},
|
|
{"Bad cidr", `D(reverse("foo.com"), "reg")`},
|
|
{"Dup domains", `D("example.org", "reg"); D("example.org", "reg")`},
|
|
{"Bad NAMESERVER", `D("example.com","reg", NAMESERVER("@","ns1.foo.com."))`},
|
|
}
|
|
for _, tst := range tests {
|
|
t.Run(tst.desc, func(t *testing.T) {
|
|
if _, err := ExecuteJavaScript(tst.text, true, nil); err == nil {
|
|
t.Fatal("Expected error but found none")
|
|
}
|
|
})
|
|
|
|
}
|
|
}
|