dnssd 2.0.1 → 3.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -4,6 +4,31 @@ require 'delegate'
4
4
  # DNSSD::TextRecord is a Hash delegate that can encode its contents for DNSSD.
5
5
 
6
6
  class DNSSD::TextRecord < DelegateClass(Hash)
7
+ def self.decode text_record
8
+ record = {}
9
+
10
+ tr = text_record.unpack 'C*'
11
+
12
+ until tr.empty? do
13
+ size = tr.shift
14
+
15
+ next if size.zero?
16
+
17
+ raise ArgumentError, 'ran out of data in text record' if tr.length < size
18
+
19
+ entry = tr.shift(size).pack('C*')
20
+
21
+ raise ArgumentError, 'key not found' unless entry =~ /^[^=]/
22
+
23
+ key, value = entry.split '=', 2
24
+
25
+ next unless key
26
+
27
+ record[key] = value
28
+ end
29
+
30
+ new record
31
+ end
7
32
 
8
33
  ##
9
34
  # Creates a new TextRecord decoding an encoded +text_record+ if given or
@@ -30,29 +55,7 @@ class DNSSD::TextRecord < DelegateClass(Hash)
30
55
  # Decodes +text_record+ and returns a Hash
31
56
 
32
57
  def decode(text_record)
33
- record = {}
34
-
35
- tr = text_record.unpack 'C*'
36
-
37
- until tr.empty? do
38
- size = tr.shift
39
-
40
- next if size.zero?
41
-
42
- raise ArgumentError, 'ran out of data in text record' if tr.length < size
43
-
44
- entry = tr.shift(size).pack('C*')
45
-
46
- raise ArgumentError, 'key not found' unless entry =~ /^[^=]/
47
-
48
- key, value = entry.split '=', 2
49
-
50
- next unless key
51
-
52
- record[key] = value
53
- end
54
-
55
- record
58
+ self.class.decode text_record
56
59
  end
57
60
 
58
61
  ##
@@ -1,60 +1,101 @@
1
- require 'minitest/autorun'
2
- require 'dnssd'
3
- require 'socket'
4
-
5
- class TestDNSSD < MiniTest::Unit::TestCase
1
+ require 'helper'
6
2
 
3
+ class TestDNSSD < DNSSD::Test
7
4
  def setup
8
5
  @abort = Thread.abort_on_exception
9
6
  Thread.abort_on_exception = true
10
7
 
11
- @port = Socket.getservbyname 'blackjack'
8
+ begin
9
+ @port = Socket.getservbyname 'blackjack'
10
+ rescue
11
+ @port = 1025
12
+ end
12
13
  end
13
14
 
14
15
  def teardown
15
16
  Thread.abort_on_exception = @abort
16
17
  end
17
18
 
19
+ def test_synchronous_register
20
+ reply = DNSSD.register! name, "_http._tcp", nil, 8080 do |r|
21
+ break r
22
+ end
23
+ assert reply
24
+ end
25
+
26
+ def test_synchronous_enumerate
27
+ Timeout.timeout(2, Minitest::Skip) do
28
+ reply = DNSSD.enumerate_domains! do |r|
29
+ break r
30
+ end
31
+ assert reply
32
+ end
33
+ end
34
+
35
+ def test_asynchronous_enumerate
36
+ latch = Latch.new
37
+ reply = DNSSD.enumerate_domains do |r|
38
+ latch.await
39
+ end
40
+ latch.release
41
+ assert reply
42
+ end
43
+
44
+ def test_synchronous_browse
45
+ register = DNSSD::Service.register name, "_http._tcp", nil, 8080
46
+ thing = nil
47
+ DNSSD.browse!('_http._tcp') do |r|
48
+ thing = true
49
+ break
50
+ end
51
+ assert thing
52
+ register.stop
53
+ end
54
+
18
55
  def test_class_announce_tcp_server
19
- t = Thread.current
20
- DNSSD.browse '_blackjack._tcp' do |reply|
56
+ t = nil
57
+ latch = Latch.new
58
+
59
+ browse = DNSSD.browse '_blackjack._tcp' do |reply|
21
60
  next unless 'blackjack tcp server' == reply.name
22
- t[:reply] = reply
61
+ t = reply
62
+ latch.release
23
63
  end
24
64
 
25
65
  s = TCPServer.new 'localhost', @port
26
66
 
27
- DNSSD.announce s, 'blackjack tcp server'
67
+ stub Socket, :getservbyport, 'blackjack' do
68
+ DNSSD.announce s, 'blackjack tcp server'
69
+ end
28
70
 
29
- sleep 1
71
+ latch.await
30
72
 
31
- assert_equal 'blackjack tcp server', t[:reply].name
73
+ assert_equal 'blackjack tcp server', t.name
32
74
  ensure
