ws_discovery 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- data/Gemfile +2 -0
- data/History.rdoc +3 -0
- data/README.rdoc +77 -0
- data/Rakefile +16 -0
- data/lib/ws_discovery/core_ext/socket_patch.rb +16 -0
- data/lib/ws_discovery/error.rb +4 -0
- data/lib/ws_discovery/multicast_connection.rb +77 -0
- data/lib/ws_discovery/network_constants.rb +13 -0
- data/lib/ws_discovery/response.rb +95 -0
- data/lib/ws_discovery/searcher.rb +91 -0
- data/lib/ws_discovery/version.rb +3 -0
- data/lib/ws_discovery.rb +61 -0
- data/spec/spec_helper.rb +26 -0
- data/spec/ws_discovery/coverage/assets/0.7.1/application.css +1110 -0
- data/spec/ws_discovery/coverage/assets/0.7.1/application.js +626 -0
- data/spec/ws_discovery/coverage/assets/0.7.1/fancybox/blank.gif +0 -0
- data/spec/ws_discovery/coverage/assets/0.7.1/fancybox/fancy_close.png +0 -0
- data/spec/ws_discovery/coverage/assets/0.7.1/fancybox/fancy_loading.png +0 -0
- data/spec/ws_discovery/coverage/assets/0.7.1/fancybox/fancy_nav_left.png +0 -0
- data/spec/ws_discovery/coverage/assets/0.7.1/fancybox/fancy_nav_right.png +0 -0
- data/spec/ws_discovery/coverage/assets/0.7.1/fancybox/fancy_shadow_e.png +0 -0
- data/spec/ws_discovery/coverage/assets/0.7.1/fancybox/fancy_shadow_n.png +0 -0
- data/spec/ws_discovery/coverage/assets/0.7.1/fancybox/fancy_shadow_ne.png +0 -0
- data/spec/ws_discovery/coverage/assets/0.7.1/fancybox/fancy_shadow_nw.png +0 -0
- data/spec/ws_discovery/coverage/assets/0.7.1/fancybox/fancy_shadow_s.png +0 -0
- data/spec/ws_discovery/coverage/assets/0.7.1/fancybox/fancy_shadow_se.png +0 -0
- data/spec/ws_discovery/coverage/assets/0.7.1/fancybox/fancy_shadow_sw.png +0 -0
- data/spec/ws_discovery/coverage/assets/0.7.1/fancybox/fancy_shadow_w.png +0 -0
- data/spec/ws_discovery/coverage/assets/0.7.1/fancybox/fancy_title_left.png +0 -0
- data/spec/ws_discovery/coverage/assets/0.7.1/fancybox/fancy_title_main.png +0 -0
- data/spec/ws_discovery/coverage/assets/0.7.1/fancybox/fancy_title_over.png +0 -0
- data/spec/ws_discovery/coverage/assets/0.7.1/fancybox/fancy_title_right.png +0 -0
- data/spec/ws_discovery/coverage/assets/0.7.1/fancybox/fancybox-x.png +0 -0
- data/spec/ws_discovery/coverage/assets/0.7.1/fancybox/fancybox-y.png +0 -0
- data/spec/ws_discovery/coverage/assets/0.7.1/fancybox/fancybox.png +0 -0
- data/spec/ws_discovery/coverage/assets/0.7.1/favicon_green.png +0 -0
- data/spec/ws_discovery/coverage/assets/0.7.1/favicon_red.png +0 -0
- data/spec/ws_discovery/coverage/assets/0.7.1/favicon_yellow.png +0 -0
- data/spec/ws_discovery/coverage/assets/0.7.1/loading.gif +0 -0
- data/spec/ws_discovery/coverage/assets/0.7.1/magnify.png +0 -0
- data/spec/ws_discovery/coverage/assets/0.7.1/smoothness/images/ui-bg_flat_0_aaaaaa_40x100.png +0 -0
- data/spec/ws_discovery/coverage/assets/0.7.1/smoothness/images/ui-bg_flat_75_ffffff_40x100.png +0 -0
- data/spec/ws_discovery/coverage/assets/0.7.1/smoothness/images/ui-bg_glass_55_fbf9ee_1x400.png +0 -0
- data/spec/ws_discovery/coverage/assets/0.7.1/smoothness/images/ui-bg_glass_65_ffffff_1x400.png +0 -0
- data/spec/ws_discovery/coverage/assets/0.7.1/smoothness/images/ui-bg_glass_75_dadada_1x400.png +0 -0
- data/spec/ws_discovery/coverage/assets/0.7.1/smoothness/images/ui-bg_glass_75_e6e6e6_1x400.png +0 -0
- data/spec/ws_discovery/coverage/assets/0.7.1/smoothness/images/ui-bg_glass_95_fef1ec_1x400.png +0 -0
- data/spec/ws_discovery/coverage/assets/0.7.1/smoothness/images/ui-bg_highlight-soft_75_cccccc_1x100.png +0 -0
- data/spec/ws_discovery/coverage/assets/0.7.1/smoothness/images/ui-icons_222222_256x240.png +0 -0
- data/spec/ws_discovery/coverage/assets/0.7.1/smoothness/images/ui-icons_2e83ff_256x240.png +0 -0
- data/spec/ws_discovery/coverage/assets/0.7.1/smoothness/images/ui-icons_454545_256x240.png +0 -0
- data/spec/ws_discovery/coverage/assets/0.7.1/smoothness/images/ui-icons_888888_256x240.png +0 -0
- data/spec/ws_discovery/coverage/assets/0.7.1/smoothness/images/ui-icons_cd0a0a_256x240.png +0 -0
- data/spec/ws_discovery/coverage/index.html +72 -0
- data/spec/ws_discovery/multicast_connection_spec.rb +108 -0
- data/spec/ws_discovery/response_spec.rb +118 -0
- data/spec/ws_discovery/searcher_spec.rb +85 -0
- data/spec/ws_discovery_spec.rb +43 -0
- data/ws_discovery.gemspec +32 -0
- metadata +296 -0
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
data/spec/ws_discovery/coverage/assets/0.7.1/smoothness/images/ui-bg_flat_75_ffffff_40x100.png
ADDED
Binary file
|
data/spec/ws_discovery/coverage/assets/0.7.1/smoothness/images/ui-bg_glass_55_fbf9ee_1x400.png
ADDED
Binary file
|
data/spec/ws_discovery/coverage/assets/0.7.1/smoothness/images/ui-bg_glass_65_ffffff_1x400.png
ADDED
Binary file
|
data/spec/ws_discovery/coverage/assets/0.7.1/smoothness/images/ui-bg_glass_75_dadada_1x400.png
ADDED
Binary file
|
data/spec/ws_discovery/coverage/assets/0.7.1/smoothness/images/ui-bg_glass_75_e6e6e6_1x400.png
ADDED
Binary file
|
data/spec/ws_discovery/coverage/assets/0.7.1/smoothness/images/ui-bg_glass_95_fef1ec_1x400.png
ADDED
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
@@ -0,0 +1,72 @@
|
|
1
|
+
<!DOCTYPE html>
|
2
|
+
<html xmlns='http://www.w3.org/1999/xhtml'>
|
3
|
+
<head>
|
4
|
+
<title>Code coverage for Ws discovery</title>
|
5
|
+
<meta http-equiv="content-type" content="text/html; charset=utf-8" />
|
6
|
+
<script src='./assets/0.7.1/application.js' type='text/javascript'></script>
|
7
|
+
<link href='./assets/0.7.1/application.css' media='screen, projection, print' rel='stylesheet' type='text/css'>
|
8
|
+
<link rel="shortcut icon" type="image/png" href="./assets/0.7.1/favicon_green.png" />
|
9
|
+
<link rel="icon" type="image/png" href="./assets/0.7.1/favicon.png" />
|
10
|
+
</head>
|
11
|
+
|
12
|
+
<body>
|
13
|
+
<div id="loading">
|
14
|
+
<img src="./assets/0.7.1/loading.gif" alt="loading"/>
|
15
|
+
</div>
|
16
|
+
<div id="wrapper" style="display:none;">
|
17
|
+
<div class="timestamp">Generated <abbr class="timeago" title="2012-11-12T13:50:26-08:00">2012-11-12T13:50:26-08:00</abbr></div>
|
18
|
+
<ul class="group_tabs"></ul>
|
19
|
+
|
20
|
+
<div id="content">
|
21
|
+
<div class="file_list_container" id="AllFiles">
|
22
|
+
<h2>
|
23
|
+
<span class="group_name">All Files</span>
|
24
|
+
(<span class="covered_percent"><span class="green">100.0%</span></span>
|
25
|
+
covered at
|
26
|
+
<span class="covered_strength">
|
27
|
+
<span class="red">
|
28
|
+
0.0
|
29
|
+
</span>
|
30
|
+
</span> hits/line)
|
31
|
+
</h2>
|
32
|
+
<a name="AllFiles"></a>
|
33
|
+
<div>
|
34
|
+
<b>0</b> files in total.
|
35
|
+
<b>0.0</b> relevant lines.
|
36
|
+
<span class="green"><b>0.0</b> lines covered</span> and
|
37
|
+
<span class="red"><b>0.0</b> lines missed </span>
|
38
|
+
</div>
|
39
|
+
<table class="file_list">
|
40
|
+
<thead>
|
41
|
+
<tr>
|
42
|
+
<th>File</th>
|
43
|
+
<th>% covered</th>
|
44
|
+
<th>Lines</th>
|
45
|
+
<th>Relevant Lines</th>
|
46
|
+
<th>Lines covered</th>
|
47
|
+
<th>Lines missed</th>
|
48
|
+
<th>Avg. Hits / Line</th>
|
49
|
+
</tr>
|
50
|
+
</thead>
|
51
|
+
<tbody>
|
52
|
+
|
53
|
+
</tbody>
|
54
|
+
</table>
|
55
|
+
</div>
|
56
|
+
|
57
|
+
|
58
|
+
|
59
|
+
</div>
|
60
|
+
|
61
|
+
<div id="footer">
|
62
|
+
Generated by <a href="http://github.com/colszowka/simplecov">simplecov</a> v0.7.1
|
63
|
+
and simplecov-html v0.7.1<br/>
|
64
|
+
using RSpec
|
65
|
+
</div>
|
66
|
+
|
67
|
+
<div class="source_files">
|
68
|
+
|
69
|
+
</div>
|
70
|
+
</div>
|
71
|
+
</body>
|
72
|
+
</html>
|
@@ -0,0 +1,108 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'ws_discovery/multicast_connection'
|
3
|
+
|
4
|
+
describe WSDiscovery::MulticastConnection do
|
5
|
+
around(:each) do |example|
|
6
|
+
EM.run do
|
7
|
+
example.run
|
8
|
+
EM.stop
|
9
|
+
end
|
10
|
+
end
|
11
|
+
|
12
|
+
subject { WSDiscovery::MulticastConnection.new(1) }
|
13
|
+
|
14
|
+
describe "#peer_info" do
|
15
|
+
before do
|
16
|
+
WSDiscovery::MulticastConnection.any_instance.stub(:setup_multicast_socket)
|
17
|
+
subject.stub_chain(:get_peername, :[], :unpack).and_return(%w(1234 1 2 3 4))
|
18
|
+
end
|
19
|
+
|
20
|
+
it "returns an Array with IP and port" do
|
21
|
+
subject.send(:peer_info).should == ['1.2.3.4', 1234]
|
22
|
+
end
|
23
|
+
|
24
|
+
it "returns IP as a String" do
|
25
|
+
subject.send(:peer_info).first.should be_a String
|
26
|
+
end
|
27
|
+
|
28
|
+
it "returns port as a Fixnum" do
|
29
|
+
subject.send(:peer_info).last.should be_a Fixnum
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
describe "#setup_multicast_socket" do
|
34
|
+
before do
|
35
|
+
WSDiscovery::MulticastConnection.any_instance.stub(:set_membership)
|
36
|
+
WSDiscovery::MulticastConnection.any_instance.stub(:switch_multicast_loop)
|
37
|
+
WSDiscovery::MulticastConnection.any_instance.stub(:set_multicast_ttl)
|
38
|
+
WSDiscovery::MulticastConnection.any_instance.stub(:set_ttl)
|
39
|
+
end
|
40
|
+
|
41
|
+
it "adds 0.0.0.0 and 239.255.255.250 to the membership group" do
|
42
|
+
subject.should_receive(:set_membership).with(
|
43
|
+
IPAddr.new('239.255.255.250').hton + IPAddr.new('0.0.0.0').hton
|
44
|
+
)
|
45
|
+
subject.send(:setup_multicast_socket)
|
46
|
+
end
|
47
|
+
|
48
|
+
it "sets multicast TTL to 1" do
|
49
|
+
subject.should_receive(:set_multicast_ttl).with(1)
|
50
|
+
subject.send(:setup_multicast_socket)
|
51
|
+
end
|
52
|
+
|
53
|
+
it "sets TTL to 1" do
|
54
|
+
subject.should_receive(:set_ttl).with(1)
|
55
|
+
subject.send(:setup_multicast_socket)
|
56
|
+
end
|
57
|
+
|
58
|
+
context "ENV['RUBY_TESTING_ENV'] != testing" do
|
59
|
+
after { ENV['RUBY_TESTING_ENV'] = "testing" }
|
60
|
+
|
61
|
+
it "turns multicast loop off" do
|
62
|
+
ENV['RUBY_TESTING_ENV'] = "development"
|
63
|
+
subject.should_receive(:switch_multicast_loop).with(:off)
|
64
|
+
subject.send(:setup_multicast_socket)
|
65
|
+
end
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
describe "#switch_multicast_loop" do
|
70
|
+
before do
|
71
|
+
WSDiscovery::MulticastConnection.any_instance.stub(:setup_multicast_socket)
|
72
|
+
end
|
73
|
+
|
74
|
+
it "passes '\\001' to the socket option call when param == :on" do
|
75
|
+
subject.should_receive(:set_sock_opt).with(
|
76
|
+
0, Socket::IP_MULTICAST_LOOP, "\001"
|
77
|
+
)
|
78
|
+
subject.send(:switch_multicast_loop, :on)
|
79
|
+
end
|
80
|
+
|
81
|
+
it "passes '\\001' to the socket option call when param == '\\001'" do
|
82
|
+
subject.should_receive(:set_sock_opt).with(
|
83
|
+
0, Socket::IP_MULTICAST_LOOP, "\001"
|
84
|
+
)
|
85
|
+
subject.send(:switch_multicast_loop,"\001")
|
86
|
+
end
|
87
|
+
|
88
|
+
it "passes '\\000' to the socket option call when param == :off" do
|
89
|
+
subject.should_receive(:set_sock_opt).with(
|
90
|
+
0, Socket::IP_MULTICAST_LOOP, "\000"
|
91
|
+
)
|
92
|
+
subject.send(:switch_multicast_loop,:off)
|
93
|
+
end
|
94
|
+
|
95
|
+
it "passes '\\000' to the socket option call when param == '\\000'" do
|
96
|
+
subject.should_receive(:set_sock_opt).with(
|
97
|
+
0, Socket::IP_MULTICAST_LOOP, "\000"
|
98
|
+
)
|
99
|
+
subject.send(:switch_multicast_loop,"\000")
|
100
|
+
end
|
101
|
+
|
102
|
+
it "raises when not :on, :off, '\\000', or '\\001'" do
|
103
|
+
expect { subject.send(:switch_multicast_loop, 12312312) }.
|
104
|
+
to raise_error(WSDiscovery::Error)
|
105
|
+
end
|
106
|
+
end
|
107
|
+
end
|
108
|
+
|
@@ -0,0 +1,118 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'ws_discovery/response'
|
3
|
+
|
4
|
+
describe WSDiscovery::Response do
|
5
|
+
let(:probe_response) do
|
6
|
+
<<-PROBE
|
7
|
+
<s:Envelope xmlns:s="http://www.w3.org/2003/05/soap-envelope"
|
8
|
+
xmlns:a="http://schemas.xmlsoap.org/ws/2004/08/addressing"
|
9
|
+
xmlns:d="http://schemas.xmlsoap.org/ws/2005/04/discovery">
|
10
|
+
<s:Header>
|
11
|
+
<a:To>http://schemas.xmlsoap.org/ws/2004/08/addressing/role/anonymous</a:To>
|
12
|
+
<a:Action>http://schemas.xmlsoap.org/ws/2005/04/discovery/ProbeMatches</a:Action>
|
13
|
+
<a:MessageID>urn:uuid:18523f7e-7a54-d92d-a18d-e7165bec8e7e</a:MessageID>
|
14
|
+
<a:RelatesTo>uuid:7dbdede0-0f2b-0130-5861-002564b29b24</a:RelatesTo>
|
15
|
+
<d:AppSequence MessageNumber="42" InstanceId="2"/>
|
16
|
+
</s:Header>
|
17
|
+
<s:Body>
|
18
|
+
<d:ProbeMatches>
|
19
|
+
<d:ProbeMatch>
|
20
|
+
<a:EndpointReference>
|
21
|
+
<a:Address>urn:uuid:0b679890-fc54-14ba-d428-f73b3e7c2400</a:Address>
|
22
|
+
</a:EndpointReference>
|
23
|
+
<d:Types xmlns:dn="http://www.onvif.org/ver10/network/wsdl">dn:NetworkVideoTransmitter</d:Types>
|
24
|
+
<d:Scopes>onvif://www.onvif.org/Profile/Streaming onvif://www.onvif.org/hardware/NET5404T onvif://www.onvif.org/type/ptz onvif://www.onvif.org/type/video_encoder onvif://www.onvif.org/location/country/usa onvif://www.onvif.org/name/NET5404T-ABEPZH7</d:Scopes>
|
25
|
+
<d:XAddrs>http://10.221.222.74/onvif/device_service</d:XAddrs>
|
26
|
+
<d:MetadataVersion>1</d:MetadataVersion>
|
27
|
+
</d:ProbeMatch>
|
28
|
+
</d:ProbeMatches>
|
29
|
+
</s:Body>
|
30
|
+
</s:Envelope>
|
31
|
+
PROBE
|
32
|
+
end
|
33
|
+
|
34
|
+
let(:probe_body_hash) do
|
35
|
+
{ probe_matches: {
|
36
|
+
probe_match: {
|
37
|
+
endpoint_reference: {
|
38
|
+
address: "urn:uuid:0b679890-fc54-14ba-d428-f73b3e7c2400" },
|
39
|
+
types: "dn:NetworkVideoTransmitter",
|
40
|
+
scopes: "onvif://www.onvif.org/Profile/Streaming onvif://www.onvif.org/hardware/NET5404T onvif://www.onvif.org/type/ptz onvif://www.onvif.org/type/video_encoder onvif://www.onvif.org/location/country/usa onvif://www.onvif.org/name/NET5404T-ABEPZH7",
|
41
|
+
x_addrs: "http://10.221.222.74/onvif/device_service",
|
42
|
+
metadata_version: "1" } } }
|
43
|
+
end
|
44
|
+
|
45
|
+
let(:probe_header_hash) do
|
46
|
+
{ to: "http://schemas.xmlsoap.org/ws/2004/08/addressing/role/anonymous",
|
47
|
+
action: "http://schemas.xmlsoap.org/ws/2005/04/discovery/ProbeMatches",
|
48
|
+
message_id: "urn:uuid:18523f7e-7a54-d92d-a18d-e7165bec8e7e",
|
49
|
+
relates_to: "uuid:7dbdede0-0f2b-0130-5861-002564b29b24",
|
50
|
+
app_sequence: {
|
51
|
+
:@message_number => "42",
|
52
|
+
:@instance_id => "2" } }
|
53
|
+
end
|
54
|
+
|
55
|
+
let(:probe_full_hash) do
|
56
|
+
{ envelope: { header: probe_header_hash, body: probe_body_hash,
|
57
|
+
:"@xmlns:s" => "http://www.w3.org/2003/05/soap-envelope",
|
58
|
+
:"@xmlns:a" => "http://schemas.xmlsoap.org/ws/2004/08/addressing",
|
59
|
+
:"@xmlns:d" => "http://schemas.xmlsoap.org/ws/2005/04/discovery" } }
|
60
|
+
end
|
61
|
+
|
62
|
+
subject { WSDiscovery::Response.new(probe_response) }
|
63
|
+
|
64
|
+
describe "#[]" do
|
65
|
+
it "should return the SOAP response body as a Hash" do
|
66
|
+
subject[:probe_matches].should == probe_body_hash[:probe_matches]
|
67
|
+
end
|
68
|
+
|
69
|
+
it "should throw an exception when the response body isn't parsable" do
|
70
|
+
expect { WSDiscovery::Response.new('').body }.to raise_error WSDiscovery::Error
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
74
|
+
describe "#header" do
|
75
|
+
it "should return the SOAP response header as a Hash" do
|
76
|
+
subject.header[:app_sequence].should == probe_header_hash[:app_sequence]
|
77
|
+
end
|
78
|
+
|
79
|
+
it "should throw an exception when the response header isn't parsable" do
|
80
|
+
expect { WSDiscovery::Response.new('').header }.to raise_error WSDiscovery::Error
|
81
|
+
end
|
82
|
+
end
|
83
|
+
|
84
|
+
%w(body to_hash).each do |method|
|
85
|
+
describe "##{method}" do
|
86
|
+
it "should return the SOAP response body as a Hash" do
|
87
|
+
subject.send(method)[:probe_matches].should == probe_body_hash[:probe_matches]
|
88
|
+
end
|
89
|
+
end
|
90
|
+
end
|
91
|
+
|
92
|
+
describe "#hash" do
|
93
|
+
it "should return the complete SOAP response XML as a Hash" do
|
94
|
+
subject.hash.should == probe_full_hash
|
95
|
+
end
|
96
|
+
end
|
97
|
+
|
98
|
+
describe "#to_xml" do
|
99
|
+
it "should return the raw SOAP response body" do
|
100
|
+
subject.to_xml.should == probe_response
|
101
|
+
end
|
102
|
+
end
|
103
|
+
|
104
|
+
describe "#doc" do
|
105
|
+
it "returns a Nokogiri::XML::Document for the SOAP response XML" do
|
106
|
+
subject.doc.should be_a(Nokogiri::XML::Document)
|
107
|
+
end
|
108
|
+
end
|
109
|
+
|
110
|
+
describe "#xpath" do
|
111
|
+
it "permits XPath access to elements in the request" do
|
112
|
+
subject.xpath("//a:Address").first.inner_text.
|
113
|
+
should == "urn:uuid:0b679890-fc54-14ba-d428-f73b3e7c2400"
|
114
|
+
subject.xpath("//d:ProbeMatch/d:XAddrs").first.inner_text.
|
115
|
+
should == "http://10.221.222.74/onvif/device_service"
|
116
|
+
end
|
117
|
+
end
|
118
|
+
end
|
@@ -0,0 +1,85 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'ws_discovery/searcher'
|
3
|
+
|
4
|
+
describe WSDiscovery::Searcher do
|
5
|
+
let(:default_probe) do
|
6
|
+
"<s:Envelope xmlns:a=\"http://schemas.xmlsoap.org/ws/2004/08/addressing\" " +
|
7
|
+
"xmlns:d=\"http://schemas.xmlsoap.org/ws/2005/04/discovery\" xmlns:s=\"h" +
|
8
|
+
"ttp://www.w3.org/2003/05/soap-envelope\"><s:Header><a:Action>http://sch" +
|
9
|
+
"emas.xmlsoap.org/ws/2005/04/discovery/Probe</a:Action><a:MessageID>uuid" +
|
10
|
+
":a-uuid</a:MessageID><a:To>urn:schemas-xmlsoap-org:ws:2005:04:discovery" +
|
11
|
+
"</a:To></s:Header><s:Body><d:Types/><d:Scopes/></s:Body></s:Envelope>"
|
12
|
+
end
|
13
|
+
|
14
|
+
around(:each) do |example|
|
15
|
+
EM.run do
|
16
|
+
example.run
|
17
|
+
EM.stop
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
before do
|
22
|
+
WSDiscovery::Searcher.log = false
|
23
|
+
WSDiscovery::MulticastConnection.any_instance.stub(:setup_multicast_socket)
|
24
|
+
UUID.stub(:generate).and_return('a-uuid')
|
25
|
+
end
|
26
|
+
|
27
|
+
subject do
|
28
|
+
WSDiscovery::Searcher.new(1)
|
29
|
+
end
|
30
|
+
|
31
|
+
describe "#initialize" do
|
32
|
+
it "does a #probe" do
|
33
|
+
WSDiscovery::Searcher.any_instance.should_receive(:probe)
|
34
|
+
|
35
|
+
subject
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
describe "#receive_data" do
|
40
|
+
let(:parsed_response) do
|
41
|
+
double 'parsed response'
|
42
|
+
end
|
43
|
+
|
44
|
+
it "takes a response and adds it to the list of responses" do
|
45
|
+
response = double 'response'
|
46
|
+
subject.stub(:peer_info).and_return(['0.0.0.0', 4567])
|
47
|
+
|
48
|
+
subject.should_receive(:parse).with(response).exactly(1).times.
|
49
|
+
and_return(parsed_response)
|
50
|
+
subject.instance_variable_get(:@discovery_responses).should_receive(:<<).
|
51
|
+
with(parsed_response)
|
52
|
+
|
53
|
+
subject.receive_data(response)
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
describe "#parse" do
|
58
|
+
before do
|
59
|
+
WSDiscovery::MulticastConnection.any_instance.stub(:setup_multicast_socket)
|
60
|
+
end
|
61
|
+
|
62
|
+
it "turns probe matches into WSDiscovery::Responses" do
|
63
|
+
result = subject.parse "<Envelope />"
|
64
|
+
result.should be_a WSDiscovery::Response
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
describe "#post_init" do
|
69
|
+
before { WSDiscovery::Searcher.any_instance.stub(:m_search).and_return("hi") }
|
70
|
+
|
71
|
+
it "sends a probe as a datagram over 239.255.255.250:3702" do
|
72
|
+
subject.should_receive(:send_datagram).
|
73
|
+
with(default_probe, '239.255.255.250', 3702).
|
74
|
+
and_return 0
|
75
|
+
subject.post_init
|
76
|
+
end
|
77
|
+
end
|
78
|
+
|
79
|
+
describe "#probe" do
|
80
|
+
it "builds the MSEARCH string using the given parameters" do
|
81
|
+
subject.probe.should == default_probe
|
82
|
+
end
|
83
|
+
end
|
84
|
+
end
|
85
|
+
|
@@ -0,0 +1,43 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'ws_discovery'
|
3
|
+
|
4
|
+
describe WSDiscovery do
|
5
|
+
subject { WSDiscovery }
|
6
|
+
|
7
|
+
describe '.search' do
|
8
|
+
let(:multicast_searcher) do
|
9
|
+
searcher = double "WSDiscovery::Searcher"
|
10
|
+
searcher.stub_chain(:discovery_responses, :subscribe).and_yield(%w[one two])
|
11
|
+
|
12
|
+
searcher
|
13
|
+
end
|
14
|
+
|
15
|
+
before do
|
16
|
+
EM.stub(:run).and_yield
|
17
|
+
EM.stub(:add_timer)
|
18
|
+
EM.stub(:open_datagram_socket).and_return multicast_searcher
|
19
|
+
end
|
20
|
+
|
21
|
+
context "reactor is already running" do
|
22
|
+
it "returns a WSDiscovery::Searcher" do
|
23
|
+
EM.stub(:reactor_running?).and_return true
|
24
|
+
subject.search.should == multicast_searcher
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
context "reactor is not already running" do
|
29
|
+
it "returns an Array of responses" do
|
30
|
+
EM.stub(:add_shutdown_hook).and_yield
|
31
|
+
subject.search.should == %w[one two]
|
32
|
+
end
|
33
|
+
|
34
|
+
it "opens a UDP socket on '0.0.0.0', port 0" do
|
35
|
+
EM.stub(:add_shutdown_hook)
|
36
|
+
EM.should_receive(:open_datagram_socket).with('0.0.0.0', 0,
|
37
|
+
WSDiscovery::Searcher, {})
|
38
|
+
subject.search
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
@@ -0,0 +1,32 @@
|
|
1
|
+
$:.push File.expand_path("../lib", __FILE__)
|
2
|
+
require 'ws_discovery/version'
|
3
|
+
|
4
|
+
Gem::Specification.new do |s|
|
5
|
+
s.name = "ws_discovery"
|
6
|
+
s.version = WSDiscovery::VERSION
|
7
|
+
s.homepage = "https://github.com/pelco-automation/ws-discovery"
|
8
|
+
s.author = "tindron"
|
9
|
+
s.email = "rstoller@gmail.com"
|
10
|
+
s.description = "Perform a multicast search for devices using WS-Discovery"
|
11
|
+
s.summary = "Search for devices using WS-Discovery"
|
12
|
+
|
13
|
+
s.required_rubygems_version = ">=1.8.0"
|
14
|
+
s.required_ruby_version = Gem::Requirement.new(">= 1.9.3")
|
15
|
+
s.files = Dir.glob("{lib,spec}/**/*") + Dir.glob("*.rdoc") +
|
16
|
+
%w(Gemfile ws_discovery.gemspec Rakefile)
|
17
|
+
s.require_paths = ["lib"]
|
18
|
+
|
19
|
+
s.add_dependency("builder")
|
20
|
+
s.add_dependency("eventmachine")
|
21
|
+
s.add_dependency("log_switch", ">=0.1.4")
|
22
|
+
s.add_dependency("nokogiri")
|
23
|
+
s.add_dependency("nori")
|
24
|
+
s.add_dependency("uuid")
|
25
|
+
|
26
|
+
s.add_development_dependency("bundler", ">= 1.0.21")
|
27
|
+
s.add_development_dependency("rake", ">= 0")
|
28
|
+
s.add_development_dependency("rspec", "~> 2.6")
|
29
|
+
s.add_development_dependency("simplecov", ">= 0")
|
30
|
+
s.add_development_dependency("simplecov-rcov", ">= 0")
|
31
|
+
s.add_development_dependency("yard", ">= 0.7.2")
|
32
|
+
end
|