diff --git a/Library/Homebrew/test/os/linux/pathname_spec.rb b/Library/Homebrew/test/os/linux/pathname_spec.rb index d0281ddcdd..7e4126585a 100644 --- a/Library/Homebrew/test/os/linux/pathname_spec.rb +++ b/Library/Homebrew/test/os/linux/pathname_spec.rb @@ -4,19 +4,96 @@ require "extend/pathname" describe Pathname do let(:elf_dir) { described_class.new "#{TEST_FIXTURE_DIR}/elf" } - let(:sho) { elf_dir/"libhello.so.0" } - let(:exec) { elf_dir/"hello" } + let(:sho) { elf_dir/"libforty.so.0" } + let(:sho_without_runpath_rpath) { elf_dir/"libhello.so.0" } + let(:exec) { elf_dir/"hello_with_rpath" } + + def patch_elfs + mktmpdir do |tmp_dir| + %w[c.elf].each do |elf| + FileUtils.cp(elf_dir/elf, tmp_dir/elf) + yield tmp_dir/elf + end + end + end describe "#interpreter" do it "returns interpreter" do expect(exec.interpreter).to eq "/lib64/ld-linux-x86-64.so.2" end + + it "returns nil when absent" do + expect(sho.interpreter).to be_nil + end end describe "#rpath" do + it "prefers runpath over rpath when both are present" do + expect(sho.rpath).to eq "runpath" + end + + it "returns runpath or rpath" do + expect(exec.rpath).to eq "@@HOMEBREW_PREFIX@@/lib" + end + it "returns nil when absent" do - expect(exec.rpath).to be_nil - expect(sho.rpath).to be_nil + expect(sho_without_runpath_rpath.rpath).to be_nil + end + end + + describe "#patch!" do + # testing only patchelf.rb as HOMEBREW_PREFIX is different for tests, + # and DevelopmentTools.locate fails to locate patchelf + HOMEBREW_PATCHELF_RB_WRITE = true + + let(:placeholder_prefix) { "@@HOMEBREW_PREFIX@@" } + let(:short_prefix) { "/home/dwarf" } + let(:standard_prefix) { "/home/linuxbrew/.linuxbrew" } + let(:long_prefix) { "/home/organized/very organized/litter/more organized than/your words can describe" } + let(:prefixes) { [short_prefix, standard_prefix, long_prefix] } + + # file is copied as modified_elf to avoid caching issues + it "only interpreter" do + prefixes.each do |new_prefix| + patch_elfs do |elf| + interpreter = elf.interpreter.gsub(placeholder_prefix, new_prefix) + elf.patch!(interpreter: interpreter) + + modified_elf = elf.dirname/"mod.#{elf.basename}" + FileUtils.cp(elf, modified_elf) + expect(modified_elf.interpreter).to eq interpreter + expect(modified_elf.rpath).to eq "@@HOMEBREW_PREFIX@@/lib" + end + end + end + + it "only rpath" do + prefixes.each do |new_prefix| + patch_elfs do |elf| + rpath = elf.rpath.gsub(placeholder_prefix, new_prefix) + elf.patch!(rpath: rpath) + + modified_elf = elf.dirname/"mod.#{elf.basename}" + FileUtils.cp(elf, modified_elf) + expect(modified_elf.interpreter).to eq "@@HOMEBREW_PREFIX@@/lib/ld.so" + expect(modified_elf.rpath).to eq rpath + end + end + end + + it "both" do + prefixes.each do |new_prefix| + patch_elfs do |elf| + interpreter = elf.interpreter.gsub(placeholder_prefix, new_prefix) + rpath = elf.rpath.gsub(placeholder_prefix, new_prefix) + elf.patch!(interpreter: interpreter, rpath: rpath) + + modified_elf = elf.dirname/"mod.#{elf.basename}" + FileUtils.cp(elf, modified_elf) + expect(modified_elf.interpreter).to eq interpreter + expect(modified_elf.rpath).to eq rpath + end + end end end end diff --git a/Library/Homebrew/test/support/fixtures/elf/c.elf b/Library/Homebrew/test/support/fixtures/elf/c.elf new file mode 100755 index 0000000000..323684c96e Binary files /dev/null and b/Library/Homebrew/test/support/fixtures/elf/c.elf differ diff --git a/Library/Homebrew/test/support/fixtures/elf/hello_with_rpath b/Library/Homebrew/test/support/fixtures/elf/hello_with_rpath new file mode 100755 index 0000000000..8a409bd747 Binary files /dev/null and b/Library/Homebrew/test/support/fixtures/elf/hello_with_rpath differ diff --git a/Library/Homebrew/test/support/fixtures/elf/libforty.so.0 b/Library/Homebrew/test/support/fixtures/elf/libforty.so.0 new file mode 100755 index 0000000000..e6c795d841 Binary files /dev/null and b/Library/Homebrew/test/support/fixtures/elf/libforty.so.0 differ