# frozen_string_literal: true require "extend/pathname" RSpec.describe Pathname do let(:elf_dir) { described_class.new "#{TEST_FIXTURE_DIR}/elf" } 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(sho_without_runpath_rpath.rpath).to be_nil end end describe "#patch!" do 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:) 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:) 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:, 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