# -*- ruby -*- require 'spec_helper' require 'yaml' describe "Pkg::Config" do Build_Params = [:apt_archive_path, :apt_archive_repo_command, :apt_host, :apt_releases, :apt_repo_path, :apt_repo_url, :apt_repo_name, :apt_repo_command, :author, :benchmark, :build_date, :build_defaults, :build_dmg, :build_doc, :build_gem, :build_ips, :build_msi, :build_pe, :build_tar, :builder_data_file, :bundle_platforms, :certificate_pem, :cows, :db_table, :deb_build_host, :deb_build_mirrors, :debversion, :debug, :default_cow, :default_mock, :description, :dmg_path, :downloads_archive_path, :email, :files, :final_mocks, :freight_archive_path, :freight_conf, :gem_default_executables, :gem_dependencies, :gem_description, :gem_devel_dependencies, :gem_development_dependencies, :gem_excludes, :gem_executables, :gem_files, :gem_forge_project, :gem_host, :gem_license, :gem_name, :gem_path, :gem_platform_dependencies, :gem_rdoc_options, :gem_require_path, :gem_required_ruby_version, :gem_required_rubygems_version, :gem_runtime_dependencies, :gem_summary, :gem_test_files, :gemversion, :gpg_key, :gpg_name, :homepage, :ips_build_host, :ips_host, :ips_inter_cert, :ips_package_host, :ips_path, :ips_repo, :ips_store, :jenkins_build_host, :jenkins_packaging_job, :jenkins_repo_path, :metrics, :metrics_url, :msi_name, :name, :nonfinal_apt_repo_command, :nonfinal_apt_repo_path, :nonfinal_apt_repo_staging_path, :nonfinal_dmg_path, :nonfinal_gem_path, :nonfinal_ips_path, :nonfinal_msi_path, :nonfinal_p5p_path, :nonfinal_repo_name, :nonfinal_repo_link_target, :nonfinal_svr4_path, :nonfinal_swix_path, :nonfinal_yum_repo_path, :notify, :project, :origversion, :osx_build_host, :packager, :packaging_repo, :packaging_root, :packaging_url, :pbuild_conf, :pe_name, :pe_version, :pg_major_version, :pre_tar_task, :pre_tasks, :privatekey_pem, :random_mockroot, :rc_mocks, :release, :rpm_build_host, :rpmrelease, :rpmversion, :ref, :repo_name, :short_ref, :sign_tar, :signing_server, :summary, :svr4_host, :svr4_path, :swix_path, :tar_excludes, :tar_host, :tarball_path, :team, :templates, :update_version_file, :version, :version_file, :version_strategy, :yum_archive_path, :yum_host, :yum_repo_path, :yum_repo_name, :yum_repo_command, ] describe "#new" do Build_Params.each do |param| it "should have r/w accessors for #{param}" do Pkg::Config.should respond_to(param) Pkg::Config.should respond_to("#{param.to_s}=") end end end describe "#config_from_hash" do good_params = { :yum_host => 'foo', :pe_name => 'bar' } context "given a valid params hash #{good_params}" do it "should set instance variable values for each param" do good_params.each do |param, value| Pkg::Config.should_receive(:instance_variable_set).with("@#{param}", value) end Pkg::Config.config_from_hash(good_params) end end bad_params = { :foo => 'bar' } context "given an invalid params hash #{bad_params}" do bad_params.each do |param, value| it "should print a warning that param '#{param}' is not valid" do Pkg::Config.should_receive(:warn).with(/No build data parameter found for '#{param}'/) Pkg::Config.config_from_hash(bad_params) end it "should not try to set instance variable @:#{param}" do Pkg::Config.should_not_receive(:instance_variable_set).with("@#{param}", value) Pkg::Config.config_from_hash(bad_params) end end end mixed_params = { :sign_tar => true, :baz => 'qux' } context "given a hash with both valid and invalid params" do it "should set the valid param" do Pkg::Config.should_receive(:instance_variable_set).with("@sign_tar", true) Pkg::Config.config_from_hash(mixed_params) end it "should issue a warning that the invalid param is not valid" do Pkg::Config.should_receive(:warn).with(/No build data parameter found for 'baz'/) Pkg::Config.config_from_hash(mixed_params) end it "should not try to set instance variable @:baz" do Pkg::Config.should_not_receive(:instance_variable_set).with("@baz", "qux") Pkg::Config.config_from_hash(mixed_params) end end end describe "#params" do it "should return a hash containing keys for all build parameters" do params = Pkg::Config.config Build_Params.each { |param| params.has_key?(param).should == true } end end describe "#platform_data" do platform_tags = [ 'osx-10.15-x86_64', 'osx-11-x86_64', 'ubuntu-16.04-i386', 'el-6-x86_64', 'el-7-ppc64le', 'sles-12-x86_64', ] artifacts = \ "./artifacts/apple/10.15/PC1/x86_64/puppet-agent-5.3.2.658.gc79ef9a-1.osx10.15.dmg\n" \ "./artifacts/apple/11/PC1/x86_64/puppet-agent-5.3.2.658.gc79ef9a-1.osx11.dmg\n" \ "./artifacts/deb/xenial/PC1/puppet-agent_5.3.2-1xenial_i386.deb\n" \ "./artifacts/el/6/PC1/x86_64/puppet-agent-5.3.2.658.gc79ef9a-1.el6.x86_64.rpm\n" \ "./artifacts/el/7/PC1/ppc64le/puppet-agent-5.3.2-1.el7.ppc64le.rpm\n" \ "./artifacts/sles/12/PC1/x86_64/puppet-agent-5.3.2-1.sles12.x86_64.rpm" aix_artifacts = \ "./artifacts/aix/7.1/PC1/ppc/puppet-agent-5.3.2-1.aix7.1.ppc.rpm" fedora_artifacts = \ "./artifacts/fedora/32/PC1/x86_64/puppet-agent-5.3.2-1.fc32.x86_64.rpm" windows_artifacts = \ "./artifacts/windows/puppet-agent-x64.msi\n" \ "./artifacts/windows/puppet-agent-5.3.2-x86.wixpdb\n" \ "./artifacts/windows/puppet-agent-5.3.2-x86.msi\n" \ "./artifacts/windows/puppet-agent-5.3.2-x64.msi\n"\ "./artifacts/windowsfips/puppet-agent-x64.msi\n" \ "./artifacts/windowsfips/puppet-agent-5.3.2-x64.msi" solaris_artifacts = \ "./artifacts/solaris/11/PC1/puppet-agent@5.3.2,5.11-1.sparc.p5p\n" \ "./artifacts/solaris/10/PC1/puppet-agent-5.3.2-1.i386.pkg.gz" stretch_artifacts = \ "./artifacts/deb/stretch/PC1/puppet-agent-dbgsym_5.3.2-1stretch_i386.deb\n" \ "./artifacts/deb/stretch/PC1/puppet-agent_5.3.2-1stretch_i386.deb\n" \ "./artifacts/deb/stretch/PC1/puppet-agent_5.3.2.658.gc79ef9a-1stretch_amd64.deb\n" \ "./artifacts/deb/stretch/PC1/puppet-agent-dbgsym_5.3.2.658.gc79ef9a-1stretch_amd64.deb" artifacts_not_matching_project = \ "./artifacts/deb/xenial/pe-postgresql-contrib_2019.1.9.6.12-1xenial_amd64.deb\n" \ "./artifacts/deb/xenial/pe-postgresql-devel_2019.1.9.6.12-1xenial_amd64.deb\n" \ "./artifacts/deb/xenial/pe-postgresql-server_2019.1.9.6.12-1xenial_amd64.deb\n" \ "./artifacts/deb/xenial/pe-postgresql_2019.1.9.6.12-1xenial_amd64.deb" project = 'puppet-agent' ref = '5.3.2' before :each do allow(Pkg::Config).to receive(:project).and_return(project) allow(Pkg::Config).to receive(:ref).and_return(ref) allow(Pkg::Util::Net).to receive(:check_host_ssh).and_return([]) end it "should return a hash mapping platform tags to paths" do allow(Pkg::Util::Net).to receive(:remote_execute).and_return(artifacts, nil) expect(Pkg::Config.platform_data.keys).to eql(platform_tags) end it "should return nil if project isn't set" do allow(Pkg::Config).to receive(:project).and_return(nil) expect(Pkg::Config.platform_data).to be_nil end it "should return nil if ref isn't set" do allow(Pkg::Config).to receive(:ref).and_return(nil) expect(Pkg::Config.platform_data).to be_nil end it "should return nil if can't connect to build server" do allow(Pkg::Util::Net).to receive(:check_host_ssh).and_return(['something']) expect(Pkg::Config.platform_data).to be_nil end it "should not use 'f' in fedora platform tags" do allow(Pkg::Util::Net).to receive(:remote_execute).and_return(fedora_artifacts, nil) data = Pkg::Config.platform_data expect(data).to include('fedora-32-x86_64') expect(data).not_to include('fedora-f32-x86_64') end it "should collect packages whose extname differ from package_format" do allow(Pkg::Util::Net).to receive(:remote_execute).and_return(solaris_artifacts, nil) data = Pkg::Config.platform_data expect(data).to include('solaris-10-i386' => {:artifact => './solaris/10/PC1/puppet-agent-5.3.2-1.i386.pkg.gz', :repo_config => nil}) expect(data).to include('solaris-11-sparc' => {:artifact => './solaris/11/PC1/puppet-agent@5.3.2,5.11-1.sparc.p5p', :repo_config => nil}) end it "should collect versioned msis" do allow(Pkg::Util::Net).to receive(:remote_execute).and_return(windows_artifacts, nil) data = Pkg::Config.platform_data expect(data['windows-2012-x86']).to include(:artifact => './windows/puppet-agent-5.3.2-x86.msi') expect(data['windows-2012-x64']).to include(:artifact => './windows/puppet-agent-5.3.2-x64.msi') expect(data['windowsfips-2012-x64']).to include(:artifact => './windowsfips/puppet-agent-5.3.2-x64.msi') end it "should not collect debug packages" do allow(Pkg::Util::Net).to receive(:remote_execute).and_return(stretch_artifacts, nil) data = Pkg::Config.platform_data expect(data['debian-9-amd64']).to include(:artifact => './deb/stretch/PC1/puppet-agent_5.3.2.658.gc79ef9a-1stretch_amd64.deb') end it "should collect packages that don't match the project name" do allow(Pkg::Util::Net).to receive(:remote_execute).and_return(artifacts_not_matching_project, nil) data = Pkg::Config.platform_data expect(data['ubuntu-16.04-amd64']).to include(:artifact => './deb/xenial/pe-postgresql-contrib_2019.1.9.6.12-1xenial_amd64.deb') expect(data['ubuntu-16.04-amd64'][:additional_artifacts].size).to eq(3) expect(data['ubuntu-16.04-amd64'][:additional_artifacts]).to include('./deb/xenial/pe-postgresql-devel_2019.1.9.6.12-1xenial_amd64.deb') expect(data['ubuntu-16.04-amd64'][:additional_artifacts]).to include('./deb/xenial/pe-postgresql-server_2019.1.9.6.12-1xenial_amd64.deb') expect(data['ubuntu-16.04-amd64'][:additional_artifacts]).to include('./deb/xenial/pe-postgresql_2019.1.9.6.12-1xenial_amd64.deb') end it "should use 'ppc' instead of 'power' in aix paths" do allow(Pkg::Util::Net).to receive(:remote_execute).and_return(aix_artifacts, nil) data = Pkg::Config.platform_data expect(data['aix-7.1-power']).to include(:artifact => './aix/7.1/PC1/ppc/puppet-agent-5.3.2-1.aix7.1.ppc.rpm') end it "should not record an aix repo config" do allow(Pkg::Util::Net).to receive(:remote_execute).and_return(aix_artifacts, nil) data = Pkg::Config.platform_data expect(data['aix-7.1-power'][:repo_config]).to be_nil end end describe "#config_to_yaml" do it "should write a valid yaml file" do file = double('file') File.should_receive(:open).with(anything(), 'w').and_yield(file) file.should_receive(:puts).with(instance_of(String)) YAML.should_receive(:load_file).with(file) expect { YAML.load_file(file) }.to_not raise_error Pkg::Config.config_to_yaml end end describe "#get_binding" do it "should return the binding of the Pkg::Config object" do # test by eval'ing using the binding before and after setting a param orig = Pkg::Config.apt_host Pkg::Config.apt_host = "foo" expect(eval("@apt_host", Pkg::Config.get_binding)).to eq("foo") Pkg::Config.apt_host = "bar" expect(eval("@apt_host", Pkg::Config.get_binding)).to eq("bar") Pkg::Config.apt_host = orig end end describe "#config_from_yaml" do context "given a yaml file" do it "should, use it to set params" do # apt_host: is set to "foo" in the fixture orig = Pkg::Config.apt_host Pkg::Config.apt_host = "bar" Pkg::Config.config_from_yaml(File.join(FIXTURES, 'config', 'ext', 'build_defaults.yaml')) expect(Pkg::Config.apt_host).to eq("foo") Pkg::Config.apt_host = orig end end end describe "#string_to_array" do ary = %W(FOO BAR ARR RAY) context "given a string with spaces in it" do it "should return an array containing the contents of that string" do space_str = "FOO BAR ARR RAY" expect(Pkg::Config.string_to_array(space_str)).to eq(ary) end end context "given a string with commas in it" do it "should return an array containing the contents of that string" do comma_str = "FOO,BAR,ARR,RAY" expect(Pkg::Config.string_to_array(comma_str)).to eq(ary) end end context "given a string with semicolons in it" do it "should return an array containing the contents of that string" do semi_str = "FOO;BAR;ARR;RAY" expect(Pkg::Config.string_to_array(semi_str)).to eq(ary) end end context "given a string with multiple delimiters in it" do delimiters = [',', ' ', ';'] mixed_str = "FOO, BAR, ARR, ; RAY" mixed_arr = Pkg::Config.string_to_array(mixed_str) it "should not return the delimiters as array items" do expect(mixed_arr).to_not include(*delimiters) end it "should not contain empty strings" do expect(mixed_arr).to_not include("\s") end it "should still return the expected array" do expect(mixed_arr).to eq(ary) end end end describe "#cow_list" do it "should return a list of the cows for a project" do Pkg::Config.cows = "base-lucid-i386.cow base-lucid-amd64.cow base-precise-i386.cow base-precise-amd64.cow base-quantal-i386.cow base-quantal-amd64.cow base-saucy-i386.cow base-saucy-amd64.cow base-sid-i386.cow base-sid-amd64.cow base-squeeze-i386.cow base-squeeze-amd64.cow base-stable-i386.cow base-stable-amd64.cow base-testing-i386.cow base-testing-amd64.cow base-trusty-i386.cow base-trusty-amd64.cow base-unstable-i386.cow base-unstable-amd64.cow base-wheezy-i386.cow base-wheezy-amd64.cow" Pkg::Config.cow_list.should eq "lucid precise quantal saucy sid squeeze stable testing trusty unstable wheezy" end end describe "#config" do context "given :format => :hash" do it "should call Pkg::Config.config_to_hash" do expect(Pkg::Config).to receive(:config_to_hash) Pkg::Config.config(:target => nil, :format => :hash) end end context "given :format => :yaml" do it "should call Pkg::Config.config_to_yaml if given :format => :yaml" do expect(Pkg::Config).to receive(:config_to_yaml) Pkg::Config.config(:target => nil, :format => :yaml) end end end describe "#issue_reassignments" do around do |example| prev_tar_host = Pkg::Config.tar_host Pkg::Config.tar_host = nil example.run Pkg::Config.tar_host = prev_tar_host end it "should set tar_host to staging_server" do Pkg::Config.config_from_hash({ :staging_server => 'foo' }) Pkg::Config.issue_reassignments Pkg::Config.tar_host.should eq("foo") end end describe "#config_to_hash" do it "should return a hash object" do hash = Pkg::Config.config_to_hash hash.should be_a(Hash) end it "should return a hash with the current parameters" do Pkg::Config.apt_host = "foo" Pkg::Config.config_to_hash[:apt_host].should eq("foo") Pkg::Config.apt_host = "bar" Pkg::Config.config_to_hash[:apt_host].should eq("bar") end end describe "#load_default_configs" do before(:each) do @project_root = double('project_root') Pkg::Config.project_root = @project_root @test_project_data = File.join(Pkg::Config.project_root, 'ext', 'project_data.yaml') @test_build_defaults = File.join(Pkg::Config.project_root, 'ext', 'build_defaults.yaml') end around do |example| orig = Pkg::Config.project_root example.run Pkg::Config.project_root = orig end context "given ext/build_defaults.yaml and ext/project_data.yaml are readable" do it "should try to load build_defaults.yaml and project_data.yaml" do allow(File).to receive(:readable?).with(@test_project_data).and_return(true) allow(File).to receive(:readable?).with(@test_build_defaults).and_return(true) expect(Pkg::Config).to receive(:config_from_yaml).with(@test_project_data) expect(Pkg::Config).to receive(:config_from_yaml).with(@test_build_defaults) Pkg::Config.load_default_configs end end context "given ext/build_defaults.yaml is readable but ext/project_data.yaml is not" do it "should try to load build_defaults.yaml but not project_data.yaml" do allow(File).to receive(:readable?).with(@test_project_data).and_return(false) allow(File).to receive(:readable?).with(@test_build_defaults).and_return(true) expect(Pkg::Config).to_not receive(:config_from_yaml).with(@test_project_data) expect(Pkg::Config).to receive(:config_from_yaml).with(@test_build_defaults) Pkg::Config.load_default_configs end end context "given ext/build_defaults.yaml is not readable but ext/project_data.yaml is" do it "should try to load build_defaults.yaml then unset project_root" do allow(File).to receive(:readable?).with(@test_project_data).and_return(true) allow(File).to receive(:readable?).with(@test_build_defaults).and_return(false) expect(Pkg::Config).to_not receive(:config_from_yaml).with(@test_build_defaults) Pkg::Config.load_default_configs expect(Pkg::Config.project_root).to be_nil end end context "given ext/build_defaults.yaml and ext/project_data.yaml are not readable" do it "should not try to load build_defaults.yaml and project_data.yaml" do Pkg::Config.project_root = 'foo' expect(Pkg::Config).to_not receive(:config_from_yaml) Pkg::Config.load_default_configs end it "should set the project root to nil" do Pkg::Config.project_root = 'foo' Pkg::Config.load_default_configs expect(Pkg::Config.project_root).to be_nil end end end describe "#load_versioning" do around do |example| orig = Pkg::Config.project_root example.run Pkg::Config.project_root = orig end # We let the actual version determination testing happen in the version # tests. Here we just test that we try when we should. context "When project root is nil" do it "should not try to load versioning" do Pkg::Config.project_root = nil expect(Pkg::Util::Version).to_not receive(:git_sha_or_tag) Pkg::Config.load_versioning end end end describe "#load_envvars" do # We're going to pollute the environment with this test, so afterwards we # explicitly set everything to nil to prevent any hazardous effects on # the rest of the tests. after(:all) do reset_env(Pkg::Params::ENV_VARS.map {|hash| hash[:envvar].to_s}) end Pkg::Params::ENV_VARS.each do |v| case v[:type] when :bool it "should set boolean value on #{v[:var]} for :type == :bool" do ENV[v[:envvar].to_s] = "FOO" Pkg::Util.stub(:boolean_value) {"FOO"} allow(Pkg::Config).to receive(:instance_variable_set) expect(Pkg::Util).to receive(:boolean_value).with("FOO") expect(Pkg::Config).to receive(:instance_variable_set).with("@#{v[:var]}", "FOO") Pkg::Config.load_envvars end when :array it "should set Pkg::Config##{v[:var]} to an Array for :type == :array" do ENV[v[:envvar].to_s] = "FOO BAR ARR RAY" Pkg::Config.stub(:string_to_array) {%w(FOO BAR ARR RAY)} allow(Pkg::Config).to receive(:instance_variable_set) expect(Pkg::Config).to receive(:string_to_array).with("FOO BAR ARR RAY") expect(Pkg::Config).to receive(:instance_variable_set).with("@#{v[:var]}", %w(FOO BAR ARR RAY)) Pkg::Config.load_envvars end else it "should set Pkg::Config##{v[:var]} to ENV[#{v[:envvar].to_s}]" do ENV[v[:envvar].to_s] = "FOO" Pkg::Util.stub(:boolean_value) {"FOO"} allow(Pkg::Config).to receive(:instance_variable_set) expect(Pkg::Config).to receive(:instance_variable_set).with("@#{v[:var]}", "FOO") Pkg::Config.load_envvars end end end end end