net-ping 2.1.0-universal-linux
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.
- checksums.yaml +7 -0
- data/CHANGES +28 -0
- data/CHANGES.out_of_date +354 -0
- data/CLAUDE.md +89 -0
- data/Gemfile +8 -0
- data/Gemfile.lock +53 -0
- data/MANIFEST +25 -0
- data/README.md +65 -0
- data/Rakefile +183 -0
- data/doc/ping.txt +246 -0
- data/docs/superpowers/plans/2026-07-25-platform-specific-gems.md +317 -0
- data/docs/superpowers/specs/2026-07-25-platform-specific-gems-design.md +71 -0
- data/examples/example_pingexternal.rb +16 -0
- data/examples/example_pinghttp.rb +22 -0
- data/examples/example_pingtcp.rb +16 -0
- data/examples/example_pingudp.rb +12 -0
- data/lib/net/ping/external.rb +185 -0
- data/lib/net/ping/http.rb +189 -0
- data/lib/net/ping/icmp.rb +188 -0
- data/lib/net/ping/ping.rb +99 -0
- data/lib/net/ping/tcp.rb +110 -0
- data/lib/net/ping/udp.rb +117 -0
- data/lib/net/ping/version.rb +6 -0
- data/lib/net/ping/wmi.rb +118 -0
- data/lib/net/ping.rb +24 -0
- data/net-ping-universal-linux.gemspec +4 -0
- data/net-ping-universal-mingw-ucrt.gemspec +7 -0
- data/net-ping.gemspec +36 -0
- data/test/test_net_ping.rb +44 -0
- data/test/test_net_ping_external.rb +232 -0
- data/test/test_net_ping_gem_packaging.rb +333 -0
- data/test/test_net_ping_http.rb +264 -0
- data/test/test_net_ping_icmp.rb +199 -0
- data/test/test_net_ping_tcp.rb +106 -0
- data/test/test_net_ping_udp.rb +117 -0
- data/test/test_net_ping_wmi.rb +81 -0
- metadata +159 -0
|
@@ -0,0 +1,333 @@
|
|
|
1
|
+
require 'open3'
|
|
2
|
+
require 'rake'
|
|
3
|
+
require 'rubygems/package'
|
|
4
|
+
require 'test/unit'
|
|
5
|
+
|
|
6
|
+
class TestNetPingGemPackaging < Test::Unit::TestCase
|
|
7
|
+
GemfileRecorder = Struct.new(:dependencies) do
|
|
8
|
+
def initialize
|
|
9
|
+
super({})
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
def source(*); end
|
|
13
|
+
def gemspec(*); end
|
|
14
|
+
|
|
15
|
+
def gem(name, *requirements)
|
|
16
|
+
dependencies[name] = requirements
|
|
17
|
+
end
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
EXPECTATIONS = {
|
|
21
|
+
'net-ping.gemspec' => ['ruby', {}],
|
|
22
|
+
'net-ping-universal-linux.gemspec' => ['universal-linux', {'cap2' => '>= 0.2.2'}],
|
|
23
|
+
'net-ping-universal-mingw-ucrt.gemspec' => [
|
|
24
|
+
'universal-mingw-ucrt',
|
|
25
|
+
{'win32-security' => '>= 0.2.0', 'win32ole' => '>= 1.8.8'}
|
|
26
|
+
]
|
|
27
|
+
}.freeze
|
|
28
|
+
ROOT = File.expand_path('..', __dir__)
|
|
29
|
+
|
|
30
|
+
def test_platforms_and_runtime_dependencies
|
|
31
|
+
gem_files = nil
|
|
32
|
+
specifications = load_specifications
|
|
33
|
+
|
|
34
|
+
Dir.chdir(ROOT) do
|
|
35
|
+
gem_files = specifications.map { |_, spec| Gem::Package.build(spec) }
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
specifications.each do |path, spec|
|
|
39
|
+
expected_platform, expected_dependencies = EXPECTATIONS.fetch(path)
|
|
40
|
+
packaged_spec = Gem::Package.new(File.join(ROOT, spec.file_name)).spec
|
|
41
|
+
dependencies = packaged_spec.runtime_dependencies.each_with_object({}) do |dependency, memo|
|
|
42
|
+
memo[dependency.name] = dependency.requirement.to_s
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
assert_equal(expected_dependencies, dependencies, path)
|
|
46
|
+
|
|
47
|
+
if platform_round_trips_for_test?(expected_platform)
|
|
48
|
+
assert_equal(expected_platform, packaged_spec.platform.to_s, path)
|
|
49
|
+
else
|
|
50
|
+
omit("this RubyGems (#{Gem::VERSION}) cannot round-trip the #{expected_platform.inspect} platform string")
|
|
51
|
+
end
|
|
52
|
+
end
|
|
53
|
+
ensure
|
|
54
|
+
delete_files(gem_files)
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
def test_rake_create_builds_all_expected_artifacts_and_validates_them
|
|
58
|
+
stdout, stderr, status = run_rake('clean', 'gem:create', 'gem:check')
|
|
59
|
+
|
|
60
|
+
assert(status.success?, [stdout, stderr].join)
|
|
61
|
+
assert_equal(expected_gem_files, built_gem_files)
|
|
62
|
+
ensure
|
|
63
|
+
delete_files(built_gem_files)
|
|
64
|
+
end
|
|
65
|
+
|
|
66
|
+
def test_gem_create_excludes_generated_artifacts_from_spec_files_and_keeps_bundle_exec_usable
|
|
67
|
+
stdout, stderr, status = run_rake('clean', 'gem:create')
|
|
68
|
+
|
|
69
|
+
assert(status.success?, [stdout, stderr].join)
|
|
70
|
+
load_specifications.each do |path, spec|
|
|
71
|
+
assert_equal([], spec.files.grep(/\.gem$/).sort, path)
|
|
72
|
+
end
|
|
73
|
+
|
|
74
|
+
stdout, stderr, status = run_bundle_exec('ruby', '-e', 'puts :bundle_exec_after_gem_create')
|
|
75
|
+
assert(status.success?, [stdout, stderr].join)
|
|
76
|
+
assert_equal("bundle_exec_after_gem_create\n", stdout)
|
|
77
|
+
ensure
|
|
78
|
+
delete_files(built_gem_files)
|
|
79
|
+
end
|
|
80
|
+
|
|
81
|
+
def test_gem_check_uses_fixed_expectations_instead_of_loaded_specifications
|
|
82
|
+
stdout, stderr, status = run_rake('clean', 'gem:create')
|
|
83
|
+
|
|
84
|
+
assert(status.success?, [stdout, stderr].join)
|
|
85
|
+
|
|
86
|
+
specifications = load_specifications.map do |path, spec|
|
|
87
|
+
if path == 'net-ping-universal-linux.gemspec'
|
|
88
|
+
[path, specification_with_reported_platform(spec, Gem::Platform::RUBY)]
|
|
89
|
+
else
|
|
90
|
+
[path, spec]
|
|
91
|
+
end
|
|
92
|
+
end
|
|
93
|
+
|
|
94
|
+
with_rakefile do |application|
|
|
95
|
+
with_stubbed_load_gem_specifications(specifications.map(&:last)) do
|
|
96
|
+
assert_nothing_raised { application['gem:check'].invoke }
|
|
97
|
+
end
|
|
98
|
+
end
|
|
99
|
+
ensure
|
|
100
|
+
delete_files(built_gem_files)
|
|
101
|
+
end
|
|
102
|
+
|
|
103
|
+
def test_gem_install_selects_local_compatible_specification
|
|
104
|
+
with_rakefile do
|
|
105
|
+
assert_equal(expected_install_platform, select_install_specification.platform.to_s)
|
|
106
|
+
end
|
|
107
|
+
end
|
|
108
|
+
|
|
109
|
+
def test_gemfile_adds_win32_security_only_for_windows_development
|
|
110
|
+
assert_nil(gemfile_dependencies_for(win_platform: false)['win32-security'])
|
|
111
|
+
assert_equal(
|
|
112
|
+
['>= 0.2.0'],
|
|
113
|
+
gemfile_dependencies_for(win_platform: true)['win32-security']
|
|
114
|
+
)
|
|
115
|
+
end
|
|
116
|
+
|
|
117
|
+
def test_with_unbundled_env_prefers_with_unbundled_env_when_available
|
|
118
|
+
calls = []
|
|
119
|
+
|
|
120
|
+
with_rakefile do
|
|
121
|
+
with_stubbed_bundler_methods(
|
|
122
|
+
:with_unbundled_env => proc do |&block|
|
|
123
|
+
calls << :with_unbundled_env
|
|
124
|
+
block.call
|
|
125
|
+
end,
|
|
126
|
+
:with_clean_env => proc do |&block|
|
|
127
|
+
calls << :with_clean_env
|
|
128
|
+
block.call
|
|
129
|
+
end
|
|
130
|
+
) do
|
|
131
|
+
assert_equal(:ran, with_unbundled_env { calls << :block; :ran })
|
|
132
|
+
end
|
|
133
|
+
end
|
|
134
|
+
|
|
135
|
+
assert_equal([:with_unbundled_env, :block], calls)
|
|
136
|
+
end
|
|
137
|
+
|
|
138
|
+
def test_with_unbundled_env_falls_back_to_with_clean_env
|
|
139
|
+
calls = []
|
|
140
|
+
|
|
141
|
+
with_rakefile do
|
|
142
|
+
with_stubbed_bundler_methods(
|
|
143
|
+
:with_clean_env => proc do |&block|
|
|
144
|
+
calls << :with_clean_env
|
|
145
|
+
block.call
|
|
146
|
+
end
|
|
147
|
+
) do
|
|
148
|
+
assert_equal(:ran, with_unbundled_env { calls << :block; :ran })
|
|
149
|
+
end
|
|
150
|
+
end
|
|
151
|
+
|
|
152
|
+
assert_equal([:with_clean_env, :block], calls)
|
|
153
|
+
end
|
|
154
|
+
|
|
155
|
+
def test_platform_installable_prefers_installable_when_available
|
|
156
|
+
spec = Struct.new(:platform).new(:preferred_platform)
|
|
157
|
+
calls = []
|
|
158
|
+
|
|
159
|
+
with_rakefile do
|
|
160
|
+
with_stubbed_platform_methods(
|
|
161
|
+
:installable? => proc do |candidate|
|
|
162
|
+
calls << [:installable?, candidate.platform]
|
|
163
|
+
true
|
|
164
|
+
end,
|
|
165
|
+
:match => proc do |platform|
|
|
166
|
+
calls << [:match, platform]
|
|
167
|
+
false
|
|
168
|
+
end
|
|
169
|
+
) do
|
|
170
|
+
assert_equal(true, platform_installable?(spec))
|
|
171
|
+
end
|
|
172
|
+
end
|
|
173
|
+
|
|
174
|
+
assert_equal([[:installable?, :preferred_platform]], calls)
|
|
175
|
+
end
|
|
176
|
+
|
|
177
|
+
def test_platform_installable_falls_back_to_match
|
|
178
|
+
spec = Struct.new(:platform).new(:fallback_platform)
|
|
179
|
+
calls = []
|
|
180
|
+
|
|
181
|
+
with_rakefile do
|
|
182
|
+
with_stubbed_platform_methods(
|
|
183
|
+
:match => proc do |platform|
|
|
184
|
+
calls << [:match, platform]
|
|
185
|
+
true
|
|
186
|
+
end
|
|
187
|
+
) do
|
|
188
|
+
assert_equal(true, platform_installable?(spec))
|
|
189
|
+
end
|
|
190
|
+
end
|
|
191
|
+
|
|
192
|
+
assert_equal([[:match, :fallback_platform]], calls)
|
|
193
|
+
end
|
|
194
|
+
|
|
195
|
+
private
|
|
196
|
+
|
|
197
|
+
def load_specifications
|
|
198
|
+
Dir.chdir(ROOT) do
|
|
199
|
+
EXPECTATIONS.keys.map do |path|
|
|
200
|
+
assert(File.exist?(path), "#{path} does not exist")
|
|
201
|
+
|
|
202
|
+
loaded_spec = Gem::Specification.load(path)
|
|
203
|
+
spec = loaded_spec ? loaded_spec.dup : nil
|
|
204
|
+
assert_not_nil(spec, "expected #{path} to load")
|
|
205
|
+
|
|
206
|
+
[path, spec]
|
|
207
|
+
end
|
|
208
|
+
end
|
|
209
|
+
end
|
|
210
|
+
|
|
211
|
+
def expected_gem_files
|
|
212
|
+
load_specifications.map { |_, spec| spec.file_name }.sort
|
|
213
|
+
end
|
|
214
|
+
|
|
215
|
+
def built_gem_files
|
|
216
|
+
Dir.chdir(ROOT) { Dir['net-ping-*.gem'].sort }
|
|
217
|
+
end
|
|
218
|
+
|
|
219
|
+
def expected_install_platform
|
|
220
|
+
specifications = load_specifications.map(&:last)
|
|
221
|
+
specific = specifications.find do |spec|
|
|
222
|
+
spec.platform != Gem::Platform::RUBY && platform_installable_for_test?(spec)
|
|
223
|
+
end
|
|
224
|
+
(specific || specifications.find { |spec| spec.platform == Gem::Platform::RUBY }).platform.to_s
|
|
225
|
+
end
|
|
226
|
+
|
|
227
|
+
def run_rake(*tasks, env: {})
|
|
228
|
+
Open3.capture3(env, Gem.ruby, '-S', 'bundle', 'exec', 'rake', *tasks, chdir: ROOT)
|
|
229
|
+
end
|
|
230
|
+
|
|
231
|
+
def run_bundle_exec(*command, env: {})
|
|
232
|
+
Open3.capture3(env, Gem.ruby, '-S', 'bundle', 'exec', *command, chdir: ROOT)
|
|
233
|
+
end
|
|
234
|
+
|
|
235
|
+
def with_rakefile
|
|
236
|
+
original = Rake.application
|
|
237
|
+
application = Rake::Application.new
|
|
238
|
+
Rake.application = application
|
|
239
|
+
|
|
240
|
+
Dir.chdir(ROOT) do
|
|
241
|
+
load File.join(ROOT, 'Rakefile')
|
|
242
|
+
yield(application)
|
|
243
|
+
end
|
|
244
|
+
ensure
|
|
245
|
+
Rake.application = original
|
|
246
|
+
end
|
|
247
|
+
|
|
248
|
+
def gemfile_dependencies_for(win_platform:)
|
|
249
|
+
recorder = GemfileRecorder.new
|
|
250
|
+
singleton_class = class << Gem; self; end
|
|
251
|
+
original = singleton_class.instance_method(:win_platform?)
|
|
252
|
+
singleton_class.send(:define_method, :win_platform?) { win_platform }
|
|
253
|
+
recorder.instance_eval(File.read(File.join(ROOT, 'Gemfile')), File.join(ROOT, 'Gemfile'))
|
|
254
|
+
|
|
255
|
+
recorder.dependencies
|
|
256
|
+
ensure
|
|
257
|
+
singleton_class.send(:define_method, :win_platform?, original) if singleton_class && original
|
|
258
|
+
end
|
|
259
|
+
|
|
260
|
+
def delete_files(paths)
|
|
261
|
+
Array(paths).each do |path|
|
|
262
|
+
file = File.join(ROOT, path)
|
|
263
|
+
File.delete(file) if File.exist?(file)
|
|
264
|
+
end
|
|
265
|
+
end
|
|
266
|
+
|
|
267
|
+
def specification_with_reported_platform(spec, platform)
|
|
268
|
+
file_name = spec.file_name
|
|
269
|
+
mutated = spec.dup
|
|
270
|
+
mutated.platform = platform
|
|
271
|
+
mutated.define_singleton_method(:file_name) { file_name }
|
|
272
|
+
mutated
|
|
273
|
+
end
|
|
274
|
+
|
|
275
|
+
def with_stubbed_load_gem_specifications(specifications)
|
|
276
|
+
original = Object.instance_method(:load_gem_specifications)
|
|
277
|
+
Object.send(:remove_method, :load_gem_specifications)
|
|
278
|
+
Object.send(:define_method, :load_gem_specifications) { specifications }
|
|
279
|
+
Object.send(:private, :load_gem_specifications)
|
|
280
|
+
yield
|
|
281
|
+
ensure
|
|
282
|
+
Object.send(:remove_method, :load_gem_specifications)
|
|
283
|
+
Object.send(:define_method, :load_gem_specifications, original)
|
|
284
|
+
Object.send(:private, :load_gem_specifications)
|
|
285
|
+
end
|
|
286
|
+
|
|
287
|
+
def with_stubbed_bundler_methods(methods)
|
|
288
|
+
bundler = Module.new
|
|
289
|
+
methods.each do |name, implementation|
|
|
290
|
+
bundler.define_singleton_method(name, &implementation)
|
|
291
|
+
end
|
|
292
|
+
|
|
293
|
+
with_replaced_constant(Object, :Bundler, bundler) do
|
|
294
|
+
yield
|
|
295
|
+
end
|
|
296
|
+
end
|
|
297
|
+
|
|
298
|
+
def with_stubbed_platform_methods(methods)
|
|
299
|
+
platform = Module.new
|
|
300
|
+
methods.each do |name, implementation|
|
|
301
|
+
platform.define_singleton_method(name, &implementation)
|
|
302
|
+
end
|
|
303
|
+
platform.const_set(:RUBY, Gem::Platform::RUBY)
|
|
304
|
+
|
|
305
|
+
with_replaced_constant(Gem, :Platform, platform) do
|
|
306
|
+
yield
|
|
307
|
+
end
|
|
308
|
+
end
|
|
309
|
+
|
|
310
|
+
def with_replaced_constant(container, name, replacement)
|
|
311
|
+
original = container.const_get(name) if container.const_defined?(name, false)
|
|
312
|
+
container.send(:remove_const, name) if container.const_defined?(name, false)
|
|
313
|
+
container.const_set(name, replacement)
|
|
314
|
+
yield
|
|
315
|
+
ensure
|
|
316
|
+
container.send(:remove_const, name) if container.const_defined?(name, false)
|
|
317
|
+
if original
|
|
318
|
+
container.const_set(name, original)
|
|
319
|
+
end
|
|
320
|
+
end
|
|
321
|
+
|
|
322
|
+
def platform_round_trips_for_test?(platform_string)
|
|
323
|
+
Gem::Platform.new(platform_string).to_s == platform_string
|
|
324
|
+
end
|
|
325
|
+
|
|
326
|
+
def platform_installable_for_test?(spec)
|
|
327
|
+
if Gem::Platform.respond_to?(:installable?)
|
|
328
|
+
Gem::Platform.installable?(spec)
|
|
329
|
+
else
|
|
330
|
+
Gem::Platform.match(spec.platform)
|
|
331
|
+
end
|
|
332
|
+
end
|
|
333
|
+
end
|
|
@@ -0,0 +1,264 @@
|
|
|
1
|
+
#################################################################################
|
|
2
|
+
# test_net_ping_http.rb
|
|
3
|
+
#
|
|
4
|
+
# Test case for the Net::PingHTTP class. This should be run via the 'test' or
|
|
5
|
+
# 'test:http' Rake task.
|
|
6
|
+
#################################################################################
|
|
7
|
+
require 'test-unit'
|
|
8
|
+
require 'webmock/test_unit'
|
|
9
|
+
require 'net/ping/http'
|
|
10
|
+
|
|
11
|
+
class TC_Net_Ping_HTTP < Test::Unit::TestCase
|
|
12
|
+
def setup
|
|
13
|
+
ENV['http_proxy'] = ENV['https_proxy'] = ENV['no_proxy'] = nil
|
|
14
|
+
@uri = 'http://www.google.com/index.html'
|
|
15
|
+
@uri_https = 'https://encrypted.google.com'
|
|
16
|
+
@uri_http_domain = 'http.com'
|
|
17
|
+
@uri_http_domain_scheme = 'http://http.com'
|
|
18
|
+
@uri_http_domain_schemes = 'https://http.com'
|
|
19
|
+
@proxy = 'http://username:password@proxymoxie:3128'
|
|
20
|
+
WebMock.disable_net_connect!
|
|
21
|
+
|
|
22
|
+
stub_request(:get, @uri).to_return(body: "PONG")
|
|
23
|
+
stub_request(:head, @uri).to_return(body: "PONG")
|
|
24
|
+
stub_request(:head, @uri_https).to_return(body: "PONG")
|
|
25
|
+
stub_request(:get, @uri_https).to_return(body: "PONG")
|
|
26
|
+
stub_request(:get, "http://#{@uri_http_domain}").to_return(body: "PONG")
|
|
27
|
+
stub_request(:head, "http://#{@uri_http_domain}").to_return(body: "PONG")
|
|
28
|
+
stub_request(:get, @uri_http_domain_scheme).to_return(body: "PONG")
|
|
29
|
+
stub_request(:head, @uri_http_domain_scheme).to_return(body: "PONG")
|
|
30
|
+
stub_request(:get, @uri_http_domain_schemes).to_return(body: "PONG")
|
|
31
|
+
stub_request(:head, @uri_http_domain_schemes).to_return(body: "PONG")
|
|
32
|
+
|
|
33
|
+
stub_request(:head, "https://jigsaw.w3.org/HTTP/300/302.html")
|
|
34
|
+
.to_return(body: "PONG", status: ["302", "Found"], headers: { 'location' => "#{@uri}" })
|
|
35
|
+
|
|
36
|
+
stub_request(:any, "http://www.blabfoobarurghxxxx.com").to_raise(SocketError)
|
|
37
|
+
stub_request(:head, "http://http502.com").to_return(body: "", status: ["502", "Bad Gateway"])
|
|
38
|
+
|
|
39
|
+
@http = Net::Ping::HTTP.new(@uri, 80, 30)
|
|
40
|
+
@http_http_domain = Net::Ping::HTTP.new(@uri_http_domain, 80, 30)
|
|
41
|
+
@http_http_domain_scheme = Net::Ping::HTTP.new(@uri_http_domain_scheme, 80, 30)
|
|
42
|
+
@http_http_domain_schemes = Net::Ping::HTTP.new(@uri_http_domain_schemes, 80, 30)
|
|
43
|
+
@bad = Net::Ping::HTTP.new('http://www.blabfoobarurghxxxx.com') # One hopes not
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
test 'ping basic functionality' do
|
|
47
|
+
assert_respond_to(@http, :ping)
|
|
48
|
+
assert_nothing_raised{ @http.ping }
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
test 'ping site with http in domain' do
|
|
52
|
+
assert_respond_to(@http_http_domain, :ping)
|
|
53
|
+
assert_nothing_raised{ @http_http_domain.ping }
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
test 'ping site with http in domain and http scheme' do
|
|
57
|
+
assert_respond_to(@http_http_domain_scheme, :ping)
|
|
58
|
+
assert_nothing_raised{ @http_http_domain_scheme.ping }
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
test 'ping site with http in domain and https scheme' do
|
|
62
|
+
assert_respond_to(@http_http_domain_schemes, :ping)
|
|
63
|
+
assert_nothing_raised{ @http_http_domain_schemes.ping }
|
|
64
|
+
end
|
|
65
|
+
|
|
66
|
+
test 'ping returns a boolean value' do
|
|
67
|
+
assert_boolean(@http.ping?)
|
|
68
|
+
assert_boolean(@bad.ping?)
|
|
69
|
+
end
|
|
70
|
+
|
|
71
|
+
test "ping? is inherited" do
|
|
72
|
+
assert_respond_to(@http, :ping?)
|
|
73
|
+
end
|
|
74
|
+
|
|
75
|
+
test "pingecho is inherited" do
|
|
76
|
+
assert_respond_to(@http, :pingecho)
|
|
77
|
+
end
|
|
78
|
+
|
|
79
|
+
test 'ping should succeed for a valid website' do
|
|
80
|
+
assert_true(@http.ping?)
|
|
81
|
+
end
|
|
82
|
+
|
|
83
|
+
test 'ping should fail for an invalid website' do
|
|
84
|
+
assert_false(@bad.ping?)
|
|
85
|
+
end
|
|
86
|
+
|
|
87
|
+
test 'duration basic functionality' do
|
|
88
|
+
assert_respond_to(@http, :duration)
|
|
89
|
+
assert_nothing_raised{ @http.ping }
|
|
90
|
+
end
|
|
91
|
+
|
|
92
|
+
test 'duration returns a float value on a successful ping' do
|
|
93
|
+
assert_true(@http.ping)
|
|
94
|
+
assert_kind_of(Float, @http.duration)
|
|
95
|
+
end
|
|
96
|
+
|
|
97
|
+
test 'duration is nil on an unsuccessful ping' do
|
|
98
|
+
assert_false(@bad.ping)
|
|
99
|
+
assert_nil(@http.duration)
|
|
100
|
+
end
|
|
101
|
+
|
|
102
|
+
test 'host attribute basic functionality' do
|
|
103
|
+
assert_respond_to(@http, :host)
|
|
104
|
+
assert_respond_to(@http, :host=)
|
|
105
|
+
assert_equal('http://www.google.com/index.html', @http.host)
|
|
106
|
+
end
|
|
107
|
+
|
|
108
|
+
test 'uri is an alias for host' do
|
|
109
|
+
assert_alias_method(@http, :uri, :host)
|
|
110
|
+
assert_alias_method(@http, :uri=, :host=)
|
|
111
|
+
end
|
|
112
|
+
|
|
113
|
+
test 'port attribute basic functionality' do
|
|
114
|
+
assert_respond_to(@http, :port)
|
|
115
|
+
assert_respond_to(@http, :port=)
|
|
116
|
+
end
|
|
117
|
+
|
|
118
|
+
test 'port attribute is set to expected value' do
|
|
119
|
+
assert_equal(80, @http.port)
|
|
120
|
+
assert_equal(443, Net::Ping::HTTP.new('https://github.com/github').port)
|
|
121
|
+
assert_equal(80, Net::Ping::HTTP.new.port)
|
|
122
|
+
end
|
|
123
|
+
|
|
124
|
+
test 'timeout attribute basic functionality' do
|
|
125
|
+
assert_respond_to(@http, :timeout)
|
|
126
|
+
assert_respond_to(@http, :timeout=)
|
|
127
|
+
end
|
|
128
|
+
|
|
129
|
+
test 'timeout attribute expected values' do
|
|
130
|
+
assert_equal(30, @http.timeout)
|
|
131
|
+
assert_equal(5, @bad.timeout)
|
|
132
|
+
end
|
|
133
|
+
|
|
134
|
+
test 'ping fails if timeout exceeded' do
|
|
135
|
+
stub_request(:head, 'https://www.google.com/').to_timeout
|
|
136
|
+
@http = Net::Ping::HTTP.new('https://www.google.com', 443, 0.001)
|
|
137
|
+
assert_false(@http.ping?)
|
|
138
|
+
assert_include(['execution expired', 'Net::OpenTimeout'], @http.exception)
|
|
139
|
+
end
|
|
140
|
+
|
|
141
|
+
test 'exception attribute basic functionality' do
|
|
142
|
+
assert_respond_to(@http, :exception)
|
|
143
|
+
assert_nil(@http.exception)
|
|
144
|
+
end
|
|
145
|
+
|
|
146
|
+
test 'exception attribute is nil if the ping is successful' do
|
|
147
|
+
assert_true(@http.ping)
|
|
148
|
+
assert_nil(@http.exception)
|
|
149
|
+
end
|
|
150
|
+
|
|
151
|
+
test 'exception attribute is not nil if the ping is unsuccessful' do
|
|
152
|
+
assert_false(@bad.ping)
|
|
153
|
+
assert_not_nil(@bad.exception)
|
|
154
|
+
end
|
|
155
|
+
|
|
156
|
+
test 'warning attribute basic functionality' do
|
|
157
|
+
assert_respond_to(@http, :warning)
|
|
158
|
+
assert_nil(@http.warning)
|
|
159
|
+
end
|
|
160
|
+
|
|
161
|
+
test 'code attribute is set' do
|
|
162
|
+
assert_true(@http.ping)
|
|
163
|
+
assert_equal('200', @http.code)
|
|
164
|
+
end
|
|
165
|
+
|
|
166
|
+
test 'user_agent accessor is defined' do
|
|
167
|
+
assert_respond_to(@http, :user_agent)
|
|
168
|
+
assert_respond_to(@http, :user_agent=)
|
|
169
|
+
end
|
|
170
|
+
|
|
171
|
+
test 'user_agent defaults to nil' do
|
|
172
|
+
assert_nil(@http.user_agent)
|
|
173
|
+
end
|
|
174
|
+
|
|
175
|
+
test 'ping with user agent' do
|
|
176
|
+
@http.user_agent = "KDDI-CA32"
|
|
177
|
+
assert_true(@http.ping)
|
|
178
|
+
assert_requested(:any, @uri, headers: { "User-Agent" => "KDDI-CA32" }, times: 1)
|
|
179
|
+
end
|
|
180
|
+
|
|
181
|
+
test 'redirect_limit accessor is defined' do
|
|
182
|
+
assert_respond_to(@http, :redirect_limit)
|
|
183
|
+
assert_respond_to(@http, :redirect_limit=)
|
|
184
|
+
end
|
|
185
|
+
|
|
186
|
+
test 'redirect_limit defaults to 5' do
|
|
187
|
+
assert_equal(5, @http.redirect_limit)
|
|
188
|
+
end
|
|
189
|
+
|
|
190
|
+
test 'redirects succeed by default' do
|
|
191
|
+
@http = Net::Ping::HTTP.new("https://jigsaw.w3.org/HTTP/300/302.html")
|
|
192
|
+
assert_true(@http.ping)
|
|
193
|
+
end
|
|
194
|
+
|
|
195
|
+
test 'redirect fail if follow_redirect is set to false' do
|
|
196
|
+
@http = Net::Ping::HTTP.new("https://jigsaw.w3.org/HTTP/300/302.html")
|
|
197
|
+
@http.follow_redirect = false
|
|
198
|
+
assert_false(@http.ping)
|
|
199
|
+
end
|
|
200
|
+
|
|
201
|
+
test 'ping with redirect limit set to zero fails' do
|
|
202
|
+
@http = Net::Ping::HTTP.new("https://jigsaw.w3.org/HTTP/300/302.html")
|
|
203
|
+
@http.redirect_limit = 0
|
|
204
|
+
assert_false(@http.ping)
|
|
205
|
+
assert_equal("Redirect limit exceeded", @http.exception)
|
|
206
|
+
end
|
|
207
|
+
|
|
208
|
+
test 'http 502 sets exception' do
|
|
209
|
+
@http = Net::Ping::HTTP.new("http://http502.com")
|
|
210
|
+
assert_false(@http.ping)
|
|
211
|
+
assert_equal('Bad Gateway', @http.exception)
|
|
212
|
+
end
|
|
213
|
+
|
|
214
|
+
test 'http 502 sets code' do
|
|
215
|
+
@http = Net::Ping::HTTP.new("http://http502.com")
|
|
216
|
+
assert_false(@http.ping)
|
|
217
|
+
assert_equal('502', @http.code)
|
|
218
|
+
end
|
|
219
|
+
|
|
220
|
+
test 'ping against https site defaults to port 443' do
|
|
221
|
+
@http = Net::Ping::HTTP.new(@uri_https)
|
|
222
|
+
assert_equal(443, @http.port)
|
|
223
|
+
end
|
|
224
|
+
|
|
225
|
+
test 'ping against https site works as expected' do
|
|
226
|
+
@http = Net::Ping::HTTP.new(@uri_https)
|
|
227
|
+
assert_true(@http.ping)
|
|
228
|
+
end
|
|
229
|
+
|
|
230
|
+
test 'ping with get option' do
|
|
231
|
+
@http = Net::Ping::HTTP.new(@uri)
|
|
232
|
+
@http.get_request = true
|
|
233
|
+
assert_true(@http.ping)
|
|
234
|
+
end
|
|
235
|
+
|
|
236
|
+
test 'ping with http proxy' do
|
|
237
|
+
ENV['http_proxy'] = "http://proxymoxie:3128"
|
|
238
|
+
@http = Net::Ping::HTTP.new(@uri)
|
|
239
|
+
@http.get_request = true
|
|
240
|
+
assert_true(@http.ping)
|
|
241
|
+
assert_true(@http.proxied)
|
|
242
|
+
end
|
|
243
|
+
|
|
244
|
+
test 'ping with https proxy' do
|
|
245
|
+
ENV['https_proxy'] = "http://proxymoxie:3128"
|
|
246
|
+
@http = Net::Ping::HTTP.new(@uri_https)
|
|
247
|
+
@http.get_request = true
|
|
248
|
+
assert_true(@http.ping)
|
|
249
|
+
assert_true(@http.proxied)
|
|
250
|
+
end
|
|
251
|
+
|
|
252
|
+
test 'ping with no_proxy' do
|
|
253
|
+
ENV['no_proxy'] = "google.com"
|
|
254
|
+
@http = Net::Ping::HTTP.new(@uri)
|
|
255
|
+
@http.get_request = true
|
|
256
|
+
assert_true(@http.ping)
|
|
257
|
+
assert_false(@http.proxied)
|
|
258
|
+
end
|
|
259
|
+
|
|
260
|
+
def teardown
|
|
261
|
+
@uri = nil
|
|
262
|
+
@http = nil
|
|
263
|
+
end
|
|
264
|
+
end
|