75
+ browse.stop
33
76
  s.close
34
77
  end
35
78
 
36
79
  def test_class_announce_tcp_server_service
37
- t = Thread.current
80
+ t = nil
81
+ latch = Latch.new
38
82
 
39
- DNSSD.resolve 'blackjack resolve', '_blackjack._tcp', 'local.' do |reply|
40
- t[:reply] = reply
83
+ rs = DNSSD.resolve 'blackjack resolve', '_blackjack._tcp', 'local.' do |reply|
84
+ t = reply
85
+ latch.release
41
86
  end
42
87
 
43
88
  s = TCPServer.new 'localhost', @port + 1
44
89
 
45
90
  DNSSD.announce s, 'blackjack resolve', 'blackjack'
46
91
 
47
- sleep 1
92
+ latch.await
48
93
 
49
- assert_equal 'blackjack resolve', t[:reply].name
50
- assert_equal @port + 1, t[:reply].port
94
+ assert_equal 'blackjack resolve', t.name
95
+ assert_equal @port + 1, t.port
51
96
  ensure
52
- s.close
53
- end
54
-
55
- def test_class_getservbyport
56
- assert_equal 'blackjack', DNSSD.getservbyport(1025),
57
- "Your /etc/services is out of date, sorry!"
97
+ rs.stop
98
+ s.close if s
58
99
  end
59
100
 
60
101
  def test_class_interface_index
@@ -69,6 +110,4 @@ class TestDNSSD < MiniTest::Unit::TestCase
69
110
 
70
111
  assert_match %r%^lo0?$%, DNSSD.interface_name(index)
71
112
  end
72
-
73
113
  end
74
-
@@ -1,7 +1,6 @@
1
- require 'minitest/autorun'
2
- require 'dnssd'
1
+ require 'helper'
3
2
 
4
- class TestDNSSDFlags < MiniTest::Unit::TestCase
3
+ class TestDNSSDFlags < DNSSD::Test
5
4
 
6
5
  def setup
7
6
  @flags = DNSSD::Flags.new
@@ -1,14 +1,13 @@
1
- require 'minitest/autorun'
2
- require 'dnssd'
1
+ require 'helper'
3
2
 
4
- class TestDNSSDRecord < MiniTest::Unit::TestCase
3
+ class TestDNSSDRecord < DNSSD::Test
5
4
 
6
5
  def setup
7
6
  @fullname = 'blackjack._blackjack._tcp.test.'
8
7
  @IN = DNSSD::Record::IN
9
- @ipv4 = "\300\000\002\001"
10
- @ipv6 = " \001\r\270\000\000\000\000\000\000\000\000\000\000\000\001"
11
- @nowhere = "\007nowhere\007example\000"
8
+ @ipv4 = "\300\000\002\001".force_encoding("ascii-8bit")
9
+ @ipv6 = " \001\r\270\000\000\000\000\000\000\000\000\000\000\000\001".force_encoding("ascii-8bit")
10
+ @nowhere = "\007nowhere\007example\000".force_encoding("ascii-8bit")
12
11
 
13
12
  @R = DNSSD::Record
14
13
  end
@@ -28,6 +27,11 @@ class TestDNSSDRecord < MiniTest::Unit::TestCase
28
27
  end
29
28
  end
30
29
 
30
+ def test_idk
31
+ a_variable = IPAddr.new '2001:db8::1'
32
+ assert_equal @ipv6, a_variable.hton
33
+ end
34
+
31
35
  def test_class_to_data_AAAA
32
36
  assert_equal @ipv6, @R.to_data(DNSSD::Record::AAAA, '2001:db8::1')
33
37
  assert_equal @ipv6,
@@ -1,7 +1,6 @@
1
- require 'minitest/autorun'
2
- require 'dnssd'
1
+ require 'helper'
3
2
 
4
- class TestDNSSDReply < MiniTest::Unit::TestCase
3
+ class TestDNSSDReply < DNSSD::Test
5
4
 
6
5
  def setup
7
6
  @reply = DNSSD::Reply.new nil, 0, 0
@@ -1,17 +1,21 @@
1
- require 'minitest/autorun'
2
- require 'dnssd'
1
+ require 'helper'
3
2
 
4
- class TestDNSSDReplyBrowse < MiniTest::Unit::TestCase
3
+ class TestDNSSDReplyBrowse < DNSSD::Test
5
4
 
6
5
  def test_connect
7
6
  reply = DNSSD::Reply::Browse.new nil, 0, 0, 'blackjack no port',
8
7
  '_blackjack._tcp', 'local'
9
8
 
