blob: 03bd66afa20d5edfab3d3cb803bad15cd0a8b36f [file]
#!/usr/bin/ruby
#
# basic_test_pb.rb is in the same directory as this test.
$LOAD_PATH.unshift(File.expand_path(File.dirname(__FILE__)))
require 'basic_test_pb'
require 'basic_test_proto2_pb'
require 'google/protobuf'
require 'test/unit'
return if defined?(JRUBY_VERSION) || Google::Protobuf::IMPLEMENTATION != :NATIVE
class OomTest < Test::Unit::TestCase
def is_available
Google::Protobuf::Internal.allocation_count_is_available
end
def reset_allocations
Google::Protobuf::Internal.allocation_count_reset
end
def get_allocations
Google::Protobuf::Internal.allocation_count_get
end
def fail_on_allocation(n)
Google::Protobuf::Internal.allocation_count_fail_on(n)
end
def many_allocs_scenario
msg = BasicTest::TestMessage.new
msg.optional_int32 = 123
msg.optional_int64 = 456
msg.optional_uint32 = 789
msg.optional_uint64 = 101112
msg.optional_bool = true
msg.optional_float = 1.5
msg.optional_double = 2.5
msg.optional_string = "hello"
msg.optional_bytes = "world\x00escape"
msg.optional_msg = BasicTest::TestMessage2.new(foo: 42)
100.times { |i| msg.repeated_int32 << i }
msg.repeated_int64 << 1000
msg.repeated_uint32 << 2000
msg.repeated_uint64 << 3000
msg.repeated_bool << false
msg.repeated_float << 3.5
msg.repeated_double << 4.5
msg.repeated_string << "foo"
msg.repeated_bytes << "bar"
msg.repeated_msg << BasicTest::TestMessage2.new(foo: 43)
serialized = BasicTest::TestMessage.encode(msg)
msg2 = BasicTest::TestMessage.decode(serialized)
msg3 = msg2.dup
msg4 = msg2.clone
msg5 = Google::Protobuf.deep_copy(msg2)
_ = msg5.optional_string
_ = msg5.optional_bytes
if defined?(BasicTestProto2::TestExtensions)
ext_msg = BasicTestProto2::TestExtensions.new
ext1 = Google::Protobuf::DescriptorPool.generated_pool.lookup('basic_test_proto2.optional_int32_extension')
ext2 = Google::Protobuf::DescriptorPool.generated_pool.lookup('basic_test_proto2.TestNestedExtension.test')
ext1.set(ext_msg, 42)
ext2.set(ext_msg, "hello")
ext_serialized = BasicTestProto2::TestExtensions.encode(ext_msg)
ext_msg2 = BasicTestProto2::TestExtensions.decode(ext_serialized)
ext_msg2_copy = Google::Protobuf.deep_copy(ext_msg2)
_val1 = ext1.get(ext_msg2_copy)
_val2 = ext2.get(ext_msg2_copy)
end
if defined?(BasicTestProto2::TestMessageSet)
mset_msg = BasicTestProto2::TestMessageSet.new
ext_mset1 = Google::Protobuf::DescriptorPool.generated_pool.lookup('basic_test_proto2.TestMessageSetExtension1.message_set_extension')
ext_mset2 = Google::Protobuf::DescriptorPool.generated_pool.lookup('basic_test_proto2.TestMessageSetExtension2.message_set_extension')
ext_mset1.set(mset_msg, BasicTestProto2::TestMessageSetExtension1.new(i: 123))
ext_mset2.set(mset_msg, BasicTestProto2::TestMessageSetExtension2.new(str: 'hello'))
mset_serialized = BasicTestProto2::TestMessageSet.encode(mset_msg)
mset_msg2 = BasicTestProto2::TestMessageSet.decode(mset_serialized)
mset_msg3 = Google::Protobuf.deep_copy(mset_msg2)
_val_mset1 = ext_mset1.get(mset_msg3).i
_val_mset2 = ext_mset2.get(mset_msg3).str
mset_unknown = BasicTestProto2::TestMessageSet.decode(
"\x0b\x10\x01\x1a\x03foo\x0c\x0b\x10\x02\x1a\x03bar\x0c".force_encoding("ASCII-8BIT")
)
_mset_unknown_copy = Google::Protobuf.deep_copy(mset_unknown)
end
if defined?(BasicTestProto2::TestExtensions)
empty = BasicTestProto2::TestExtensions.decode(serialized)
_empty_copy = Google::Protobuf.deep_copy(empty)
Google::Protobuf.discard_unknown(_empty_copy)
end
end
def test_oom
omit 'Requires Debug-only allocation_count API' unless is_available
# Warm up so we get a consistent set of allocations in the loop
many_allocs_scenario
reset_allocations
many_allocs_scenario
total = get_allocations
assert_operator total, :>, 0
total.times do |i|
reset_allocations
fail_on_allocation(i)
begin
many_allocs_scenario
rescue NoMemoryError
next
end
if get_allocations > i
flunk("NoMemoryError exception was expected at allocation #{i}, but completed with #{get_allocations} allocations.")
end
end
reset_allocations
end
end