blob: 70003faa1e5ef1d0452dd225d186b411f6d99ed3 (
plain)
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
|
#!/usr/bin/env ruby
Dir.chdir(File.dirname(__FILE__)) { (s = lambda { |f| File.exist?(f) ? require(f) : Dir.chdir("..") { s.call(f) } }).call("spec/spec_helper.rb") }
require 'puppet/util/file_locking'
class FileLocker
include Puppet::Util::FileLocking
end
describe Puppet::Util::FileLocking do
it "should have a module method for getting a read lock on files" do
Puppet::Util::FileLocking.should respond_to(:readlock)
end
it "should have a module method for getting a write lock on files" do
Puppet::Util::FileLocking.should respond_to(:writelock)
end
it "should have an instance method for getting a read lock on files" do
FileLocker.new.private_methods.should be_include("readlock")
end
it "should have an instance method for getting a write lock on files" do
FileLocker.new.private_methods.should be_include("writelock")
end
describe "when acquiring a read lock" do
it "should use a global shared mutex" do
sync = mock 'sync'
sync.expects(:synchronize).with(Sync::SH)
Puppet::Util.expects(:sync).with("/file").returns sync
Puppet::Util::FileLocking.readlock '/file'
end
it "should use a shared lock on the file" do
sync = mock 'sync'
sync.expects(:synchronize).yields
Puppet::Util.expects(:sync).with("/file").returns sync
fh = mock 'filehandle'
File.expects(:open).with("/file").yields fh
fh.expects(:lock_shared).yields "locked_fh"
result = nil
Puppet::Util::FileLocking.readlock('/file') { |l| result = l }
result.should == "locked_fh"
end
end
describe "when acquiring a write lock" do
before do
@sync = mock 'sync'
Puppet::Util.stubs(:sync).returns @sync
@sync.stubs(:synchronize).yields
end
it "should fail if the parent directory does not exist" do
FileTest.expects(:directory?).with("/my/dir").returns false
lambda { Puppet::Util::FileLocking.writelock('/my/dir/file') }.should raise_error(Puppet::DevError)
end
it "should use a global exclusive mutex" do
sync = mock 'sync'
sync.expects(:synchronize).with(Sync::EX)
Puppet::Util.expects(:sync).with("/file").returns sync
Puppet::Util::FileLocking.writelock '/file'
end
it "should use any specified mode when opening the file" do
File.expects(:open).with("/file", "w", :mymode)
Puppet::Util::FileLocking.writelock('/file', :mymode)
end
it "should use the mode of the existing file if no mode is specified" do
File.expects(:stat).with("/file").returns(mock("stat", :mode => 0755))
File.expects(:open).with("/file", "w", 0755)
Puppet::Util::FileLocking.writelock('/file')
end
it "should use 0600 as the mode if no mode is specified and the file does not exist" do
File.expects(:stat).raises(Errno::ENOENT)
File.expects(:open).with("/file", "w", 0600)
Puppet::Util::FileLocking.writelock('/file')
end
it "should create an exclusive file lock" do
fh = mock 'fh'
File.expects(:open).yields fh
fh.expects(:lock_exclusive)
Puppet::Util::FileLocking.writelock('/file')
end
it "should allow the caller to write to the locked file" do
fh = mock 'fh'
File.expects(:open).yields fh
lfh = mock 'locked_filehandle'
fh.expects(:lock_exclusive).yields(lfh)
lfh.expects(:print).with "foo"
Puppet::Util::FileLocking.writelock('/file') do |f|
f.print "foo"
end
end
end
end
|