10
- port = Socket.getservbyname 'blackjack'
9
+ port = stub Socket, :getservbyname, 1025 do
10
+ Socket.getservbyname('blackjack')
11
+ end
12
+
11
13
  server = TCPServer.new nil, port
12
14
  Thread.start do server.accept end
13
15
 
14
- DNSSD.announce server, 'blackjack no port'
16
+ stub Socket, :getservbyport, "blackjack" do
17
+ DNSSD.announce server, 'blackjack no port'
18
+ end
15
19
 
16
20
  socket = reply.connect
17
21
 
@@ -29,14 +33,18 @@ class TestDNSSDReplyBrowse < MiniTest::Unit::TestCase
29
33
  '_blackjack._tcp', 'local'
30
34
 
31
35
 
32
- port = Socket.getservbyname 'blackjack'
36
+ port = stub Socket, :getservbyname, 1025 do
37
+ Socket.getservbyname 'blackjack'
38
+ end
33
39
  server = TCPServer.new nil, port
34
40
  Thread.start do server.accept end
35
41
 
36
42
  name = "\u00E9"
37
43
  name.encode! Encoding::ISO_8859_1
38
44
 
39
- DNSSD.announce server, name
45
+ stub Socket, :getservbyport, 'blackjack' do
46
+ DNSSD.announce server, name
47
+ end
40
48
 
41
49
  socket = reply.connect
42
50
 
@@ -46,6 +54,4 @@ class TestDNSSDReplyBrowse < MiniTest::Unit::TestCase
46
54
  socket.close if socket
47
55
  server.close if server
48
56
  end
49
-
50
57
  end
51
-
@@ -1,7 +1,6 @@
1
- require 'minitest/autorun'
2
- require 'dnssd'
1
+ require 'helper'
3
2
 
4
- class TestDNSSDReplyQueryRecord < MiniTest::Unit::TestCase
3
+ class TestDNSSDReplyQueryRecord < DNSSD::Test
5
4
 
6
5
  def setup
7
6
  @fullname = 'blackjack._blackjack._tcp.test.'
@@ -1,11 +1,13 @@
1
- require 'minitest/autorun'
2
- require 'dnssd'
1
+ require 'helper'
3
2
 
4
- class TestDNSSDReplyResolve < MiniTest::Unit::TestCase
3
+ class TestDNSSDReplyResolve < DNSSD::Test
5
4
 
6
5
  def setup
7
- @port = Socket.getservbyname 'blackjack'
6
+ @port = stub Socket, :getservbyname, 1025 do
7
+ Socket.getservbyname 'blackjack'
8
+ end
8
9
  @interface = DNSSD::InterfaceAny
10
+ super
9
11
  end
10
12
 
11
13
  def test_connect_tcp
@@ -1,7 +1,6 @@
1
- require 'minitest/autorun'
2
- require 'dnssd'
1
+ require 'helper'
3
2
 
4
- class TestDNSSDService < MiniTest::Unit::TestCase
3
+ class TestDNSSDService < DNSSD::Test
5
4
 
6
5
  def test_class_get_property
7
6
  skip 'DNSSD::Service::get_property not defined' unless
@@ -12,11 +11,10 @@ class TestDNSSDService < MiniTest::Unit::TestCase
12
11
  end
13
12
 
14
13
  def test_class_getaddrinfo
15
- service = DNSSD::Service.new
16
-
17
14
  addresses = []
15
+ service = DNSSD::Service.getaddrinfo 'localhost'
18
16
 
19
- service.getaddrinfo 'localhost' do |addrinfo|
17
+ service.each do |addrinfo|
20
18
  addresses << addrinfo.address
21
19
  break unless addrinfo.flags.more_coming?
22
20
  end
@@ -24,5 +22,175 @@ class TestDNSSDService < MiniTest::Unit::TestCase
24
22
  assert addresses.index('127.0.0.1')
25
23
  end
26
24
 
