3
require 'puppet/indirector/file'
6
describe Puppet::Indirector::File do
8
Puppet::Indirector::Terminus.stubs(:register_terminus_class)
10
@indirection = stub 'indirection', :name => :mystuff, :register_terminus_type => nil, :model => @model
11
Puppet::Indirector::Indirection.stubs(:instance).returns(@indirection)
14
@file_class = class Testing::MyFile < Puppet::Indirector::File
18
@searcher = @file_class.new
23
@request = stub 'request', :key => @path
26
describe "when finding files" do
27
it "should provide a method to return file contents at a specified path" do
28
@searcher.should respond_to(:find)
31
it "should use the server data directory plus the indirection name if the run_mode is master" do
32
Puppet.run_mode.expects(:master?).returns true
33
Puppet.settings.expects(:value).with(:server_datadir).returns "/my/dir"
35
@searcher.data_directory.should == File.join("/my/dir", "mystuff")
38
it "should use the client data directory plus the indirection name if the run_mode is not master" do
39
Puppet.run_mode.expects(:master?).returns false
40
Puppet.settings.expects(:value).with(:client_datadir).returns "/my/dir"
42
@searcher.data_directory.should == File.join("/my/dir", "mystuff")
45
it "should use the newest file in the data directory matching the indirection key without extension" do
46
@searcher.expects(:data_directory).returns "/data/dir"
47
@request.stubs(:key).returns "foo"
48
Dir.expects(:glob).with("/data/dir/foo.*").returns %w{/data1.stuff /data2.stuff}
50
stat1 = stub 'data1', :mtime => (Time.now - 5)
51
stat2 = stub 'data2', :mtime => Time.now
52
File.expects(:stat).with("/data1.stuff").returns stat1
53
File.expects(:stat).with("/data2.stuff").returns stat2
55
@searcher.latest_path(@request).should == "/data2.stuff"
58
it "should return nil when no files are found" do
59
@searcher.stubs(:latest_path).returns nil
61
@searcher.find(@request).should be_nil
64
it "should determine the file format from the file extension" do
65
@searcher.file_format("/data2.pson").should == "pson"
68
it "should fail if the model does not support the file format" do
69
@searcher.stubs(:latest_path).returns "/my/file.pson"
71
@model.expects(:support_format?).with("pson").returns false
73
lambda { @searcher.find(@request) }.should raise_error(ArgumentError)
77
describe "when saving files" do
79
@content = "my content"
80
@file = stub 'file', :content => @content, :path => @path, :name => @path, :render => "mydata"
81
@request.stubs(:instance).returns @file
84
it "should provide a method to save file contents at a specified path" do
85
@searcher.should respond_to(:save)
88
it "should choose the file extension based on the default format of the model" do
89
@model.expects(:default_format).returns "pson"
91
@searcher.serialization_format.should == "pson"
94
it "should place the file in the data directory, named after the indirection, key, and format" do
95
@searcher.stubs(:data_directory).returns "/my/dir"
96
@searcher.stubs(:serialization_format).returns "pson"
98
@request.stubs(:key).returns "foo"
99
@searcher.file_path(@request).should == File.join("/my/dir", "foo.pson")
102
it "should fail intelligently if the file's parent directory does not exist" do
103
@searcher.stubs(:file_path).returns "/my/dir/file.pson"
104
@searcher.stubs(:serialization_format).returns "pson"
106
@request.stubs(:key).returns "foo"
107
File.expects(:directory?).with(File.join("/my/dir")).returns(false)
109
proc { @searcher.save(@request) }.should raise_error(Puppet::Error)
112
it "should render the instance using the file format and print it to the file path" do
113
@searcher.stubs(:file_path).returns "/my/file.pson"
114
@searcher.stubs(:serialization_format).returns "pson"
116
File.stubs(:directory?).returns true
118
@request.instance.expects(:render).with("pson").returns "data"
120
fh = mock 'filehandle'
121
File.expects(:open).with("/my/file.pson", "w").yields fh
122
fh.expects(:print).with("data")
124
@searcher.save(@request)
127
it "should fail intelligently if a file cannot be written" do
128
filehandle = mock 'file'
129
File.stubs(:directory?).returns(true)
130
File.stubs(:open).yields(filehandle)
131
filehandle.expects(:print).raises(ArgumentError)
133
@searcher.stubs(:file_path).returns "/my/file.pson"
134
@model.stubs(:default_format).returns "pson"
136
@instance.stubs(:render).returns "stuff"
138
proc { @searcher.save(@request) }.should raise_error(Puppet::Error)
142
describe "when removing files" do
143
it "should provide a method to remove files" do
144
@searcher.should respond_to(:destroy)
147
it "should remove files in all formats found in the data directory that match the request key" do
148
@searcher.stubs(:data_directory).returns "/my/dir"
149
@request.stubs(:key).returns "me"
151
Dir.expects(:glob).with(File.join("/my/dir", "me.*")).returns %w{/one /two}
153
File.expects(:unlink).with("/one")
154
File.expects(:unlink).with("/two")
156
@searcher.destroy(@request)
159
it "should throw an exception if no file is found" do
160
@searcher.stubs(:data_directory).returns "/my/dir"
161
@request.stubs(:key).returns "me"
163
Dir.expects(:glob).with(File.join("/my/dir", "me.*")).returns []
165
proc { @searcher.destroy(@request) }.should raise_error(Puppet::Error)
168
it "should fail intelligently if a file cannot be removed" do
169
@searcher.stubs(:data_directory).returns "/my/dir"
170
@request.stubs(:key).returns "me"
172
Dir.expects(:glob).with(File.join("/my/dir", "me.*")).returns %w{/one}
174
File.expects(:unlink).with("/one").raises ArgumentError
176
proc { @searcher.destroy(@request) }.should raise_error(Puppet::Error)