require "spec_helper" module Omnibus describe Packager::Solaris do let(:project) do Project.new.tap do |project| project.name("project") project.homepage("https://example.com") project.install_dir("/opt/project") project.build_version("1.2.3") project.build_iteration("1") project.maintainer("Chef Software") end end subject { described_class.new(project) } let(:project_root) { File.join(tmp_path, "project/root") } let(:package_dir) { File.join(tmp_path, "package/dir") } let(:staging_dir) { File.join(tmp_path, "staging/dir") } let(:architecture) { "i86pc" } before do # This is here to allow this unit test to run on windows. allow(File).to receive(:expand_path).and_wrap_original do |m, *args| m.call(*args).sub(/^[A-Za-z]:/, "") end Config.project_root(project_root) Config.package_dir(package_dir) allow(subject).to receive(:staging_dir).and_return(staging_dir) create_directory(staging_dir) stub_ohai(platform: "solaris2", version: "5.11") do |data| data["kernel"]["machine"] = architecture end end describe "#id" do it "is :solaris" do expect(subject.id).to eq(:solaris) end end describe "#package_name" do it "includes the name, version, iteration and architecture" do expect(subject.package_name).to eq("project-1.2.3-1.i386.solaris") end end describe "#pkgmk_version" do it "includes the version and iteration" do expect(subject.pkgmk_version).to eq("1.2.3-1") end end describe "#install_dirname" do it "returns the parent directory" do expect(subject.install_dirname).to eq("/opt") end end describe "#install_basename" do it "name of the install directory" do expect(subject.install_basename).to eq("project") end end describe "#write_scripts" do context "when scripts are given" do let(:scripts) { %w{ postinstall postremove } } before do scripts.each do |script_name| create_file("#{project_root}/package-scripts/project/#{script_name}") do "Contents of #{script_name}" end end end it "writes the scripts into scripts staging dir" do subject.write_scripts scripts.each do |script_name| script_file = "#{staging_dir}/#{script_name}" contents = File.read(script_file) expect(contents).to include("Contents of #{script_name}") end end end context "when scripts with default omnibus naming are given" do let(:default_scripts) { %w{ postinst postrm } } before do default_scripts.each do |script_name| create_file("#{project_root}/package-scripts/project/#{script_name}") do "Contents of #{script_name}" end end end it "writes the scripts into scripts staging dir" do subject.write_scripts default_scripts.each do |script_name| mapped_name = Packager::Solaris::SCRIPT_MAP[script_name.to_sym] script_file = "#{staging_dir}/#{mapped_name}" contents = File.read(script_file) expect(contents).to include("Contents of #{script_name}") end end end end describe "#write_prototype_file" do let(:prototype_file) { File.join(staging_dir, "Prototype") } before do allow(subject).to receive(:shellout!) File.open("#{staging_dir}/files", "w+") do |f| f.write <<~EOF /foo/bar/baz /a file with spaces EOF end end it "creates the prototype file" do subject.write_prototype_file contents = File.read(prototype_file) expect(contents).to include( <<-EOH.gsub(/^ {12}/, "") i pkginfo i postinstall i postremove EOH ) end it "uses the correct commands" do expect(subject).to receive(:shellout!) .with("cd /opt && find project -print > #{File.join(staging_dir, "files")}") expect(subject).to receive(:shellout!) .with("cd /opt && pkgproto < #{File.join(staging_dir, "files.clean")} > #{File.join(staging_dir, "Prototype.files")}") expect(subject).to receive(:shellout!) .with("awk '{ $5 = \"root\"; $6 = \"root\"; print }' < #{File.join(staging_dir, "Prototype.files")} >> #{File.join(staging_dir, "Prototype")}") subject.write_prototype_file end it "strips out the file with spaces from files.clean" do subject.write_prototype_file contents = File.read(File.join(staging_dir, "files.clean")) expect(contents).not_to include("a file with spaces") expect(contents).to include("/foo/bar/baz") end end describe "#create_solaris_file" do it "uses the correct commands" do expect(subject).to receive(:shellout!) .with("pkgmk -o -r /opt -d #{staging_dir} -f #{File.join(staging_dir, "Prototype")}") expect(subject).to receive(:shellout!) .with("pkgchk -vd #{staging_dir} project") expect(subject).to receive(:shellout!) .with("pkgtrans #{staging_dir} #{File.join(package_dir, "project-1.2.3-1.i386.solaris")} project") subject.create_solaris_file end end describe "#write_pkginfo_file" do let(:pkginfo_file) { File.join(staging_dir, "pkginfo") } let(:hostname) { Socket.gethostname } let(:now) { Time.now } it "generates the file" do subject.write_pkginfo_file expect(pkginfo_file).to be_a_file end it "has the correct content" do allow(Time).to receive(:now).and_return(now) subject.write_pkginfo_file contents = File.read(pkginfo_file) expect(contents).to include("CLASSES=none") expect(contents).to include("TZ=PST") expect(contents).to include("PATH=/sbin:/usr/sbin:/usr/bin:/usr/sadm/install/bin") expect(contents).to include("BASEDIR=/opt") expect(contents).to include("PKG=project") expect(contents).to include("NAME=project") expect(contents).to include("ARCH=i386") expect(contents).to include("VERSION=1.2.3-1") expect(contents).to include("CATEGORY=application") expect(contents).to include("DESC=") expect(contents).to include("VENDOR=Chef Software") expect(contents).to include("EMAIL=Chef Software") expect(contents).to include("PSTAMP=#{hostname}#{now.utc.iso8601}") end end describe "#create_solaris_file" do before do allow(subject).to receive(:shellout!) allow(Dir).to receive(:chdir) { |_, &b| b.call } end it "uses the correct commands" do expect(subject).to receive(:shellout!) .with("pkgmk -o -r /opt -d #{staging_dir} -f #{File.join(staging_dir, "Prototype")}") expect(subject).to receive(:shellout!) .with("pkgchk -vd #{staging_dir} project") expect(subject).to receive(:shellout!) .with("pkgtrans #{staging_dir} #{File.join(package_dir, "project-1.2.3-1.i386.solaris")} project") subject.create_solaris_file end end describe "#safe_architecture" do context "the architecture is Intel-based" do let(:architecture) { "i86pc" } it "returns `i386`" do expect(subject.safe_architecture).to eq("i386") end end context "the architecture is SPARC-based" do let(:architecture) { "sun4v" } it "returns `sparc`" do expect(subject.safe_architecture).to eq("sparc") end end context "anything else" do let(:architecture) { "FOO" } it "returns the value from Ohai" do expect(subject.safe_architecture).to eq("FOO") end end end end end