mirror of
https://github.com/ruby/ruby.git
synced 2022-11-09 12:17:21 -05:00
* test/test_securerandom.rb: Add testcase. This testcase does NOT aim
to test cryptographically strongness and randomness. It includes the test for PID recycle issue of OpenSSL described in #4579 but it's disabled by default. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@32122 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
parent
513e0ee53b
commit
a15dfa6b4a
2 changed files with 182 additions and 0 deletions
|
@ -1,3 +1,10 @@
|
|||
Thu Jun 16 19:27:12 2011 Hiroshi Nakamura <nahi@ruby-lang.org>
|
||||
|
||||
* test/test_securerandom.rb: Add testcase. This testcase does NOT aim
|
||||
to test cryptographically strongness and randomness. It includes
|
||||
the test for PID recycle issue of OpenSSL described in #4579 but
|
||||
it's disabled by default.
|
||||
|
||||
Thu Jun 16 17:55:07 2011 KOSAKI Motohiro <kosaki.motohiro@gmail.com>
|
||||
|
||||
* test/ruby/test_io.rb (TestIO#test_copy_stream_socket): fix
|
||||
|
|
175
test/test_securerandom.rb
Normal file
175
test/test_securerandom.rb
Normal file
|
@ -0,0 +1,175 @@
|
|||
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)
|
||||
require 'securerandom'
|
||||
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
|
||||
assert_equal(16 * 2, @it.hex.size)
|
||||
33.times do |idx|
|
||||
assert_equal(idx * 2, @it.hex(idx).size)
|
||||
assert_equal(idx, @it.hex(idx).gsub(/(..)/) { [$1].pack('H*') }.size)
|
||||
end
|
||||
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
|
||||
10001.times do |idx|
|
||||
return if safe =~ @it.base64(idx)
|
||||
end
|
||||
flunk
|
||||
end
|
||||
|
||||
def test_s_random_number_float
|
||||
101.times do
|
||||
v = @it.random_number
|
||||
assert(0.0 <= v && v < 1.0)
|
||||
end
|
||||
end
|
||||
|
||||
def test_s_random_number_float_by_zero
|
||||
101.times do
|
||||
v = @it.random_number(0)
|
||||
assert(0.0 <= v && v < 1.0)
|
||||
end
|
||||
end
|
||||
|
||||
def test_s_random_number_int
|
||||
101.times do |idx|
|
||||
next if idx.zero?
|
||||
v = @it.random_number(idx)
|
||||
assert(0 <= v && v < idx)
|
||||
end
|
||||
end
|
||||
|
||||
def test_uuid
|
||||
uuid = @it.uuid
|
||||
assert_equal(36, uuid.size)
|
||||
uuid.unpack('a8xa4xa4xa4xa12').each do |e|
|
||||
assert_match(/^[0-9a-f]+$/, e)
|
||||
end
|
||||
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.exists?(File.join(dir, basename))
|
||||
}
|
||||
end
|
||||
}
|
||||
end
|
||||
|
||||
end
|
Loading…
Reference in a new issue