ws_discovery 0.0.1
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.
- 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
|