require 'spec_helper' describe Omnibus::PackageRelease do let(:s3_key) { 's3key' } let(:s3_secret) { 'hey-bezos-store-my-stuff' } let(:s3_bucket) { 'myorg-omnibus-packages' } let(:pkg_path) { 'pkg/chef_11.4.0-183-g2c0040c-0.el6.x86_64.rpm' } let(:pkg_metadata_path) { "#{pkg_path}.metadata.json" } let(:config) do { release_s3_access_key: s3_key, release_s3_secret_key: s3_secret, release_s3_bucket: s3_bucket, } end subject(:package_release) do Omnibus::PackageRelease.new(pkg_path) end it 'has a package path' do expect(package_release.package_path).to eq(pkg_path) end it "defaults to `:private' access policy" do expect(package_release.access_policy).to eq(:private) end describe 'validating configuration' do before do Omnibus.stub(:config).and_return(config) end it 'validates that the s3 key is set' do config.delete(:release_s3_access_key) expect { package_release.validate_config! }.to raise_error(Omnibus::InvalidS3ReleaseConfiguration) end it 'validates that the s3 secret key is set' do config.delete(:release_s3_secret_key) expect { package_release.validate_config! }.to raise_error(Omnibus::InvalidS3ReleaseConfiguration) end it 'validates that the s3 bucket is set' do config.delete(:release_s3_bucket) expect { package_release.validate_config! }.to raise_error(Omnibus::InvalidS3ReleaseConfiguration) end it 'does not error on a valid configuration' do expect { package_release.validate_config! }.to_not raise_error end end describe 'validating package for upload' do it 'ensures that the package file exists' do expect { package_release.validate_package! }.to raise_error(Omnibus::NoPackageFile) end it 'ensures that there is a metadata file for the package' do expect(File).to receive(:exist?).with(pkg_path).and_return(true) expect(File).to receive(:exist?).with(pkg_metadata_path).and_return(false) expect { package_release.validate_package! }.to raise_error(Omnibus::NoPackageMetadataFile) end end context 'with a valid config and package' do let(:basename) { 'chef_11.4.0-183-g2c0040c-0.el6.x86_64.rpm' } let(:md5) { '016f2e0854c69901b3f0ad8f99ffdb75' } let(:platform_path) { 'el/6/x86_64' } let(:pkg_content) { 'expected package content' } let(:metadata_json) do <<-E { "platform": "el", "platform_version": "6", "arch": "x86_64", "version": "11.4.0-183-g2c0040c", "basename": "#{basename}", "md5": "#{md5}", "sha256": "21191ab698d1663a5e738e470fad16a2c6efee05ed597002f2e846ec80ade38c" } E end before do package_release.stub(:config).and_return(config) File.stub(:exist?).with(pkg_metadata_path).and_return(true) File.stub(:exist?).with(pkg_path).and_return(true) IO.stub(:read).with(pkg_metadata_path).and_return(metadata_json) IO.stub(:read).with(pkg_path).and_return(pkg_content) end it 'configures s3 with the given credentials' do expected_s3_config = { access_key: s3_key, secret_access_key: s3_secret, bucket: s3_bucket, adaper: :net_http, } expect(UberS3).to receive(:new).with(expected_s3_config) package_release.s3_client end it 'generates the relative path for the package s3 key' do expect(package_release.platform_path).to eq(platform_path) end it 'uploads the package and metadata' do expect(package_release.s3_client).to receive(:store).with( "#{platform_path}/#{basename}.metadata.json", metadata_json, access: :private, ) expect(package_release.s3_client).to receive(:store).with( "#{platform_path}/#{basename}", pkg_content, access: :private, content_md5: md5, ) package_release.release end context 'and a callback is given for after upload' do let(:upload_records) { [] } subject(:package_release) do Omnibus::PackageRelease.new(pkg_path) do |uploaded| upload_records << uploaded end end it 'fires the after_upload callback for each item uploaded' do expect(package_release.s3_client).to receive(:store).with( "#{platform_path}/#{basename}.metadata.json", metadata_json, access: :private, ) expect(package_release.s3_client).to receive(:store).with( "#{platform_path}/#{basename}", pkg_content, access: :private, content_md5: md5, ) package_release.release expect(upload_records).to eq [ "#{platform_path}/#{basename}.metadata.json", "#{platform_path}/#{basename}", ] end end context 'and the package is public' do subject(:package_release) do Omnibus::PackageRelease.new(pkg_path, access: :public_read) end it 'uploads the package and metadata' do expect(package_release.s3_client).to receive(:store).with( "#{platform_path}/#{basename}.metadata.json", metadata_json, access: :public_read, ) expect(package_release.s3_client).to receive(:store).with( "#{platform_path}/#{basename}", pkg_content, access: :public_read, content_md5: md5, ) package_release.release end end end end