Validating RPM Package Generation Workflow in jordansissel/fpm
This test suite validates the RPM package generation functionality in the FPM (Effing Package Management) library. It verifies core RPM package attributes, metadata handling, file permissions, and script integration to ensure reliable package building across different platforms.
Test Coverage Overview
Implementation Analysis
Technical Details
Best Practices Demonstrated
jordansissel/fpm
spec/fpm/package/rpm_spec.rb
require "spec_setup"
require "fpm" # local
require "fpm/package/rpm" # local
require "fpm/package/dir" # local
require "arr-pm/file" # gem 'arr-pm'
require "stud/temporary" # gem 'stud'
if !program_exists?("rpmbuild")
Cabin::Channel.get("rspec") \
.warn("Skipping RPM#output tests because 'rpmbuild' isn't in your PATH")
end
describe FPM::Package::RPM do
after :each do
subject.cleanup
end
describe "#architecture" do
it "should convert amd64 to x86_64" do
subject.architecture = "amd64"
insist { subject.architecture } == "x86_64"
end
it "should convert arm64 to aarch64" do
subject.architecture = "arm64"
expect(subject.architecture).to(be == "aarch64")
end
it "should convert 'all' to 'noarch'" do
subject.architecture = "all"
insist { subject.architecture } == "noarch"
end
it "should default to native" do
expected = %x{uname -m}.chomp
insist { subject.instance_eval { @architecture } } == "native"
insist { subject.architecture } == expected
end
end
describe "#iteration" do
it "should default to 1" do
insist { subject.iteration } == 1
end
end
describe "#summary" do
it "should default to description" do
expected = subject.description
insist { subject.summary } == expected
end
it "should return description override" do
subject.attributes[:rpm_summary] = "a summary"
expected = subject.description
insist { subject.summary } != expected
end
end
describe "#epoch" do
it "should default to empty" do
insist { subject.epoch.to_s } == ""
end
it "should cope with it being zero" do
subject.epoch = 0
insist { subject.epoch.to_s } == "0"
end
end
describe "#to_s" do
it "should have a default output usable as a filename" do
subject.name = "name"
subject.version = "123"
subject.architecture = "all"
subject.iteration = "100"
subject.epoch = "5"
# This is the default filename I see commonly output by rpmbuild
insist { subject.to_s } == "name-123-100.noarch.rpm"
end
it "should include the dist when specified" do
subject.name = "name"
subject.version = "123"
subject.architecture = "all"
subject.iteration = "100"
subject.epoch = "5"
insist { subject.to_s } == "name-123-100.noarch.rpm"
subject.attributes[:rpm_dist] = "el6"
insist { subject.to_s } == "name-123-100.el6.noarch.rpm"
end
end
describe "#templating" do
context "default user and group" do
before :each do
FileUtils.mkdir_p(subject.staging_path(File.dirname(__FILE__)))
FileUtils.cp(__FILE__, subject.staging_path(__FILE__))
# set the list of files for this RPM
def subject.files; [__FILE__]; end
def subject.rpmspec; @rpmspec; end
def subject.render_template; @rpmspec = template("rpm.erb").result(binding); end
subject.render_template
end
after :each do
subject.cleanup
end
it "should set the user and group of each file in the RPM" do
expect(subject.rpmspec).to include('%defattr(-,root,root,-')
end
end # context
context "non-default user and group" do
before :each do
subject.attributes[:rpm_user] = "some_user"
subject.attributes[:rpm_group] = "some_group"
FileUtils.mkdir_p(subject.staging_path(File.dirname(__FILE__)))
FileUtils.cp(__FILE__, subject.staging_path(__FILE__))
# set the list of files for this RPM
def subject.files; [__FILE__]; end
def subject.rpmspec; @rpmspec; end
def subject.render_template; @rpmspec = template("rpm.erb").result(binding); end
subject.render_template
end
after :each do
subject.cleanup
end
it "should set the user and group of each file in the RPM" do
expect(subject.rpmspec).to include('%defattr(-,some_user,some_group,-')
end
end # context
end
describe "#output" do
before do
skip("Missing rpmbuild program") unless program_exists?("rpmbuild")
end
context "architecture" do
it "can be basically anything" do
subject.name = "example"
subject.architecture = "fancypants"
subject.version = "1.0"
target = Stud::Temporary.pathname
# Should not fail.
subject.output(target)
# Verify the arch tag.
rpm = ::RPM::File.new(target)
insist { rpm.tags[:arch] } == subject.architecture
File.unlink(target)
end
end
context "with slight corrections" do
context "on the version attribute" do
it "should replace dash(-) with underscore(_)" do
subject.version = "123-456"
insist { subject.version } == "123_456"
end
end
context "on the iteration attribute" do
# Found in https://github.com/electron-userland/electron-builder/issues/5976
it "should replace dash(-) with underscore(_)" do
subject.iteration = "123-456"
insist { subject.iteration } == "123_456"
end
end
end
context "package attributes" do
before :each do
@target = Stud::Temporary.pathname
subject.name = "name"
subject.version = "123"
subject.architecture = "all"
subject.iteration = "100"
subject.epoch = "5"
subject.dependencies << "something > 10"
subject.dependencies << "hello >= 20"
subject.conflicts << "bad < 2"
subject.attributes[:rpm_os] = "fancypants"
subject.attributes[:rpm_summary] = "fancypants"
# Make sure multi-line licenses are hacked to work in rpm (#252)
subject.license = "this\nis\nan\example"
subject.provides << "bacon = 1.0"
# TODO(sissel): This api sucks, yo.
subject.scripts[:before_install] = "example before_install"
subject.scripts[:after_install] = "example after_install"
subject.scripts[:before_remove] = "example before_remove"
subject.scripts[:after_remove] = "example after_remove"
subject.scripts[:rpm_verifyscript] = "example rpm_verifyscript"
subject.scripts[:rpm_posttrans] = "example rpm_posttrans"
subject.scripts[:rpm_pretrans] = "example rpm_pretrans"
# Test for triggers #626
subject.attributes[:rpm_trigger_before_install] = [["test","#!/bin/sh\necho before_install trigger executed\n"]]
subject.attributes[:rpm_trigger_after_install] = [["test","#!/bin/sh\necho after_install trigger executed\n"]]
subject.attributes[:rpm_trigger_before_uninstall] = [["test","#!/bin/sh\necho before_uninstall trigger executed\n"]]
subject.attributes[:rpm_trigger_after_target_uninstall] = [["test","#!/bin/sh\necho after_target_uninstall trigger executed\n"]]
# Write the rpm out
subject.output(@target)
# Read the rpm
@rpm = ::RPM::File.new(@target)
@rpmtags = {}
@rpm.header.tags.each do |tag|
@rpmtags[tag.tag] = tag.value
end
end # before :each
after :each do
subject.cleanup
File.delete(@target)
end # after :each
it "should have the correct name" do
insist { @rpmtags[:name] } == subject.name
end
it "should obey the os attribute" do
insist { @rpmtags[:os] } == subject.attributes[:rpm_os]
end
it "should have a different summary and description" do
insist { @rpmtags[:summary] } == subject.summary
insist { @rpmtags[:summary] } != subject.description
end
it "should have the correct version" do
insist { @rpmtags[:version] } == subject.version
end
it "should have the correct iteration" do
insist { @rpmtags[:release] } == subject.iteration
end
it "should have the correct epoch" do
insist { @rpmtags[:epoch].first.to_s } == subject.epoch
end
it "should output a package with the correct dependencies" do
# @rpm.requires is an array of [name, op, requires] elements
# fpm uses strings here, so convert.
requires = @rpm.requires.collect { |a| a.join(" ") }
subject.dependencies.each do |dep|
insist { requires }.include?(dep)
end
end
it "should output a package with the correct conflicts" do
# @rpm.requires is an array of [name, op, requires] elements
# fpm uses strings here, so convert.
conflicts = @rpm.conflicts.collect { |a| a.join(" ") }
subject.conflicts.each do |dep|
insist { conflicts }.include?(dep)
end
end
it "should output a package with the correct provides" do
# @rpm.requires is an array of [name, op, requires] elements
# fpm uses strings here, so convert.
provides = @rpm.provides.collect { |a| a.join(" ") }
subject.provides.each do |dep|
insist { provides }.include?(dep)
end
end
it "should replace newlines with spaces in the license field (issue#252)" do
insist { @rpm.tags[:license] } == subject.license.split("\n").join(" ")
end
it "should have the correct 'preun' script" do
insist { @rpm.tags[:preun] } == "example before_remove"
insist { @rpm.tags[:preunprog] } == "/bin/sh"
end
it "should have the correct 'postun' script" do
insist { @rpm.tags[:postun] } == "example after_remove"
insist { @rpm.tags[:postunprog] } == "/bin/sh"
end
it "should have the correct 'verify' script" do
insist { @rpm.tags[:verifyscript] } == "example rpm_verifyscript"
insist { @rpm.tags[:verifyscriptprog] } == "/bin/sh"
end
it "should have the correct 'pretrans' script" do
insist { @rpm.tags[:pretrans] } == "example rpm_pretrans"
insist { @rpm.tags[:pretransprog] } == "/bin/sh"
end
it "should have the correct 'posttrans' script" do
insist { @rpm.tags[:posttrans] } == "example rpm_posttrans"
insist { @rpm.tags[:posttransprog] } == "/bin/sh"
end
it "should have the correct 'prein' script" do
insist { @rpm.tags[:prein] } == "example before_install"
insist { @rpm.tags[:preinprog] } == "/bin/sh"
end
it "should have the correct 'postin' script" do
insist { @rpm.tags[:postin] } == "example after_install"
insist { @rpm.tags[:postinprog] } == "/bin/sh"
end
it "should have the correct 'before_install' trigger script" do
insist { @rpm.tags[:triggername][0] } == "test"
insist { @rpm.tags[:triggerversion][0] } == ""
# This specific check is broken in newer versions of rpm/rpmbuild? -Jordan
#insist { @rpm.tags[:triggerflags][0] & (1 << 25)} == ( 1 << 25) # See FPM::Package::RPM#rpm_get_trigger_type
#insist { @rpm.tags[:triggerindex][0] } == 0
insist { @rpm.tags[:triggerscriptprog][0] } == "/bin/sh"
insist { @rpm.tags[:triggerscripts][0] } == "#!/bin/sh\necho before_install trigger executed"
end
it "should have the correct 'after_install' trigger script" do
insist { @rpm.tags[:triggername][1] } == "test"
insist { @rpm.tags[:triggerversion][1] } == ""
# This specific check is broken in newer versions of rpm/rpmbuild? -Jordan
#insist { @rpm.tags[:triggerflags][1] & (1 << 16)} == ( 1 << 16) # See FPM::Package::RPM#rpm_get_trigger_type
#insist { @rpm.tags[:triggerindex][1] } == 1
insist { @rpm.tags[:triggerscriptprog][1] } == "/bin/sh"
insist { @rpm.tags[:triggerscripts][1] } == "#!/bin/sh\necho after_install trigger executed"
end
it "should have the correct 'before_uninstall' trigger script" do
insist { @rpm.tags[:triggername][2] } == "test"
insist { @rpm.tags[:triggerversion][2] } == ""
# This specific check is broken in newer versions of rpm/rpmbuild? -Jordan
#insist { @rpm.tags[:triggerflags][2] & (1 << 17)} == ( 1 << 17) # See FPM::Package::RPM#rpm_get_trigger_type
#insist { @rpm.tags[:triggerindex][2] } == 2
insist { @rpm.tags[:triggerscriptprog][2] } == "/bin/sh"
insist { @rpm.tags[:triggerscripts][2] } == "#!/bin/sh\necho before_uninstall trigger executed"
end
it "should have the correct 'after_target_uninstall' trigger script" do
insist { @rpm.tags[:triggername][3] } == "test"
insist { @rpm.tags[:triggerversion][3] } == ""
# This specific check is broken in newer versions of rpm/rpmbuild? -Jordan
#insist { @rpm.tags[:triggerflags][3] & (1 << 18)} == ( 1 << 18) # See FPM::Package::RPM#rpm_get_trigger_type
#insist { @rpm.tags[:triggerindex][3] } == 3
insist { @rpm.tags[:triggerscriptprog][3] } == "/bin/sh"
insist { @rpm.tags[:triggerscripts][3] } == "#!/bin/sh\necho after_target_uninstall trigger executed"
end
it "should use md5/gzip by default" do
insist { @rpmtags[:payloadcompressor] } == "gzip"
# For whatever reason, the 'filedigestalgo' tag is an array of numbers.
# I only ever see one element in this array, so just do value.first
#
# Even though you can specify a file digest algorithm of md5, not
# specifying one at all is also valid in the RPM file itself,
# and not having one at all means md5. So accept 'nil' or the digest
# identifier for md5 (1).
insist { [nil, FPM::Package::RPM::DIGEST_ALGORITHM_MAP["md5"]] } \
.include?((@rpmtags[:filedigestalgo].first rescue nil))
end
end # package attributes
context "package default attributes" do
before :each do
@target = Stud::Temporary.pathname
subject.name = "name"
subject.version = "123"
# Write the rpm out
subject.output(@target)
# Read the rpm
@rpm = ::RPM::File.new(@target)
@rpmtags = {}
@rpm.header.tags.each do |tag|
@rpmtags[tag.tag] = tag.value
end
end # before :each
after :each do
subject.cleanup
File.delete(@target)
end # after :each
it "should have the correct name" do
insist { @rpmtags[:name] } == subject.name
end
# I don't know the 'os' values for any other OS.
it "should have a default OS value" do
os = `uname -s`.chomp.downcase
# The 'os' tag will be set to \x01 if the package 'target'
# was set incorrectly.
reject { @rpmtags[:os] } == "\x01"
insist { @rpmtags[:os] } == os
insist { `rpm -q --qf '%{OS}' -p #{@target}`.chomp } == os
end
it "should have the correct version" do
insist { @rpmtags[:version] } == subject.version
end
it "should have the default iteration" do
insist { @rpmtags[:release].to_s } == "1"
end
#it "should have the correct epoch" do
#insist { @rpmtags[:epoch].first.to_s } == ""
#end
it "should have the default summary as first line of description" do
insist { @rpmtags[:summary] } == @rpmtags[:description].split("\n").first
end
it "should output a package with the no conflicts" do
# @rpm.requires is an array of [name, op, requires] elements
# fpm uses strings here, so convert.
conflicts = @rpm.conflicts.collect { |a| a.join(" ") }
subject.conflicts.each do |dep|
insist { conflicts }.include?(dep)
end
end
it "should output a package with no provides" do
# @rpm.requires is an array of [name, op, requires] elements
# fpm uses strings here, so convert.
provides = @rpm.provides.collect { |a| a.join(" ") }
subject.provides.each do |dep|
insist { provides }.include?(dep)
end
end
end # package attributes
context "dist" do
it "should have the dist in the release" do
subject.name = "example"
subject.attributes[:rpm_dist] = "el6"
subject.version = "1.0"
@target = Stud::Temporary.pathname
# Write RPM
subject.output(@target)
@rpm = ::RPM::File.new(@target)
insist { @rpm.tags[:release] } == "#{subject.iteration}.el6"
File.unlink(@target)
end
it "should accept the dist in the iteration" do
subject.name = "example"
subject.iteration = "1.el6"
subject.version = "1.0"
@target = Stud::Temporary.pathname
# Write RPM
subject.output(@target)
@rpm = ::RPM::File.new(@target)
insist { @rpm.tags[:release] } == "#{subject.iteration}"
File.unlink(@target)
end
end # dist
context "changelog" do
it "should generate a changelog in the release" do
subject.name = "example"
subject.attributes[:rpm_dist] = 'rhel'
subject.version = "1.2.3"
subject.maintainer = "Spec Test <[email protected]>"
@target = Stud::Temporary.pathname
# Write RPM
subject.output(@target)
@rpm = ::RPM::File.new(@target)
insist { @rpm.tags[:changelogname] } == [ "Spec Test <[email protected]> - 1.2.3-1.rhel" ]
insist { @rpm.tags[:changelogtext] } == [ "- Package created with FPM" ]
File.unlink(@target)
end
it "should have the changelog in the release" do
subject.name = "example"
subject.attributes[:rpm_changelog] = <<CHANGELOG
* Tue May 31 2016 Example Maintainers <[email protected]> - 1.0-1
- First example package
CHANGELOG
subject.version = "1.0"
@target = Stud::Temporary.pathname
# Write RPM
subject.output(@target)
@rpm = ::RPM::File.new(@target)
insist { @rpm.tags[:changelogtime] } == [ 1464696000 ]
insist { @rpm.tags[:changelogname] } == [ "Example Maintainers <[email protected]> - 1.0-1" ]
insist { @rpm.tags[:changelogtext] } == [ "- First example package" ]
File.unlink(@target)
end
end # changelog
end # #output
describe "prefix attribute" do
it "should default to slash" do
insist { subject.prefix } == "/"
end
it "should leave a single slash as it is" do
subject.attributes[:prefix] = "/"
insist { subject.prefix } == "/"
end
it "should leave a path without trailing slash it is" do
subject.attributes[:prefix] = "/foo/bar"
insist { subject.prefix } == "/foo/bar"
end
it "should remove trailing slashes" do
subject.attributes[:prefix] = "/foo/bar/"
insist { subject.prefix } == "/foo/bar"
end
end
describe "regressions should not occur" do
before do
skip("Missing rpmbuild program") unless program_exists?("rpmbuild")
end
before :each do
@tempfile_handle =
@target = Stud::Temporary.pathname
subject.name = "name"
subject.version = "1.23"
end
after :each do
subject.cleanup
File.delete(@target) rescue nil
end # after
it "should escape '%' characters in filenames" do
Dir.mkdir(subject.staging_path("/example"))
File.write(subject.staging_path("/example/%name%"), "Hello")
subject.output(@target)
rpm = ::RPM::File.new(@target)
insist { rpm.files } == [ "/example/%name%" ]
end
it "should correctly include files with spaces and quotation marks" do
names = [
"/It's time to go.txt",
"/It's \"time\" to go.txt"
]
names.each do |n|
File.write(subject.staging_path("#{n}"), "Hello")
end
subject.output(@target)
rpm = ::RPM::File.new(@target)
insist { rpm.files.sort } == names.sort
end
it "should escape '%' characters in filenames while preserving permissions" do
Dir.mkdir(subject.staging_path("/example"))
File.write(subject.staging_path("/example/%name%"), "Hello")
File.chmod(01777,subject.staging_path("/example/%name%"))
subject.attributes[:rpm_use_file_permissions?] = true
subject.output(@target)
rpm = ::RPM::File.new(@target)
insist { rpm.files } == [ "/example/%name%" ]
insist { `rpm -qlv -p #{@target}`.chomp.split.first } == "-rwxrwxrwt"
end
it "should permit spaces in filenames (issue #164)" do
File.write(subject.staging_path("file with space"), "Hello")
# This will raise an exception if rpmbuild fails.
subject.output(@target)
rpm = ::RPM::File.new(@target)
insist { rpm.files } == [ "/file with space" ]
end
it "should permit brackets in filenames (issue #202)" do
File.write(subject.staging_path("file[with]bracket"), "Hello")
# This will raise an exception if rpmbuild fails.
subject.output(@target)
rpm = ::RPM::File.new(@target)
insist { rpm.files } == [ "/file[with]bracket" ]
end
it "should permit asterisks in filenames (issue #202)" do
File.write(subject.staging_path("file*asterisk"), "Hello")
# This will raise an exception if rpmbuild fails.
subject.output(@target)
rpm = ::RPM::File.new(@target)
insist { rpm.files } == [ "/file*asterisk" ]
end
it "should have some reasonable defaults that never change" do
subject.output(@target)
# Read the rpm
rpm = ::RPM::File.new(@target)
rpmtags = {}
rpm.header.tags.each do |tag|
rpmtags[tag.tag] = tag.value
end
# Default epoch must be empty, see #381
# For some reason, epoch is an array of numbers in rpm?
insist { rpmtags[:epoch] } == nil
# Default release must be '1'
insist { rpmtags[:release] } == "1"
end
context "with an empty description" do
it "should build a package" do
subject.description = ""
expect do
subject.output(@target)
end.not_to raise_error
end
end
context "with an one-line description" do
it "should build a package" do
subject.description = "hello world"
expect do
subject.output(@target)
end.not_to raise_error
end
end
end # regression stuff
describe "input validation stuff" do
before do
skip("Missing rpmbuild program") unless program_exists?("rpmbuild")
end
before :each do
@tempfile_handle =
@target = Stud::Temporary.pathname
@generator = FPM::Package::RPM.new
@generator.name = "name"
@generator.version = "1.23"
end
after :each do
subject.cleanup
@generator.cleanup
#File.delete(@target) rescue nil
end # after
it "should not cause errors when reading basic rpm in input (#802)" do
# Write the rpm out
@generator.output(@target)
# Load generated rpm
subject.input(@target)
# Value sanity check
insist { subject.name } == "name"
insist { subject.version } == "1.23"
end
it "should not cause errors when reading more complete rpm in input (#802)" do
@generator.architecture = "all"
@generator.iteration = "100"
@generator.epoch = "5"
@generator.dependencies << "something > 10"
@generator.dependencies << "hello >= 20"
@generator.conflicts << "bad < 2"
@generator.license = "this\nis\nan\example"
@generator.provides << "bacon = 1.0"
# Write the rpm out
@generator.output(@target)
# Load generated rpm
subject.input(@target)
# Value sanity check
insist { subject.name } == "name"
insist { subject.version } == "1.23"
insist { subject.architecture } == "noarch" # see #architecture
insist { subject.iteration } == "100"
insist { subject.epoch } == 5
insist { subject.dependencies }.include?("something > 10")
insist { subject.dependencies }.include?("hello >= 20")
insist { subject.conflicts[0] } == "bad < 2"
insist { subject.license } == @generator.license.split("\n").join(" ") # See issue #252
insist { subject.provides[0] } == "bacon = 1.0"
end
it "should not cause errors when reading rpm with script in input (#802)" do
@generator.scripts[:before_install] = "example before_install"
@generator.scripts[:after_install] = "example after_install"
@generator.scripts[:before_remove] = "example before_remove"
@generator.scripts[:after_remove] = "example after_remove"
@generator.scripts[:rpm_verifyscript] = "example rpm_verifyscript"
@generator.scripts[:rpm_posttrans] = "example rpm_posttrans"
@generator.scripts[:rpm_pretrans] = "example rpm_pretrans"
# Write the rpm out
@generator.output(@target)
# Load generated rpm
subject.input(@target)
# Value sanity check
insist { subject.name } == "name"
insist { subject.version } == "1.23"
insist { subject.scripts[:before_install] } == "example before_install"
insist { subject.scripts[:after_install] } == "example after_install"
insist { subject.scripts[:before_remove] } == "example before_remove"
insist { subject.scripts[:after_remove] } == "example after_remove"
insist { subject.scripts[:rpm_verifyscript] } == "example rpm_verifyscript"
insist { subject.scripts[:rpm_posttrans] } == "example rpm_posttrans"
insist { subject.scripts[:rpm_pretrans] } == "example rpm_pretrans"
end
it "should not cause errors when reading rpm with triggers in input (#802)" do
@generator.attributes[:rpm_trigger_before_install] = [["test","#!/bin/sh\necho before_install trigger executed\n"]]
@generator.attributes[:rpm_trigger_after_install] = [["test","#!/bin/sh\necho after_install trigger executed\n"]]
@generator.attributes[:rpm_trigger_before_uninstall] = [["test","#!/bin/sh\necho before_uninstall trigger executed\n"]]
@generator.attributes[:rpm_trigger_after_target_uninstall] = [["test","#!/bin/sh\necho after_target_uninstall trigger executed\n"]]
# Write the rpm out
@generator.output(@target)
# Load generated rpm
subject.input(@target)
# Value sanity check
insist { subject.name } == "name"
insist { subject.version } == "1.23"
insist { subject.attributes[:rpm_trigger_before_install] } == [["test","#!/bin/sh\necho before_install trigger executed", ""]]
insist { subject.attributes[:rpm_trigger_after_install] } == [["test","#!/bin/sh\necho after_install trigger executed", ""]]
insist { subject.attributes[:rpm_trigger_before_uninstall] } == [["test","#!/bin/sh\necho before_uninstall trigger executed", ""]]
insist { subject.attributes[:rpm_trigger_after_target_uninstall] } == [["test","#!/bin/sh\necho after_target_uninstall trigger executed", ""]]
end
end # input validation stuff
describe "rpm_use_file_permissions" do
let(:target) { Stud::Temporary.pathname }
let(:rpm) { ::RPM::File.new(target) }
let(:path) { "hello.txt" }
let(:path_stat) { File.lstat(subject.staging_path(path)) }
before :each do
File.write(subject.staging_path(path), "Hello world")
subject.name = "example"
subject.version = "1.0"
end
after :each do
subject.cleanup
File.delete(target) rescue nil
end
it "should respect file user and group ownership" do
skip("Missing rpmbuild program") unless program_exists?("rpmbuild")
subject.attributes[:rpm_use_file_permissions?] = true
subject.output(target)
insist { rpm.tags[:fileusername].first } == Etc.getpwuid(path_stat.uid).name
insist { rpm.tags[:filegroupname].first } == Etc.getgrgid(path_stat.gid).name
end
it "rpm_group should override rpm_use_file_permissions-derived owner" do
skip("Missing rpmbuild program") unless program_exists?("rpmbuild")
subject.attributes[:rpm_use_file_permissions?] = true
subject.attributes[:rpm_user] = "hello"
subject.attributes[:rpm_group] = "world"
subject.output(target)
insist { rpm.tags[:fileusername].first } == subject.attributes[:rpm_user]
insist { rpm.tags[:filegroupname].first } == subject.attributes[:rpm_group]
end
end
describe "#output with digest and compression settings" do
before do
skip("Missing rpmbuild program") unless program_exists?("rpmbuild")
end
context "bzip2/sha1" do
before :each do
@target = Stud::Temporary.pathname
subject.name = "name"
subject.version = "123"
subject.architecture = "all"
subject.iteration = "100"
subject.epoch = "5"
subject.attributes[:rpm_compression] = "bzip2"
subject.attributes[:rpm_digest] = "sha1"
# Write the rpm out
subject.output(@target)
# Read the rpm
@rpm = ::RPM::File.new(@target)
@rpmtags = {}
@rpm.header.tags.each do |tag|
@rpmtags[tag.tag] = tag.value
end
end
after :each do
subject.cleanup
File.delete(@target)
end # after
it "should have the compressor and digest algorithm listed" do
insist { @rpmtags[:payloadcompressor] } == "bzip2"
# For whatever reason, the 'filedigestalgo' tag is an array of numbers.
# I only ever see one element in this array, so just do value.first
insist { @rpmtags[:filedigestalgo].first } \
== FPM::Package::RPM::DIGEST_ALGORITHM_MAP["sha1"]
end
end # bzip2/sha1
end # #output with digest/compression settings
end # describe FPM::Package::RPM