27
- end
25
+ def test_enumerate
26
+ service = DNSSD::Service.enumerate_domains
27
+
28
+ begin
29
+ Timeout.timeout(2) do
30
+ service.each do |reply|
31
+ # I *think* there will be a local. on every machine??
32
+ break if reply.domain == 'local.'
33
+ end
34
+ assert true
35
+ end
36
+ rescue Timeout::Error
37
+ skip "couldn't find any domains to enumerate"
38
+ end
39
+ ensure
40
+ service.stop
41
+ end
42
+
43
+ def test_async_register_browse
44
+ registered = Latch.new
45
+ found = Latch.new
46
+ name = SecureRandom.hex
47
+
48
+ register = DNSSD::Service.register name, "_http._tcp", nil, 8080
49
+ register.async_each do |reply|
50
+ if reply.domain == "local."
51
+ registered.release
52
+ found.await
53
+ end
54
+ end
55
+
56
+ registered.await
57
+
58
+ browse = DNSSD::Service.browse '_http._tcp'
59
+ browse.async_each do |r|
60
+ if r.name == name && r.domain == "local."
61
+ found.release
62
+ assert_equal name, r.name
63
+ assert_equal "_http._tcp", r.type
64
+ end
65
+ end
66
+
67
+ register.stop
68
+ browse.stop
69
+ end
70
+
71
+ def test_register_browse
72
+ registered = Latch.new
73
+ found = Latch.new
74
+ name = SecureRandom.hex
75
+
76
+ broadcast = Thread.new do
77
+ service = DNSSD::Service.register name, "_http._tcp", nil, 8080
78
+ service.each do |reply|
79
+ if reply.domain == "local."
80
+ registered.release
81
+ found.await
82
+ service.stop
83
+ end
84
+ end
85
+ end
86
+
87
+ find = Thread.new do
88
+ registered.await
89
+ service = DNSSD::Service.browse '_http._tcp'
90
+ service.each do |r|
91
+ if r.name == name && r.domain == "local."
92
+ found.release
93
+ service.stop
94
+ assert_equal name, r.name
95
+ assert_equal "_http._tcp", r.type
96
+ end
97
+ end
98
+ end
28
99
 
100
+ found.await
101
+ broadcast.join
102
+ find.join
103
+ end
104
+
105
+ def test_resolve
106
+ done = Latch.new
107
+ name = SecureRandom.hex
108
+
109
+ broadcast = Thread.new do
110
+ txt = DNSSD::TextRecord.new 'foo' => 'bar'
111
+ service = DNSSD::Service.register name, "_http._tcp", nil, 8080, nil, txt
112
+ done.await
113
+ service.stop
114
+ end
115
+
116
+ service = DNSSD::Service.browse '_http._tcp'
117
+ reply = service.each.find do |r|
118
+ r.name == name && r.domain == "local."
119
+ end
120
+
121
+ resolver = DNSSD::Service.resolve reply.name, reply.type, reply.domain
122
+ text = resolver.each.find(&:text_record).text_record
123
+ assert_equal 'bar', text['foo']
124
+
125
+ done.release
126
+ broadcast.join
127
+ end
128
+
129
+ def test_query_record
130
+ done = Latch.new
131
+ name = SecureRandom.hex
132
+
133
+ broadcast = Thread.new do
134
+ txt = DNSSD::TextRecord.new 'foo' => 'bar'
135
+ service = DNSSD::Service.register name, "_http._tcp", nil, 8080, nil, txt
136
+ done.await
137
+ service.stop
138
+ end
139
+
140
+ service = DNSSD::Service.browse '_http._tcp'
141
+ reply = service.each.find do |r|
142
+ r.name == name && r.domain == "local."
143
+ end
144
+ service.stop
145
+
146
+ service = DNSSD::Service.query_record reply.fullname, DNSSD::Record::SRV
147
+ assert service.each.first
148
+ service.stop
149
+
150
+ done.release
151
+ broadcast.join
152
+ end
153
+
154
+ def test_add_record
155
+ skip "not supported" if RbConfig::CONFIG['target_os'] =~ /linux/
156
+ done = Latch.new
157
+ registered = Latch.new
158
+ broadcast = Thread.new do
159
+ txt = DNSSD::TextRecord.new 'bar' => 'baz'
160
+ service = DNSSD::Service.register name, "_http._tcp", nil, 8080
161
+ service.add_record(DNSSD::Record::TXT, txt.encode)
162
+ registered.release
163
+ done.await
164
+ end
165
+
166
+ registered.await
167
+ service = DNSSD::Service.browse '_http._tcp'
168
+ reply = service.each.find { |r|
169
+ r.name == name && r.domain == "local."
170
+ }
171
+
172
+ query = DNSSD::Service.query_record reply.fullname, DNSSD::Record::TXT
173
+ r = query.each.find do |response|
174
+ !response.flags.more_coming?
175
+ end
176
+ record = DNSSD::TextRecord.decode r.record
177
+ done.release
178
+ assert_equal 'baz', record['bar']
179
+ broadcast.join
180
+ end
181
+
182
+ def test_stop
183
+ service = DNSSD::Service.browse '_http._tcp'
184
+ assert_predicate service, :started?
185
+ service.stop
186
+ refute_predicate service, :started?
187
+
188
+ assert_raises(DNSSD::Error) { service.each { } }
189
+ end
190
+
191
+ def test_stop_twice
192
+ service = DNSSD::Service.browse '_http._tcp'
193
+ service.stop
194
+ assert_raises(DNSSD::Error) { service.stop }
195
+ end
196
+ end