# -*- ruby -*- require 'spec_helper' require 'yaml' CONFIGURATION_KEYS = %i[ 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 'Pkg::Config' do describe '#new' do CONFIGURATION_KEYS.each do |configuration_key| it "should have r/w accessors for #{configuration_key}" do expect(Pkg::Config).to respond_to(configuration_key) expect(Pkg::Config).to respond_to("#{configuration_key.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| expect(Pkg::Config).to 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 expect(Pkg::Config).to 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 expect(Pkg::Config).to_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 expect(Pkg::Config).to 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 expect(Pkg::Config).to 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 expect(Pkg::Config).to_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 CONFIGURATION_KEYS.each { |param| expect(params.key?(param)).to be true } end end describe '#platform_data' do platform_tags = %w[ osx-11-x86_64 ubuntu-18.04-amd64 el-6-x86_64 el-7-ppc64le sles-12-x86_64 ] artifacts = "./artifacts/apple/11/PC1/x86_64/puppet-agent-5.3.2.658.gc79ef9a-1.osx11.dmg\n" \ "./artifacts/deb/bionic/PC1/puppet-agent_5.3.2-1bionic_amd64.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/36/PC1/x86_64/puppet-agent-5.3.2-1.fc36.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" buster_artifacts = \ "./artifacts/deb/buster/PC1/puppet-agent-dbgsym_5.3.2-1buster_i386.deb\n" \ "./artifacts/deb/buster/PC1/puppet-agent_5.3.2-1buster_i386.deb\n" \ "./artifacts/deb/buster/PC1/puppet-agent_5.3.2.658.gc79ef9a-1buster_amd64.deb\n" \ "./artifacts/deb/buster/PC1/puppet-agent-dbgsym_5.3.2.658.gc79ef9a-1buster_amd64.deb" artifacts_not_matching_project = \ "./artifacts/deb/bionic/pe-postgresql-contrib_2019.1.9.6.12-1bionic_amd64.deb\n" \ "./artifacts/deb/bionic/pe-postgresql-devel_2019.1.9.6.12-1bionic_amd64.deb\n" \ "./artifacts/deb/bionic/pe-postgresql-server_2019.1.9.6.12-1bionic_amd64.deb\n" \ "./artifacts/deb/bionic/pe-postgresql_2019.1.9.6.12-1bionic_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-36-x86_64') expect(data).not_to include('fedora-f36-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(buster_artifacts, nil) data = Pkg::Config.platform_data expect(data['debian-10-amd64']).to include(artifact: './deb/buster/PC1/puppet-agent_5.3.2.658.gc79ef9a-1buster_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-18.04-amd64']).to include(artifact: './deb/bionic/pe-postgresql-contrib_2019.1.9.6.12-1bionic_amd64.deb') expect(data['ubuntu-18.04-amd64'][:additional_artifacts].size).to eq(3) expect(data['ubuntu-18.04-amd64'][:additional_artifacts]).to include('./deb/bionic/pe-postgresql-devel_2019.1.9.6.12-1bionic_amd64.deb') expect(data['ubuntu-18.04-amd64'][:additional_artifacts]).to include('./deb/bionic/pe-postgresql-server_2019.1.9.6.12-1bionic_amd64.deb') expect(data['ubuntu-18.04-amd64'][:additional_artifacts]).to include('./deb/bionic/pe-postgresql_2019.1.9.6.12-1bionic_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') expect(File).to receive(:open).with(anything, 'w').and_yield(file) expect(file).to receive(:puts).with(instance_of(String)) expect(YAML).to 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, __FILE__, __LINE__)).to eq("foo") Pkg::Config.apt_host = "bar" expect(eval('@apt_host', Pkg::Config.get_binding, __FILE__, __LINE__)).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 sample_array = %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(sample_array) 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(sample_array) 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(sample_array) end end context 'given a string with multiple delimiters in it' do delimiters = [',', ' ', ';'] sample_string = "FOO, BAR, ARR, ; RAY" sample_array = Pkg::Config.string_to_array(sample_string) it 'should not return the delimiters as array items' do expect(sample_array).to_not include(*delimiters) end it 'should not contain empty strings' do expect(sample_array).to_not include("\s") end it 'should still return the expected array' do expect(sample_array).to eq(sample_array) end end end describe '#cow_list' do it "should return a list of the cows for a project" do Pkg::Config.cows = %w[ 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 ].join(' ') expect(Pkg::Config.cow_list) .to 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| original_tar_host = Pkg::Config.tar_host Pkg::Config.tar_host = nil example.run Pkg::Config.tar_host = original_tar_host end it 'should set tar_host to staging_server' do Pkg::Config.config_from_hash({ staging_server: 'foo' }) Pkg::Config.issue_reassignments expect(Pkg::Config.tar_host).to eq('foo') end end describe '#config_to_hash' do it 'should return a hash object' do expect(Pkg::Config.config_to_hash).to be_a(Hash) end it 'should return a hash with the current parameters' do Pkg::Config.apt_host = 'foo' expect(Pkg::Config.config_to_hash[:apt_host]).to eq('foo') Pkg::Config.apt_host = 'bar' expect(Pkg::Config.config_to_hash[:apt_host]).to eq('bar') end end describe '#load_default_configs' do before(:each) do @project_root = '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| project_root_save = Pkg::Config.project_root example.run Pkg::Config.project_root = project_root_save 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| project_root_save = Pkg::Config.project_root example.run Pkg::Config.project_root = project_root_save 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' allow(Pkg::Util).to receive(:boolean_value).and_return('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' allow(Pkg::Config).to receive(:string_to_array).and_return(%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" allow(Pkg::Util).to receive(:boolean_value).and_return('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