refactor: remove ParseZone and parseZone (#1099)
This commit is contained in:
parent
5bfe94bb6e
commit
d128d10d17
|
@ -62,22 +62,23 @@ $GENERATE 0-1/0 dhcp-${0,4,d} A 10.0.0.$
|
||||||
{`@ IN SOA ns.test. hostmaster.test. ( 1 8h 2h 7d 1d )
|
{`@ IN SOA ns.test. hostmaster.test. ( 1 8h 2h 7d 1d )
|
||||||
$GENERATE 0-1 $$INCLUDE ` + tmpdir + string(filepath.Separator) + `${0,4,d}.conf
|
$GENERATE 0-1 $$INCLUDE ` + tmpdir + string(filepath.Separator) + `${0,4,d}.conf
|
||||||
`, false},
|
`, false},
|
||||||
{`@ IN SOA ns.test. hostmaster.test. ( 1 8h 2h 7d 1d )
|
{`@ IN SOA ns.test. hostmaster.test. ( 1 8h 2h 7d 1d )
|
||||||
$GENERATE 0-1 dhcp-${0,4,d} A 10.0.0.$
|
$GENERATE 0-1 dhcp-${0,4,d} A 10.0.0.$
|
||||||
$GENERATE 0-2 dhcp-${0,4,d} A 10.1.0.$
|
$GENERATE 0-2 dhcp-${0,4,d} A 10.1.0.$
|
||||||
`, false},
|
`, false},
|
||||||
}
|
}
|
||||||
Outer:
|
|
||||||
for i := range tests {
|
for i := range tests {
|
||||||
for tok := range ParseZone(strings.NewReader(tests[i].zone), "test.", "test") {
|
z := NewZoneParser(strings.NewReader(tests[i].zone), "test.", "test")
|
||||||
if tok.Error != nil {
|
z.SetIncludeAllowed(true)
|
||||||
if !tests[i].fail {
|
|
||||||
t.Errorf("expected \n\n%s\nto be parsed, but got %v", tests[i].zone, tok.Error)
|
for _, ok := z.Next(); ok; _, ok = z.Next() {
|
||||||
}
|
|
||||||
continue Outer
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
if tests[i].fail {
|
|
||||||
|
err := z.Err()
|
||||||
|
if err != nil && !tests[i].fail {
|
||||||
|
t.Errorf("expected \n\n%s\nto be parsed, but got %v", tests[i].zone, err)
|
||||||
|
} else if err == nil && tests[i].fail {
|
||||||
t.Errorf("expected \n\n%s\nto fail, but got no error", tests[i].zone)
|
t.Errorf("expected \n\n%s\nto fail, but got no error", tests[i].zone)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -546,25 +546,25 @@ $TTL 314
|
||||||
example.com. DNAME 10 ; TTL=314 after second $TTL
|
example.com. DNAME 10 ; TTL=314 after second $TTL
|
||||||
`
|
`
|
||||||
reCaseFromComment := regexp.MustCompile(`TTL=(\d+)\s+(.*)`)
|
reCaseFromComment := regexp.MustCompile(`TTL=(\d+)\s+(.*)`)
|
||||||
records := ParseZone(strings.NewReader(zone), "", "")
|
z := NewZoneParser(strings.NewReader(zone), "", "")
|
||||||
var i int
|
var i int
|
||||||
for record := range records {
|
|
||||||
|
for rr, ok := z.Next(); ok; rr, ok = z.Next() {
|
||||||
i++
|
i++
|
||||||
if record.Error != nil {
|
expected := reCaseFromComment.FindStringSubmatch(z.Comment())
|
||||||
t.Error(record.Error)
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
expected := reCaseFromComment.FindStringSubmatch(record.Comment)
|
|
||||||
if len(expected) != 3 {
|
if len(expected) != 3 {
|
||||||
t.Errorf("regexp didn't match for record %d", i)
|
t.Errorf("regexp didn't match for record %d", i)
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
expectedTTL, _ := strconv.ParseUint(expected[1], 10, 32)
|
expectedTTL, _ := strconv.ParseUint(expected[1], 10, 32)
|
||||||
ttl := record.RR.Header().Ttl
|
ttl := rr.Header().Ttl
|
||||||
if ttl != uint32(expectedTTL) {
|
if ttl != uint32(expectedTTL) {
|
||||||
t.Errorf("%s: expected TTL %d, got %d", expected[2], expectedTTL, ttl)
|
t.Errorf("%s: expected TTL %d, got %d", expected[2], expectedTTL, ttl)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if err := z.Err(); err != nil {
|
||||||
|
t.Error(err)
|
||||||
|
}
|
||||||
if i != 10 {
|
if i != 10 {
|
||||||
t.Errorf("expected %d records, got %d", 5, i)
|
t.Errorf("expected %d records, got %d", 5, i)
|
||||||
}
|
}
|
||||||
|
@ -603,16 +603,12 @@ func TestRelativeNameErrors(t *testing.T) {
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
for _, errorCase := range badZones {
|
for _, errorCase := range badZones {
|
||||||
entries := ParseZone(strings.NewReader(errorCase.zoneContents), "", "")
|
z := NewZoneParser(strings.NewReader(errorCase.zoneContents), "", "")
|
||||||
for entry := range entries {
|
z.Next()
|
||||||
if entry.Error == nil {
|
if err := z.Err(); err == nil {
|
||||||
t.Errorf("%s: expected error, got nil", errorCase.label)
|
t.Errorf("%s: expected error, got nil", errorCase.label)
|
||||||
continue
|
} else if !strings.Contains(err.Error(), errorCase.expectedErr) {
|
||||||
}
|
t.Errorf("%s: expected error `%s`, got `%s`", errorCase.label, errorCase.expectedErr, err)
|
||||||
err := entry.Error.err
|
|
||||||
if err != errorCase.expectedErr {
|
|
||||||
t.Errorf("%s: expected error `%s`, got `%s`", errorCase.label, errorCase.expectedErr, err)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -719,9 +715,13 @@ func TestRfc1982(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestEmpty(t *testing.T) {
|
func TestEmpty(t *testing.T) {
|
||||||
for range ParseZone(strings.NewReader(""), "", "") {
|
z := NewZoneParser(strings.NewReader(""), "", "")
|
||||||
|
for _, ok := z.Next(); ok; _, ok = z.Next() {
|
||||||
t.Errorf("should be empty")
|
t.Errorf("should be empty")
|
||||||
}
|
}
|
||||||
|
if err := z.Err(); err != nil {
|
||||||
|
t.Error("got an error when it shouldn't")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestLowercaseTokens(t *testing.T) {
|
func TestLowercaseTokens(t *testing.T) {
|
||||||
|
@ -889,18 +889,20 @@ foo. IN DNSKEY 256 3 5 AwEAAb+8l ; this is comment 6
|
||||||
foo. IN NSEC miek.nl. TXT RRSIG NSEC; this is comment 7
|
foo. IN NSEC miek.nl. TXT RRSIG NSEC; this is comment 7
|
||||||
foo. IN TXT "THIS IS TEXT MAN"; this is comment 8
|
foo. IN TXT "THIS IS TEXT MAN"; this is comment 8
|
||||||
`
|
`
|
||||||
for x := range ParseZone(strings.NewReader(zone), ".", "") {
|
z := NewZoneParser(strings.NewReader(zone), ".", "")
|
||||||
if x.Error == nil {
|
for _, ok := z.Next(); ok; _, ok = z.Next() {
|
||||||
if x.Comment != "" {
|
if z.Comment() != "" {
|
||||||
if _, ok := comments[x.Comment]; !ok {
|
if _, okC := comments[z.Comment()]; !okC {
|
||||||
t.Errorf("wrong comment %q", x.Comment)
|
t.Errorf("wrong comment %q", z.Comment())
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if err := z.Err(); err != nil {
|
||||||
|
t.Error("got an error when it shouldn't")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestParseZoneComments(t *testing.T) {
|
func TestZoneParserComments(t *testing.T) {
|
||||||
for i, test := range []struct {
|
for i, test := range []struct {
|
||||||
zone string
|
zone string
|
||||||
comments []string
|
comments []string
|
||||||
|
@ -975,24 +977,25 @@ func TestParseZoneComments(t *testing.T) {
|
||||||
r := strings.NewReader(test.zone)
|
r := strings.NewReader(test.zone)
|
||||||
|
|
||||||
var j int
|
var j int
|
||||||
for r := range ParseZone(r, "", "") {
|
z := NewZoneParser(r, "", "")
|
||||||
if r.Error != nil {
|
for rr, ok := z.Next(); ok; rr, ok = z.Next() {
|
||||||
t.Fatal(r.Error)
|
|
||||||
}
|
|
||||||
|
|
||||||
if j >= len(test.comments) {
|
if j >= len(test.comments) {
|
||||||
t.Fatalf("too many records for zone %d at %d record, expected %d", i, j+1, len(test.comments))
|
t.Fatalf("too many records for zone %d at %d record, expected %d", i, j+1, len(test.comments))
|
||||||
}
|
}
|
||||||
|
|
||||||
if r.Comment != test.comments[j] {
|
if z.Comment() != test.comments[j] {
|
||||||
t.Errorf("invalid comment for record %d:%d %v / %v", i, j, r.RR, r.Error)
|
t.Errorf("invalid comment for record %d:%d %v", i, j, rr)
|
||||||
t.Logf("expected %q", test.comments[j])
|
t.Logf("expected %q", test.comments[j])
|
||||||
t.Logf("got %q", r.Comment)
|
t.Logf("got %q", z.Comment())
|
||||||
}
|
}
|
||||||
|
|
||||||
j++
|
j++
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if err := z.Err(); err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
if j != len(test.comments) {
|
if j != len(test.comments) {
|
||||||
t.Errorf("too few records for zone %d, got %d, expected %d", i, j, len(test.comments))
|
t.Errorf("too few records for zone %d, got %d, expected %d", i, j, len(test.comments))
|
||||||
}
|
}
|
||||||
|
|
|
@ -158,9 +158,11 @@ func TestPrivateZoneParser(t *testing.T) {
|
||||||
defer dns.PrivateHandleRemove(TypeVERSION)
|
defer dns.PrivateHandleRemove(TypeVERSION)
|
||||||
|
|
||||||
r := strings.NewReader(smallzone)
|
r := strings.NewReader(smallzone)
|
||||||
for x := range dns.ParseZone(r, ".", "") {
|
z := dns.NewZoneParser(r, ".", "")
|
||||||
if err := x.Error; err != nil {
|
|
||||||
t.Fatal(err)
|
for _, ok := z.Next(); ok; _, ok = z.Next() {
|
||||||
}
|
}
|
||||||
|
if err := z.Err(); err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
74
scan.go
74
scan.go
|
@ -87,16 +87,6 @@ type lex struct {
|
||||||
column int // column in the file
|
column int // column in the file
|
||||||
}
|
}
|
||||||
|
|
||||||
// Token holds the token that are returned when a zone file is parsed.
|
|
||||||
type Token struct {
|
|
||||||
// The scanned resource record when error is not nil.
|
|
||||||
RR
|
|
||||||
// When an error occurred, this has the error specifics.
|
|
||||||
Error *ParseError
|
|
||||||
// A potential comment positioned after the RR and on the same line.
|
|
||||||
Comment string
|
|
||||||
}
|
|
||||||
|
|
||||||
// ttlState describes the state necessary to fill in an omitted RR TTL
|
// ttlState describes the state necessary to fill in an omitted RR TTL
|
||||||
type ttlState struct {
|
type ttlState struct {
|
||||||
ttl uint32 // ttl is the current default TTL
|
ttl uint32 // ttl is the current default TTL
|
||||||
|
@ -130,70 +120,6 @@ func ReadRR(r io.Reader, file string) (RR, error) {
|
||||||
return rr, zp.Err()
|
return rr, zp.Err()
|
||||||
}
|
}
|
||||||
|
|
||||||
// ParseZone reads a RFC 1035 style zonefile from r. It returns
|
|
||||||
// Tokens on the returned channel, each consisting of either a
|
|
||||||
// parsed RR and optional comment or a nil RR and an error. The
|
|
||||||
// channel is closed by ParseZone when the end of r is reached.
|
|
||||||
//
|
|
||||||
// The string file is used in error reporting and to resolve relative
|
|
||||||
// $INCLUDE directives. The string origin is used as the initial
|
|
||||||
// origin, as if the file would start with an $ORIGIN directive.
|
|
||||||
//
|
|
||||||
// The directives $INCLUDE, $ORIGIN, $TTL and $GENERATE are all
|
|
||||||
// supported. Note that $GENERATE's range support up to a maximum of
|
|
||||||
// of 65535 steps.
|
|
||||||
//
|
|
||||||
// Basic usage pattern when reading from a string (z) containing the
|
|
||||||
// zone data:
|
|
||||||
//
|
|
||||||
// for x := range dns.ParseZone(strings.NewReader(z), "", "") {
|
|
||||||
// if x.Error != nil {
|
|
||||||
// // log.Println(x.Error)
|
|
||||||
// } else {
|
|
||||||
// // Do something with x.RR
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// Comments specified after an RR (and on the same line!) are
|
|
||||||
// returned too:
|
|
||||||
//
|
|
||||||
// foo. IN A 10.0.0.1 ; this is a comment
|
|
||||||
//
|
|
||||||
// The text "; this is comment" is returned in Token.Comment.
|
|
||||||
// Comments inside the RR are returned concatenated along with the
|
|
||||||
// RR. Comments on a line by themselves are discarded.
|
|
||||||
//
|
|
||||||
// To prevent memory leaks it is important to always fully drain the
|
|
||||||
// returned channel. If an error occurs, it will always be the last
|
|
||||||
// Token sent on the channel.
|
|
||||||
//
|
|
||||||
// Deprecated: New users should prefer the ZoneParser API.
|
|
||||||
func ParseZone(r io.Reader, origin, file string) chan *Token {
|
|
||||||
t := make(chan *Token, 10000)
|
|
||||||
go parseZone(r, origin, file, t)
|
|
||||||
return t
|
|
||||||
}
|
|
||||||
|
|
||||||
func parseZone(r io.Reader, origin, file string, t chan *Token) {
|
|
||||||
defer close(t)
|
|
||||||
|
|
||||||
zp := NewZoneParser(r, origin, file)
|
|
||||||
zp.SetIncludeAllowed(true)
|
|
||||||
|
|
||||||
for rr, ok := zp.Next(); ok; rr, ok = zp.Next() {
|
|
||||||
t <- &Token{RR: rr, Comment: zp.Comment()}
|
|
||||||
}
|
|
||||||
|
|
||||||
if err := zp.Err(); err != nil {
|
|
||||||
pe, ok := err.(*ParseError)
|
|
||||||
if !ok {
|
|
||||||
pe = &ParseError{file: file, err: err.Error()}
|
|
||||||
}
|
|
||||||
|
|
||||||
t <- &Token{Error: pe}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// ZoneParser is a parser for an RFC 1035 style zonefile.
|
// ZoneParser is a parser for an RFC 1035 style zonefile.
|
||||||
//
|
//
|
||||||
// Each parsed RR in the zone is returned sequentially from Next. An
|
// Each parsed RR in the zone is returned sequentially from Next. An
|
||||||
|
|
70
scan_test.go
70
scan_test.go
|
@ -9,7 +9,7 @@ import (
|
||||||
"testing"
|
"testing"
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestParseZoneGenerate(t *testing.T) {
|
func TestZoneParserGenerate(t *testing.T) {
|
||||||
zone := "$ORIGIN example.org.\n$GENERATE 10-12 foo${2,3,d} IN A 127.0.0.$"
|
zone := "$ORIGIN example.org.\n$GENERATE 10-12 foo${2,3,d} IN A 127.0.0.$"
|
||||||
|
|
||||||
wantRRs := []RR{
|
wantRRs := []RR{
|
||||||
|
@ -17,22 +17,21 @@ func TestParseZoneGenerate(t *testing.T) {
|
||||||
&A{Hdr: RR_Header{Name: "foo013.example.org."}, A: net.ParseIP("127.0.0.11")},
|
&A{Hdr: RR_Header{Name: "foo013.example.org."}, A: net.ParseIP("127.0.0.11")},
|
||||||
&A{Hdr: RR_Header{Name: "foo014.example.org."}, A: net.ParseIP("127.0.0.12")},
|
&A{Hdr: RR_Header{Name: "foo014.example.org."}, A: net.ParseIP("127.0.0.12")},
|
||||||
}
|
}
|
||||||
|
|
||||||
wantIdx := 0
|
wantIdx := 0
|
||||||
|
|
||||||
tok := ParseZone(strings.NewReader(zone), "", "")
|
z := NewZoneParser(strings.NewReader(zone), "", "")
|
||||||
for x := range tok {
|
|
||||||
|
for rr, ok := z.Next(); ok; rr, ok = z.Next() {
|
||||||
if wantIdx >= len(wantRRs) {
|
if wantIdx >= len(wantRRs) {
|
||||||
t.Fatalf("expected %d RRs, but got more", len(wantRRs))
|
t.Fatalf("expected %d RRs, but got more", len(wantRRs))
|
||||||
}
|
}
|
||||||
if x.Error != nil {
|
if got, want := rr.Header().Name, wantRRs[wantIdx].Header().Name; got != want {
|
||||||
t.Fatalf("expected no error, but got %s", x.Error)
|
|
||||||
}
|
|
||||||
if got, want := x.RR.Header().Name, wantRRs[wantIdx].Header().Name; got != want {
|
|
||||||
t.Fatalf("expected name %s, but got %s", want, got)
|
t.Fatalf("expected name %s, but got %s", want, got)
|
||||||
}
|
}
|
||||||
a, ok := x.RR.(*A)
|
a, okA := rr.(*A)
|
||||||
if !ok {
|
if !okA {
|
||||||
t.Fatalf("expected *A RR, but got %T", x.RR)
|
t.Fatalf("expected *A RR, but got %T", rr)
|
||||||
}
|
}
|
||||||
if got, want := a.A, wantRRs[wantIdx].(*A).A; !got.Equal(want) {
|
if got, want := a.A, wantRRs[wantIdx].(*A).A; !got.Equal(want) {
|
||||||
t.Fatalf("expected A with IP %v, but got %v", got, want)
|
t.Fatalf("expected A with IP %v, but got %v", got, want)
|
||||||
|
@ -40,12 +39,16 @@ func TestParseZoneGenerate(t *testing.T) {
|
||||||
wantIdx++
|
wantIdx++
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if err := z.Err(); err != nil {
|
||||||
|
t.Fatalf("expected no error, but got %s", err)
|
||||||
|
}
|
||||||
|
|
||||||
if wantIdx != len(wantRRs) {
|
if wantIdx != len(wantRRs) {
|
||||||
t.Errorf("too few records, expected %d, got %d", len(wantRRs), wantIdx)
|
t.Errorf("too few records, expected %d, got %d", len(wantRRs), wantIdx)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestParseZoneInclude(t *testing.T) {
|
func TestZoneParserInclude(t *testing.T) {
|
||||||
|
|
||||||
tmpfile, err := ioutil.TempFile("", "dns")
|
tmpfile, err := ioutil.TempFile("", "dns")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -63,18 +66,19 @@ func TestParseZoneInclude(t *testing.T) {
|
||||||
zone := "$ORIGIN example.org.\n$INCLUDE " + tmpfile.Name() + "\nbar\tIN\tA\t127.0.0.2"
|
zone := "$ORIGIN example.org.\n$INCLUDE " + tmpfile.Name() + "\nbar\tIN\tA\t127.0.0.2"
|
||||||
|
|
||||||
var got int
|
var got int
|
||||||
tok := ParseZone(strings.NewReader(zone), "", "")
|
z := NewZoneParser(strings.NewReader(zone), "", "")
|
||||||
for x := range tok {
|
z.SetIncludeAllowed(true)
|
||||||
if x.Error != nil {
|
for rr, ok := z.Next(); ok; _, ok = z.Next() {
|
||||||
t.Fatalf("expected no error, but got %s", x.Error)
|
switch rr.Header().Name {
|
||||||
}
|
|
||||||
switch x.RR.Header().Name {
|
|
||||||
case "foo.example.org.", "bar.example.org.":
|
case "foo.example.org.", "bar.example.org.":
|
||||||
default:
|
default:
|
||||||
t.Fatalf("expected foo.example.org. or bar.example.org., but got %s", x.RR.Header().Name)
|
t.Fatalf("expected foo.example.org. or bar.example.org., but got %s", rr.Header().Name)
|
||||||
}
|
}
|
||||||
got++
|
got++
|
||||||
}
|
}
|
||||||
|
if err := z.Err(); err != nil {
|
||||||
|
t.Fatalf("expected no error, but got %s", err)
|
||||||
|
}
|
||||||
|
|
||||||
if expected := 2; got != expected {
|
if expected := 2; got != expected {
|
||||||
t.Errorf("failed to parse zone after include, expected %d records, got %d", expected, got)
|
t.Errorf("failed to parse zone after include, expected %d records, got %d", expected, got)
|
||||||
|
@ -82,17 +86,15 @@ func TestParseZoneInclude(t *testing.T) {
|
||||||
|
|
||||||
os.Remove(tmpfile.Name())
|
os.Remove(tmpfile.Name())
|
||||||
|
|
||||||
tok = ParseZone(strings.NewReader(zone), "", "")
|
z = NewZoneParser(strings.NewReader(zone), "", "")
|
||||||
for x := range tok {
|
z.SetIncludeAllowed(true)
|
||||||
if x.Error == nil {
|
z.Next()
|
||||||
t.Fatalf("expected first token to contain an error but it didn't")
|
if err := z.Err(); err == nil ||
|
||||||
}
|
!strings.Contains(err.Error(), "failed to open") ||
|
||||||
if !strings.Contains(x.Error.Error(), "failed to open") ||
|
!strings.Contains(err.Error(), tmpfile.Name()) ||
|
||||||
!strings.Contains(x.Error.Error(), tmpfile.Name()) ||
|
!strings.Contains(err.Error(), "no such file or directory") {
|
||||||
!strings.Contains(x.Error.Error(), "no such file or directory") {
|
t.Fatalf(`expected error to contain: "failed to open", %q and "no such file or directory" but got: %s`,
|
||||||
t.Fatalf(`expected error to contain: "failed to open", %q and "no such file or directory" but got: %s`,
|
tmpfile.Name(), err)
|
||||||
tmpfile.Name(), x.Error)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -274,16 +276,6 @@ foo. IN NSEC miek.nl. TXT RRSIG NSEC; this is comment 7
|
||||||
foo. IN TXT "THIS IS TEXT MAN"; this is comment 8
|
foo. IN TXT "THIS IS TEXT MAN"; this is comment 8
|
||||||
`
|
`
|
||||||
|
|
||||||
func BenchmarkParseZone(b *testing.B) {
|
|
||||||
for n := 0; n < b.N; n++ {
|
|
||||||
for tok := range ParseZone(strings.NewReader(benchZone), "example.org.", "") {
|
|
||||||
if tok.Error != nil {
|
|
||||||
b.Fatal(tok.Error)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func BenchmarkZoneParser(b *testing.B) {
|
func BenchmarkZoneParser(b *testing.B) {
|
||||||
for n := 0; n < b.N; n++ {
|
for n := 0; n < b.N; n++ {
|
||||||
zp := NewZoneParser(strings.NewReader(benchZone), "example.org.", "")
|
zp := NewZoneParser(strings.NewReader(benchZone), "example.org.", "")
|
||||||
|
|
Loading…
Reference in New Issue