mirror of
https://github.com/ruby/ruby.git
synced 2022-11-09 12:17:21 -05:00
2c3656f5e8
* test/test_prime.rb (test_eratosthenes_works_fine_after_timeout): use assert_raise to check timeout. * test/test_securerandom.rb: check if results are hexadecimal strings, and refine failure messages. * test/test_tracer.rb (test_tracer_with_option_r_without_gems): use assert_equal to compare. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@51023 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
186 lines
4.1 KiB
Ruby
186 lines
4.1 KiB
Ruby
require 'test/unit'
|
|
require 'securerandom'
|
|
require 'tempfile'
|
|
|
|
# This testcase does NOT aim to test cryptographically strongness and randomness.
|
|
class TestSecureRandom < Test::Unit::TestCase
|
|
def setup
|
|
@it = SecureRandom
|
|
end
|
|
|
|
def test_s_random_bytes
|
|
assert_equal(16, @it.random_bytes.size)
|
|
assert_equal(Encoding::ASCII_8BIT, @it.random_bytes.encoding)
|
|
65.times do |idx|
|
|
assert_equal(idx, @it.random_bytes(idx).size)
|
|
end
|
|
end
|
|
|
|
# This test took 2 minutes on my machine.
|
|
# And 65536 times loop could not be enough for forcing PID recycle.
|
|
if false
|
|
def test_s_random_bytes_is_fork_safe
|
|
begin
|
|
require 'openssl'
|
|
rescue LoadError
|
|
return
|
|
end
|
|
SecureRandom.random_bytes(8)
|
|
pid, v1 = forking_random_bytes
|
|
assert(check_forking_random_bytes(pid, v1), 'Process ID not recycled?')
|
|
end
|
|
|
|
def forking_random_bytes
|
|
r, w = IO.pipe
|
|
pid = fork {
|
|
r.close
|
|
w.write SecureRandom.random_bytes(8)
|
|
w.close
|
|
}
|
|
w.close
|
|
v = r.read(8)
|
|
r.close
|
|
Process.waitpid2(pid)
|
|
[pid, v]
|
|
end
|
|
|
|
def check_forking_random_bytes(target_pid, target)
|
|
65536.times do
|
|
pid = fork {
|
|
if $$ == target_pid
|
|
v2 = SecureRandom.random_bytes(8)
|
|
if v2 == target
|
|
exit(1)
|
|
else
|
|
exit(2)
|
|
end
|
|
end
|
|
exit(3)
|
|
}
|
|
pid, status = Process.waitpid2(pid)
|
|
case status.exitstatus
|
|
when 1
|
|
raise 'returned same sequence for same PID'
|
|
when 2
|
|
return true
|
|
end
|
|
end
|
|
false # not recycled?
|
|
end
|
|
end
|
|
|
|
def test_s_random_bytes_without_openssl
|
|
begin
|
|
require 'openssl'
|
|
rescue LoadError
|
|
return
|
|
end
|
|
begin
|
|
load_path = $LOAD_PATH.dup
|
|
loaded_features = $LOADED_FEATURES.dup
|
|
openssl = Object.instance_eval { remove_const(:OpenSSL) }
|
|
|
|
remove_feature('securerandom.rb')
|
|
remove_feature('openssl.rb')
|
|
Dir.mktmpdir do |dir|
|
|
open(File.join(dir, 'openssl.rb'), 'w') { |f|
|
|
f << 'raise LoadError'
|
|
}
|
|
$LOAD_PATH.unshift(dir)
|
|
v = $VERBOSE
|
|
begin
|
|
$VERBOSE = false
|
|
require 'securerandom'
|
|
ensure
|
|
$VERBOSE = v
|
|
end
|
|
test_s_random_bytes
|
|
end
|
|
ensure
|
|
$LOADED_FEATURES.replace(loaded_features)
|
|
$LOAD_PATH.replace(load_path)
|
|
Object.const_set(:OpenSSL, openssl)
|
|
end
|
|
end
|
|
|
|
def test_s_hex
|
|
s = @it.hex
|
|
assert_equal(16 * 2, s.size)
|
|
assert_match(/\A\h+\z/, s)
|
|
33.times do |idx|
|
|
s = @it.hex(idx)
|
|
assert_equal(idx * 2, s.size)
|
|
assert_match(/\A\h*\z/, s)
|
|
end
|
|
end
|
|
|
|
def test_hex_encoding
|
|
assert_equal(Encoding::US_ASCII, @it.hex.encoding)
|
|
end
|
|
|
|
def test_s_base64
|
|
assert_equal(16, @it.base64.unpack('m*')[0].size)
|
|
17.times do |idx|
|
|
assert_equal(idx, @it.base64(idx).unpack('m*')[0].size)
|
|
end
|
|
end
|
|
|
|
def test_s_urlsafe_base64
|
|
safe = /[\n+\/]/
|
|
65.times do |idx|
|
|
assert_not_match(safe, @it.urlsafe_base64(idx))
|
|
end
|
|
# base64 can include unsafe byte
|
|
assert((0..10000).any? {|idx| safe =~ @it.base64(idx)}, "None of base64(0..10000) is url-safe")
|
|
end
|
|
|
|
def test_s_random_number_float
|
|
101.times do
|
|
v = @it.random_number
|
|
assert_in_range(0.0...1.0, v)
|
|
end
|
|
end
|
|
|
|
def test_s_random_number_float_by_zero
|
|
101.times do
|
|
v = @it.random_number(0)
|
|
assert_in_range(0.0...1.0, v)
|
|
end
|
|
end
|
|
|
|
def test_s_random_number_int
|
|
101.times do |idx|
|
|
next if idx.zero?
|
|
v = @it.random_number(idx)
|
|
assert_in_range(0...idx, v)
|
|
end
|
|
end
|
|
|
|
def test_uuid
|
|
uuid = @it.uuid
|
|
assert_equal(36, uuid.size)
|
|
assert_match(/\A\h{8}-\h{4}-\h{4}-\h{4}-\h{12}\z/, uuid)
|
|
end
|
|
|
|
def protect
|
|
begin
|
|
yield
|
|
rescue NotImplementedError
|
|
# ignore
|
|
end
|
|
end
|
|
|
|
def remove_feature(basename)
|
|
$LOADED_FEATURES.delete_if { |path|
|
|
if File.basename(path) == basename
|
|
$LOAD_PATH.any? { |dir|
|
|
File.exist?(File.join(dir, basename))
|
|
}
|
|
end
|
|
}
|
|
end
|
|
|
|
def assert_in_range(range, result, mesg = nil)
|
|
assert(range.cover?(result), message(mesg) {"Expected #{result} to be in #{range}"})
|
|
end
|
|
end
|