require 'spec_helper' describe RightPublish::AptRepo do before(:each) do @cache_dir = 'somedir/' @repo_subdir = 'fake/' @repo = flexmock(RightPublish::RepoManager.get_repository(:apt_repo)) do |obj| obj.should_receive(:pull) obj.should_receive(:annotate) obj.should_receive(:push) obj.should_receive(:do_in_subdir).and_return {|dir,block| block.call} obj.should_receive(:prune_all) obj.should_receive(:write_conf_file) end flexmock(RightPublish::Profile) do |obj| obj.should_receive(:log).and_return { |str,dbg| } end flexmock(File) { |obj| obj.should_receive(:file?).and_return(true) } end context "#publish" do # Test the Pool (not flat) repo profile type [false, true].each do |should_sign| context "Pool layout#{" (with signature)" if should_sign}" do def build_expectations(pkgs, expected_dists) pkgs = Array(pkgs) expected_dists = Array(expected_dists) pkgs.each do |pkg| expected_dists.each do |dist| @remove_expectations[dist] ||= [] @remove_expectations[dist] << RightPublish::AptRepo.pkg_parts(pkg)[:name] @install_expectations[dist] ||= [] @install_expectations[dist] << pkg end end system_calls = (pkgs.size * expected_dists.size) * 2 @repo.should_receive(@system_func).times(system_calls).and_return do |cmd| path, subcmd, distro, pkg = /reprepro\s+(?:--ask-passphrase )?(?:-C main )?-b\s+(.+)\s+(includedeb|includedsc|removefilter)\s+([^\s]+)\s+(.+)$/.match(cmd).captures path.should be_eql(File.join(@cache_dir,@repo_subdir)) # Now we are using listfilter, that is why our package name is really filter. # reprepro -b somedir/fake/ removefilter quantal '$PackageType (== deb), Package (% foo)' # We need to extract package name from '$PackageType (== deb), Package (% foo)' real_pkg = pkg[35..-3] # 35 is an index of space after '%', and -3 is a index of ')' if @remove_expectations.has_key?(distro) && @remove_expectations[distro].include?(real_pkg) subcmd.should == 'removefilter' @remove_expectations.should be_has_key(distro) @remove_expectations[distro].delete(real_pkg) @remove_expectations.delete(distro) if @remove_expectations[distro].empty? else subcmd.should be_eql((pkg.end_with?(RightPublish::AptRepo::SRC_EXTENSION) && 'includedsc') || 'includedeb') @install_expectations.should be_has_key(distro) @install_expectations[distro].delete(pkg) @install_expectations.delete(distro) if @install_expectations[distro].empty? end 0 end end before(:each) do @apt_dists = ['quantal', 'precise', 'wheezy'] @install_expectations = {} @remove_expectations = {} @system_func = should_sign ? :shellout_with_password : :system flexmock(RightPublish::Profile) do |obj| obj.should_receive(:config).and_return { { :verbose=>false, :remote_storage=>{:provider=>'mockremote'}, :local_storage=>{:provider=>'mocklocal',:cache_dir=>@cache_dir}, :apt_repo=>{ :auto=>true, :subdir=>@repo_subdir, :dists=>@apt_dists, :gpg_key_id=>should_sign, :gpg_password=>"fakepass"} } } end end after(:each) do @install_expectations.should be_empty @remove_expectations.should be_empty end # Test for publish noarch packages (multicasting) context "NoArch Packages" do it "installs a single noarch deb file to all dists" do deb_file = 'foo_1_all.deb' build_expectations(deb_file,@apt_dists) @repo.publish(deb_file, nil) end it "installs a single src dsc file to all dists" do dsc_file = 'foo_1.dsc' build_expectations(dsc_file,@apt_dists) @repo.publish(dsc_file, nil) end it "installs a list of noarch deb files to all dists" do deb_files = ['foo_1_all.deb', 'bar_1_all.deb'] build_expectations(deb_files,@apt_dists) @repo.publish(deb_files, nil) end it "globs and installs a directory of noarch deb files to all dists" do deb_files = ['foo_1_all.deb', 'bar_1_all.deb'] build_expectations(deb_files,@apt_dists) flexmock(File) { |obj| obj.should_receive(:directory?).and_return(true) } flexmock(Dir) { |obj| obj.should_receive(:glob).and_return(deb_files) } @repo.publish('somedir/', nil) end it "fails with no files in a dir" do flexmock(File) { |obj| obj.should_receive(:directory?).and_return(true) } flexmock(Dir) { |obj| obj.should_receive(:glob).and_return([]) } @repo.should_receive(@system_func).never expect { @repo.publish('some_dir/', nil) }.to raise_error(RuntimeError) end it "fails with files missing a deb extenstion" do deb_files = ['foo_1_all.deb', 'bar.all.rpm'] @repo.should_receive(@system_func).never expect { @repo.publish(deb_files, nil) }.to raise_error(RuntimeError) end it "fails with a mix of noarch and binary debs" do deb_files = ['foo_1_all.deb', 'bar_2_amd64.deb'] @repo.should_receive(@system_func).never expect { @repo.publish(deb_files, nil) }.to raise_error(RuntimeError) end end # end NoArch context context "Architecture Dependant Packages" do before(:each) do @target_distribution_str = 'quantal' end it "installs a single amd64 deb file to a dist" do deb_file = 'foo_1_amd64.deb' build_expectations(deb_file,@target_distribution_str) @repo.publish(deb_file, @target_distribution_str) end it "installs a list of amd64 debs to a dist" do deb_files = ['foo1.9_1.2~precise_amd64.deb', 'bar_1_amd64.deb'] build_expectations(deb_files,@target_distribution_str) @repo.publish(deb_files, @target_distribution_str) end it "installs a directory mixed of amd64 and i386 debs to a dist" do deb_files = ['foo_1_amd64.deb', 'bar_1_i386.deb'] build_expectations(deb_files,@target_distribution_str) flexmock(File) { |obj| obj.should_receive(:directory?).and_return(true) } flexmock(Dir) { |obj| obj.should_receive(:glob).and_return(deb_files) } @repo.publish('some_dir/', @target_distribution_str) end it "fails with no files in a dir" do flexmock(File) { |obj| obj.should_receive(:directory?).and_return(true) } flexmock(Dir) { |obj| obj.should_receive(:glob).and_return([]) } @repo.should_receive(@system_func).never expect { @repo.publish('some_dir/', @target_distribution_str) }.to raise_error(RuntimeError) end it "fails with files missing a deb extension" do deb_files = ['foo_1_amd64.deb', 'bar_1_i386.rpm'] @repo.should_receive(@system_func).never expect { @repo.publish(deb_files, @target_distribution_str) }.to raise_error(RuntimeError) end it "fails with unknown architectures" do deb_files = ['foo.ppc.deb', 'bar.ppc.deb'] @repo.should_receive(@system_func).never expect { @repo.publish(deb_files, @target_distribution_str) }.to raise_error(RuntimeError) end it "fails when not provided with a target" do deb_files = ['foo_1_amd64.deb', 'bar_1_i386.deb'] @repo.should_receive(@system_func).never expect { @repo.publish(deb_files, nil) }.to raise_error(RuntimeError) end end # end Architecture Dependant context end # end Pool context end # Test the Flat repo profile type context "Flat layout" do def build_expectations(pkgs) pkgs = Array(pkgs) pkgs.each do |pkg| dist_path = File.join(@repo_subdir, (pkg.end_with?(RightPublish::AptRepo::BIN_EXTENSION) && 'binaries') || 'sources') @install_expectations[dist_path] ||= [] @install_expectations[dist_path] << pkg end @repo.should_receive(:install_file).and_return do |pkg,dir| @install_expectations.should be_has_key(dir) @install_expectations[dir].delete(pkg) @install_expectations.delete(dir) if @install_expectations[dir].empty? end @repo.should_receive(:system).twice.and_return(0) end before(:each) do @install_expectations = {} flexmock(RightPublish::Profile) do |obj| obj.should_receive(:config).and_return { { :verbose=>false, :remote_storage=>{:provider=>'mockremote'}, :local_storage=>{:provider=>'mocklocal',:cache_dir=>@cache_dir}, :apt_repo=>{ :apt=>false, :subdir=>@repo_subdir } } } end end after(:each) do @install_expectations.should be_empty end it "installs a single deb file to repo" do deb_file = 'foo_1_all.deb' build_expectations(deb_file) @repo.publish(deb_file, nil) end it "installs a single src deb file to repo" do dsc_file = 'foo_1.dsc' src_file = 'foo_1.orig.tar.gz' diff_file = 'foo_1.diff.gz' all_files = [dsc_file, src_file, diff_file] flexmock(Dir).should_receive(:glob).and_return([src_file]) build_expectations(all_files) @repo.publish(dsc_file, nil) end it "installs a list of deb files to repo" do deb_files = ['foo_1_amd64.deb', 'bar_1_amd64.deb'] build_expectations(deb_files) @repo.publish(deb_files, nil) end it "globs and installs a directory of deb files to repo" do deb_files = ['foo_1_all.deb', 'bar_1.dsc'] src_file = 'bar_1.orig.tar.gz' diff_file = 'bar_1.diff.gz' all_files = ([deb_files, src_file, diff_file]).flatten build_expectations(all_files) flexmock(File) { |obj| obj.should_receive(:directory?).and_return(true) } flexmock(Dir).should_receive(:glob).and_return do |pattern| (pattern.end_with?('orig.tar.gz') && [src_file]) || deb_files end @repo.publish('somedir/', nil) end it "succeeds with a mix of noarch and binary debs" do deb_files = ['foo_1_all.deb', 'bar_1_amd64.deb'] build_expectations(deb_files) @repo.publish(deb_files, nil) end it "fails with no files in a dir" do flexmock(File) { |obj| obj.should_receive(:directory?).and_return(true) } flexmock(Dir) { |obj| obj.should_receive(:glob).and_return([]) } @repo.should_receive(:system).never expect { @repo.publish('some_dir/', nil) }.to raise_error(RuntimeError) end it "fails with files missing a deb extenstion" do deb_files = ['foo_1_i386.deb', 'bar.all.rpm'] @repo.should_receive(:system).never expect { @repo.publish('some_dir/', nil) }.to raise_error(RuntimeError) end end # end Trivial context end # end #publish context end