dnssd 2.0.1 → 3.0.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -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