1package dns
2
3import (
4	"testing"
5)
6
7func TestCmToM(t *testing.T) {
8	s := cmToM(0, 0)
9	if s != "0.00" {
10		t.Error("0, 0")
11	}
12
13	s = cmToM(1, 0)
14	if s != "0.01" {
15		t.Error("1, 0")
16	}
17
18	s = cmToM(3, 1)
19	if s != "0.30" {
20		t.Error("3, 1")
21	}
22
23	s = cmToM(4, 2)
24	if s != "4" {
25		t.Error("4, 2")
26	}
27
28	s = cmToM(5, 3)
29	if s != "50" {
30		t.Error("5, 3")
31	}
32
33	s = cmToM(7, 5)
34	if s != "7000" {
35		t.Error("7, 5")
36	}
37
38	s = cmToM(9, 9)
39	if s != "90000000" {
40		t.Error("9, 9")
41	}
42}
43
44func TestSplitN(t *testing.T) {
45	xs := splitN("abc", 5)
46	if len(xs) != 1 && xs[0] != "abc" {
47		t.Errorf("failure to split abc")
48	}
49
50	s := ""
51	for i := 0; i < 255; i++ {
52		s += "a"
53	}
54
55	xs = splitN(s, 255)
56	if len(xs) != 1 && xs[0] != s {
57		t.Errorf("failure to split 255 char long string")
58	}
59
60	s += "b"
61	xs = splitN(s, 255)
62	if len(xs) != 2 || xs[1] != "b" {
63		t.Errorf("failure to split 256 char long string: %d", len(xs))
64	}
65
66	// Make s longer
67	for i := 0; i < 255; i++ {
68		s += "a"
69	}
70	xs = splitN(s, 255)
71	if len(xs) != 3 || xs[2] != "a" {
72		t.Errorf("failure to split 510 char long string: %d", len(xs))
73	}
74}
75
76func TestSprintName(t *testing.T) {
77	tests := map[string]string{
78		// Non-numeric escaping of special printable characters.
79		" '@;()\"\\..example": `\ \'\@\;\(\)\"\..example`,
80		"\\032\\039\\064\\059\\040\\041\\034\\046\\092.example": `\ \'\@\;\(\)\"\.\\.example`,
81
82		// Numeric escaping of nonprintable characters.
83		"\x00\x07\x09\x0a\x1f.\x7f\x80\xad\xef\xff":           `\000\007\009\010\031.\127\128\173\239\255`,
84		"\\000\\007\\009\\010\\031.\\127\\128\\173\\239\\255": `\000\007\009\010\031.\127\128\173\239\255`,
85
86		// No escaping of other printable characters, at least after a prior escape.
87		";[a-zA-Z0-9_]+/*.~": `\;[a-zA-Z0-9_]+/*.~`,
88		";\\091\\097\\045\\122\\065\\045\\090\\048\\045\\057\\095\\093\\043\\047\\042.\\126": `\;[a-zA-Z0-9_]+/*.~`,
89		// "\\091\\097\\045\\122\\065\\045\\090\\048\\045\\057\\095\\093\\043\\047\\042.\\126": `[a-zA-Z0-9_]+/*.~`,
90
91		// Incomplete "dangling" escapes are dropped regardless of prior escaping.
92		"a\\": `a`,
93		";\\": `\;`,
94
95		// Escaped dots stay escaped regardless of prior escaping.
96		"a\\.\\046.\\.\\046": `a\.\..\.\.`,
97		"a\\046\\..\\046\\.": `a\.\..\.\.`,
98	}
99	for input, want := range tests {
100		got := sprintName(input)
101		if got != want {
102			t.Errorf("input %q: expected %q, got %q", input, want, got)
103		}
104	}
105}
106
107func TestSprintTxtOctet(t *testing.T) {
108	got := sprintTxtOctet("abc\\.def\007\"\127@\255\x05\xef\\")
109
110	if want := "\"abc\\.def\\007\\\"W@\\173\\005\\239\""; got != want {
111		t.Errorf("expected %q, got %q", want, got)
112	}
113}
114
115func TestSprintTxt(t *testing.T) {
116	got := sprintTxt([]string{
117		"abc\\.def\007\"\127@\255\x05\xef\\",
118		"example.com",
119	})
120
121	if want := "\"abc.def\\007\\\"W@\\173\\005\\239\" \"example.com\""; got != want {
122		t.Errorf("expected %q, got %q", want, got)
123	}
124}
125
126func TestRPStringer(t *testing.T) {
127	rp := &RP{
128		Hdr: RR_Header{
129			Name:   "test.example.com.",
130			Rrtype: TypeRP,
131			Class:  ClassINET,
132			Ttl:    600,
133		},
134		Mbox: "\x05first.example.com.",
135		Txt:  "second.\x07example.com.",
136	}
137
138	const expected = "test.example.com.\t600\tIN\tRP\t\\005first.example.com. second.\\007example.com."
139	if rp.String() != expected {
140		t.Errorf("expected %v, got %v", expected, rp)
141	}
142
143	_, err := NewRR(rp.String())
144	if err != nil {
145		t.Fatalf("error parsing %q: %v", rp, err)
146	}
147}
148
149func BenchmarkSprintName(b *testing.B) {
150	for n := 0; n < b.N; n++ {
151		got := sprintName("abc\\.def\007\"\127@\255\x05\xef\\")
152
153		if want := "abc\\.def\\007\\\"W\\@\\173\\005\\239"; got != want {
154			b.Fatalf("expected %q, got %q", want, got)
155		}
156	}
157}
158
159func BenchmarkSprintName_NoEscape(b *testing.B) {
160	for n := 0; n < b.N; n++ {
161		got := sprintName("large.example.com")
162
163		if want := "large.example.com"; got != want {
164			b.Fatalf("expected %q, got %q", want, got)
165		}
166	}
167}
168
169func BenchmarkSprintTxtOctet(b *testing.B) {
170	for n := 0; n < b.N; n++ {
171		got := sprintTxtOctet("abc\\.def\007\"\127@\255\x05\xef\\")
172
173		if want := "\"abc\\.def\\007\\\"W@\\173\\005\\239\""; got != want {
174			b.Fatalf("expected %q, got %q", want, got)
175		}
176	}
177}
178
179func BenchmarkSprintTxt(b *testing.B) {
180	txt := []string{
181		"abc\\.def\007\"\127@\255\x05\xef\\",
182		"example.com",
183	}
184
185	b.ResetTimer()
186	for n := 0; n < b.N; n++ {
187		got := sprintTxt(txt)
188
189		if want := "\"abc.def\\007\\\"W@\\173\\005\\239\" \"example.com\""; got != want {
190			b.Fatalf("expected %q, got %q", got, want)
191		}
192	}
193}
194