dns-zone2 0.3.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (60) hide show
  1. checksums.yaml +7 -0
  2. data/Gemfile +2 -0
  3. data/HISTORY.md +45 -0
  4. data/README.md +151 -0
  5. data/Rakefile +15 -0
  6. data/dns-zone2.gemspec +41 -0
  7. data/lib/dns/zone.rb +207 -0
  8. data/lib/dns/zone/rr.rb +87 -0
  9. data/lib/dns/zone/rr/a.rb +21 -0
  10. data/lib/dns/zone/rr/aaaa.rb +5 -0
  11. data/lib/dns/zone/rr/cdnskey.rb +5 -0
  12. data/lib/dns/zone/rr/cds.rb +5 -0
  13. data/lib/dns/zone/rr/cname.rb +21 -0
  14. data/lib/dns/zone/rr/dlv.rb +5 -0
  15. data/lib/dns/zone/rr/dnskey.rb +38 -0
  16. data/lib/dns/zone/rr/ds.rb +38 -0
  17. data/lib/dns/zone/rr/hinfo.rb +31 -0
  18. data/lib/dns/zone/rr/mx.rb +33 -0
  19. data/lib/dns/zone/rr/naptr.rb +44 -0
  20. data/lib/dns/zone/rr/ns.rb +21 -0
  21. data/lib/dns/zone/rr/nsec.rb +32 -0
  22. data/lib/dns/zone/rr/nsec3.rb +45 -0
  23. data/lib/dns/zone/rr/nsec3param.rb +38 -0
  24. data/lib/dns/zone/rr/ptr.rb +21 -0
  25. data/lib/dns/zone/rr/record.rb +88 -0
  26. data/lib/dns/zone/rr/rrsig.rb +54 -0
  27. data/lib/dns/zone/rr/soa.rb +51 -0
  28. data/lib/dns/zone/rr/spf.rb +5 -0
  29. data/lib/dns/zone/rr/srv.rb +38 -0
  30. data/lib/dns/zone/rr/sshfp.rb +35 -0
  31. data/lib/dns/zone/rr/txt.rb +24 -0
  32. data/lib/dns/zone/test_case.rb +27 -0
  33. data/lib/dns/zone/version.rb +6 -0
  34. data/test/rr/a_test.rb +37 -0
  35. data/test/rr/aaaa_test.rb +27 -0
  36. data/test/rr/cdnskey_test.rb +31 -0
  37. data/test/rr/cds_test.rb +28 -0
  38. data/test/rr/cname_test.rb +19 -0
  39. data/test/rr/dlv_test.rb +28 -0
  40. data/test/rr/dnskey_test.rb +31 -0
  41. data/test/rr/ds_test.rb +28 -0
  42. data/test/rr/hinfo_test.rb +44 -0
  43. data/test/rr/mx_test.rb +26 -0
  44. data/test/rr/naptr_test.rb +60 -0
  45. data/test/rr/ns_test.rb +18 -0
  46. data/test/rr/nsec3_test.rb +33 -0
  47. data/test/rr/nsec3param_test.rb +29 -0
  48. data/test/rr/nsec_test.rb +24 -0
  49. data/test/rr/ptr_test.rb +19 -0
  50. data/test/rr/record_test.rb +37 -0
  51. data/test/rr/rrsig_test.rb +40 -0
  52. data/test/rr/soa_test.rb +34 -0
  53. data/test/rr/spf_test.rb +20 -0
  54. data/test/rr/srv_test.rb +24 -0
  55. data/test/rr/sshfp_test.rb +24 -0
  56. data/test/rr/txt_test.rb +44 -0
  57. data/test/rr_test.rb +50 -0
  58. data/test/version_test.rb +9 -0
  59. data/test/zone_test.rb +273 -0
  60. metadata +217 -0
