diff options
Diffstat (limited to 'jni/ruby/test/openssl/test_pair.rb')
| -rw-r--r-- | jni/ruby/test/openssl/test_pair.rb | 372 | 
1 files changed, 372 insertions, 0 deletions
diff --git a/jni/ruby/test/openssl/test_pair.rb b/jni/ruby/test/openssl/test_pair.rb new file mode 100644 index 0000000..3aca5f4 --- /dev/null +++ b/jni/ruby/test/openssl/test_pair.rb @@ -0,0 +1,372 @@ +require_relative 'utils' + +if defined?(OpenSSL::TestUtils) + +require 'socket' +require_relative '../ruby/ut_eof' + +module OpenSSL::SSLPairM +  def server +    host = "127.0.0.1" +    port = 0 +    ctx = OpenSSL::SSL::SSLContext.new() +    ctx.ciphers = "ADH" +    ctx.tmp_dh_callback = proc { OpenSSL::TestUtils::TEST_KEY_DH1024 } +    tcps = create_tcp_server(host, port) +    ssls = OpenSSL::SSL::SSLServer.new(tcps, ctx) +    return ssls +  end + +  def client(port) +    host = "127.0.0.1" +    ctx = OpenSSL::SSL::SSLContext.new() +    ctx.ciphers = "ADH" +    s = create_tcp_client(host, port) +    ssl = OpenSSL::SSL::SSLSocket.new(s, ctx) +    ssl.connect +    ssl.sync_close = true +    ssl +  end + +  def ssl_pair +    ssls = server +    th = Thread.new { +      ns = ssls.accept +      ssls.close +      ns +    } +    port = ssls.to_io.local_address.ip_port +    c = client(port) +    s = th.value +    if block_given? +      begin +        yield c, s +      ensure +        c.close unless c.closed? +        s.close unless s.closed? +      end +    else +      return c, s +    end +  ensure +    if th && th.alive? +      th.kill +      th.join +    end +  end +end + +module OpenSSL::SSLPair +  include OpenSSL::SSLPairM + +  def create_tcp_server(host, port) +    TCPServer.new(host, port) +  end + +  def create_tcp_client(host, port) +    TCPSocket.new(host, port) +  end +end + +module OpenSSL::SSLPairLowlevelSocket +  include OpenSSL::SSLPairM + +  def create_tcp_server(host, port) +    Addrinfo.tcp(host, port).listen +  end + +  def create_tcp_client(host, port) +    Addrinfo.tcp(host, port).connect +  end +end + +module OpenSSL::TestEOF1M +  def open_file(content) +    s1, s2 = ssl_pair +    th = Thread.new { s2 << content; s2.close } +    yield s1 +  ensure +    th.join +    s1.close +  end +end + +module OpenSSL::TestEOF2M +  def open_file(content) +    s1, s2 = ssl_pair +    th = Thread.new { s1 << content; s1.close } +    yield s2 +  ensure +    th.join +    s2.close +  end +end + +module OpenSSL::TestPairM +  def test_getc +    ssl_pair {|s1, s2| +      s1 << "a" +      assert_equal(?a, s2.getc) +    } +  end + +  def test_readpartial +    ssl_pair {|s1, s2| +      s2.write "a\nbcd" +      assert_equal("a\n", s1.gets) +      result = "" +      result << s1.readpartial(10) until result.length == 3 +      assert_equal("bcd", result) +      s2.write "efg" +      result = "" +      result << s1.readpartial(10) until result.length == 3 +      assert_equal("efg", result) +      s2.close +      assert_raise(EOFError) { s1.readpartial(10) } +      assert_raise(EOFError) { s1.readpartial(10) } +      assert_equal("", s1.readpartial(0)) +    } +  end + +  def test_readall +    ssl_pair {|s1, s2| +      s2.close +      assert_equal("", s1.read) +    } +  end + +  def test_readline +    ssl_pair {|s1, s2| +      s2.close +      assert_raise(EOFError) { s1.readline } +    } +  end + +  def test_puts_meta +    ssl_pair {|s1, s2| +      begin +        old = $/ +        $/ = '*' +        s1.puts 'a' +      ensure +        $/ = old +      end +      s1.close +      assert_equal("a\n", s2.read) +    } +  end + +  def test_puts_empty +    ssl_pair {|s1, s2| +      s1.puts +      s1.close +      assert_equal("\n", s2.read) +    } +  end + +  def test_read_nonblock +    ssl_pair {|s1, s2| +      err = nil +      assert_raise(OpenSSL::SSL::SSLErrorWaitReadable) { +        begin +          s2.read_nonblock(10) +        ensure +          err = $! +        end +      } +      assert_kind_of(IO::WaitReadable, err) +      s1.write "abc\ndef\n" +      IO.select([s2]) +      assert_equal("ab", s2.read_nonblock(2)) +      assert_equal("c\n", s2.gets) +      ret = nil +      assert_nothing_raised("[ruby-core:20298]") { ret = s2.read_nonblock(10) } +      assert_equal("def\n", ret) +      s1.close +      sleep 0.1 +      assert_raise(EOFError) { s2.read_nonblock(10) } +    } +  end + +  def test_read_nonblock_no_exception +    ssl_pair {|s1, s2| +      assert_equal :wait_readable, s2.read_nonblock(10, exception: false) +      s1.write "abc\ndef\n" +      IO.select([s2]) +      assert_equal("ab", s2.read_nonblock(2, exception: false)) +      assert_equal("c\n", s2.gets) +      ret = nil +      assert_nothing_raised("[ruby-core:20298]") { ret = s2.read_nonblock(10, exception: false) } +      assert_equal("def\n", ret) +      s1.close +      sleep 0.1 +      assert_equal(nil, s2.read_nonblock(10, exception: false)) +    } +  end + +  def write_nonblock(socket, meth, str) +    ret = socket.send(meth, str) +    ret.is_a?(Symbol) ? 0 : ret +  end + +  def write_nonblock_no_ex(socket, str) +    ret = socket.write_nonblock str, exception: false +    ret.is_a?(Symbol) ? 0 : ret +  end + +  def test_write_nonblock +    ssl_pair {|s1, s2| +      n = 0 +      begin +        n += write_nonblock s1, :write_nonblock, "a" * 100000 +        n += write_nonblock s1, :write_nonblock, "b" * 100000 +        n += write_nonblock s1, :write_nonblock, "c" * 100000 +        n += write_nonblock s1, :write_nonblock, "d" * 100000 +        n += write_nonblock s1, :write_nonblock, "e" * 100000 +        n += write_nonblock s1, :write_nonblock, "f" * 100000 +      rescue IO::WaitWritable +      end +      s1.close +      assert_equal(n, s2.read.length) +    } +  end + +  def test_write_nonblock_no_exceptions +    ssl_pair {|s1, s2| +      n = 0 +      begin +        n += write_nonblock_no_ex s1, "a" * 100000 +        n += write_nonblock_no_ex s1, "b" * 100000 +        n += write_nonblock_no_ex s1, "c" * 100000 +        n += write_nonblock_no_ex s1, "d" * 100000 +        n += write_nonblock_no_ex s1, "e" * 100000 +        n += write_nonblock_no_ex s1, "f" * 100000 +      rescue OpenSSL::SSL::SSLError => e +        # on some platforms (maybe depend on OpenSSL version), writing to +        # SSLSocket after SSL_ERROR_WANT_WRITE causes this error. +        raise e if n == 0 +      end +      s1.close +      assert_equal(n, s2.read.length) +    } +  end + +  def test_write_nonblock_with_buffered_data +    ssl_pair {|s1, s2| +      s1.write "foo" +      s1.write_nonblock("bar") +      s1.write "baz" +      s1.close +      assert_equal("foobarbaz", s2.read) +    } +  end + +  def test_write_nonblock_with_buffered_data_no_exceptions +    ssl_pair {|s1, s2| +      s1.write "foo" +      s1.write_nonblock("bar", exception: false) +      s1.write "baz" +      s1.close +      assert_equal("foobarbaz", s2.read) +    } +  end + +  def tcp_pair +    host = "127.0.0.1" +    serv = TCPServer.new(host, 0) +    port = serv.connect_address.ip_port +    sock1 = TCPSocket.new(host, port) +    sock2 = serv.accept +    serv.close +    [sock1, sock2] +  ensure +    serv.close if serv && !serv.closed? +  end + +  def test_connect_accept_nonblock +    ctx = OpenSSL::SSL::SSLContext.new() +    ctx.ciphers = "ADH" +    ctx.tmp_dh_callback = proc { OpenSSL::TestUtils::TEST_KEY_DH1024 } + +    sock1, sock2 = tcp_pair + +    th = Thread.new { +      s2 = OpenSSL::SSL::SSLSocket.new(sock2, ctx) +      s2.sync_close = true +      begin +        sleep 0.2 +        s2.accept_nonblock +      rescue IO::WaitReadable +        IO.select([s2]) +        retry +      rescue IO::WaitWritable +        IO.select(nil, [s2]) +        retry +      end +      s2 +    } + +    sleep 0.1 +    ctx = OpenSSL::SSL::SSLContext.new() +    ctx.ciphers = "ADH" +    s1 = OpenSSL::SSL::SSLSocket.new(sock1, ctx) +    begin +      sleep 0.2 +      s1.connect_nonblock +    rescue IO::WaitReadable +      IO.select([s1]) +      retry +    rescue IO::WaitWritable +      IO.select(nil, [s1]) +      retry +    end +    s1.sync_close = true + +    s2 = th.value + +    s1.print "a\ndef" +    assert_equal("a\n", s2.gets) +  ensure +    th.join +    s1.close if s1 && !s1.closed? +    s2.close if s2 && !s2.closed? +    sock1.close if sock1 && !sock1.closed? +    sock2.close if sock2 && !sock2.closed? +  end +end + +class OpenSSL::TestEOF1 < Test::Unit::TestCase +  include TestEOF +  include OpenSSL::SSLPair +  include OpenSSL::TestEOF1M +end + +class OpenSSL::TestEOF1LowlevelSocket < Test::Unit::TestCase +  include TestEOF +  include OpenSSL::SSLPairLowlevelSocket +  include OpenSSL::TestEOF1M +end + +class OpenSSL::TestEOF2 < Test::Unit::TestCase +  include TestEOF +  include OpenSSL::SSLPair +  include OpenSSL::TestEOF2M +end + +class OpenSSL::TestEOF2LowlevelSocket < Test::Unit::TestCase +  include TestEOF +  include OpenSSL::SSLPairLowlevelSocket +  include OpenSSL::TestEOF2M +end + +class OpenSSL::TestPair < Test::Unit::TestCase +  include OpenSSL::SSLPair +  include OpenSSL::TestPairM +end + +class OpenSSL::TestPairLowlevelSocket < Test::Unit::TestCase +  include OpenSSL::SSLPairLowlevelSocket +  include OpenSSL::TestPairM +end + +end  | 
