summaryrefslogtreecommitdiff
path: root/test/fiddle
diff options
context:
space:
mode:
Diffstat (limited to 'test/fiddle')
-rw-r--r--test/fiddle/helper.rb10
-rw-r--r--test/fiddle/test_c_struct_entry.rb8
-rw-r--r--test/fiddle/test_closure.rb123
-rw-r--r--test/fiddle/test_cparser.rb40
-rw-r--r--test/fiddle/test_fiddle.rb41
-rw-r--r--test/fiddle/test_func.rb53
-rw-r--r--test/fiddle/test_function.rb28
-rw-r--r--test/fiddle/test_handle.rb10
-rw-r--r--test/fiddle/test_import.rb23
-rw-r--r--test/fiddle/test_pack.rb37
-rw-r--r--test/fiddle/test_pointer.rb19
11 files changed, 322 insertions, 70 deletions
diff --git a/test/fiddle/helper.rb b/test/fiddle/helper.rb
index 0ea3bf57f4..e470f5a276 100644
--- a/test/fiddle/helper.rb
+++ b/test/fiddle/helper.rb
@@ -49,8 +49,14 @@ when /linux/
libm_so = libc_so
else
# glibc
- libc_so = "libc.so.6"
- libm_so = "libm.so.6"
+ case RUBY_PLATFORM
+ when /alpha-linux/, /ia64-linux/
+ libc_so = "libc.so.6.1"
+ libm_so = "libm.so.6.1"
+ else
+ libc_so = "libc.so.6"
+ libm_so = "libm.so.6"
+ end
end
when /mingw/, /mswin/
require "rbconfig"
diff --git a/test/fiddle/test_c_struct_entry.rb b/test/fiddle/test_c_struct_entry.rb
index 9fd16d7101..45de2efe21 100644
--- a/test/fiddle/test_c_struct_entry.rb
+++ b/test/fiddle/test_c_struct_entry.rb
@@ -8,7 +8,7 @@ end
module Fiddle
class TestCStructEntity < TestCase
def test_class_size
- types = [TYPE_DOUBLE, TYPE_CHAR]
+ types = [TYPE_DOUBLE, TYPE_CHAR, TYPE_DOUBLE, TYPE_BOOL]
size = CStructEntity.size types
@@ -20,6 +20,12 @@ module Fiddle
expected = PackInfo.align expected, alignments[1]
expected += PackInfo::SIZE_MAP[TYPE_CHAR]
+ expected = PackInfo.align expected, alignments[2]
+ expected += PackInfo::SIZE_MAP[TYPE_DOUBLE]
+
+ expected = PackInfo.align expected, alignments[3]
+ expected += PackInfo::SIZE_MAP[TYPE_BOOL]
+
expected = PackInfo.align expected, alignments.max
assert_equal expected, size
diff --git a/test/fiddle/test_closure.rb b/test/fiddle/test_closure.rb
index 9e748bf5ee..abb6bdbd32 100644
--- a/test/fiddle/test_closure.rb
+++ b/test/fiddle/test_closure.rb
@@ -6,6 +6,17 @@ end
module Fiddle
class TestClosure < Fiddle::TestCase
+ def teardown
+ super
+ # Ensure freeing all closures.
+ # See https://github.com/ruby/fiddle/issues/102#issuecomment-1241763091 .
+ not_freed_closures = []
+ ObjectSpace.each_object(Fiddle::Closure) do |closure|
+ not_freed_closures << closure unless closure.freed?
+ end
+ assert_equal([], not_freed_closures)
+ end
+
def test_argument_errors
assert_raise(TypeError) do
Closure.new(TYPE_INT, TYPE_INT)
@@ -21,37 +32,40 @@ module Fiddle
end
def test_type_symbol
- closure = Closure.new(:int, [:void])
- assert_equal([
- TYPE_INT,
- [TYPE_VOID],
- ],
- [
- closure.instance_variable_get(:@ctype),
- closure.instance_variable_get(:@args),
- ])
+ Closure.create(:int, [:void]) do |closure|
+ assert_equal([
+ TYPE_INT,
+ [TYPE_VOID],
+ ],
+ [
+ closure.instance_variable_get(:@ctype),
+ closure.instance_variable_get(:@args),
+ ])
+ end
end
def test_call
- closure = Class.new(Closure) {
+ closure_class = Class.new(Closure) do
def call
10
end
- }.new(TYPE_INT, [])
-
- func = Function.new(closure, [], TYPE_INT)
- assert_equal 10, func.call
+ end
+ closure_class.create(TYPE_INT, []) do |closure|
+ func = Function.new(closure, [], TYPE_INT)
+ assert_equal 10, func.call
+ end
end
def test_returner
- closure = Class.new(Closure) {
+ closure_class = Class.new(Closure) do
def call thing
thing
end
- }.new(TYPE_INT, [TYPE_INT])
-
- func = Function.new(closure, [TYPE_INT], TYPE_INT)
- assert_equal 10, func.call(10)
+ end
+ closure_class.create(TYPE_INT, [TYPE_INT]) do |closure|
+ func = Function.new(closure, [TYPE_INT], TYPE_INT)
+ assert_equal 10, func.call(10)
+ end
end
def test_const_string
@@ -61,25 +75,53 @@ module Fiddle
@return_string
end
end
- closure = closure_class.new(:const_string, [:const_string])
+ closure_class.create(:const_string, [:const_string]) do |closure|
+ func = Function.new(closure, [:const_string], :const_string)
+ assert_equal("Hello! World!", func.call("World!"))
+ end
+ end
- func = Function.new(closure, [:const_string], :const_string)
- assert_equal("Hello! World!", func.call("World!"))
+ def test_bool
+ closure_class = Class.new(Closure) do
+ def call(bool)
+ not bool
+ end
+ end
+ closure_class.create(:bool, [:bool]) do |closure|
+ func = Function.new(closure, [:bool], :bool)
+ assert_equal(false, func.call(true))
+ end
+ end
+
+ def test_free
+ Closure.create(:int, [:void]) do |closure|
+ assert(!closure.freed?)
+ closure.free
+ assert(closure.freed?)
+ closure.free
+ end
end
def test_block_caller
cb = Closure::BlockCaller.new(TYPE_INT, [TYPE_INT]) do |one|
one
end
- func = Function.new(cb, [TYPE_INT], TYPE_INT)
- assert_equal 11, func.call(11)
+ begin
+ func = Function.new(cb, [TYPE_INT], TYPE_INT)
+ assert_equal 11, func.call(11)
+ ensure
+ cb.free
+ end
end
- def test_memsize
+ def test_memsize_ruby_dev_42480
require 'objspace'
- bug = '[ruby-dev:42480]'
n = 10000
- assert_equal(n, n.times {ObjectSpace.memsize_of(Closure.allocate)}, bug)
+ n.times do
+ Closure.create(:int, [:void]) do |closure|
+ ObjectSpace.memsize_of(closure)
+ end
+ end
end
%w[INT SHORT CHAR LONG LONG_LONG].each do |name|
@@ -89,20 +131,21 @@ module Fiddle
define_method("test_conversion_#{n.downcase}") do
arg = nil
- clos = Class.new(Closure) do
+ closure_class = Class.new(Closure) do
define_method(:call) {|x| arg = x}
- end.new(t, [t])
-
- v = ~(~0 << (8*s))
-
- arg = nil
- assert_equal(v, clos.call(v))
- assert_equal(arg, v, n)
-
- arg = nil
- func = Function.new(clos, [t], t)
- assert_equal(v, func.call(v))
- assert_equal(arg, v, n)
+ end
+ closure_class.create(t, [t]) do |closure|
+ v = ~(~0 << (8*s))
+
+ arg = nil
+ assert_equal(v, closure.call(v))
+ assert_equal(arg, v, n)
+
+ arg = nil
+ func = Function.new(closure, [t], t)
+ assert_equal(v, func.call(v))
+ assert_equal(arg, v, n)
+ end
end
end
end
diff --git a/test/fiddle/test_cparser.rb b/test/fiddle/test_cparser.rb
index ae319197a4..f1b67476ba 100644
--- a/test/fiddle/test_cparser.rb
+++ b/test/fiddle/test_cparser.rb
@@ -24,14 +24,32 @@ module Fiddle
assert_equal(TYPE_SHORT, parse_ctype('const short'))
assert_equal(TYPE_SHORT, parse_ctype('short int'))
assert_equal(TYPE_SHORT, parse_ctype('const short int'))
+ assert_equal(TYPE_SHORT, parse_ctype('int short'))
+ assert_equal(TYPE_SHORT, parse_ctype('const int short'))
assert_equal(TYPE_SHORT, parse_ctype('signed short'))
assert_equal(TYPE_SHORT, parse_ctype('const signed short'))
+ assert_equal(TYPE_SHORT, parse_ctype('short signed'))
+ assert_equal(TYPE_SHORT, parse_ctype('const short signed'))
assert_equal(TYPE_SHORT, parse_ctype('signed short int'))
assert_equal(TYPE_SHORT, parse_ctype('const signed short int'))
+ assert_equal(TYPE_SHORT, parse_ctype('signed int short'))
+ assert_equal(TYPE_SHORT, parse_ctype('const signed int short'))
+ assert_equal(TYPE_SHORT, parse_ctype('int signed short'))
+ assert_equal(TYPE_SHORT, parse_ctype('const int signed short'))
+ assert_equal(TYPE_SHORT, parse_ctype('int short signed'))
+ assert_equal(TYPE_SHORT, parse_ctype('const int short signed'))
assert_equal(-TYPE_SHORT, parse_ctype('unsigned short'))
assert_equal(-TYPE_SHORT, parse_ctype('const unsigned short'))
assert_equal(-TYPE_SHORT, parse_ctype('unsigned short int'))
assert_equal(-TYPE_SHORT, parse_ctype('const unsigned short int'))
+ assert_equal(-TYPE_SHORT, parse_ctype('unsigned int short'))
+ assert_equal(-TYPE_SHORT, parse_ctype('const unsigned int short'))
+ assert_equal(-TYPE_SHORT, parse_ctype('short int unsigned'))
+ assert_equal(-TYPE_SHORT, parse_ctype('const short int unsigned'))
+ assert_equal(-TYPE_SHORT, parse_ctype('int unsigned short'))
+ assert_equal(-TYPE_SHORT, parse_ctype('const int unsigned short'))
+ assert_equal(-TYPE_SHORT, parse_ctype('int short unsigned'))
+ assert_equal(-TYPE_SHORT, parse_ctype('const int short unsigned'))
end
def test_int_ctype
@@ -50,14 +68,32 @@ module Fiddle
assert_equal(TYPE_LONG, parse_ctype('const long'))
assert_equal(TYPE_LONG, parse_ctype('long int'))
assert_equal(TYPE_LONG, parse_ctype('const long int'))
+ assert_equal(TYPE_LONG, parse_ctype('int long'))
+ assert_equal(TYPE_LONG, parse_ctype('const int long'))
assert_equal(TYPE_LONG, parse_ctype('signed long'))
assert_equal(TYPE_LONG, parse_ctype('const signed long'))
assert_equal(TYPE_LONG, parse_ctype('signed long int'))
assert_equal(TYPE_LONG, parse_ctype('const signed long int'))
+ assert_equal(TYPE_LONG, parse_ctype('signed int long'))
+ assert_equal(TYPE_LONG, parse_ctype('const signed int long'))
+ assert_equal(TYPE_LONG, parse_ctype('long signed'))
+ assert_equal(TYPE_LONG, parse_ctype('const long signed'))
+ assert_equal(TYPE_LONG, parse_ctype('long int signed'))
+ assert_equal(TYPE_LONG, parse_ctype('const long int signed'))
+ assert_equal(TYPE_LONG, parse_ctype('int long signed'))
+ assert_equal(TYPE_LONG, parse_ctype('const int long signed'))
assert_equal(-TYPE_LONG, parse_ctype('unsigned long'))
assert_equal(-TYPE_LONG, parse_ctype('const unsigned long'))
assert_equal(-TYPE_LONG, parse_ctype('unsigned long int'))
assert_equal(-TYPE_LONG, parse_ctype('const unsigned long int'))
+ assert_equal(-TYPE_LONG, parse_ctype('long int unsigned'))
+ assert_equal(-TYPE_LONG, parse_ctype('const long int unsigned'))
+ assert_equal(-TYPE_LONG, parse_ctype('unsigned int long'))
+ assert_equal(-TYPE_LONG, parse_ctype('const unsigned int long'))
+ assert_equal(-TYPE_LONG, parse_ctype('int unsigned long'))
+ assert_equal(-TYPE_LONG, parse_ctype('const int unsigned long'))
+ assert_equal(-TYPE_LONG, parse_ctype('int long unsigned'))
+ assert_equal(-TYPE_LONG, parse_ctype('const int long unsigned'))
end
def test_size_t_ctype
@@ -85,6 +121,10 @@ module Fiddle
assert_equal(TYPE_UINTPTR_T, parse_ctype("const uintptr_t"))
end
+ def test_bool_ctype
+ assert_equal(TYPE_BOOL, parse_ctype('bool'))
+ end
+
def test_undefined_ctype
assert_raise(DLError) { parse_ctype('DWORD') }
end
diff --git a/test/fiddle/test_fiddle.rb b/test/fiddle/test_fiddle.rb
index 8751d96920..9bddb056c9 100644
--- a/test/fiddle/test_fiddle.rb
+++ b/test/fiddle/test_fiddle.rb
@@ -5,6 +5,13 @@ rescue LoadError
end
class TestFiddle < Fiddle::TestCase
+ def test_nil_true_etc
+ assert_equal Fiddle::Qtrue, Fiddle.dlwrap(true)
+ assert_equal Fiddle::Qfalse, Fiddle.dlwrap(false)
+ assert_equal Fiddle::Qnil, Fiddle.dlwrap(nil)
+ assert Fiddle::Qundef
+ end
+
def test_windows_constant
require 'rbconfig'
if RbConfig::CONFIG['host_os'] =~ /mswin|mingw/
@@ -14,4 +21,38 @@ class TestFiddle < Fiddle::TestCase
end
end
+ def test_dlopen_linker_script_input_linux
+ omit("This is only for Linux") unless RUBY_PLATFORM.match?("linux")
+ if Dir.glob("/usr/lib/*/libncurses.so").empty?
+ omit("libncurses.so is needed")
+ end
+ # libncurses.so uses INPUT() on Debian GNU/Linux
+ # $ cat /usr/lib/x86_64-linux-gnu/libncurses.so
+ # INPUT(libncurses.so.6 -ltinfo)
+ handle = Fiddle.dlopen("libncurses.so")
+ begin
+ assert_equal("libncurses.so",
+ File.basename(handle.file_name, ".*"))
+ ensure
+ handle.close
+ end
+ end
+
+ def test_dlopen_linker_script_group_linux
+ omit("This is only for Linux") unless RUBY_PLATFORM.match?("linux")
+ # libc.so uses GROUP() on Debian GNU/Linux
+ # $ cat /usr/lib/x86_64-linux-gnu/libc.so
+ # /* GNU ld script
+ # Use the shared library, but some functions are only in
+ # the static library, so try that secondarily. */
+ # OUTPUT_FORMAT(elf64-x86-64)
+ # GROUP ( /lib/x86_64-linux-gnu/libc.so.6 /usr/lib/x86_64-linux-gnu/libc_nonshared.a AS_NEEDED ( /lib64/ld-linux-x86-64.so.2 ) )
+ handle = Fiddle.dlopen("libc.so")
+ begin
+ assert_equal("libc.so",
+ File.basename(handle.file_name, ".*"))
+ ensure
+ handle.close
+ end
+ end
end if defined?(Fiddle)
diff --git a/test/fiddle/test_func.rb b/test/fiddle/test_func.rb
index 44893017e8..df79539e76 100644
--- a/test/fiddle/test_func.rb
+++ b/test/fiddle/test_func.rb
@@ -60,25 +60,35 @@ module Fiddle
end
def test_qsort1
- cb = Class.new(Closure) {
+ closure_class = Class.new(Closure) do
def call(x, y)
Pointer.new(x)[0] <=> Pointer.new(y)[0]
end
- }.new(TYPE_INT, [TYPE_VOIDP, TYPE_VOIDP])
+ end
- qsort = Function.new(@libc['qsort'],
- [TYPE_VOIDP, TYPE_SIZE_T, TYPE_SIZE_T, TYPE_VOIDP],
- TYPE_VOID)
- buff = "9341"
- qsort.call(buff, buff.size, 1, cb)
- assert_equal("1349", buff)
+ closure_class.create(TYPE_INT, [TYPE_VOIDP, TYPE_VOIDP]) do |callback|
+ qsort = Function.new(@libc['qsort'],
+ [TYPE_VOIDP, TYPE_SIZE_T, TYPE_SIZE_T, TYPE_VOIDP],
+ TYPE_VOID)
+ buff = "9341"
+ qsort.call(buff, buff.size, 1, callback)
+ assert_equal("1349", buff)
- bug4929 = '[ruby-core:37395]'
- buff = "9341"
- under_gc_stress do
- qsort.call(buff, buff.size, 1, cb)
+ bug4929 = '[ruby-core:37395]'
+ buff = "9341"
+ under_gc_stress do
+ qsort.call(buff, buff.size, 1, callback)
+ end
+ assert_equal("1349", buff, bug4929)
+ end
+ ensure
+ # Ensure freeing all closures.
+ # See https://github.com/ruby/fiddle/issues/102#issuecomment-1241763091 .
+ not_freed_closures = []
+ ObjectSpace.each_object(Fiddle::Closure) do |closure|
+ not_freed_closures << closure unless closure.freed?
end
- assert_equal("1349", buff, bug4929)
+ assert_equal([], not_freed_closures)
end
def test_snprintf
@@ -135,5 +145,22 @@ module Fiddle
assert_equal("string: He, const string: World, uint: 29\n",
output_buffer[0, written])
end
+
+ def test_rb_memory_view_available_p
+ omit "MemoryView is unavailable" unless defined? Fiddle::MemoryView
+ libruby = Fiddle.dlopen(nil)
+ case Fiddle::SIZEOF_VOIDP
+ when Fiddle::SIZEOF_LONG_LONG
+ value_type = -Fiddle::TYPE_LONG_LONG
+ else
+ value_type = -Fiddle::TYPE_LONG
+ end
+ rb_memory_view_available_p =
+ Function.new(libruby["rb_memory_view_available_p"],
+ [value_type],
+ :bool,
+ need_gvl: true)
+ assert_equal(false, rb_memory_view_available_p.call(Fiddle::Qnil))
+ end
end
end if defined?(Fiddle)
diff --git a/test/fiddle/test_function.rb b/test/fiddle/test_function.rb
index 8ac4f60aa3..847df3793a 100644
--- a/test/fiddle/test_function.rb
+++ b/test/fiddle/test_function.rb
@@ -15,6 +15,16 @@ module Fiddle
end
end
+ def teardown
+ # Ensure freeing all closures.
+ # See https://github.com/ruby/fiddle/issues/102#issuecomment-1241763091 .
+ not_freed_closures = []
+ ObjectSpace.each_object(Fiddle::Closure) do |closure|
+ not_freed_closures << closure unless closure.freed?
+ end
+ assert_equal([], not_freed_closures)
+ end
+
def test_default_abi
func = Function.new(@libm['sin'], [TYPE_DOUBLE], TYPE_DOUBLE)
assert_equal Function::DEFAULT, func.abi
@@ -75,18 +85,20 @@ module Fiddle
end
def test_argument_count
- closure = Class.new(Closure) {
+ closure_class = Class.new(Closure) do
def call one
10 + one
end
- }.new(TYPE_INT, [TYPE_INT])
- func = Function.new(closure, [TYPE_INT], TYPE_INT)
-
- assert_raise(ArgumentError) do
- func.call(1,2,3)
end
- assert_raise(ArgumentError) do
- func.call
+ closure_class.create(TYPE_INT, [TYPE_INT]) do |closure|
+ func = Function.new(closure, [TYPE_INT], TYPE_INT)
+
+ assert_raise(ArgumentError) do
+ func.call(1,2,3)
+ end
+ assert_raise(ArgumentError) do
+ func.call
+ end
end
end
diff --git a/test/fiddle/test_handle.rb b/test/fiddle/test_handle.rb
index 7e3ff9d844..412c10e09d 100644
--- a/test/fiddle/test_handle.rb
+++ b/test/fiddle/test_handle.rb
@@ -22,12 +22,14 @@ module Fiddle
def test_static_sym_unknown
assert_raise(DLError) { Fiddle::Handle.sym('fooo') }
assert_raise(DLError) { Fiddle::Handle['fooo'] }
+ refute Fiddle::Handle.sym_defined?('fooo')
end
def test_static_sym
begin
# Linux / Darwin / FreeBSD
refute_nil Fiddle::Handle.sym('dlopen')
+ assert Fiddle::Handle.sym_defined?('dlopen')
assert_equal Fiddle::Handle.sym('dlopen'), Fiddle::Handle['dlopen']
return
rescue
@@ -54,6 +56,7 @@ module Fiddle
handle = Fiddle::Handle.new(LIBC_SO)
assert_raise(DLError) { handle.sym('fooo') }
assert_raise(DLError) { handle['fooo'] }
+ refute handle.sym_defined?('fooo')
end
def test_sym_with_bad_args
@@ -66,6 +69,7 @@ module Fiddle
handle = Handle.new(LIBC_SO)
refute_nil handle.sym('calloc')
refute_nil handle['calloc']
+ assert handle.sym_defined?('calloc')
end
def test_handle_close
@@ -179,12 +183,18 @@ module Fiddle
# it calls _nss_cache_cycle_prevention_function with dlsym(3).
# So our Fiddle::Handle#sym must call dlerror(3) before call dlsym.
# In general uses of dlerror(3) should call it before use it.
+ verbose, $VERBOSE = $VERBOSE, nil
require 'socket'
Socket.gethostbyname("localhost")
Fiddle.dlopen("/lib/libc.so.7").sym('strcpy')
+ ensure
+ $VERBOSE = verbose
end if /freebsd/=~ RUBY_PLATFORM
def test_no_memory_leak
+ # https://github.com/ruby/fiddle/actions/runs/3202406059/jobs/5231356410
+ omit if RUBY_VERSION >= '3.2'
+
if respond_to?(:assert_nothing_leaked_memory)
n_tries = 100_000
assert_nothing_leaked_memory(SIZEOF_VOIDP * (n_tries / 100)) do
diff --git a/test/fiddle/test_import.rb b/test/fiddle/test_import.rb
index afa8df9e00..090ace620d 100644
--- a/test/fiddle/test_import.rb
+++ b/test/fiddle/test_import.rb
@@ -22,7 +22,6 @@ module Fiddle
extern "int fprintf(FILE*, char*)" rescue nil
extern "int gettimeofday(timeval*, timezone*)" rescue nil
- BoundQsortCallback = bind("void *bound_qsort_callback(void*, void*)"){|ptr1,ptr2| ptr1[0] <=> ptr2[0]}
Timeval = struct [
"long tv_sec",
"long tv_usec",
@@ -59,11 +58,6 @@ module Fiddle
]
}
]
-
- CallCallback = bind("void call_callback(void*, void*)"){ | ptr1, ptr2|
- f = Function.new(ptr1.to_i, [TYPE_VOIDP], TYPE_VOID)
- f.call(ptr2)
- }
end
class TestImport < TestCase
@@ -130,11 +124,28 @@ module Fiddle
name = $1.sub(/P\z/,"*").gsub(/_(?!T\z)/, " ").downcase
type_name = name
end
+ type_name = "unsigned #{$1}" if type_name =~ /\Au(long|short|char|int|long long)\z/
+
define_method("test_sizeof_#{name}") do
assert_equal(size, Fiddle::Importer.sizeof(type_name), type)
end
end
+ # Assert that the unsigned constants are equal to the "negative" signed ones
+ # for backwards compatibility
+ def test_unsigned_equals_negative_signed
+ Fiddle.constants.grep(/\ATYPE_(?!VOID|VARIADIC\z)(U.*)/) do |unsigned|
+ assert_equal(-Fiddle.const_get(unsigned.to_s.sub(/U/, '')),
+ Fiddle.const_get(unsigned))
+ end
+ end
+
+ def test_type_constants
+ Fiddle::Types.constants.each do |const|
+ assert_equal Fiddle::Types.const_get(const), Fiddle.const_get("TYPE_#{const}")
+ end
+ end
+
def test_unsigned_result()
d = (2 ** 31) + 1
diff --git a/test/fiddle/test_pack.rb b/test/fiddle/test_pack.rb
new file mode 100644
index 0000000000..ade1dd5040
--- /dev/null
+++ b/test/fiddle/test_pack.rb
@@ -0,0 +1,37 @@
+begin
+ require_relative 'helper'
+ require 'fiddle/pack'
+rescue LoadError
+ return
+end
+
+module Fiddle
+ class TestPack < TestCase
+ def test_pack_map
+ if defined?(TYPE_LONG_LONG)
+ assert_equal [0xffff_ffff_ffff_ffff], [0xffff_ffff_ffff_ffff].pack(PackInfo::PACK_MAP[-TYPE_LONG_LONG]).unpack(PackInfo::PACK_MAP[-TYPE_LONG_LONG])
+ end
+
+ case Fiddle::SIZEOF_VOIDP
+ when 8
+ assert_equal [0xffff_ffff_ffff_ffff], [0xffff_ffff_ffff_ffff].pack(PackInfo::PACK_MAP[TYPE_VOIDP]).unpack(PackInfo::PACK_MAP[TYPE_VOIDP])
+ when 4
+ assert_equal [0xffff_ffff], [0xffff_ffff].pack(PackInfo::PACK_MAP[TYPE_VOIDP]).unpack(PackInfo::PACK_MAP[TYPE_VOIDP])
+ end
+
+ case Fiddle::SIZEOF_LONG
+ when 8
+ assert_equal [0xffff_ffff_ffff_ffff], [0xffff_ffff_ffff_ffff].pack(PackInfo::PACK_MAP[-TYPE_LONG]).unpack(PackInfo::PACK_MAP[-TYPE_LONG])
+ when 4
+ assert_equal [0xffff_ffff], [0xffff_ffff].pack(PackInfo::PACK_MAP[-TYPE_LONG]).unpack(PackInfo::PACK_MAP[-TYPE_LONG])
+ end
+
+ if Fiddle::SIZEOF_INT == 4
+ assert_equal [0xffff_ffff], [0xffff_ffff].pack(PackInfo::PACK_MAP[-TYPE_INT]).unpack(PackInfo::PACK_MAP[-TYPE_INT])
+ end
+
+ assert_equal [0xffff], [0xffff].pack(PackInfo::PACK_MAP[-TYPE_SHORT]).unpack(PackInfo::PACK_MAP[-TYPE_SHORT])
+ assert_equal [0xff], [0xff].pack(PackInfo::PACK_MAP[-TYPE_CHAR]).unpack(PackInfo::PACK_MAP[-TYPE_CHAR])
+ end
+ end
+end
diff --git a/test/fiddle/test_pointer.rb b/test/fiddle/test_pointer.rb
index 7d708ee417..f2c1d285ad 100644
--- a/test/fiddle/test_pointer.rb
+++ b/test/fiddle/test_pointer.rb
@@ -10,6 +10,22 @@ module Fiddle
Fiddle.dlwrap arg
end
+ def test_can_read_write_memory
+ # Allocate some memory
+ address = Fiddle.malloc(Fiddle::SIZEOF_VOIDP)
+
+ bytes_to_write = Fiddle::SIZEOF_VOIDP.times.to_a.pack("C*")
+
+ # Write to the memory
+ Fiddle::Pointer.write(address, bytes_to_write)
+
+ # Read the bytes out again
+ bytes = Fiddle::Pointer.read(address, Fiddle::SIZEOF_VOIDP)
+ assert_equal bytes_to_write, bytes
+ ensure
+ Fiddle.free address
+ end
+
def test_cptr_to_int
null = Fiddle::NULL
assert_equal(null.to_i, null.to_int)
@@ -272,6 +288,9 @@ module Fiddle
end
def test_no_memory_leak
+ # https://github.com/ruby/fiddle/actions/runs/3202406059/jobs/5231356410
+ omit if RUBY_VERSION >= '3.2'
+
if respond_to?(:assert_nothing_leaked_memory)
n_tries = 100_000
assert_nothing_leaked_memory(SIZEOF_VOIDP * (n_tries / 100)) do