summaryrefslogtreecommitdiff
path: root/test
diff options
context:
space:
mode:
authorPeter Zhu <peter@peterzhu.ca>2022-02-18 10:59:45 -0500
committerPeter Zhu <peter@peterzhu.ca>2022-02-22 09:55:21 -0500
commit3df16924b45adfd88c20ef5fe25b10a1acb82dd7 (patch)
treeb943497ee6802001a6cd06de1e51470c0f920dad /test
parent37d5890e4941cedf6918821b29bb4a7e3a092e62 (diff)
[Feature #18249] Implement ABI checking
Header file include/ruby/internal/abi.h contains RUBY_ABI_VERSION which is the ABI version. This value should be bumped whenever an ABI incompatible change is introduced. When loading dynamic libraries, Ruby will compare its own `ruby_abi_version` and the `ruby_abi_version` of the loaded library. If these two values don't match it will raise a `LoadError`. This feature can also be turned off by setting the environment variable `RUBY_RUBY_ABI_CHECK=0`. This feature will prevent cases where previously installed native gems fail in unexpected ways due to incompatibility of changes in header files. This will force the developer to recompile their gems to use the same header files as the built Ruby. In Ruby, the ABI version is exposed through `RbConfig::CONFIG["ruby_abi_version"]`.
Notes
Notes: Merged: https://github.com/ruby/ruby/pull/5474
Diffstat (limited to 'test')
-rw-r--r--test/-ext-/test_abi.rb43
1 files changed, 43 insertions, 0 deletions
diff --git a/test/-ext-/test_abi.rb b/test/-ext-/test_abi.rb
new file mode 100644
index 0000000000..ec2050ecad
--- /dev/null
+++ b/test/-ext-/test_abi.rb
@@ -0,0 +1,43 @@
+# frozen_string_literal: true
+
+class TestABI < Test::Unit::TestCase
+ def test_require_lib_with_incorrect_abi_on_dev_ruby
+ omit "ABI is not checked" unless abi_checking_supported?
+
+ assert_separately [], <<~RUBY
+ err = assert_raise(LoadError) { require "-test-/abi" }
+ assert_match(/ABI version of binary is incompatible with this Ruby/, err.message)
+ RUBY
+ end
+
+ def test_disable_abi_check_using_environment_variable
+ omit "ABI is not checked" unless abi_checking_supported?
+
+ assert_separately [{ "RUBY_ABI_CHECK" => "0" }], <<~RUBY
+ assert_nothing_raised { require "-test-/abi" }
+ RUBY
+ end
+
+ def test_enable_abi_check_using_environment_variable
+ omit "ABI is not checked" unless abi_checking_supported?
+
+ assert_separately [{ "RUBY_ABI_CHECK" => "1" }], <<~RUBY
+ err = assert_raise(LoadError) { require "-test-/abi" }
+ assert_match(/ABI version of binary is incompatible with this Ruby/, err.message)
+ RUBY
+ end
+
+ def test_require_lib_with_incorrect_abi_on_release_ruby
+ omit "ABI is enforced" if abi_checking_supported?
+
+ assert_separately [], <<~RUBY
+ assert_nothing_raised { require "-test-/abi" }
+ RUBY
+ end
+
+ private
+
+ def abi_checking_supported?
+ !(RUBY_PLATFORM =~ /mswin|mingw/)
+ end
+end