The reconcile package is used for DOM reconcilation in Isomorphic Go web applications.

message_test.go 28KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116
  1. // Copyright 2009 The Go Authors. All rights reserved.
  2. // Use of this source code is governed by a BSD-style
  3. // license that can be found in the LICENSE file.
  4. package dnsmessage
  5. import (
  6. "bytes"
  7. "fmt"
  8. "reflect"
  9. "testing"
  10. )
  11. func mustNewName(name string) Name {
  12. n, err := NewName(name)
  13. if err != nil {
  14. panic(err)
  15. }
  16. return n
  17. }
  18. func (m *Message) String() string {
  19. s := fmt.Sprintf("Message: %#v\n", &m.Header)
  20. if len(m.Questions) > 0 {
  21. s += "-- Questions\n"
  22. for _, q := range m.Questions {
  23. s += fmt.Sprintf("%#v\n", q)
  24. }
  25. }
  26. if len(m.Answers) > 0 {
  27. s += "-- Answers\n"
  28. for _, a := range m.Answers {
  29. s += fmt.Sprintf("%#v\n", a)
  30. }
  31. }
  32. if len(m.Authorities) > 0 {
  33. s += "-- Authorities\n"
  34. for _, ns := range m.Authorities {
  35. s += fmt.Sprintf("%#v\n", ns)
  36. }
  37. }
  38. if len(m.Additionals) > 0 {
  39. s += "-- Additionals\n"
  40. for _, e := range m.Additionals {
  41. s += fmt.Sprintf("%#v\n", e)
  42. }
  43. }
  44. return s
  45. }
  46. func TestNameString(t *testing.T) {
  47. want := "foo"
  48. name := mustNewName(want)
  49. if got := fmt.Sprint(name); got != want {
  50. t.Errorf("got fmt.Sprint(%#v) = %s, want = %s", name, got, want)
  51. }
  52. }
  53. func TestQuestionPackUnpack(t *testing.T) {
  54. want := Question{
  55. Name: mustNewName("."),
  56. Type: TypeA,
  57. Class: ClassINET,
  58. }
  59. buf, err := want.pack(make([]byte, 1, 50), map[string]int{})
  60. if err != nil {
  61. t.Fatal("Packing failed:", err)
  62. }
  63. var p Parser
  64. p.msg = buf
  65. p.header.questions = 1
  66. p.section = sectionQuestions
  67. p.off = 1
  68. got, err := p.Question()
  69. if err != nil {
  70. t.Fatalf("Unpacking failed: %v\n%s", err, string(buf[1:]))
  71. }
  72. if p.off != len(buf) {
  73. t.Errorf("Unpacked different amount than packed: got n = %d, want = %d", p.off, len(buf))
  74. }
  75. if !reflect.DeepEqual(got, want) {
  76. t.Errorf("Got = %+v, want = %+v", got, want)
  77. }
  78. }
  79. func TestName(t *testing.T) {
  80. tests := []string{
  81. "",
  82. ".",
  83. "google..com",
  84. "google.com",
  85. "google..com.",
  86. "google.com.",
  87. ".google.com.",
  88. "www..google.com.",
  89. "www.google.com.",
  90. }
  91. for _, test := range tests {
  92. n, err := NewName(test)
  93. if err != nil {
  94. t.Errorf("Creating name for %q: %v", test, err)
  95. continue
  96. }
  97. if ns := n.String(); ns != test {
  98. t.Errorf("Got %#v.String() = %q, want = %q", n, ns, test)
  99. continue
  100. }
  101. }
  102. }
  103. func TestNamePackUnpack(t *testing.T) {
  104. tests := []struct {
  105. in string
  106. want string
  107. err error
  108. }{
  109. {"", "", errNonCanonicalName},
  110. {".", ".", nil},
  111. {"google..com", "", errNonCanonicalName},
  112. {"google.com", "", errNonCanonicalName},
  113. {"google..com.", "", errZeroSegLen},
  114. {"google.com.", "google.com.", nil},
  115. {".google.com.", "", errZeroSegLen},
  116. {"www..google.com.", "", errZeroSegLen},
  117. {"www.google.com.", "www.google.com.", nil},
  118. }
  119. for _, test := range tests {
  120. in := mustNewName(test.in)
  121. want := mustNewName(test.want)
  122. buf, err := in.pack(make([]byte, 0, 30), map[string]int{})
  123. if err != test.err {
  124. t.Errorf("Packing of %q: got err = %v, want err = %v", test.in, err, test.err)
  125. continue
  126. }
  127. if test.err != nil {
  128. continue
  129. }
  130. var got Name
  131. n, err := got.unpack(buf, 0)
  132. if err != nil {
  133. t.Errorf("Unpacking for %q failed: %v", test.in, err)
  134. continue
  135. }
  136. if n != len(buf) {
  137. t.Errorf(
  138. "Unpacked different amount than packed for %q: got n = %d, want = %d",
  139. test.in,
  140. n,
  141. len(buf),
  142. )
  143. }
  144. if got != want {
  145. t.Errorf("Unpacking packing of %q: got = %#v, want = %#v", test.in, got, want)
  146. }
  147. }
  148. }
  149. func checkErrorPrefix(err error, prefix string) bool {
  150. e, ok := err.(*nestedError)
  151. return ok && e.s == prefix
  152. }
  153. func TestHeaderUnpackError(t *testing.T) {
  154. wants := []string{
  155. "id",
  156. "bits",
  157. "questions",
  158. "answers",
  159. "authorities",
  160. "additionals",
  161. }
  162. var buf []byte
  163. var h header
  164. for _, want := range wants {
  165. n, err := h.unpack(buf, 0)
  166. if n != 0 || !checkErrorPrefix(err, want) {
  167. t.Errorf("got h.unpack([%d]byte, 0) = %d, %v, want = 0, %s", len(buf), n, err, want)
  168. }
  169. buf = append(buf, 0, 0)
  170. }
  171. }
  172. func TestParserStart(t *testing.T) {
  173. const want = "unpacking header"
  174. var p Parser
  175. for i := 0; i <= 1; i++ {
  176. _, err := p.Start([]byte{})
  177. if !checkErrorPrefix(err, want) {
  178. t.Errorf("got p.Start(nil) = _, %v, want = _, %s", err, want)
  179. }
  180. }
  181. }
  182. func TestResourceNotStarted(t *testing.T) {
  183. tests := []struct {
  184. name string
  185. fn func(*Parser) error
  186. }{
  187. {"CNAMEResource", func(p *Parser) error { _, err := p.CNAMEResource(); return err }},
  188. {"MXResource", func(p *Parser) error { _, err := p.MXResource(); return err }},
  189. {"NSResource", func(p *Parser) error { _, err := p.NSResource(); return err }},
  190. {"PTRResource", func(p *Parser) error { _, err := p.PTRResource(); return err }},
  191. {"SOAResource", func(p *Parser) error { _, err := p.SOAResource(); return err }},
  192. {"TXTResource", func(p *Parser) error { _, err := p.TXTResource(); return err }},
  193. {"SRVResource", func(p *Parser) error { _, err := p.SRVResource(); return err }},
  194. {"AResource", func(p *Parser) error { _, err := p.AResource(); return err }},
  195. {"AAAAResource", func(p *Parser) error { _, err := p.AAAAResource(); return err }},
  196. }
  197. for _, test := range tests {
  198. if err := test.fn(&Parser{}); err != ErrNotStarted {
  199. t.Errorf("got _, %v = p.%s(), want = _, %v", err, test.name, ErrNotStarted)
  200. }
  201. }
  202. }
  203. func TestDNSPackUnpack(t *testing.T) {
  204. wants := []Message{
  205. {
  206. Questions: []Question{
  207. {
  208. Name: mustNewName("."),
  209. Type: TypeAAAA,
  210. Class: ClassINET,
  211. },
  212. },
  213. Answers: []Resource{},
  214. Authorities: []Resource{},
  215. Additionals: []Resource{},
  216. },
  217. largeTestMsg(),
  218. }
  219. for i, want := range wants {
  220. b, err := want.Pack()
  221. if err != nil {
  222. t.Fatalf("%d: packing failed: %v", i, err)
  223. }
  224. var got Message
  225. err = got.Unpack(b)
  226. if err != nil {
  227. t.Fatalf("%d: unpacking failed: %v", i, err)
  228. }
  229. if !reflect.DeepEqual(got, want) {
  230. t.Errorf("%d: got = %+v, want = %+v", i, &got, &want)
  231. }
  232. }
  233. }
  234. func TestSkipAll(t *testing.T) {
  235. msg := largeTestMsg()
  236. buf, err := msg.Pack()
  237. if err != nil {
  238. t.Fatal("Packing large test message:", err)
  239. }
  240. var p Parser
  241. if _, err := p.Start(buf); err != nil {
  242. t.Fatal(err)
  243. }
  244. tests := []struct {
  245. name string
  246. f func() error
  247. }{
  248. {"SkipAllQuestions", p.SkipAllQuestions},
  249. {"SkipAllAnswers", p.SkipAllAnswers},
  250. {"SkipAllAuthorities", p.SkipAllAuthorities},
  251. {"SkipAllAdditionals", p.SkipAllAdditionals},
  252. }
  253. for _, test := range tests {
  254. for i := 1; i <= 3; i++ {
  255. if err := test.f(); err != nil {
  256. t.Errorf("Call #%d to %s(): %v", i, test.name, err)
  257. }
  258. }
  259. }
  260. }
  261. func TestSkipEach(t *testing.T) {
  262. msg := smallTestMsg()
  263. buf, err := msg.Pack()
  264. if err != nil {
  265. t.Fatal("Packing test message:", err)
  266. }
  267. var p Parser
  268. if _, err := p.Start(buf); err != nil {
  269. t.Fatal(err)
  270. }
  271. tests := []struct {
  272. name string
  273. f func() error
  274. }{
  275. {"SkipQuestion", p.SkipQuestion},
  276. {"SkipAnswer", p.SkipAnswer},
  277. {"SkipAuthority", p.SkipAuthority},
  278. {"SkipAdditional", p.SkipAdditional},
  279. }
  280. for _, test := range tests {
  281. if err := test.f(); err != nil {
  282. t.Errorf("First call: got %s() = %v, want = %v", test.name, err, nil)
  283. }
  284. if err := test.f(); err != ErrSectionDone {
  285. t.Errorf("Second call: got %s() = %v, want = %v", test.name, err, ErrSectionDone)
  286. }
  287. }
  288. }
  289. func TestSkipAfterRead(t *testing.T) {
  290. msg := smallTestMsg()
  291. buf, err := msg.Pack()
  292. if err != nil {
  293. t.Fatal("Packing test message:", err)
  294. }
  295. var p Parser
  296. if _, err := p.Start(buf); err != nil {
  297. t.Fatal(err)
  298. }
  299. tests := []struct {
  300. name string
  301. skip func() error
  302. read func() error
  303. }{
  304. {"Question", p.SkipQuestion, func() error { _, err := p.Question(); return err }},
  305. {"Answer", p.SkipAnswer, func() error { _, err := p.Answer(); return err }},
  306. {"Authority", p.SkipAuthority, func() error { _, err := p.Authority(); return err }},
  307. {"Additional", p.SkipAdditional, func() error { _, err := p.Additional(); return err }},
  308. }
  309. for _, test := range tests {
  310. if err := test.read(); err != nil {
  311. t.Errorf("Got %s() = _, %v, want = _, %v", test.name, err, nil)
  312. }
  313. if err := test.skip(); err != ErrSectionDone {
  314. t.Errorf("Got Skip%s() = %v, want = %v", test.name, err, ErrSectionDone)
  315. }
  316. }
  317. }
  318. func TestSkipNotStarted(t *testing.T) {
  319. var p Parser
  320. tests := []struct {
  321. name string
  322. f func() error
  323. }{
  324. {"SkipAllQuestions", p.SkipAllQuestions},
  325. {"SkipAllAnswers", p.SkipAllAnswers},
  326. {"SkipAllAuthorities", p.SkipAllAuthorities},
  327. {"SkipAllAdditionals", p.SkipAllAdditionals},
  328. }
  329. for _, test := range tests {
  330. if err := test.f(); err != ErrNotStarted {
  331. t.Errorf("Got %s() = %v, want = %v", test.name, err, ErrNotStarted)
  332. }
  333. }
  334. }
  335. func TestTooManyRecords(t *testing.T) {
  336. const recs = int(^uint16(0)) + 1
  337. tests := []struct {
  338. name string
  339. msg Message
  340. want error
  341. }{
  342. {
  343. "Questions",
  344. Message{
  345. Questions: make([]Question, recs),
  346. },
  347. errTooManyQuestions,
  348. },
  349. {
  350. "Answers",
  351. Message{
  352. Answers: make([]Resource, recs),
  353. },
  354. errTooManyAnswers,
  355. },
  356. {
  357. "Authorities",
  358. Message{
  359. Authorities: make([]Resource, recs),
  360. },
  361. errTooManyAuthorities,
  362. },
  363. {
  364. "Additionals",
  365. Message{
  366. Additionals: make([]Resource, recs),
  367. },
  368. errTooManyAdditionals,
  369. },
  370. }
  371. for _, test := range tests {
  372. if _, got := test.msg.Pack(); got != test.want {
  373. t.Errorf("Packing %d %s: got = %v, want = %v", recs, test.name, got, test.want)
  374. }
  375. }
  376. }
  377. func TestVeryLongTxt(t *testing.T) {
  378. want := Resource{
  379. ResourceHeader{
  380. Name: mustNewName("foo.bar.example.com."),
  381. Type: TypeTXT,
  382. Class: ClassINET,
  383. },
  384. &TXTResource{loremIpsum},
  385. }
  386. buf, err := want.pack(make([]byte, 0, 8000), map[string]int{})
  387. if err != nil {
  388. t.Fatal("Packing failed:", err)
  389. }
  390. var got Resource
  391. off, err := got.Header.unpack(buf, 0)
  392. if err != nil {
  393. t.Fatal("Unpacking ResourceHeader failed:", err)
  394. }
  395. body, n, err := unpackResourceBody(buf, off, got.Header)
  396. if err != nil {
  397. t.Fatal("Unpacking failed:", err)
  398. }
  399. got.Body = body
  400. if n != len(buf) {
  401. t.Errorf("Unpacked different amount than packed: got n = %d, want = %d", n, len(buf))
  402. }
  403. if !reflect.DeepEqual(got, want) {
  404. t.Errorf("Got = %#v, want = %#v", got, want)
  405. }
  406. }
  407. func TestStartError(t *testing.T) {
  408. tests := []struct {
  409. name string
  410. fn func(*Builder) error
  411. }{
  412. {"Questions", func(b *Builder) error { return b.StartQuestions() }},
  413. {"Answers", func(b *Builder) error { return b.StartAnswers() }},
  414. {"Authorities", func(b *Builder) error { return b.StartAuthorities() }},
  415. {"Additionals", func(b *Builder) error { return b.StartAdditionals() }},
  416. }
  417. envs := []struct {
  418. name string
  419. fn func() *Builder
  420. want error
  421. }{
  422. {"sectionNotStarted", func() *Builder { return &Builder{section: sectionNotStarted} }, ErrNotStarted},
  423. {"sectionDone", func() *Builder { return &Builder{section: sectionDone} }, ErrSectionDone},
  424. }
  425. for _, env := range envs {
  426. for _, test := range tests {
  427. if got := test.fn(env.fn()); got != env.want {
  428. t.Errorf("got Builder{%s}.Start%s = %v, want = %v", env.name, test.name, got, env.want)
  429. }
  430. }
  431. }
  432. }
  433. func TestBuilderResourceError(t *testing.T) {
  434. tests := []struct {
  435. name string
  436. fn func(*Builder) error
  437. }{
  438. {"CNAMEResource", func(b *Builder) error { return b.CNAMEResource(ResourceHeader{}, CNAMEResource{}) }},
  439. {"MXResource", func(b *Builder) error { return b.MXResource(ResourceHeader{}, MXResource{}) }},
  440. {"NSResource", func(b *Builder) error { return b.NSResource(ResourceHeader{}, NSResource{}) }},
  441. {"PTRResource", func(b *Builder) error { return b.PTRResource(ResourceHeader{}, PTRResource{}) }},
  442. {"SOAResource", func(b *Builder) error { return b.SOAResource(ResourceHeader{}, SOAResource{}) }},
  443. {"TXTResource", func(b *Builder) error { return b.TXTResource(ResourceHeader{}, TXTResource{}) }},
  444. {"SRVResource", func(b *Builder) error { return b.SRVResource(ResourceHeader{}, SRVResource{}) }},
  445. {"AResource", func(b *Builder) error { return b.AResource(ResourceHeader{}, AResource{}) }},
  446. {"AAAAResource", func(b *Builder) error { return b.AAAAResource(ResourceHeader{}, AAAAResource{}) }},
  447. }
  448. envs := []struct {
  449. name string
  450. fn func() *Builder
  451. want error
  452. }{
  453. {"sectionNotStarted", func() *Builder { return &Builder{section: sectionNotStarted} }, ErrNotStarted},
  454. {"sectionHeader", func() *Builder { return &Builder{section: sectionHeader} }, ErrNotStarted},
  455. {"sectionQuestions", func() *Builder { return &Builder{section: sectionQuestions} }, ErrNotStarted},
  456. {"sectionDone", func() *Builder { return &Builder{section: sectionDone} }, ErrSectionDone},
  457. }
  458. for _, env := range envs {
  459. for _, test := range tests {
  460. if got := test.fn(env.fn()); got != env.want {
  461. t.Errorf("got Builder{%s}.%s = %v, want = %v", env.name, test.name, got, env.want)
  462. }
  463. }
  464. }
  465. }
  466. func TestFinishError(t *testing.T) {
  467. var b Builder
  468. want := ErrNotStarted
  469. if _, got := b.Finish(); got != want {
  470. t.Errorf("got Builder{}.Finish() = %v, want = %v", got, want)
  471. }
  472. }
  473. func TestBuilder(t *testing.T) {
  474. msg := largeTestMsg()
  475. want, err := msg.Pack()
  476. if err != nil {
  477. t.Fatal("Packing without builder:", err)
  478. }
  479. var b Builder
  480. b.Start(nil, msg.Header)
  481. if err := b.StartQuestions(); err != nil {
  482. t.Fatal("b.StartQuestions():", err)
  483. }
  484. for _, q := range msg.Questions {
  485. if err := b.Question(q); err != nil {
  486. t.Fatalf("b.Question(%#v): %v", q, err)
  487. }
  488. }
  489. if err := b.StartAnswers(); err != nil {
  490. t.Fatal("b.StartAnswers():", err)
  491. }
  492. for _, a := range msg.Answers {
  493. switch a.Header.Type {
  494. case TypeA:
  495. if err := b.AResource(a.Header, *a.Body.(*AResource)); err != nil {
  496. t.Fatalf("b.AResource(%#v): %v", a, err)
  497. }
  498. case TypeNS:
  499. if err := b.NSResource(a.Header, *a.Body.(*NSResource)); err != nil {
  500. t.Fatalf("b.NSResource(%#v): %v", a, err)
  501. }
  502. case TypeCNAME:
  503. if err := b.CNAMEResource(a.Header, *a.Body.(*CNAMEResource)); err != nil {
  504. t.Fatalf("b.CNAMEResource(%#v): %v", a, err)
  505. }
  506. case TypeSOA:
  507. if err := b.SOAResource(a.Header, *a.Body.(*SOAResource)); err != nil {
  508. t.Fatalf("b.SOAResource(%#v): %v", a, err)
  509. }
  510. case TypePTR:
  511. if err := b.PTRResource(a.Header, *a.Body.(*PTRResource)); err != nil {
  512. t.Fatalf("b.PTRResource(%#v): %v", a, err)
  513. }
  514. case TypeMX:
  515. if err := b.MXResource(a.Header, *a.Body.(*MXResource)); err != nil {
  516. t.Fatalf("b.MXResource(%#v): %v", a, err)
  517. }
  518. case TypeTXT:
  519. if err := b.TXTResource(a.Header, *a.Body.(*TXTResource)); err != nil {
  520. t.Fatalf("b.TXTResource(%#v): %v", a, err)
  521. }
  522. case TypeAAAA:
  523. if err := b.AAAAResource(a.Header, *a.Body.(*AAAAResource)); err != nil {
  524. t.Fatalf("b.AAAAResource(%#v): %v", a, err)
  525. }
  526. case TypeSRV:
  527. if err := b.SRVResource(a.Header, *a.Body.(*SRVResource)); err != nil {
  528. t.Fatalf("b.SRVResource(%#v): %v", a, err)
  529. }
  530. }
  531. }
  532. if err := b.StartAuthorities(); err != nil {
  533. t.Fatal("b.StartAuthorities():", err)
  534. }
  535. for _, a := range msg.Authorities {
  536. if err := b.NSResource(a.Header, *a.Body.(*NSResource)); err != nil {
  537. t.Fatalf("b.NSResource(%#v): %v", a, err)
  538. }
  539. }
  540. if err := b.StartAdditionals(); err != nil {
  541. t.Fatal("b.StartAdditionals():", err)
  542. }
  543. for _, a := range msg.Additionals {
  544. if err := b.TXTResource(a.Header, *a.Body.(*TXTResource)); err != nil {
  545. t.Fatalf("b.TXTResource(%#v): %v", a, err)
  546. }
  547. }
  548. got, err := b.Finish()
  549. if err != nil {
  550. t.Fatal("b.Finish():", err)
  551. }
  552. if !bytes.Equal(got, want) {
  553. t.Fatalf("Got from Builder: %#v\nwant = %#v", got, want)
  554. }
  555. }
  556. func TestResourcePack(t *testing.T) {
  557. for _, tt := range []struct {
  558. m Message
  559. err error
  560. }{
  561. {
  562. Message{
  563. Questions: []Question{
  564. {
  565. Name: mustNewName("."),
  566. Type: TypeAAAA,
  567. Class: ClassINET,
  568. },
  569. },
  570. Answers: []Resource{{ResourceHeader{}, nil}},
  571. },
  572. &nestedError{"packing Answer", errNilResouceBody},
  573. },
  574. {
  575. Message{
  576. Questions: []Question{
  577. {
  578. Name: mustNewName("."),
  579. Type: TypeAAAA,
  580. Class: ClassINET,
  581. },
  582. },
  583. Authorities: []Resource{{ResourceHeader{}, (*NSResource)(nil)}},
  584. },
  585. &nestedError{"packing Authority",
  586. &nestedError{"ResourceHeader",
  587. &nestedError{"Name", errNonCanonicalName},
  588. },
  589. },
  590. },
  591. {
  592. Message{
  593. Questions: []Question{
  594. {
  595. Name: mustNewName("."),
  596. Type: TypeA,
  597. Class: ClassINET,
  598. },
  599. },
  600. Additionals: []Resource{{ResourceHeader{}, nil}},
  601. },
  602. &nestedError{"packing Additional", errNilResouceBody},
  603. },
  604. } {
  605. _, err := tt.m.Pack()
  606. if !reflect.DeepEqual(err, tt.err) {
  607. t.Errorf("got %v for %v; want %v", err, tt.m, tt.err)
  608. }
  609. }
  610. }
  611. func BenchmarkParsing(b *testing.B) {
  612. b.ReportAllocs()
  613. name := mustNewName("foo.bar.example.com.")
  614. msg := Message{
  615. Header: Header{Response: true, Authoritative: true},
  616. Questions: []Question{
  617. {
  618. Name: name,
  619. Type: TypeA,
  620. Class: ClassINET,
  621. },
  622. },
  623. Answers: []Resource{
  624. {
  625. ResourceHeader{
  626. Name: name,
  627. Class: ClassINET,
  628. },
  629. &AResource{[4]byte{}},
  630. },
  631. {
  632. ResourceHeader{
  633. Name: name,
  634. Class: ClassINET,
  635. },
  636. &AAAAResource{[16]byte{}},
  637. },
  638. {
  639. ResourceHeader{
  640. Name: name,
  641. Class: ClassINET,
  642. },
  643. &CNAMEResource{name},
  644. },
  645. {
  646. ResourceHeader{
  647. Name: name,
  648. Class: ClassINET,
  649. },
  650. &NSResource{name},
  651. },
  652. },
  653. }
  654. buf, err := msg.Pack()
  655. if err != nil {
  656. b.Fatal("msg.Pack():", err)
  657. }
  658. for i := 0; i < b.N; i++ {
  659. var p Parser
  660. if _, err := p.Start(buf); err != nil {
  661. b.Fatal("p.Start(buf):", err)
  662. }
  663. for {
  664. _, err := p.Question()
  665. if err == ErrSectionDone {
  666. break
  667. }
  668. if err != nil {
  669. b.Fatal("p.Question():", err)
  670. }
  671. }
  672. for {
  673. h, err := p.AnswerHeader()
  674. if err == ErrSectionDone {
  675. break
  676. }
  677. if err != nil {
  678. panic(err)
  679. }
  680. switch h.Type {
  681. case TypeA:
  682. if _, err := p.AResource(); err != nil {
  683. b.Fatal("p.AResource():", err)
  684. }
  685. case TypeAAAA:
  686. if _, err := p.AAAAResource(); err != nil {
  687. b.Fatal("p.AAAAResource():", err)
  688. }
  689. case TypeCNAME:
  690. if _, err := p.CNAMEResource(); err != nil {
  691. b.Fatal("p.CNAMEResource():", err)
  692. }
  693. case TypeNS:
  694. if _, err := p.NSResource(); err != nil {
  695. b.Fatal("p.NSResource():", err)
  696. }
  697. default:
  698. b.Fatalf("unknown type: %T", h)
  699. }
  700. }
  701. }
  702. }
  703. func BenchmarkBuilding(b *testing.B) {
  704. b.ReportAllocs()
  705. name := mustNewName("foo.bar.example.com.")
  706. buf := make([]byte, 0, packStartingCap)
  707. for i := 0; i < b.N; i++ {
  708. var bld Builder
  709. bld.StartWithoutCompression(buf, Header{Response: true, Authoritative: true})
  710. if err := bld.StartQuestions(); err != nil {
  711. b.Fatal("bld.StartQuestions():", err)
  712. }
  713. q := Question{
  714. Name: name,
  715. Type: TypeA,
  716. Class: ClassINET,
  717. }
  718. if err := bld.Question(q); err != nil {
  719. b.Fatalf("bld.Question(%+v): %v", q, err)
  720. }
  721. hdr := ResourceHeader{
  722. Name: name,
  723. Class: ClassINET,
  724. }
  725. if err := bld.StartAnswers(); err != nil {
  726. b.Fatal("bld.StartQuestions():", err)
  727. }
  728. ar := AResource{[4]byte{}}
  729. if err := bld.AResource(hdr, ar); err != nil {
  730. b.Fatalf("bld.AResource(%+v, %+v): %v", hdr, ar, err)
  731. }
  732. aaar := AAAAResource{[16]byte{}}
  733. if err := bld.AAAAResource(hdr, aaar); err != nil {
  734. b.Fatalf("bld.AAAAResource(%+v, %+v): %v", hdr, aaar, err)
  735. }
  736. cnr := CNAMEResource{name}
  737. if err := bld.CNAMEResource(hdr, cnr); err != nil {
  738. b.Fatalf("bld.CNAMEResource(%+v, %+v): %v", hdr, cnr, err)
  739. }
  740. nsr := NSResource{name}
  741. if err := bld.NSResource(hdr, nsr); err != nil {
  742. b.Fatalf("bld.NSResource(%+v, %+v): %v", hdr, nsr, err)
  743. }
  744. if _, err := bld.Finish(); err != nil {
  745. b.Fatal("bld.Finish():", err)
  746. }
  747. }
  748. }
  749. func smallTestMsg() Message {
  750. name := mustNewName("example.com.")
  751. return Message{
  752. Header: Header{Response: true, Authoritative: true},
  753. Questions: []Question{
  754. {
  755. Name: name,
  756. Type: TypeA,
  757. Class: ClassINET,
  758. },
  759. },
  760. Answers: []Resource{
  761. {
  762. ResourceHeader{
  763. Name: name,
  764. Type: TypeA,
  765. Class: ClassINET,
  766. },
  767. &AResource{[4]byte{127, 0, 0, 1}},
  768. },
  769. },
  770. Authorities: []Resource{
  771. {
  772. ResourceHeader{
  773. Name: name,
  774. Type: TypeA,
  775. Class: ClassINET,
  776. },
  777. &AResource{[4]byte{127, 0, 0, 1}},
  778. },
  779. },
  780. Additionals: []Resource{
  781. {
  782. ResourceHeader{
  783. Name: name,
  784. Type: TypeA,
  785. Class: ClassINET,
  786. },
  787. &AResource{[4]byte{127, 0, 0, 1}},
  788. },
  789. },
  790. }
  791. }
  792. func largeTestMsg() Message {
  793. name := mustNewName("foo.bar.example.com.")
  794. return Message{
  795. Header: Header{Response: true, Authoritative: true},
  796. Questions: []Question{
  797. {
  798. Name: name,
  799. Type: TypeA,
  800. Class: ClassINET,
  801. },
  802. },
  803. Answers: []Resource{
  804. {
  805. ResourceHeader{
  806. Name: name,
  807. Type: TypeA,
  808. Class: ClassINET,
  809. },
  810. &AResource{[4]byte{127, 0, 0, 1}},
  811. },
  812. {
  813. ResourceHeader{
  814. Name: name,
  815. Type: TypeA,
  816. Class: ClassINET,
  817. },
  818. &AResource{[4]byte{127, 0, 0, 2}},
  819. },
  820. {
  821. ResourceHeader{
  822. Name: name,
  823. Type: TypeAAAA,
  824. Class: ClassINET,
  825. },
  826. &AAAAResource{[16]byte{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16}},
  827. },
  828. {
  829. ResourceHeader{
  830. Name: name,
  831. Type: TypeCNAME,
  832. Class: ClassINET,
  833. },
  834. &CNAMEResource{mustNewName("alias.example.com.")},
  835. },
  836. {
  837. ResourceHeader{
  838. Name: name,
  839. Type: TypeSOA,
  840. Class: ClassINET,
  841. },
  842. &SOAResource{
  843. NS: mustNewName("ns1.example.com."),
  844. MBox: mustNewName("mb.example.com."),
  845. Serial: 1,
  846. Refresh: 2,
  847. Retry: 3,
  848. Expire: 4,
  849. MinTTL: 5,
  850. },
  851. },
  852. {
  853. ResourceHeader{
  854. Name: name,
  855. Type: TypePTR,
  856. Class: ClassINET,
  857. },
  858. &PTRResource{mustNewName("ptr.example.com.")},
  859. },
  860. {
  861. ResourceHeader{
  862. Name: name,
  863. Type: TypeMX,
  864. Class: ClassINET,
  865. },
  866. &MXResource{
  867. 7,
  868. mustNewName("mx.example.com."),
  869. },
  870. },
  871. {
  872. ResourceHeader{
  873. Name: name,
  874. Type: TypeSRV,
  875. Class: ClassINET,
  876. },
  877. &SRVResource{
  878. 8,
  879. 9,
  880. 11,
  881. mustNewName("srv.example.com."),
  882. },
  883. },
  884. },
  885. Authorities: []Resource{
  886. {
  887. ResourceHeader{
  888. Name: name,
  889. Type: TypeNS,
  890. Class: ClassINET,
  891. },
  892. &NSResource{mustNewName("ns1.example.com.")},
  893. },
  894. {
  895. ResourceHeader{
  896. Name: name,
  897. Type: TypeNS,
  898. Class: ClassINET,
  899. },
  900. &NSResource{mustNewName("ns2.example.com.")},
  901. },
  902. },
  903. Additionals: []Resource{
  904. {
  905. ResourceHeader{
  906. Name: name,
  907. Type: TypeTXT,
  908. Class: ClassINET,
  909. },
  910. &TXTResource{"So Long, and Thanks for All the Fish"},
  911. },
  912. {
  913. ResourceHeader{
  914. Name: name,
  915. Type: TypeTXT,
  916. Class: ClassINET,
  917. },
  918. &TXTResource{"Hamster Huey and the Gooey Kablooie"},
  919. },
  920. },
  921. }
  922. }
  923. const loremIpsum = `
  924. Lorem ipsum dolor sit amet, nec enim antiopam id, an ullum choro
  925. nonumes qui, pro eu debet honestatis mediocritatem. No alia enim eos,
  926. magna signiferumque ex vis. Mei no aperiri dissentias, cu vel quas
  927. regione. Malorum quaeque vim ut, eum cu semper aliquid invidunt, ei
  928. nam ipsum assentior.
  929. Nostrum appellantur usu no, vis ex probatus adipiscing. Cu usu illum
  930. facilis eleifend. Iusto conceptam complectitur vim id. Tale omnesque
  931. no usu, ei oblique sadipscing vim. At nullam voluptua usu, mei laudem
  932. reformidans et. Qui ei eros porro reformidans, ius suas veritus
  933. torquatos ex. Mea te facer alterum consequat.
  934. Soleat torquatos democritum sed et, no mea congue appareat, facer
  935. aliquam nec in. Has te ipsum tritani. At justo dicta option nec, movet
  936. phaedrum ad nam. Ea detracto verterem liberavisse has, delectus
  937. suscipiantur in mei. Ex nam meliore complectitur. Ut nam omnis
  938. honestatis quaerendum, ea mea nihil affert detracto, ad vix rebum
  939. mollis.
  940. Ut epicurei praesent neglegentur pri, prima fuisset intellegebat ad
  941. vim. An habemus comprehensam usu, at enim dignissim pro. Eam reque
  942. vivendum adipisci ea. Vel ne odio choro minimum. Sea admodum
  943. dissentiet ex. Mundi tamquam evertitur ius cu. Homero postea iisque ut
  944. pro, vel ne saepe senserit consetetur.
  945. Nulla utamur facilisis ius ea, in viderer diceret pertinax eum. Mei no
  946. enim quodsi facilisi, ex sed aeterno appareat mediocritatem, eum
  947. sententiae deterruisset ut. At suas timeam euismod cum, offendit
  948. appareat interpretaris ne vix. Vel ea civibus albucius, ex vim quidam
  949. accusata intellegebat, noluisse instructior sea id. Nec te nonumes
  950. habemus appellantur, quis dignissim vituperata eu nam.
  951. At vix apeirian patrioque vituperatoribus, an usu agam assum. Debet
  952. iisque an mea. Per eu dicant ponderum accommodare. Pri alienum
  953. placerat senserit an, ne eum ferri abhorreant vituperatoribus. Ut mea
  954. eligendi disputationi. Ius no tation everti impedit, ei magna quidam
  955. mediocritatem pri.
  956. Legendos perpetua iracundia ne usu, no ius ullum epicurei intellegam,
  957. ad modus epicuri lucilius eam. In unum quaerendum usu. Ne diam paulo
  958. has, ea veri virtute sed. Alia honestatis conclusionemque mea eu, ut
  959. iudico albucius his.
  960. Usu essent probatus eu, sed omnis dolor delicatissimi ex. No qui augue
  961. dissentias dissentiet. Laudem recteque no usu, vel an velit noluisse,
  962. an sed utinam eirmod appetere. Ne mea fuisset inimicus ocurreret. At
  963. vis dicant abhorreant, utinam forensibus nec ne, mei te docendi
  964. consequat. Brute inermis persecuti cum id. Ut ipsum munere propriae
  965. usu, dicit graeco disputando id has.
  966. Eros dolore quaerendum nam ei. Timeam ornatus inciderint pro id. Nec
  967. torquatos sadipscing ei, ancillae molestie per in. Malis principes duo
  968. ea, usu liber postulant ei.
  969. Graece timeam voluptatibus eu eam. Alia probatus quo no, ea scripta
  970. feugiat duo. Congue option meliore ex qui, noster invenire appellantur
  971. ea vel. Eu exerci legendos vel. Consetetur repudiandae vim ut. Vix an
  972. probo minimum, et nam illud falli tempor.
  973. Cum dico signiferumque eu. Sed ut regione maiorum, id veritus insolens
  974. tacimates vix. Eu mel sint tamquam lucilius, duo no oporteat
  975. tacimates. Atqui augue concludaturque vix ei, id mel utroque menandri.
  976. Ad oratio blandit aliquando pro. Vis et dolorum rationibus
  977. philosophia, ad cum nulla molestie. Hinc fuisset adversarium eum et,
  978. ne qui nisl verear saperet, vel te quaestio forensibus. Per odio
  979. option delenit an. Alii placerat has no, in pri nihil platonem
  980. cotidieque. Est ut elit copiosae scaevola, debet tollit maluisset sea
  981. an.
  982. Te sea hinc debet pericula, liber ridens fabulas cu sed, quem mutat
  983. accusam mea et. Elitr labitur albucius et pri, an labore feugait mel.
  984. Velit zril melius usu ea. Ad stet putent interpretaris qui. Mel no
  985. error volumus scripserit. In pro paulo iudico, quo ei dolorem
  986. verterem, affert fabellas dissentiet ea vix.
  987. Vis quot deserunt te. Error aliquid detraxit eu usu, vis alia eruditi
  988. salutatus cu. Est nostrud bonorum an, ei usu alii salutatus. Vel at
  989. nisl primis, eum ex aperiri noluisse reformidans. Ad veri velit
  990. utroque vis, ex equidem detraxit temporibus has.
  991. Inermis appareat usu ne. Eros placerat periculis mea ad, in dictas
  992. pericula pro. Errem postulant at usu, ea nec amet ornatus mentitum. Ad
  993. mazim graeco eum, vel ex percipit volutpat iudicabit, sit ne delicata
  994. interesset. Mel sapientem prodesset abhorreant et, oblique suscipit
  995. eam id.
  996. An maluisset disputando mea, vidit mnesarchum pri et. Malis insolens
  997. inciderint no sea. Ea persius maluisset vix, ne vim appellantur
  998. instructior, consul quidam definiebas pri id. Cum integre feugiat
  999. pericula in, ex sed persius similique, mel ne natum dicit percipitur.
  1000. Primis discere ne pri, errem putent definitionem at vis. Ei mel dolore
  1001. neglegentur, mei tincidunt percipitur ei. Pro ad simul integre
  1002. rationibus. Eu vel alii honestatis definitiones, mea no nonumy
  1003. reprehendunt.
  1004. Dicta appareat legendos est cu. Eu vel congue dicunt omittam, no vix
  1005. adhuc minimum constituam, quot noluisse id mel. Eu quot sale mutat
  1006. duo, ex nisl munere invenire duo. Ne nec ullum utamur. Pro alterum
  1007. debitis nostrum no, ut vel aliquid vivendo.
  1008. Aliquip fierent praesent quo ne, id sit audiam recusabo delicatissimi.
  1009. Usu postulant incorrupte cu. At pro dicit tibique intellegam, cibo
  1010. dolore impedit id eam, et aeque feugait assentior has. Quando sensibus
  1011. nec ex. Possit sensibus pri ad, unum mutat periculis cu vix.
  1012. Mundi tibique vix te, duo simul partiendo qualisque id, est at vidit
  1013. sonet tempor. No per solet aeterno deseruisse. Petentium salutandi
  1014. definiebas pri cu. Munere vivendum est in. Ei justo congue eligendi
  1015. vis, modus offendit omittantur te mel.
  1016. Integre voluptaria in qui, sit habemus tractatos constituam no. Utinam
  1017. melius conceptam est ne, quo in minimum apeirian delicata, ut ius
  1018. porro recusabo. Dicant expetenda vix no, ludus scripserit sed ex, eu
  1019. his modo nostro. Ut etiam sonet his, quodsi inciderint philosophia te
  1020. per. Nullam lobortis eu cum, vix an sonet efficiendi repudiandae. Vis
  1021. ad idque fabellas intellegebat.
  1022. Eum commodo senserit conclusionemque ex. Sed forensibus sadipscing ut,
  1023. mei in facer delicata periculis, sea ne hinc putent cetero. Nec ne
  1024. alia corpora invenire, alia prima soleat te cum. Eleifend posidonium
  1025. nam at.
  1026. Dolorum indoctum cu quo, ex dolor legendos recteque eam, cu pri zril
  1027. discere. Nec civibus officiis dissentiunt ex, est te liber ludus
  1028. elaboraret. Cum ea fabellas invenire. Ex vim nostrud eripuit
  1029. comprehensam, nam te inermis delectus, saepe inermis senserit.
  1030. `