1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220
|
#! /usr/bin/env ruby
require 'spec_helper'
require 'yaml'
require 'fileutils'
require 'puppet/transaction/persistence'
describe Puppet::Transaction::Persistence do
include PuppetSpec::Files
before(:each) do
@basepath = File.expand_path("/somepath")
end
describe "when loading from file" do
before do
Puppet.settings.stubs(:use).returns(true)
end
describe "when the file/directory does not exist" do
before(:each) do
@path = tmpfile('storage_test')
end
it "should not fail to load" do
expect(Puppet::FileSystem.exist?(@path)).to be_falsey
Puppet[:statedir] = @path
persistence = Puppet::Transaction::Persistence.new
persistence.load
Puppet[:transactionstorefile] = @path
persistence = Puppet::Transaction::Persistence.new
persistence.load
end
end
describe "when the file/directory exists" do
before(:each) do
@tmpfile = tmpfile('storage_test')
Puppet[:transactionstorefile] = @tmpfile
end
def write_state_file(contents)
File.open(@tmpfile, 'w') { |f| f.write(contents) }
end
it "should overwrite its internal state if load() is called" do
resource = "Foo[bar]"
property = "my"
value = "something"
Puppet.expects(:err).never
persistence = Puppet::Transaction::Persistence.new
persistence.set_system_value(resource, property, value)
persistence.load
expect(persistence.get_system_value(resource, property)).to eq(nil)
end
it "should restore its internal state if the file contains valid YAML" do
test_yaml = {"resources"=>{"a"=>"b"}}
write_state_file(test_yaml.to_yaml)
Puppet.expects(:err).never
persistence = Puppet::Transaction::Persistence.new
persistence.load
expect(persistence.data).to eq(test_yaml)
end
it "should initialize with a clear internal state if the file does not contain valid YAML" do
write_state_file('{ invalid')
Puppet.expects(:err).with(regexp_matches(/Transaction store file .* is corrupt/))
persistence = Puppet::Transaction::Persistence.new
persistence.load
expect(persistence.data).to eq({})
end
it "should initialize with a clear internal state if the file does not contain a hash of data" do
write_state_file("not_a_hash")
Puppet.expects(:err).with(regexp_matches(/Transaction store file .* is valid YAML but not returning a hash/))
persistence = Puppet::Transaction::Persistence.new
persistence.load
expect(persistence.data).to eq({})
end
it "should raise an error if the file does not contain valid YAML and cannot be renamed" do
write_state_file('{ invalid')
File.expects(:rename).raises(SystemCallError)
Puppet.expects(:err).with(regexp_matches(/Transaction store file .* is corrupt/))
Puppet.expects(:err).with(regexp_matches(/Unable to rename/))
persistence = Puppet::Transaction::Persistence.new
expect { persistence.load }.to raise_error(Puppet::Error, /Could not rename/)
end
it "should attempt to rename the file if the file is corrupted" do
write_state_file('{ invalid')
File.expects(:rename).at_least_once
Puppet.expects(:err).with(regexp_matches(/Transaction store file .* is corrupt/))
persistence = Puppet::Transaction::Persistence.new
persistence.load
end
it "should fail gracefully on load() if the file is not a regular file" do
FileUtils.rm_f(@tmpfile)
Dir.mkdir(@tmpfile)
Puppet.expects(:warning).with(regexp_matches(/Transaction store file .* is not a file/))
persistence = Puppet::Transaction::Persistence.new
persistence.load
end
end
end
describe "when storing to the file" do
before(:each) do
@tmpfile = tmpfile('persistence_test')
@saved = Puppet[:transactionstorefile]
Puppet[:transactionstorefile] = @tmpfile
end
it "should create the file if it does not exist" do
expect(Puppet::FileSystem.exist?(Puppet[:transactionstorefile])).to be_falsey
persistence = Puppet::Transaction::Persistence.new
persistence.save
expect(Puppet::FileSystem.exist?(Puppet[:transactionstorefile])).to be_truthy
end
it "should raise an exception if the file is not a regular file" do
Dir.mkdir(Puppet[:transactionstorefile])
persistence = Puppet::Transaction::Persistence.new
if Puppet.features.microsoft_windows?
expect do
persistence.save
end.to raise_error do |error|
expect(error).to be_a(Puppet::Util::Windows::Error)
expect(error.code).to eq(5) # ERROR_ACCESS_DENIED
end
else
expect { persistence.save }.to raise_error(Errno::EISDIR, /Is a directory/)
end
Dir.rmdir(Puppet[:transactionstorefile])
end
it "should load the same information that it saves" do
resource = "File[/tmp/foo]"
property = "content"
value = "foo"
persistence = Puppet::Transaction::Persistence.new
persistence.set_system_value(resource, property, value)
persistence.save
persistence.load
expect(persistence.get_system_value(resource, property)).to eq(value)
end
end
describe "when checking if persistence is enabled" do
let(:mock_catalog) do
mock
end
let (:persistence) do
Puppet::Transaction::Persistence.new
end
before :all do
@preferred_run_mode = Puppet.settings.preferred_run_mode
end
after :all do
Puppet.settings.preferred_run_mode = @preferred_run_mode
end
it "should not be enabled when not running in agent mode" do
Puppet.settings.preferred_run_mode = :user
mock_catalog.stubs(:host_config?).returns(true)
expect(persistence.enabled?(mock_catalog)).to be false
end
it "should not be enabled when the catalog is not the host catalog" do
Puppet.settings.preferred_run_mode = :agent
mock_catalog.stubs(:host_config?).returns(false)
expect(persistence.enabled?(mock_catalog)).to be false
end
it "should not be enabled outside of agent mode and the catalog is not the host catalog" do
Puppet.settings.preferred_run_mode = :user
mock_catalog.stubs(:host_config?).returns(false)
expect(persistence.enabled?(mock_catalog)).to be false
end
it "should be enabled in agent mode and when the catalog is the host catalog" do
Puppet.settings.preferred_run_mode = :agent
mock_catalog.stubs(:host_config?).returns(true)
expect(persistence.enabled?(mock_catalog)).to be true
end
end
end
|