spec/unit/git_cache_spec.rb (219 lines of code) (raw):
require "spec_helper"
module Omnibus
describe GitCache do
let(:project) do
Project.new("/path/to/demo.rb").evaluate do
name "demo"
install_dir "/opt/demo"
build_version "1.0.0"
maintainer "Chef Software, Inc"
homepage "http://getchef.com"
dependency "preparation"
dependency "snoopy"
dependency "zlib"
end
end
let(:install_dir) { project.install_dir }
let(:zlib) do
Software.new(project, "zlib.rb").evaluate do
name "zlib"
default_version "1.7.2"
end
end
let(:snoopy) do
Software.new(project, "snoopy.rb").evaluate do
name "snoopy"
default_version "1.0.0"
end
end
let(:preparation) do
Software.new(project, "preparation.rb").evaluate do
name "preparation"
default_version "1.0.0"
end
end
let(:cache_path) { File.join("/var/cache/omnibus/cache/git_cache", install_dir) }
let(:cache_serial_number) { described_class::SERIAL_NUMBER }
let(:ipc) do
project.library.component_added(preparation)
project.library.component_added(snoopy)
project.library.component_added(zlib)
described_class.new(zlib)
end
let(:git_flags) { %Q{-c core.autocrlf=false -c core.ignorecase=false --git-dir="#{cache_path}" --work-tree="#{install_dir}"} }
describe "#cache_path" do
it "returns the install path appended to the install_cache path" do
expect(ipc.cache_path).to eq(cache_path)
end
end
describe "#tag" do
it "returns the correct tag" do
expect(ipc.tag).to eql("zlib-24a8ec71da04059dcf7ed3c6e8e0fd9d155476abe4b5156d1f13c42e85478c2b-#{cache_serial_number}")
end
describe "with no deps" do
let(:ipc) do
described_class.new(zlib)
end
it "returns the correct tag" do
expect(ipc.tag).to eql("zlib-ee71fc1a512f03b9dd46c1fd9b5ab71fcc51b638857bf328496a31abb2654c2b-#{cache_serial_number}")
end
end
end
describe "#create_cache_path" do
it "runs git init if the cache path does not exist" do
allow(File).to receive(:directory?)
.with(ipc.cache_path)
.and_return(false)
allow(File).to receive(:directory?)
.with(File.dirname(ipc.cache_path))
.and_return(false)
expect(FileUtils).to receive(:mkdir_p)
.with(File.dirname(ipc.cache_path))
expect(ipc).to receive(:shellout!)
.with("git #{git_flags} init -q")
expect(ipc).to receive(:shellout!)
.with("git #{git_flags} config --local user.name \"Omnibus Git Cache\"")
expect(ipc).to receive(:shellout!)
.with("git #{git_flags} config --local user.email \"omnibus@localhost\"")
ipc.create_cache_path
end
it "does not run git init if the cache path exists" do
allow(File).to receive(:directory?)
.with(ipc.cache_path)
.and_return(true)
allow(File).to receive(:directory?)
.with(File.dirname(ipc.cache_path))
.and_return(true)
expect(ipc).to_not receive(:shellout!)
ipc.create_cache_path
end
end
describe "#incremental" do
before(:each) do
allow(ipc).to receive(:shellout!)
allow(ipc).to receive(:create_cache_path)
end
it "creates the cache path" do
expect(ipc).to receive(:create_cache_path)
ipc.incremental
end
it "adds all the changes to git removing git directories" do
expect(ipc).to receive(:remove_git_dirs)
expect(ipc).to receive(:shellout!)
.with("git #{git_flags} add -A -f")
ipc.incremental
end
it "commits the backup for the software" do
expect(ipc).to receive(:shellout!)
.with(%Q{git #{git_flags} commit -q -m "Backup of #{ipc.tag}"})
ipc.incremental
end
it "tags the software backup" do
expect(ipc).to receive(:shellout!)
.with(%Q{git #{git_flags} tag -f "#{ipc.tag}"})
ipc.incremental
end
end
describe "#remove_git_dirs" do
let(:git_files) { ["git/HEAD", "git/description", "git/hooks", "git/info", "git/objects", "git/refs" ] }
it "removes bare git directories" do
allow(Dir).to receive(:glob).and_return(["git/config"])
git_files.each do |git_file|
expect(File).to receive(:exist?).with(git_file).and_return(true)
end
allow(File).to receive(:dirname).and_return("git")
expect(FileUtils).to receive(:rm_rf).with("git")
ipc.remove_git_dirs
end
it "does ignores non git directories" do
allow(Dir).to receive(:glob).and_return(["not_git/config"])
expect(File).to receive(:exist?).with("not_git/HEAD").and_return(false)
allow(File).to receive(:dirname).and_return("not_git")
expect(FileUtils).not_to receive(:rm_rf).with("not_git")
ipc.remove_git_dirs
end
end
describe "#restore" do
let(:git_tag_output) { "#{ipc.tag}\n" }
let(:tag_cmd) do
cmd_double = double(Mixlib::ShellOut)
allow(cmd_double).to receive(:stdout).and_return(git_tag_output)
allow(cmd_double).to receive(:error!).and_return(cmd_double)
cmd_double
end
before(:each) do
allow(ipc).to receive(:shellout!)
.with(%Q{git #{git_flags} tag -l "#{ipc.tag}"})
.and_return(tag_cmd)
allow(ipc).to receive(:shellout!)
.with(%Q{git #{git_flags} tag -f restore_here "#{ipc.tag}"})
allow(ipc).to receive(:create_cache_path)
end
it "creates the cache path" do
expect(ipc).to receive(:create_cache_path)
ipc.restore
end
it "checks for a tag with the software and version, and if it finds it, marks it as restoration point" do
expect(ipc).to receive(:shellout!)
.with(%Q{git #{git_flags} tag -l "#{ipc.tag}"})
.and_return(tag_cmd)
expect(ipc).to receive(:shellout!)
.with(%Q{git #{git_flags} tag -f restore_here "#{ipc.tag}"})
ipc.restore
end
describe "if the tag does not exist" do
let(:git_tag_output) { "\n" }
let(:restore_tag_cmd) do
cmd_double = double(Mixlib::ShellOut)
allow(cmd_double).to receive(:stdout).and_return(git_restore_tag_output)
allow(cmd_double).to receive(:error!).and_return(cmd_double)
cmd_double
end
describe "if the restore marker tag exists" do
let(:git_restore_tag_output) { "restore_here\n" }
it "checks out the last save restoration point and deletes the marker tag" do
expect(ipc).to receive(:shellout!)
.with(%Q{git #{git_flags} tag -l "restore_here"})
.and_return(restore_tag_cmd)
expect(ipc).to receive(:shellout!)
.with(%Q{git #{git_flags} tag -l "#{ipc.tag}"})
.and_return(tag_cmd)
expect(ipc).to receive(:shellout!)
.with(%Q{git #{git_flags} checkout -f restore_here})
expect(ipc).to receive(:shellout!)
.with(%Q{git #{git_flags} tag -d restore_here})
ipc.restore
end
end
describe "if the restore marker tag does not exist" do
let(:git_restore_tag_output) { "\n" }
it "does nothing" do
expect(ipc).to receive(:shellout!)
.with(%Q{git #{git_flags} tag -l "restore_here"})
.and_return(restore_tag_cmd)
expect(ipc).to receive(:shellout!)
.with(%Q{git #{git_flags} tag -l "#{ipc.tag}"})
.and_return(tag_cmd)
ipc.restore
end
end
end
end
describe "#git_cmd" do
let(:terrible_install_dir) { %q{/opt/why please don't do this} }
before(:each) do
allow(project).to receive(:install_dir)
.and_return(terrible_install_dir)
allow(ipc).to receive(:shellout!)
.with(%Q{git #{git_flags} version})
.and_return("git version 2.11.0")
end
it "doesn't mangle an #install_dir with spaces" do
expect(ipc.send(:install_dir)).to eq(terrible_install_dir)
expect(ipc).to receive(:shellout!)
.with(%Q{git #{git_flags} version})
ipc.send(:git_cmd, "version")
end
end
end
end