@@ -0,0 +1,40 @@
1
+ require 'dns/zone/test_case'
2
+
3
+ class RR_RRSIG_Test < DNS::Zone::TestCase
4
+
5
+ TEST_SIGNATURE = 'oJB1W6WNGv+ldvQ3WDG0MQkg5IEhjRip8WTrPYGv07h108dUKGMeDPKijVCHX3DDKdfb+v6oB9wfuh3DTJXUAfI/M0zmO/zz8bW0Rznl8O3tGNazPwQKkRN20XPXV6nwwfoXmJQbsLNrLfkGJ5D6fwFm8nN+6pBzeDQfsS3Ap3o='
6
+
7
+ def test_build_rr__rrsig
8
+ rr = DNS::Zone::RR::RRSIG.new
9
+ rr.label = 'host.example.com.'
10
+ rr.type_covered = 'A'
11
+ rr.algorithm = 5
12
+ rr.labels = 3
13
+ rr.original_ttl = 86400
14
+ rr.signature_expiration = 20030322173103
15
+ rr.signature_inception = 20030220173103
16
+ rr.key_tag = 2642
17
+ rr.signer = 'example.com.'
18
+ rr.signature = TEST_SIGNATURE
19
+
20
+ assert_equal "host.example.com. IN RRSIG A 5 3 86400 20030322173103 20030220173103 2642 example.com. #{TEST_SIGNATURE}", rr.dump
21
+
22
+ end
23
+
24
+ def test_load_rr__rrsig
25
+ rr = DNS::Zone::RR::RRSIG.new.load("host.example.com. IN RRSIG A 5 3 86400 20030322173103 20030220173103 2642 example.com. #{TEST_SIGNATURE}")
26
+ assert_equal 'host.example.com.', rr.label
27
+ assert_equal 'RRSIG', rr.type
28
+
29
+ assert_equal 'A', rr.type_covered
30
+ assert_equal 5, rr.algorithm
31
+ assert_equal 3, rr.labels
32
+ assert_equal 86400, rr.original_ttl
33
+ assert_equal 20030322173103, rr.signature_expiration
34
+ assert_equal 20030220173103, rr.signature_inception
35
+ assert_equal 2642, rr.key_tag
36
+ assert_equal 'example.com.', rr.signer
37
+ assert_equal TEST_SIGNATURE, rr.signature
38
+ end
39
+
40
+ end
@@ -0,0 +1,34 @@
1
+ require 'dns/zone/test_case'
2
+
3
+ class RR_SOA_Test < DNS::Zone::TestCase
4
+
5
+ EXAMPLE_SOA_IN = '@ IN SOA ns0.lividpenguin.com. luke.lividpenguin.com. 2014021601 3h 15m 4w 30m'
6
+ EXAMPLE_SOA_OUT = '@ IN SOA ns0.lividpenguin.com. luke.lividpenguin.com. ( 2014021601 3h 15m 4w 30m )'
7
+
8
+ def test_build_rr__soa
9
+ rr = DNS::Zone::RR::SOA.new
10
+ rr.nameserver = 'ns0.lividpenguin.com.'
11
+ rr.email = 'luke.lividpenguin.com.'
12
+ rr.serial = 2014_02_16_01
13
+ rr.refresh_ttl = '3h'
14
+ rr.retry_ttl = '15m'
15
+ rr.expiry_ttl = '4w'
16
+ rr.minimum_ttl = '30m'
17
+ assert_equal EXAMPLE_SOA_OUT, rr.dump
18
+ end
19
+
20
+ def test_load_rr__soa
21
+ rr = DNS::Zone::RR::SOA.new.load(EXAMPLE_SOA_IN)
22
+ assert_equal '@', rr.label
23
+ assert_equal 'SOA', rr.type
24
+
25
+ assert_equal 'ns0.lividpenguin.com.', rr.nameserver
26
+ assert_equal 'luke.lividpenguin.com.', rr.email
27
+ assert_equal 2014_02_16_01, rr.serial
28
+ assert_equal '3h', rr.refresh_ttl
29
+ assert_equal '15m', rr.retry_ttl
30
+ assert_equal '4w', rr.expiry_ttl
31
+ assert_equal '30m', rr.minimum_ttl
32
+ end
33
+
34
+ end
@@ -0,0 +1,20 @@
1
+ require 'dns/zone/test_case'
2
+
3
+ class RR_SPF_Test < DNS::Zone::TestCase
4
+
5
+ def test_build_rr__spf
6
+ rr = DNS::Zone::RR::SPF.new
7
+ rr.ttl = '2w'
8
+ rr.text = '"v=spf1 +mx -all"'
9
+ assert_equal '@ 2w IN SPF "v=spf1 +mx -all"', rr.dump
10
+ end
11
+
12
+ def test_load_rr__spf
13
+ rr = DNS::Zone::RR::SPF.new.load('@ 2w IN SPF "v=spf1 +mx -all"')
14
+ assert_equal '@', rr.label
15
+ assert_equal 'IN', rr.klass
16
+ assert_equal 'SPF', rr.type
17
+ assert_equal '"v=spf1 +mx -all"', rr.text
18
+ end
19
+
20
+ end
@@ -0,0 +1,24 @@
1
+ require 'dns/zone/test_case'
2
+
3
+ class RR_SRV_Test < DNS::Zone::TestCase
4
+
5
+ def test_build_rr__srv
6
+ rr = DNS::Zone::RR::SRV.new
7
+ rr.priority = 5
8
+ rr.weight = 0
9
+ rr.port = 5269
10
+ rr.target = 'xmpp-server.l.google.com.'
11
+ assert_equal '@ IN SRV 5 0 5269 xmpp-server.l.google.com.', rr.dump
12
+ end
13
+
14
+ def test_load_rr__srv
15
+ rr = DNS::Zone::RR::SRV.new.load('@ IN SRV 5 0 5269 xmpp-server.l.google.com.')
16
+ assert_equal '@', rr.label
17
+ assert_equal 'SRV', rr.type
18
+ assert_equal 5, rr.priority
19
+ assert_equal 0, rr.weight
20
+ assert_equal 5269, rr.port
21
+ assert_equal 'xmpp-server.l.google.com.', rr.target
22
+ end
23
+
24
+ end
@@ -0,0 +1,24 @@
1
+ require 'dns/zone/test_case'
2
+
3
+ class RR_SSHFP_Test < DNS::Zone::TestCase
4
+
5
+ def test_build_rr__sshfp
6
+ rr = DNS::Zone::RR::SSHFP.new
7
+ rr.label = 'host.example.'
8
+ rr.algorithm_number = 2
9
+ rr.fingerprint_type = 1
10
+ rr.fingerprint = '123456789abcdef67890123456789abcdef67890'
11
+
12
+ assert_equal 'host.example. IN SSHFP 2 1 123456789abcdef67890123456789abcdef67890', rr.dump
13
+ end
14
+
15
+ def test_load_rr__sshfp
16
+ rr = DNS::Zone::RR::SSHFP.new.load('host.example. IN SSHFP 2 1 123456789abcdef67890123456789abcdef67890')
17
+ assert_equal 'host.example.', rr.label
18
+ assert_equal 'SSHFP', rr.type
19
+ assert_equal 2, rr.algorithm_number
20
+ assert_equal 1, rr.fingerprint_type
21
+ assert_equal '123456789abcdef67890123456789abcdef67890', rr.fingerprint
22
+ end
23
+
24
+ end
@@ -0,0 +1,44 @@
1
+ require 'dns/zone/test_case'
2
+
3
+ class RR_TXT_Test < DNS::Zone::TestCase
4
+
5
+ def test_build_rr__txt
6
+ rr = DNS::Zone::RR::TXT.new
7
+
8
+ # ensure we can set text parameter
9
+ rr.text = '"test text"'
10
+ assert_equal '@ IN TXT "test text"', rr.dump
11
+
12
+ # with a label set
13
+ rr.label = 'labelname'
14
+ assert_equal 'labelname IN TXT "test text"', rr.dump
15
+
16
+ # with a ttl
17
+ rr.ttl = '2w'
18
+ assert_equal 'labelname 2w IN TXT "test text"', rr.dump
19
+ end
20
+
21
+ def test_load_rr__txt
22
+ rr = DNS::Zone::RR::TXT.new.load('txtrecord IN TXT "test text"')
23
+ assert_equal 'txtrecord', rr.label
24
+ assert_equal 'IN', rr.klass
25
+ assert_equal 'TXT', rr.type
26
+ assert_equal '"test text"', rr.text
27
+ end
28
+
29
+ def test_load_multiple_quoted_strings
30
+ rr = DNS::Zone::RR::TXT.new.load('txtrecord IN TXT "part1 yo" " part2 yo"')
31
+ assert_equal '"part1 yo" " part2 yo"', rr.text
32
+ end
33
+
34
+ def test_load_string_with_quotes
35
+ rr = DNS::Zone::RR::TXT.new.load('txtrecord IN TXT "we have \"double\" quotes"')
36
+ assert_equal %q{"we have \"double\" quotes"}, rr.text
37
+ end
38
+
39
+ def test_load_multiple_strings_with_quotes
40
+ rr = DNS::Zone::RR::TXT.new.load('txtrecord IN TXT "part1 " "we have \"double\" quotes" " part3"')
41
+ assert_equal %q{"part1 " "we have \"double\" quotes" " part3"}, rr.text
42
+ end
43
+
44
+ end
@@ -0,0 +1,50 @@
1
+ require 'dns/zone/test_case'
2
+
3
+ class RRTest < DNS::Zone::TestCase
4
+
5
+ def test_load_ignores_comments
6
+ rr = DNS::Zone::RR.load('; comment lines are ignored')
7
+ assert_nil rr, 'should be nil when its a comment line'
8
+ end
9
+
10
+ def test_load_ignores_unparsable_input
11
+ rr = DNS::Zone::RR.load('invalid input should not be parsed')
12
+ assert_nil rr, 'should be nil when input cant be parsed at all'
13
+ end
14
+
15
+ def test_load_a_rr
16
+ rr = DNS::Zone::RR.load('www IN A 10.2.3.1')
17
+ assert_instance_of DNS::Zone::RR::A, rr, 'should be instance of A RR'
18
+ assert_equal 'www', rr.label
19
+ assert_equal 'A', rr.type
20
+ assert_equal '10.2.3.1', rr.address
21
+ end
22
+
23
+ def test_load_txt_rr
24
+ rr = DNS::Zone::RR.load('mytxt IN TXT "test text"')
25
+ assert_instance_of DNS::Zone::RR::TXT, rr, 'should be instance of TXT RR'
26
+ assert_equal 'mytxt', rr.label
27
+ assert_equal 'TXT', rr.type
28
+ assert_equal '"test text"', rr.text
29
+ end
30
+
31
+ def test_load_txt_semicolon_rr
32
+ rr = DNS::Zone::RR.load('_domainkey IN TXT "t=y; o=~;"')
33
+ assert_instance_of DNS::Zone::RR::TXT, rr, 'should be instance of TXT RR'
34
+ assert_equal '_domainkey', rr.label
35
+ assert_equal 'TXT', rr.type
36
+ assert_equal '"t=y; o=~;"', rr.text
37
+ end
38
+
39
+ def test_load_a_rr_with_options_hash
40
+ rr = DNS::Zone::RR.load(' IN A 10.2.3.1', { last_label: 'www' })
41
+ assert_equal 'www', rr.label
42
+
43
+ rr = DNS::Zone::RR.load('blog IN A 10.2.3.1', { last_label: 'www' })
44
+ assert_equal 'blog', rr.label
45
+
46
+ rr = DNS::Zone::RR.load('@ IN A 10.2.3.1', { last_label: 'mail' })
47
+ assert_equal '@', rr.label
48
+ end
49
+
50
+ end
@@ -0,0 +1,9 @@
1
+ require 'dns/zone/test_case'
2
+
3
+ class VersionTest < DNS::Zone::TestCase
4
+
5
+ def test_should_have_a_version
6
+ assert DNS::Zone::Version, 'unable to access the version number'
7
+ end
8
+
9
+ end
@@ -0,0 +1,273 @@
1
+ require 'dns/zone/test_case'
2
+
3
+ class ZoneTest < DNS::Zone::TestCase
4
+
5
+ # example zone file, with a couple of things that could trip us up.
6
+ ZONE_FILE_EXAMPLE =<<-EOL
7
+ $ORIGIN lividpenguin.com.
8
+ $TTL 3d
9
+ @ IN SOA ns0.lividpenguin.com. luke.lividpenguin.com. (
10
+ 2013101406 ; zone serial number
11
+ 12h ; refresh ttl
12
+ 15m ; retry ttl
13
+ 3w ; expiry ttl
14
+ 3h ; minimum ttl
15
+ )
16
+
17
+ ; a more difficult ; comment ( that is trying to break things!
18
+
19
+ @ IN NS ns0.lividpenguin.com.
20
+ @ IN NS ns1.lividpenguin.com.
21
+ @ IN NS ns2.lividpenguin.com.
22
+
23
+ @ IN MX 10 mx0.lividpenguin.com.
24
+ @ IN MX 20 mx1.lividpenguin.com.
25
+
26
+ @ IN A 78.47.253.85
27
+ ns0 IN A 78.47.253.85
28
+ ns0 IN HINFO "Intel" "Ubuntu"
29
+
30
+ ns0 IN AAAA 2a01:4f8:d12:5ca::2
31
+
32
+ foo IN TXT "part1" "part2"
33
+ bar IN TXT ("part1 "
34
+ "part2 "
35
+ "part3")
36
+ _domainkey IN TXT "t=y; o=~;"
37
+
38
+ longttl 5d IN A 10.1.2.3
39
+
40
+ cake IN CNAME the.cake.is.a.lie.com.
41
+ xmpp IN SRV 5 0 5269 xmpp-server.google.com.
42
+ @ IN SPF "v=spf1 +mx -all"
43
+
44
+ ; a record to be expanded
45
+ @ IN NS ns3
46
+
47
+ ; a record that uses tab spaces
48
+ tabed IN A 10.1.2.3
49
+
50
+ EOL
51
+
52
+ # basic zone file example
53
+ ZONE_FILE_BASIC_EXAMPLE =<<-EOL
54
+ @ IN SOA ns0.lividpenguin.com. luke.lividpenguin.com. ( 2013101406 12h 15m 3w 3h )
55
+ @ IN NS ns0.lividpenguin.com.
56
+ @ IN MX 10 mail
57
+ @ IN MX 99 mx.fakemx.net.
58
+ @ IN A 78.47.253.85
59
+ mail IN A 78.47.253.85
60
+ foo IN TXT "part1" "part2"
61
+ EOL
62
+
63
+ # zone file with multiple zones
64
+ ZONE_FILE_MULTIPLE_ORIGINS_EXAMPLE =<<-EOL
65
+ $ORIGIN lividpenguin.com.
66
+ $TTL 3d
67
+ @ IN SOA ns0.lividpenguin.com. luke.lividpenguin.com. (
68
+ 2013101406 ; zone serial number
69
+ 12h ; refresh ttl
70
+ 15m ; retry ttl
71
+ 3w ; expiry ttl
72
+ 3h ; minimum ttl
73
+ )
74
+
75
+ @ IN NS ns0.lividpenguin.com.
76
+ @ IN NS ns1.lividpenguin.com.
77
+ @ IN NS ns2.lividpenguin.com.
78
+
79
+ @ IN A 78.47.253.85
80
+ www IN A 78.47.253.85
81
+
82
+ foo IN TXT "part1" "part2"
83
+
84
+ $ORIGIN sub.lividpenguin.com.
85
+ app1 60 A 1.2.3.4
86
+ app2 60 A 1.2.3.5
87
+ app3 60 A 1.2.3.6
88
+ $ORIGIN another.lividpenguin.com.
89
+ @ 3600 A 1.1.1.1
90
+ app1 60 A 4.3.2.1
91
+
92
+ EOL
93
+
94
+ def test_create_new_instance
95
+ assert DNS::Zone.new
96
+ end
97
+
98
+ def test_programmatic_readme_example
99
+ zone = DNS::Zone.new
100
+ zone.origin = 'example.com.'
101
+ zone.ttl = '1d'
102
+ # quick access to SOA RR
103
+ zone.soa.nameserver = 'ns0.lividpenguin.com.'
104
+ zone.soa.email = 'hostmaster.lividpenguin.com.'
105
+ # create and add new record
106
+ rec = DNS::Zone::RR::A.new
107
+ rec.address = '127.0.0.1'
108
+ zone.records << rec
109
+
110
+ assert_equal 2, zone.records.length, "were expecting 2 records, including the SOA"
111
+ end
112
+
113
+ def test_load_zone_basic
114
+ # load zone file.
115
+ zone = DNS::Zone.load(ZONE_FILE_BASIC_EXAMPLE)
116
+ # dump zone file.
117
+ dump = zone.dump
118
+ # check input matches output.
119
+ assert_equal ZONE_FILE_BASIC_EXAMPLE, dump, 'loaded zone file should match dumped zone file'
120
+ end
121
+
122
+ def test_load_zone_with_origin_param
123
+ # --- zone without $ORIGIN directive
124
+
125
+ zone = DNS::Zone.load(ZONE_FILE_BASIC_EXAMPLE, 'lividpenguin.com.')
126
+ dump = zone.dump
127
+ assert_equal ZONE_FILE_BASIC_EXAMPLE, dump, 'loaded zone file should match dumped zone file'
128
+ assert_equal 'lividpenguin.com.', zone.origin, 'check origin matches example input'
129
+
130
+ # --- zone with $ORIGIN directive
131
+
132
+ zone = DNS::Zone.load(ZONE_FILE_EXAMPLE, 'ignore.this.origin.favor.zone.com.')
133
+ assert_equal 'lividpenguin.com.', zone.origin, 'origin should come from test zone, not passed param'
134
+ end
135
+
136
+ def test_load_zone_labels_are_correct
137
+ zone = DNS::Zone.load(ZONE_FILE_BASIC_EXAMPLE, 'lividpenguin.com.')
138
+ assert_equal 'mail', zone.records[5].label, 'check label is correct'
139
+
140
+ zone = DNS::Zone.load(ZONE_FILE_EXAMPLE)
141
+ assert_equal 'ns0', zone.records[7].label, 'check label is correct'
142
+ end
143
+
144
+ def test_load_zone
145
+ # load example dns master zone file.
146
+ zone = DNS::Zone.load(ZONE_FILE_EXAMPLE)
147
+
148
+ # test attributes are correct.
149
+ assert_equal '3d', zone.ttl, 'check ttl matches example input'
150
+ assert_equal 'lividpenguin.com.', zone.origin, 'check origin matches example input'
151
+ assert_equal 19, zone.records.length, 'we should have multiple records (including SOA)'
152
+
153
+ #p ''
154
+ #zone.records.each do |rec|
155
+ # p rec
156
+ #end
157
+ end
158
+
159
+ def test_load_zone_with_empty_labels
160
+ # basic zone file that uses empty labels (ie. use previous)
161
+ zone_as_string =<<-EOL
162
+ @ IN A 78.47.253.85
163
+ IN AAAA 2a01:4f8:d12:5ca::2
164
+ www IN A 78.47.253.85
165
+ IN AAAA 2a01:4f8:d12:5ca::2
166
+ EOL
167
+
168
+ # load zone file.
169
+ zone = DNS::Zone.load(zone_as_string)
170
+
171
+ # test labels are 'inherited' from last used.
172
+ assert_equal '@', zone.records[0].label
173
+ assert_equal '@', zone.records[1].label, 'label should be inherited from last label used'
174
+ assert_equal 'www', zone.records[2].label
175
+ assert_equal 'www', zone.records[3].label, 'label should be inherited from last label used'
176
+ end
177
+
178
+ def test_load_zone_that_uses_tabs_rather_then_spaces
179
+ zone_as_string =<<-EOL
180
+ * IN A 78.47.253.85
181
+ EOL
182
+
183
+ # load zone file.
184
+ zone = DNS::Zone.load(zone_as_string)
185
+
186
+ record = zone.records[0]
187
+ assert_equal '*', record.label
188
+ assert_equal 'A', record.type
189
+ assert_equal '78.47.253.85', record.address
190
+ end
191
+
192
+ def test_load_multiple_origins
193
+ zone = DNS::Zone.load(ZONE_FILE_MULTIPLE_ORIGINS_EXAMPLE)
194
+ assert_equal 'lividpenguin.com.', zone.origin
195
+ assert_equal 12, zone.records.length, 'we should have multiple records (including SOA)'
196
+ assert_equal 'app1.sub', zone.records[7].label
197
+ assert_equal '1.2.3.4', zone.records[7].address
198
+ assert_equal 'another', zone.records[10].label
199
+ assert_equal '1.1.1.1', zone.records[10].address
200
+ assert_equal 'app1.another', zone.records[11].label
201
+ assert_equal '4.3.2.1', zone.records[11].address
202
+ end
203
+
204
+ def test_extract_entry_from_one_line
205
+ entries = DNS::Zone.extract_entries(%Q{maiow IN TXT "purr"})
206
+ assert_equal 1, entries.length, 'we should have 1 entry'
207
+ assert_equal 'maiow IN TXT "purr"', entries[0], 'entry should match expected'
208
+ end
209
+
210
+ def test_extract_entry_including_semicolon_within_quotes
211
+ entries = DNS::Zone.extract_entries(%Q{_domainkey IN TXT "t=y; o=~;"})
212
+ assert_equal 1, entries.length, 'we should have 1 entry'
213
+ assert_equal '_domainkey IN TXT "t=y; o=~;"', entries[0], 'entry should match expected'
214
+ end
215
+
216
+ def test_extract_entry_should_ignore_comments
217
+ entries = DNS::Zone.extract_entries(%Q{maiow IN TXT "purr"; this is a comment})
218
+ assert_equal 1, entries.length, 'we should have 1 entry'
219
+ assert_equal 'maiow IN TXT "purr"', entries[0], 'entry should match expected'
220
+ end
221
+
222
+ def test_extract_entry_should_ignore_empty_lines
223
+ entries = DNS::Zone.extract_entries(%Q{\n\nmaiow IN TXT "purr";\n\n})
224
+ assert_equal 1, entries.length, 'we should have 1 entry'
225
+ assert_equal 'maiow IN TXT "purr"', entries[0], 'entry should match expected'
226
+ end
227
+
228
+ def test_extract_entry_using_parentheses_but_not_crossing_line_boundary
229
+ entries = DNS::Zone.extract_entries(%Q{maiow IN TXT ("part1" "part2")})
230
+ assert_equal 1, entries.length, 'we should have 1 entry'
231
+ assert_equal 'maiow IN TXT "part1" "part2"', entries[0], 'entry should match expected'
232
+ end
233
+
234
+ def test_extract_entry_crossing_line_boundary
235
+ entries = DNS::Zone.extract_entries(%Q{maiow1 IN TXT ("part1"\n "part2" )})
236
+ assert_equal 1, entries.length, 'we should have 1 entry'
237
+ assert_equal 'maiow1 IN TXT "part1" "part2"', entries[0], 'entry should match expected'
238
+ end
239
+
240
+ def test_extract_entry_soa_crossing_line_boundary
241
+ entries = DNS::Zone.extract_entries(%Q{
242
+ @ IN SOA ns0.lividpenguin.com. luke.lividpenguin.com. (
243
+ 2013101406 ; zone serial number
244
+ 12h ; refresh ttl
245
+ 15m ; retry ttl
246
+ 3w ; expiry ttl
247
+ 3h ; minimum ttl
248
+ )})
249
+ assert_equal 1, entries.length, 'we should have 1 entry'
250
+
251
+ expected_soa = '@ IN SOA ns0.lividpenguin.com. luke.lividpenguin.com. 2013101406 12h 15m 3w 3h'
252
+ assert_equal expected_soa, entries[0], 'entry should match expected'
253
+ end
254
+
255
+ def test_extract_entries_with_parentheses_crossing_multiple_line_boundaries
256
+ entries = DNS::Zone.extract_entries(%Q{maiow1 IN TXT (\n"part1"\n "part2"\n)})
257
+ assert_equal 1, entries.length, 'we should have 1 entry'
258
+ assert_equal 'maiow1 IN TXT "part1" "part2"', entries[0], 'entry should match expected'
259
+ end
260
+
261
+ def test_extract_entries_with_legal_but_crazy_parentheses_used
262
+ entries = DNS::Zone.extract_entries(%Q{maiow IN TXT (\n(\n("part1")\n \n("part2" \n("part3"\n)\n)\n)\n)})
263
+ assert_equal 1, entries.length, 'we should have 1 entry'
264
+ assert_equal 'maiow IN TXT "part1" "part2" "part3"', entries[0], 'entry should match expected'
265
+ end
266
+
267
+ def test_extract_entry_with_parentheses_in_character_string
268
+ entries = DNS::Zone.extract_entries(%Q{maiow IN TXT ("purr((maiow)")})
269
+ assert_equal 1, entries.length, 'we should have 1 entry'
270
+ assert_equal 'maiow IN TXT "purr((maiow)"', entries[0], 'entry should match expected'
271
+ end
272
+
273
+ end