puppet 2.7.5 → 2.7.6
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of puppet might be problematic. Click here for more details.
- data/CHANGELOG +121 -0
- data/conf/redhat/puppet.spec +16 -7
- data/lib/puppet.rb +1 -1
- data/lib/puppet/application/cert.rb +17 -3
- data/lib/puppet/application/device.rb +1 -0
- data/lib/puppet/application/kick.rb +0 -2
- data/lib/puppet/application/resource.rb +73 -66
- data/lib/puppet/configurer/plugin_handler.rb +6 -2
- data/lib/puppet/defaults.rb +60 -5
- data/lib/puppet/face/ca.rb +11 -2
- data/lib/puppet/face/certificate.rb +33 -4
- data/lib/puppet/file_serving/fileset.rb +1 -1
- data/lib/puppet/file_serving/indirection_hooks.rb +2 -2
- data/lib/puppet/file_serving/metadata.rb +43 -4
- data/lib/puppet/indirector.rb +0 -1
- data/lib/puppet/indirector/request.rb +3 -4
- data/lib/puppet/indirector/resource/active_record.rb +3 -10
- data/lib/puppet/indirector/resource/ral.rb +2 -2
- data/lib/puppet/indirector/rest.rb +1 -1
- data/lib/puppet/network/handler/ca.rb +16 -106
- data/lib/puppet/network/handler/master.rb +0 -3
- data/lib/puppet/network/handler/runner.rb +1 -0
- data/lib/puppet/parser/scope.rb +10 -0
- data/lib/puppet/provider/file/posix.rb +72 -34
- data/lib/puppet/provider/file/windows.rb +100 -0
- data/lib/puppet/provider/group/windows_adsi.rb +2 -2
- data/lib/puppet/provider/user/windows_adsi.rb +19 -4
- data/lib/puppet/resource.rb +16 -0
- data/lib/puppet/resource/catalog.rb +1 -1
- data/lib/puppet/ssl/certificate.rb +2 -2
- data/lib/puppet/ssl/certificate_authority.rb +86 -10
- data/lib/puppet/ssl/certificate_authority/interface.rb +64 -19
- data/lib/puppet/ssl/certificate_factory.rb +112 -91
- data/lib/puppet/ssl/certificate_request.rb +88 -1
- data/lib/puppet/ssl/host.rb +20 -3
- data/lib/puppet/type/file.rb +15 -34
- data/lib/puppet/type/file/group.rb +11 -91
- data/lib/puppet/type/file/mode.rb +11 -41
- data/lib/puppet/type/file/owner.rb +18 -34
- data/lib/puppet/type/file/source.rb +22 -7
- data/lib/puppet/type/group.rb +4 -3
- data/lib/puppet/type/user.rb +4 -1
- data/lib/puppet/util.rb +59 -6
- data/lib/puppet/util/adsi.rb +11 -0
- data/lib/puppet/util/log.rb +4 -0
- data/lib/puppet/util/log/destinations.rb +7 -1
- data/lib/puppet/util/monkey_patches.rb +19 -0
- data/lib/puppet/util/network_device/config.rb +4 -5
- data/lib/puppet/util/settings.rb +5 -0
- data/lib/puppet/util/suidmanager.rb +0 -1
- data/lib/puppet/util/windows.rb +4 -0
- data/lib/puppet/util/windows/error.rb +16 -0
- data/lib/puppet/util/windows/security.rb +593 -0
- data/spec/integration/defaults_spec.rb +27 -0
- data/spec/integration/network/handler_spec.rb +1 -1
- data/spec/integration/type/file_spec.rb +382 -145
- data/spec/integration/util/windows/security_spec.rb +468 -0
- data/spec/shared_behaviours/file_serving.rb +4 -3
- data/spec/unit/application/agent_spec.rb +1 -0
- data/spec/unit/application/device_spec.rb +5 -0
- data/spec/unit/application/resource_spec.rb +62 -101
- data/spec/unit/configurer/downloader_spec.rb +2 -2
- data/spec/unit/configurer/plugin_handler_spec.rb +15 -8
- data/spec/unit/configurer_spec.rb +2 -2
- data/spec/unit/face/ca_spec.rb +34 -0
- data/spec/unit/face/certificate_spec.rb +168 -1
- data/spec/unit/file_serving/fileset_spec.rb +1 -1
- data/spec/unit/file_serving/indirection_hooks_spec.rb +1 -1
- data/spec/unit/file_serving/metadata_spec.rb +151 -107
- data/spec/unit/indirector/certificate_request/ca_spec.rb +0 -3
- data/spec/unit/indirector/direct_file_server_spec.rb +10 -9
- data/spec/unit/indirector/file_metadata/file_spec.rb +6 -4
- data/spec/unit/indirector/request_spec.rb +13 -3
- data/spec/unit/indirector/resource/active_record_spec.rb +4 -10
- data/spec/unit/indirector/resource/ral_spec.rb +6 -4
- data/spec/unit/indirector/rest_spec.rb +5 -6
- data/spec/unit/network/handler/ca_spec.rb +86 -0
- data/spec/unit/parser/collector_spec.rb +7 -7
- data/spec/unit/parser/scope_spec.rb +20 -0
- data/spec/unit/provider/file/posix_spec.rb +226 -0
- data/spec/unit/provider/file/windows_spec.rb +136 -0
- data/spec/unit/provider/group/windows_adsi_spec.rb +7 -2
- data/spec/unit/provider/user/windows_adsi_spec.rb +36 -3
- data/spec/unit/resource/catalog_spec.rb +20 -10
- data/spec/unit/resource_spec.rb +55 -8
- data/spec/unit/ssl/certificate_authority/interface_spec.rb +97 -54
- data/spec/unit/ssl/certificate_authority_spec.rb +133 -23
- data/spec/unit/ssl/certificate_factory_spec.rb +90 -70
- data/spec/unit/ssl/certificate_request_spec.rb +62 -1
- data/spec/unit/ssl/certificate_spec.rb +20 -14
- data/spec/unit/ssl/host_spec.rb +52 -6
- data/spec/unit/type/file/content_spec.rb +4 -4
- data/spec/unit/type/file/group_spec.rb +34 -96
- data/spec/unit/type/file/mode_spec.rb +88 -0
- data/spec/unit/type/file/owner_spec.rb +32 -123
- data/spec/unit/type/file/source_spec.rb +120 -41
- data/spec/unit/type/file_spec.rb +1033 -753
- data/spec/unit/type_spec.rb +19 -1
- data/spec/unit/util/adsi_spec.rb +19 -0
- data/spec/unit/util/log/destinations_spec.rb +75 -0
- data/spec/unit/util/log_spec.rb +15 -0
- data/spec/unit/util/network_device/config_spec.rb +7 -0
- data/spec/unit/util/settings_spec.rb +10 -0
- data/spec/unit/util_spec.rb +126 -13
- data/test/language/functions.rb +0 -1
- data/test/language/snippets.rb +0 -9
- data/test/lib/puppettest/exetest.rb +1 -1
- data/test/lib/puppettest/servertest.rb +0 -1
- data/test/rails/rails.rb +0 -1
- data/test/ral/type/filesources.rb +0 -60
- metadata +13 -33
- data/lib/puppet/network/client.rb +0 -174
- data/lib/puppet/network/client/ca.rb +0 -56
- data/lib/puppet/network/client/file.rb +0 -6
- data/lib/puppet/network/client/proxy.rb +0 -27
- data/lib/puppet/network/client/report.rb +0 -26
- data/lib/puppet/network/client/runner.rb +0 -10
- data/lib/puppet/network/client/status.rb +0 -4
- data/lib/puppet/network/http_server.rb +0 -3
- data/lib/puppet/network/http_server/mongrel.rb +0 -130
- data/lib/puppet/network/http_server/webrick.rb +0 -155
- data/lib/puppet/network/xmlrpc/client.rb +0 -211
- data/lib/puppet/provider/file/win32.rb +0 -72
- data/lib/puppet/sslcertificates.rb +0 -146
- data/lib/puppet/sslcertificates/ca.rb +0 -375
- data/lib/puppet/sslcertificates/certificate.rb +0 -255
- data/lib/puppet/sslcertificates/inventory.rb +0 -38
- data/lib/puppet/sslcertificates/support.rb +0 -146
- data/spec/integration/network/client_spec.rb +0 -18
- data/spec/unit/network/xmlrpc/client_spec.rb +0 -172
- data/spec/unit/sslcertificates/ca_spec.rb +0 -106
- data/test/certmgr/certmgr.rb +0 -308
- data/test/certmgr/inventory.rb +0 -69
- data/test/certmgr/support.rb +0 -105
- data/test/network/client/ca.rb +0 -69
- data/test/network/client/dipper.rb +0 -34
- data/test/network/handler/ca.rb +0 -273
- data/test/network/server/mongrel_test.rb +0 -99
- data/test/network/server/webrick.rb +0 -111
- data/test/network/xmlrpc/client.rb +0 -45
@@ -1,5 +1,6 @@
|
|
1
1
|
#!/usr/bin/env rspec
|
2
2
|
require 'spec_helper'
|
3
|
+
require 'uri'
|
3
4
|
|
4
5
|
source = Puppet::Type.type(:file).attrclass(:source)
|
5
6
|
describe Puppet::Type.type(:file).attrclass(:source) do
|
@@ -8,26 +9,83 @@ describe Puppet::Type.type(:file).attrclass(:source) do
|
|
8
9
|
before do
|
9
10
|
# Wow that's a messy interface to the resource.
|
10
11
|
@resource = stub 'resource', :[]= => nil, :property => nil, :catalog => stub("catalog", :dependent_data_expired? => false), :line => 0, :file => ''
|
11
|
-
@foobar = make_absolute("/foo/bar")
|
12
|
-
@feebooz = make_absolute("/fee/booz")
|
12
|
+
@foobar = make_absolute("/foo/bar baz")
|
13
|
+
@feebooz = make_absolute("/fee/booz baz")
|
14
|
+
|
15
|
+
@foobar_uri = URI.unescape(Puppet::Util.path_to_uri(@foobar).to_s)
|
16
|
+
@feebooz_uri = URI.unescape(Puppet::Util.path_to_uri(@feebooz).to_s)
|
13
17
|
end
|
14
18
|
|
15
19
|
it "should be a subclass of Parameter" do
|
16
20
|
source.superclass.must == Puppet::Parameter
|
17
21
|
end
|
18
22
|
|
19
|
-
describe "
|
23
|
+
describe "#validate" do
|
24
|
+
let(:path) { tmpfile('file_source_validate') }
|
25
|
+
let(:resource) { Puppet::Type.type(:file).new(:path => path) }
|
26
|
+
|
20
27
|
it "should fail if the set values are not URLs" do
|
21
|
-
s = source.new(:resource => @resource)
|
22
28
|
URI.expects(:parse).with('foo').raises RuntimeError
|
23
29
|
|
24
|
-
lambda {
|
30
|
+
lambda { resource[:source] = %w{foo} }.must raise_error(Puppet::Error)
|
25
31
|
end
|
26
32
|
|
27
33
|
it "should fail if the URI is not a local file, file URI, or puppet URI" do
|
28
|
-
|
34
|
+
lambda { resource[:source] = %w{http://foo/bar} }.must raise_error(Puppet::Error, /Cannot use URLs of type 'http' as source for fileserving/)
|
35
|
+
end
|
36
|
+
|
37
|
+
it "should strip trailing forward slashes", :unless => Puppet.features.microsoft_windows? do
|
38
|
+
resource[:source] = "/foo/bar\\//"
|
39
|
+
resource[:source].should == %w{file:/foo/bar\\}
|
40
|
+
end
|
41
|
+
|
42
|
+
it "should strip trailing forward and backslashes", :if => Puppet.features.microsoft_windows? do
|
43
|
+
resource[:source] = "X:/foo/bar\\//"
|
44
|
+
resource[:source].should == %w{file:/X:/foo/bar}
|
45
|
+
end
|
46
|
+
|
47
|
+
it "should accept an array of sources" do
|
48
|
+
resource[:source] = %w{file:///foo/bar puppet://host:8140/foo/bar}
|
49
|
+
resource[:source].should == %w{file:///foo/bar puppet://host:8140/foo/bar}
|
50
|
+
end
|
29
51
|
|
30
|
-
|
52
|
+
it "should accept file path characters that are not valid in URI" do
|
53
|
+
resource[:source] = 'file:///foo bar'
|
54
|
+
end
|
55
|
+
|
56
|
+
it "should reject relative URI sources" do
|
57
|
+
lambda { resource[:source] = 'foo/bar' }.must raise_error(Puppet::Error)
|
58
|
+
end
|
59
|
+
|
60
|
+
it "should reject opaque sources" do
|
61
|
+
lambda { resource[:source] = 'mailto:foo@com' }.must raise_error(Puppet::Error)
|
62
|
+
end
|
63
|
+
|
64
|
+
it "should accept URI authority component" do
|
65
|
+
resource[:source] = 'file://host/foo'
|
66
|
+
resource[:source].should == %w{file://host/foo}
|
67
|
+
end
|
68
|
+
|
69
|
+
it "should accept when URI authority is absent" do
|
70
|
+
resource[:source] = 'file:///foo/bar'
|
71
|
+
resource[:source].should == %w{file:///foo/bar}
|
72
|
+
end
|
73
|
+
end
|
74
|
+
|
75
|
+
describe "#munge" do
|
76
|
+
let(:path) { tmpfile('file_source_munge') }
|
77
|
+
let(:resource) { Puppet::Type.type(:file).new(:path => path) }
|
78
|
+
|
79
|
+
it "should prefix file scheme to absolute paths" do
|
80
|
+
resource[:source] = path
|
81
|
+
resource[:source].should == [URI.unescape(Puppet::Util.path_to_uri(path).to_s)]
|
82
|
+
end
|
83
|
+
|
84
|
+
%w[file puppet].each do |scheme|
|
85
|
+
it "should not prefix valid #{scheme} URIs" do
|
86
|
+
resource[:source] = "#{scheme}:///foo bar"
|
87
|
+
resource[:source].should == ["#{scheme}:///foo bar"]
|
88
|
+
end
|
31
89
|
end
|
32
90
|
end
|
33
91
|
|
@@ -49,30 +107,30 @@ describe Puppet::Type.type(:file).attrclass(:source) do
|
|
49
107
|
|
50
108
|
it "should collect its metadata using the Metadata class if it is not already set" do
|
51
109
|
@source = source.new(:resource => @resource, :value => @foobar)
|
52
|
-
Puppet::FileServing::Metadata.indirection.expects(:find).with(@
|
110
|
+
Puppet::FileServing::Metadata.indirection.expects(:find).with(@foobar_uri).returns @metadata
|
53
111
|
@source.metadata
|
54
112
|
end
|
55
113
|
|
56
114
|
it "should use the metadata from the first found source" do
|
57
115
|
metadata = stub 'metadata', :source= => nil
|
58
116
|
@source = source.new(:resource => @resource, :value => [@foobar, @feebooz])
|
59
|
-
Puppet::FileServing::Metadata.indirection.expects(:find).with(@
|
60
|
-
Puppet::FileServing::Metadata.indirection.expects(:find).with(@
|
117
|
+
Puppet::FileServing::Metadata.indirection.expects(:find).with(@foobar_uri).returns nil
|
118
|
+
Puppet::FileServing::Metadata.indirection.expects(:find).with(@feebooz_uri).returns metadata
|
61
119
|
@source.metadata.should equal(metadata)
|
62
120
|
end
|
63
121
|
|
64
122
|
it "should store the found source as the metadata's source" do
|
65
123
|
metadata = mock 'metadata'
|
66
124
|
@source = source.new(:resource => @resource, :value => @foobar)
|
67
|
-
Puppet::FileServing::Metadata.indirection.expects(:find).with(@
|
125
|
+
Puppet::FileServing::Metadata.indirection.expects(:find).with(@foobar_uri).returns metadata
|
68
126
|
|
69
|
-
metadata.expects(:source=).with(@
|
127
|
+
metadata.expects(:source=).with(@foobar_uri)
|
70
128
|
@source.metadata
|
71
129
|
end
|
72
130
|
|
73
131
|
it "should fail intelligently if an exception is encountered while querying for metadata" do
|
74
132
|
@source = source.new(:resource => @resource, :value => @foobar)
|
75
|
-
Puppet::FileServing::Metadata.indirection.expects(:find).with(@
|
133
|
+
Puppet::FileServing::Metadata.indirection.expects(:find).with(@foobar_uri).raises RuntimeError
|
76
134
|
|
77
135
|
@source.expects(:fail).raises ArgumentError
|
78
136
|
lambda { @source.metadata }.should raise_error(ArgumentError)
|
@@ -80,7 +138,7 @@ describe Puppet::Type.type(:file).attrclass(:source) do
|
|
80
138
|
|
81
139
|
it "should fail if no specified sources can be found" do
|
82
140
|
@source = source.new(:resource => @resource, :value => @foobar)
|
83
|
-
Puppet::FileServing::Metadata.indirection.expects(:find).with(@
|
141
|
+
Puppet::FileServing::Metadata.indirection.expects(:find).with(@foobar_uri).returns nil
|
84
142
|
|
85
143
|
@source.expects(:fail).raises RuntimeError
|
86
144
|
|
@@ -185,67 +243,88 @@ describe Puppet::Type.type(:file).attrclass(:source) do
|
|
185
243
|
end
|
186
244
|
|
187
245
|
context "when accessing source properties" do
|
188
|
-
|
189
|
-
|
190
|
-
|
191
|
-
@source.stubs(:metadata).returns(@metadata)
|
192
|
-
end
|
246
|
+
let(:path) { tmpfile('file_resource') }
|
247
|
+
let(:resource) { Puppet::Type.type(:file).new(:path => path) }
|
248
|
+
let(:sourcepath) { tmpfile('file_source') }
|
193
249
|
|
194
250
|
describe "for local sources" do
|
195
|
-
before
|
196
|
-
|
197
|
-
@metadata.stubs(:source).returns("file:///path/to/source")
|
251
|
+
before :each do
|
252
|
+
FileUtils.touch(sourcepath)
|
198
253
|
end
|
199
254
|
|
200
|
-
|
201
|
-
|
255
|
+
describe "on POSIX systems", :if => Puppet.features.posix? do
|
256
|
+
['', "file:", "file://"].each do |prefix|
|
257
|
+
it "with prefix '#{prefix}' should be local" do
|
258
|
+
resource[:source] = "#{prefix}#{sourcepath}"
|
259
|
+
resource.parameter(:source).must be_local
|
260
|
+
end
|
261
|
+
|
262
|
+
it "should be able to return the metadata source full path" do
|
263
|
+
resource[:source] = "#{prefix}#{sourcepath}"
|
264
|
+
resource.parameter(:source).full_path.should == sourcepath
|
265
|
+
end
|
266
|
+
end
|
202
267
|
end
|
203
268
|
|
204
|
-
|
205
|
-
|
206
|
-
|
207
|
-
|
269
|
+
describe "on Windows systems", :if => Puppet.features.microsoft_windows? do
|
270
|
+
['', "file:/", "file:///"].each do |prefix|
|
271
|
+
it "should be local with prefix '#{prefix}'" do
|
272
|
+
resource[:source] = "#{prefix}#{sourcepath}"
|
273
|
+
resource.parameter(:source).must be_local
|
274
|
+
end
|
275
|
+
|
276
|
+
it "should be able to return the metadata source full path" do
|
277
|
+
resource[:source] = "#{prefix}#{sourcepath}"
|
278
|
+
resource.parameter(:source).full_path.should == sourcepath
|
279
|
+
end
|
280
|
+
|
281
|
+
it "should convert backslashes to forward slashes" do
|
282
|
+
resource[:source] = "#{prefix}#{sourcepath.gsub(/\\/, '/')}"
|
283
|
+
end
|
284
|
+
end
|
208
285
|
|
209
|
-
|
210
|
-
@source.full_path.should == "/path/to/source"
|
286
|
+
it "should be UNC with two slashes"
|
211
287
|
end
|
212
288
|
end
|
213
289
|
|
214
290
|
describe "for remote sources" do
|
291
|
+
let(:sourcepath) { "/path/to/source" }
|
292
|
+
let(:uri) { URI::Generic.build(:scheme => 'puppet', :host => 'server', :port => 8192, :path => sourcepath).to_s }
|
293
|
+
|
215
294
|
before(:each) do
|
216
|
-
|
217
|
-
|
295
|
+
metadata = Puppet::FileServing::Metadata.new(path, :source => uri, 'type' => 'file')
|
296
|
+
#metadata = stub('remote', :ftype => "file", :source => uri)
|
297
|
+
Puppet::FileServing::Metadata.indirection.stubs(:find).with(uri).returns metadata
|
298
|
+
resource[:source] = uri
|
218
299
|
end
|
219
300
|
|
220
301
|
it "should not be local" do
|
221
|
-
|
302
|
+
resource.parameter(:source).should_not be_local
|
222
303
|
end
|
223
304
|
|
224
305
|
it "should be able to return the metadata source full path" do
|
225
|
-
|
306
|
+
resource.parameter(:source).full_path.should == "/path/to/source"
|
226
307
|
end
|
227
308
|
|
228
309
|
it "should be able to return the source server" do
|
229
|
-
|
310
|
+
resource.parameter(:source).server.should == "server"
|
230
311
|
end
|
231
312
|
|
232
313
|
it "should be able to return the source port" do
|
233
|
-
|
314
|
+
resource.parameter(:source).port.should == 8192
|
234
315
|
end
|
235
316
|
|
236
317
|
describe "which don't specify server or port" do
|
237
|
-
|
238
|
-
@metadata.stubs(:source).returns("puppet:///path/to/source")
|
239
|
-
end
|
318
|
+
let(:uri) { "puppet:///path/to/source" }
|
240
319
|
|
241
320
|
it "should return the default source server" do
|
242
321
|
Puppet.settings.expects(:[]).with(:server).returns("myserver")
|
243
|
-
|
322
|
+
resource.parameter(:source).server.should == "myserver"
|
244
323
|
end
|
245
324
|
|
246
325
|
it "should return the default source port" do
|
247
326
|
Puppet.settings.expects(:[]).with(:masterport).returns(1234)
|
248
|
-
|
327
|
+
resource.parameter(:source).port.should == 1234
|
249
328
|
end
|
250
329
|
end
|
251
330
|
end
|
data/spec/unit/type/file_spec.rb
CHANGED
@@ -2,622 +2,635 @@
|
|
2
2
|
require 'spec_helper'
|
3
3
|
|
4
4
|
describe Puppet::Type.type(:file) do
|
5
|
+
include PuppetSpec::Files
|
6
|
+
|
7
|
+
let(:path) { tmpfile('file_testing') }
|
8
|
+
let(:file) { described_class.new(:path => path, :catalog => catalog) }
|
9
|
+
let(:provider) { file.provider }
|
10
|
+
let(:catalog) { Puppet::Resource::Catalog.new }
|
11
|
+
|
5
12
|
before do
|
6
|
-
Puppet.settings.stubs(:use)
|
7
13
|
@real_posix = Puppet.features.posix?
|
8
14
|
Puppet.features.stubs("posix?").returns(true)
|
9
|
-
|
10
|
-
@path = Tempfile.new("puppetspec")
|
11
|
-
pathname = @path.path
|
12
|
-
@path.close!()
|
13
|
-
@path = pathname
|
14
|
-
@file = Puppet::Type::File.new(:name => @path)
|
15
|
-
|
16
|
-
@catalog = Puppet::Resource::Catalog.new
|
17
|
-
@file.catalog = @catalog
|
18
15
|
end
|
19
16
|
|
20
|
-
describe "
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
it "should consider #{value} to enable recursion" do
|
26
|
-
@file[:recurse] = value
|
27
|
-
@file.must be_recurse
|
17
|
+
describe "the path parameter" do
|
18
|
+
describe "on POSIX systems", :if => Puppet.features.posix? do
|
19
|
+
it "should remove trailing slashes" do
|
20
|
+
file[:path] = "/foo/bar/baz/"
|
21
|
+
file[:path].should == "/foo/bar/baz"
|
28
22
|
end
|
29
|
-
end
|
30
23
|
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
@file.should_not be_recurse
|
24
|
+
it "should remove double slashes" do
|
25
|
+
file[:path] = "/foo/bar//baz"
|
26
|
+
file[:path].should == "/foo/bar/baz"
|
35
27
|
end
|
36
|
-
end
|
37
|
-
end
|
38
|
-
|
39
|
-
describe "#write" do
|
40
|
-
it "should propagate failures encountered when renaming the temporary file" do
|
41
|
-
File.stubs(:open)
|
42
28
|
|
43
|
-
|
44
|
-
|
29
|
+
it "should remove trailing double slashes" do
|
30
|
+
file[:path] = "/foo/bar/baz//"
|
31
|
+
file[:path].should == "/foo/bar/baz"
|
32
|
+
end
|
45
33
|
|
46
|
-
|
34
|
+
it "should leave a single slash alone" do
|
35
|
+
file[:path] = "/"
|
36
|
+
file[:path].should == "/"
|
37
|
+
end
|
47
38
|
|
48
|
-
|
49
|
-
|
39
|
+
it "should accept a double-slash at the start of the path" do
|
40
|
+
expect {
|
41
|
+
file[:path] = "//tmp/xxx"
|
42
|
+
# REVISIT: This should be wrong, later. See the next test.
|
43
|
+
# --daniel 2011-01-31
|
44
|
+
file[:path].should == '/tmp/xxx'
|
45
|
+
}.should_not raise_error
|
46
|
+
end
|
50
47
|
|
51
|
-
|
48
|
+
# REVISIT: This is pending, because I don't want to try and audit the
|
49
|
+
# entire codebase to make sure we get this right. POSIX treats two (and
|
50
|
+
# exactly two) '/' characters at the start of the path specially.
|
51
|
+
#
|
52
|
+
# See sections 3.2 and 4.11, which allow DomainOS to be all special like
|
53
|
+
# and still have the POSIX branding and all. --daniel 2011-01-31
|
54
|
+
it "should preserve the double-slash at the start of the path"
|
52
55
|
end
|
53
56
|
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
file = Puppet::Type::File.new(:name => "/my/file", :backup => "puppet")
|
60
|
-
file.stubs(:validate_checksum?).returns(false)
|
61
|
-
file.stubs(:property).with(:content).returns(property)
|
57
|
+
describe "on Windows systems", :if => Puppet.features.microsoft_windows? do
|
58
|
+
it "should remove trailing slashes" do
|
59
|
+
file[:path] = "X:/foo/bar/baz/"
|
60
|
+
file[:path].should == "X:/foo/bar/baz"
|
61
|
+
end
|
62
62
|
|
63
|
-
|
63
|
+
it "should remove double slashes" do
|
64
|
+
file[:path] = "X:/foo/bar//baz"
|
65
|
+
file[:path].should == "X:/foo/bar/baz"
|
66
|
+
end
|
64
67
|
|
65
|
-
|
66
|
-
|
68
|
+
it "should remove trailing double slashes" do
|
69
|
+
file[:path] = "X:/foo/bar/baz//"
|
70
|
+
file[:path].should == "X:/foo/bar/baz"
|
71
|
+
end
|
67
72
|
|
68
|
-
|
69
|
-
|
73
|
+
it "should leave a drive letter with a slash alone", :'fails_on_ruby_1.9.2' => true do
|
74
|
+
file[:path] = "X:/"
|
75
|
+
file[:path].should == "X:/"
|
76
|
+
end
|
70
77
|
|
71
|
-
it "should
|
72
|
-
|
73
|
-
|
78
|
+
it "should not accept a drive letter without a slash", :'fails_on_ruby_1.9.2' => true do
|
79
|
+
lambda { file[:path] = "X:" }.should raise_error(/File paths must be fully qualified/)
|
80
|
+
end
|
74
81
|
|
75
|
-
|
76
|
-
|
82
|
+
describe "when using UNC filenames", :if => Puppet.features.microsoft_windows?, :'fails_on_ruby_1.9.2' => true do
|
83
|
+
before :each do
|
84
|
+
pending("UNC file paths not yet supported")
|
85
|
+
end
|
77
86
|
|
78
|
-
|
79
|
-
|
80
|
-
|
87
|
+
it "should remove trailing slashes" do
|
88
|
+
file[:path] = "//server/foo/bar/baz/"
|
89
|
+
file[:path].should == "//server/foo/bar/baz"
|
90
|
+
end
|
81
91
|
|
82
|
-
|
83
|
-
|
92
|
+
it "should remove double slashes" do
|
93
|
+
file[:path] = "//server/foo/bar//baz"
|
94
|
+
file[:path].should == "//server/foo/bar/baz"
|
95
|
+
end
|
84
96
|
|
85
|
-
|
86
|
-
|
87
|
-
|
97
|
+
it "should remove trailing double slashes" do
|
98
|
+
file[:path] = "//server/foo/bar/baz//"
|
99
|
+
file[:path].should == "//server/foo/bar/baz"
|
100
|
+
end
|
88
101
|
|
89
|
-
|
90
|
-
|
102
|
+
it "should remove a trailing slash from a sharename" do
|
103
|
+
file[:path] = "//server/foo/"
|
104
|
+
file[:path].should == "//server/foo"
|
105
|
+
end
|
91
106
|
|
92
|
-
|
107
|
+
it "should not modify a sharename" do
|
108
|
+
file[:path] = "//server/foo"
|
109
|
+
file[:path].should == "//server/foo"
|
110
|
+
end
|
93
111
|
end
|
94
112
|
end
|
95
113
|
end
|
96
114
|
|
97
|
-
|
98
|
-
|
99
|
-
|
115
|
+
describe "the backup parameter" do
|
116
|
+
[false, 'false', :false].each do |value|
|
117
|
+
it "should disable backup if the value is #{value.inspect}" do
|
118
|
+
file[:backup] = value
|
119
|
+
file[:backup].should == false
|
120
|
+
end
|
121
|
+
end
|
100
122
|
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
123
|
+
[true, 'true', '.puppet-bak'].each do |value|
|
124
|
+
it "should use .puppet-bak if the value is #{value.inspect}" do
|
125
|
+
file[:backup] = value
|
126
|
+
file[:backup].should == '.puppet-bak'
|
127
|
+
end
|
128
|
+
end
|
105
129
|
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
130
|
+
it "should use the provided value if it's any other string" do
|
131
|
+
file[:backup] = "over there"
|
132
|
+
file[:backup].should == "over there"
|
133
|
+
end
|
110
134
|
|
111
|
-
|
112
|
-
|
135
|
+
it "should fail if backup is set to anything else" do
|
136
|
+
expect do
|
137
|
+
file[:backup] = 97
|
138
|
+
end.to raise_error(Puppet::Error, /Invalid backup type 97/)
|
139
|
+
end
|
113
140
|
end
|
114
141
|
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
142
|
+
describe "the recurse parameter" do
|
143
|
+
it "should default to recursion being disabled" do
|
144
|
+
file[:recurse].should be_false
|
145
|
+
end
|
119
146
|
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
147
|
+
[true, "true", 10, "inf", "remote"].each do |value|
|
148
|
+
it "should consider #{value} to enable recursion" do
|
149
|
+
file[:recurse] = value
|
150
|
+
file[:recurse].should be_true
|
151
|
+
end
|
152
|
+
end
|
125
153
|
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
|
154
|
+
[false, "false", 0].each do |value|
|
155
|
+
it "should consider #{value} to disable recursion" do
|
156
|
+
file[:recurse] = value
|
157
|
+
file[:recurse].should be_false
|
158
|
+
end
|
159
|
+
end
|
130
160
|
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
|
161
|
+
it "should warn if recurse is specified as a number" do
|
162
|
+
file[:recurse] = 3
|
163
|
+
message = /Setting recursion depth with the recurse parameter is now deprecated, please use recurselimit/
|
164
|
+
@logs.find { |log| log.level == :warning and log.message =~ message}.should_not be_nil
|
165
|
+
end
|
135
166
|
end
|
136
167
|
|
137
|
-
|
138
|
-
|
139
|
-
|
140
|
-
|
168
|
+
describe "the recurselimit parameter" do
|
169
|
+
it "should accept integers" do
|
170
|
+
file[:recurselimit] = 12
|
171
|
+
file[:recurselimit].should == 12
|
172
|
+
end
|
141
173
|
|
142
|
-
|
143
|
-
|
144
|
-
|
145
|
-
|
174
|
+
it "should munge string numbers to number numbers" do
|
175
|
+
file[:recurselimit] = '12'
|
176
|
+
file[:recurselimit].should == 12
|
177
|
+
end
|
146
178
|
|
147
|
-
|
148
|
-
|
149
|
-
|
179
|
+
it "should fail if given a non-number" do
|
180
|
+
expect do
|
181
|
+
file[:recurselimit] = 'twelve'
|
182
|
+
end.to raise_error(Puppet::Error, /Invalid value "twelve"/)
|
183
|
+
end
|
150
184
|
end
|
151
185
|
|
152
|
-
describe "
|
153
|
-
|
154
|
-
|
155
|
-
|
156
|
-
|
157
|
-
|
158
|
-
reqs = file.autorequire
|
159
|
-
reqs[0].source.must == dir
|
160
|
-
reqs[0].target.must == file
|
186
|
+
describe "the replace parameter" do
|
187
|
+
[true, :true, :yes].each do |value|
|
188
|
+
it "should consider #{value} to be true" do
|
189
|
+
file[:replace] = value
|
190
|
+
file[:replace].should == :true
|
191
|
+
end
|
161
192
|
end
|
162
193
|
|
163
|
-
|
164
|
-
|
165
|
-
|
166
|
-
|
167
|
-
|
168
|
-
@catalog.add_resource dir
|
169
|
-
@catalog.add_resource root
|
170
|
-
reqs = file.autorequire
|
171
|
-
reqs.length.must == 1
|
172
|
-
reqs[0].source.must == dir
|
173
|
-
reqs[0].target.must == file
|
194
|
+
[false, :false, :no].each do |value|
|
195
|
+
it "should consider #{value} to be false" do
|
196
|
+
file[:replace] = value
|
197
|
+
file[:replace].should == :false
|
198
|
+
end
|
174
199
|
end
|
200
|
+
end
|
175
201
|
|
176
|
-
|
177
|
-
|
178
|
-
|
179
|
-
|
202
|
+
describe "#[]" do
|
203
|
+
it "should raise an exception" do
|
204
|
+
expect do
|
205
|
+
described_class['anything']
|
206
|
+
end.to raise_error("Global resource access is deprecated")
|
180
207
|
end
|
208
|
+
end
|
181
209
|
|
182
|
-
|
183
|
-
|
184
|
-
|
185
|
-
file.autorequire.should be_empty
|
210
|
+
describe ".instances" do
|
211
|
+
it "should return an empty array" do
|
212
|
+
described_class.instances.should == []
|
186
213
|
end
|
214
|
+
end
|
187
215
|
|
188
|
-
|
189
|
-
|
190
|
-
|
216
|
+
describe "#asuser" do
|
217
|
+
before :each do
|
218
|
+
# Mocha won't let me just stub SUIDManager.asuser to yield and return,
|
219
|
+
# but it will do exactly that if we're not root.
|
220
|
+
Puppet.features.stubs(:root?).returns false
|
191
221
|
end
|
192
222
|
|
193
|
-
it "should
|
194
|
-
file =
|
195
|
-
file[:path].
|
196
|
-
end
|
223
|
+
it "should return the desired owner if they can write to the parent directory" do
|
224
|
+
file[:owner] = 1001
|
225
|
+
FileTest.stubs(:writable?).with(File.dirname file[:path]).returns true
|
197
226
|
|
198
|
-
|
199
|
-
file = Puppet::Type::File.new(:path => "/foo/bar/baz//")
|
200
|
-
file[:path].should == "/foo/bar/baz"
|
227
|
+
file.asuser.should == 1001
|
201
228
|
end
|
202
229
|
|
203
|
-
it "should
|
204
|
-
file =
|
205
|
-
file[:path].
|
206
|
-
end
|
230
|
+
it "should return nil if the desired owner can't write to the parent directory" do
|
231
|
+
file[:owner] = 1001
|
232
|
+
FileTest.stubs(:writable?).with(File.dirname file[:path]).returns false
|
207
233
|
|
208
|
-
|
209
|
-
expect {
|
210
|
-
file = Puppet::Type::File.new(:path => "//tmp/xxx")
|
211
|
-
# REVISIT: This should be wrong, later. See the next test.
|
212
|
-
# --daniel 2011-01-31
|
213
|
-
file[:path].should == '/tmp/xxx'
|
214
|
-
}.should_not raise_error
|
234
|
+
file.asuser.should == nil
|
215
235
|
end
|
216
236
|
|
217
|
-
|
218
|
-
|
219
|
-
|
220
|
-
#
|
221
|
-
# See sections 3.2 and 4.11, which allow DomainOS to be all special like
|
222
|
-
# and still have the POSIX branding and all. --daniel 2011-01-31
|
223
|
-
it "should preserve the double-slash at the start of the path"
|
237
|
+
it "should return nil if not managing owner" do
|
238
|
+
file.asuser.should == nil
|
239
|
+
end
|
224
240
|
end
|
225
241
|
|
226
|
-
describe "
|
227
|
-
it "should
|
228
|
-
file =
|
229
|
-
|
230
|
-
@catalog.add_resource file
|
231
|
-
@catalog.add_resource dir
|
232
|
-
reqs = file.autorequire
|
233
|
-
reqs[0].source.must == dir
|
234
|
-
reqs[0].target.must == file
|
242
|
+
describe "#bucket" do
|
243
|
+
it "should return nil if backup is off" do
|
244
|
+
file[:backup] = false
|
245
|
+
file.bucket.should == nil
|
235
246
|
end
|
236
247
|
|
237
|
-
it "should
|
238
|
-
file =
|
239
|
-
dir = Puppet::Type::File.new(:path => "X:/foo")
|
240
|
-
root = Puppet::Type::File.new(:path => "X:/")
|
241
|
-
@catalog.add_resource file
|
242
|
-
@catalog.add_resource dir
|
243
|
-
@catalog.add_resource root
|
244
|
-
reqs = file.autorequire
|
245
|
-
reqs.length.must == 1
|
246
|
-
reqs[0].source.must == dir
|
247
|
-
reqs[0].target.must == file
|
248
|
-
end
|
248
|
+
it "should not return a bucket if using a file extension for backup" do
|
249
|
+
file[:backup] = '.backup'
|
249
250
|
|
250
|
-
|
251
|
-
file = Puppet::Type::File.new(:path => "X:/foo/bar/baz")
|
252
|
-
@catalog.add_resource file
|
253
|
-
file.autorequire.should be_empty
|
251
|
+
file.bucket.should == nil
|
254
252
|
end
|
255
253
|
|
256
|
-
it "should
|
257
|
-
file =
|
258
|
-
|
259
|
-
file.
|
260
|
-
end
|
254
|
+
it "should return the default filebucket if using the 'puppet' filebucket" do
|
255
|
+
file[:backup] = 'puppet'
|
256
|
+
bucket = stub('bucket')
|
257
|
+
file.stubs(:default_bucket).returns bucket
|
261
258
|
|
262
|
-
|
263
|
-
file = Puppet::Type::File.new(:path => "X:/foo/bar/baz/")
|
264
|
-
file[:path].should == "X:/foo/bar/baz"
|
259
|
+
file.bucket.should == bucket
|
265
260
|
end
|
266
261
|
|
267
|
-
it "should
|
268
|
-
file =
|
269
|
-
file[:
|
270
|
-
end
|
262
|
+
it "should fail if using a remote filebucket and no catalog exists" do
|
263
|
+
file.catalog = nil
|
264
|
+
file[:backup] = 'my_bucket'
|
271
265
|
|
272
|
-
|
273
|
-
file = Puppet::Type::File.new(:path => "X:/foo/bar/baz//")
|
274
|
-
file[:path].should == "X:/foo/bar/baz"
|
266
|
+
expect { file.bucket }.to raise_error(Puppet::Error, "Can not find filebucket for backups without a catalog")
|
275
267
|
end
|
276
268
|
|
277
|
-
it "should
|
278
|
-
file =
|
279
|
-
|
269
|
+
it "should fail if the specified filebucket isn't in the catalog" do
|
270
|
+
file[:backup] = 'my_bucket'
|
271
|
+
|
272
|
+
expect { file.bucket }.to raise_error(Puppet::Error, "Could not find filebucket my_bucket specified in backup")
|
280
273
|
end
|
281
274
|
|
282
|
-
it "should
|
283
|
-
|
275
|
+
it "should use the specified filebucket if it is in the catalog" do
|
276
|
+
file[:backup] = 'my_bucket'
|
277
|
+
filebucket = Puppet::Type.type(:filebucket).new(:name => 'my_bucket')
|
278
|
+
catalog.add_resource(filebucket)
|
279
|
+
|
280
|
+
file.bucket.should == filebucket.bucket
|
284
281
|
end
|
285
282
|
end
|
286
283
|
|
287
|
-
describe "
|
284
|
+
describe "#asuser" do
|
288
285
|
before :each do
|
289
|
-
|
286
|
+
# Mocha won't let me just stub SUIDManager.asuser to yield and return,
|
287
|
+
# but it will do exactly that if we're not root.
|
288
|
+
Puppet.features.stubs(:root?).returns false
|
290
289
|
end
|
291
290
|
|
292
|
-
it "should
|
293
|
-
file =
|
294
|
-
|
295
|
-
|
296
|
-
|
297
|
-
reqs = file.autorequire
|
298
|
-
reqs[0].source.must == dir
|
299
|
-
reqs[0].target.must == file
|
291
|
+
it "should return the desired owner if they can write to the parent directory" do
|
292
|
+
file[:owner] = 1001
|
293
|
+
FileTest.stubs(:writable?).with(File.dirname file[:path]).returns true
|
294
|
+
|
295
|
+
file.asuser.should == 1001
|
300
296
|
end
|
301
297
|
|
302
|
-
it "should
|
303
|
-
file =
|
304
|
-
|
305
|
-
|
306
|
-
|
307
|
-
@catalog.add_resource dir
|
308
|
-
@catalog.add_resource root
|
309
|
-
reqs = file.autorequire
|
310
|
-
reqs.length.must == 1
|
311
|
-
reqs[0].source.must == dir
|
312
|
-
reqs[0].target.must == file
|
298
|
+
it "should return nil if the desired owner can't write to the parent directory" do
|
299
|
+
file[:owner] = 1001
|
300
|
+
FileTest.stubs(:writable?).with(File.dirname file[:path]).returns false
|
301
|
+
|
302
|
+
file.asuser.should == nil
|
313
303
|
end
|
314
304
|
|
315
|
-
it "should
|
316
|
-
file
|
317
|
-
@catalog.add_resource file
|
318
|
-
file.autorequire.should be_empty
|
305
|
+
it "should return nil if not managing owner" do
|
306
|
+
file.asuser.should == nil
|
319
307
|
end
|
308
|
+
end
|
320
309
|
|
321
|
-
|
322
|
-
|
323
|
-
|
324
|
-
|
325
|
-
file.autorequire.should be_empty
|
310
|
+
describe "#bucket" do
|
311
|
+
it "should return nil if backup is off" do
|
312
|
+
file[:backup] = false
|
313
|
+
file.bucket.should == nil
|
326
314
|
end
|
327
315
|
|
328
|
-
it "should
|
329
|
-
file =
|
330
|
-
|
316
|
+
it "should return nil if using a file extension for backup" do
|
317
|
+
file[:backup] = '.backup'
|
318
|
+
|
319
|
+
file.bucket.should == nil
|
331
320
|
end
|
332
321
|
|
333
|
-
it "should
|
334
|
-
file =
|
335
|
-
|
322
|
+
it "should return the default filebucket if using the 'puppet' filebucket" do
|
323
|
+
file[:backup] = 'puppet'
|
324
|
+
bucket = stub('bucket')
|
325
|
+
file.stubs(:default_bucket).returns bucket
|
326
|
+
|
327
|
+
file.bucket.should == bucket
|
336
328
|
end
|
337
329
|
|
338
|
-
it "should
|
339
|
-
file =
|
340
|
-
file[:
|
330
|
+
it "should fail if using a remote filebucket and no catalog exists" do
|
331
|
+
file.catalog = nil
|
332
|
+
file[:backup] = 'my_bucket'
|
333
|
+
|
334
|
+
expect { file.bucket }.to raise_error(Puppet::Error, "Can not find filebucket for backups without a catalog")
|
341
335
|
end
|
342
336
|
|
343
|
-
it "should
|
344
|
-
file =
|
345
|
-
|
337
|
+
it "should fail if the specified filebucket isn't in the catalog" do
|
338
|
+
file[:backup] = 'my_bucket'
|
339
|
+
|
340
|
+
expect { file.bucket }.to raise_error(Puppet::Error, "Could not find filebucket my_bucket specified in backup")
|
346
341
|
end
|
347
342
|
|
348
|
-
it "should
|
349
|
-
file =
|
350
|
-
|
343
|
+
it "should use the specified filebucket if it is in the catalog" do
|
344
|
+
file[:backup] = 'my_bucket'
|
345
|
+
filebucket = Puppet::Type.type(:filebucket).new(:name => 'my_bucket')
|
346
|
+
catalog.add_resource(filebucket)
|
347
|
+
|
348
|
+
file.bucket.should == filebucket.bucket
|
351
349
|
end
|
352
350
|
end
|
353
351
|
|
354
|
-
describe "
|
355
|
-
it "should
|
356
|
-
file
|
357
|
-
file
|
352
|
+
describe "#exist?" do
|
353
|
+
it "should be considered existent if it can be stat'ed" do
|
354
|
+
file.expects(:stat).returns mock('stat')
|
355
|
+
file.must be_exist
|
358
356
|
end
|
359
357
|
|
360
|
-
it "should
|
361
|
-
file
|
362
|
-
file
|
358
|
+
it "should be considered nonexistent if it can not be stat'ed" do
|
359
|
+
file.expects(:stat).returns nil
|
360
|
+
file.must_not be_exist
|
363
361
|
end
|
364
362
|
end
|
365
363
|
|
366
|
-
describe "
|
367
|
-
|
368
|
-
|
369
|
-
|
370
|
-
end
|
364
|
+
describe "#eval_generate" do
|
365
|
+
before do
|
366
|
+
@graph = stub 'graph', :add_edge => nil
|
367
|
+
catalog.stubs(:relationship_graph).returns @graph
|
371
368
|
end
|
372
369
|
|
373
|
-
|
374
|
-
|
375
|
-
|
376
|
-
|
377
|
-
|
370
|
+
it "should recurse if recursion is enabled" do
|
371
|
+
resource = stub('resource', :[] => 'resource')
|
372
|
+
file.expects(:recurse).returns [resource]
|
373
|
+
|
374
|
+
file[:recurse] = true
|
378
375
|
|
379
|
-
|
380
|
-
Puppet::Type.type(:file).key_attributes.should == [:path]
|
376
|
+
file.eval_generate.should == [resource]
|
381
377
|
end
|
382
|
-
end
|
383
378
|
|
384
|
-
|
385
|
-
|
379
|
+
it "should not recurse if recursion is disabled" do
|
380
|
+
file.expects(:recurse).never
|
386
381
|
|
387
|
-
|
388
|
-
describe "on POSIX systems" do
|
389
|
-
before do
|
390
|
-
@basedir = tempfile
|
391
|
-
Dir.mkdir(@basedir)
|
392
|
-
@file = File.join(@basedir, "file")
|
393
|
-
@link = File.join(@basedir, "link")
|
382
|
+
file[:recurse] = false
|
394
383
|
|
395
|
-
|
396
|
-
|
384
|
+
file.eval_generate.should == []
|
385
|
+
end
|
386
|
+
end
|
397
387
|
|
398
|
-
|
399
|
-
|
400
|
-
|
388
|
+
describe "#flush" do
|
389
|
+
it "should flush all properties that respond to :flush" do
|
390
|
+
file[:source] = File.expand_path(__FILE__)
|
391
|
+
file.parameter(:source).expects(:flush)
|
392
|
+
file.flush
|
393
|
+
end
|
401
394
|
|
402
|
-
|
403
|
-
|
404
|
-
|
395
|
+
it "should reset its stat reference" do
|
396
|
+
FileUtils.touch(path)
|
397
|
+
stat1 = file.stat
|
405
398
|
|
406
|
-
|
407
|
-
@catalog.apply
|
408
|
-
# I convert them to strings so they display correctly if there's an error.
|
409
|
-
("%o" % (File.stat(@file).mode & 007777)).should == "%o" % 0644
|
410
|
-
end
|
399
|
+
file.stat.should equal(stat1)
|
411
400
|
|
412
|
-
|
413
|
-
@resource[:links] = :follow
|
414
|
-
@catalog.apply
|
401
|
+
file.flush
|
415
402
|
|
416
|
-
|
417
|
-
end
|
418
|
-
end
|
419
|
-
else # @real_posix
|
420
|
-
# should recode tests using expectations instead of using the filesystem
|
403
|
+
file.stat.should_not equal(stat1)
|
421
404
|
end
|
405
|
+
end
|
422
406
|
|
423
|
-
|
424
|
-
|
425
|
-
|
426
|
-
|
427
|
-
|
407
|
+
describe "#initialize" do
|
408
|
+
it "should remove a trailing slash from the title to create the path" do
|
409
|
+
title = File.expand_path("/abc/\n\tdef/")
|
410
|
+
file = described_class.new(:title => title)
|
411
|
+
file[:path].should == title
|
412
|
+
end
|
428
413
|
|
429
|
-
|
414
|
+
it "should set a desired 'ensure' value if none is set and 'content' is set" do
|
415
|
+
file = described_class.new(:path => path, :content => "/foo/bar")
|
416
|
+
file[:ensure].should == :file
|
430
417
|
end
|
431
|
-
end
|
432
418
|
|
433
|
-
|
434
|
-
|
419
|
+
it "should set a desired 'ensure' value if none is set and 'target' is set" do
|
420
|
+
file = described_class.new(:path => path, :target => File.expand_path(__FILE__))
|
421
|
+
file[:ensure].should == :symlink
|
422
|
+
end
|
435
423
|
end
|
436
424
|
|
437
|
-
describe "
|
438
|
-
|
439
|
-
|
440
|
-
|
441
|
-
|
425
|
+
describe "#mark_children_for_purging" do
|
426
|
+
it "should set each child's ensure to absent" do
|
427
|
+
paths = %w[foo bar baz]
|
428
|
+
children = paths.inject({}) do |children,child|
|
429
|
+
children.merge child => described_class.new(:path => File.join(path, child), :ensure => :present)
|
430
|
+
end
|
442
431
|
|
443
|
-
|
444
|
-
@resource[:links] = :follow
|
445
|
-
File.expects(:stat)
|
432
|
+
file.mark_children_for_purging(children)
|
446
433
|
|
447
|
-
|
434
|
+
children.length.should == 3
|
435
|
+
children.values.each do |child|
|
436
|
+
child[:ensure].should == :absent
|
437
|
+
end
|
448
438
|
end
|
449
439
|
|
450
|
-
it "should
|
451
|
-
|
452
|
-
File.expects(:lstat)
|
453
|
-
|
454
|
-
@resource.stat
|
455
|
-
end
|
440
|
+
it "should skip children which have a source" do
|
441
|
+
child = described_class.new(:path => path, :ensure => :present, :source => File.expand_path(__FILE__))
|
456
442
|
|
457
|
-
|
458
|
-
File.expects(:lstat).with("/foo/bar")
|
443
|
+
file.mark_children_for_purging('foo' => child)
|
459
444
|
|
460
|
-
|
445
|
+
child[:ensure].should == :present
|
461
446
|
end
|
447
|
+
end
|
462
448
|
|
463
|
-
|
464
|
-
it "should
|
465
|
-
|
466
|
-
|
467
|
-
|
449
|
+
describe "#newchild" do
|
450
|
+
it "should create a new resource relative to the parent" do
|
451
|
+
child = file.newchild('bar')
|
452
|
+
|
453
|
+
child.should be_a(described_class)
|
454
|
+
child[:path].should == File.join(file[:path], 'bar')
|
455
|
+
end
|
456
|
+
|
457
|
+
{
|
458
|
+
:ensure => :present,
|
459
|
+
:recurse => true,
|
460
|
+
:recurselimit => 5,
|
461
|
+
:target => "some_target",
|
462
|
+
:source => File.expand_path("some_source"),
|
463
|
+
}.each do |param, value|
|
464
|
+
it "should omit the #{param} parameter" do
|
465
|
+
# Make a new file, because we have to set the param at initialization
|
466
|
+
# or it wouldn't be copied regardless.
|
467
|
+
file = described_class.new(:path => path, param => value)
|
468
|
+
child = file.newchild('bar')
|
469
|
+
child[param].should_not == value
|
470
|
+
end
|
468
471
|
end
|
469
472
|
|
470
|
-
it "should
|
471
|
-
|
472
|
-
|
473
|
-
@resource.stat.should be_nil
|
474
|
-
end
|
473
|
+
it "should copy all of the parent resource's 'should' values that were set at initialization" do
|
474
|
+
parent = described_class.new(:path => path, :owner => 'root', :group => 'wheel')
|
475
475
|
|
476
|
-
|
477
|
-
File.expects(:lstat).raises(Errno::EACCES)
|
476
|
+
child = parent.newchild("my/path")
|
478
477
|
|
479
|
-
|
478
|
+
child[:owner].should == 'root'
|
479
|
+
child[:group].should == 'wheel'
|
480
480
|
end
|
481
481
|
|
482
|
-
it "should
|
483
|
-
|
484
|
-
|
485
|
-
@resource.stat.should == "mystat"
|
482
|
+
it "should not copy default values to the new child" do
|
483
|
+
child = file.newchild("my/path")
|
484
|
+
child.original_parameters.should_not include(:backup)
|
486
485
|
end
|
487
486
|
|
488
|
-
it "should
|
489
|
-
|
490
|
-
|
487
|
+
it "should not copy values to the child which were set by the source" do
|
488
|
+
file[:source] = File.expand_path(__FILE__)
|
489
|
+
metadata = stub 'metadata', :owner => "root", :group => "root", :mode => 0755, :ftype => "file", :checksum => "{md5}whatever"
|
490
|
+
file.parameter(:source).stubs(:metadata).returns metadata
|
491
491
|
|
492
|
-
|
493
|
-
@resource.catalog = catalog
|
492
|
+
file.parameter(:source).copy_source_values
|
494
493
|
|
495
|
-
|
496
|
-
|
497
|
-
@resource.stat.should equal(@resource.stat)
|
494
|
+
file.class.expects(:new).with { |params| params[:group].nil? }
|
495
|
+
file.newchild("my/path")
|
498
496
|
end
|
499
497
|
end
|
500
498
|
|
501
|
-
describe "
|
502
|
-
it "should
|
503
|
-
|
504
|
-
@resource.parameter(:source).expects(:flush)
|
505
|
-
@resource.flush
|
499
|
+
describe "#purge?" do
|
500
|
+
it "should return false if purge is not set" do
|
501
|
+
file.must_not be_purge
|
506
502
|
end
|
507
503
|
|
508
|
-
it "should
|
509
|
-
|
510
|
-
|
511
|
-
|
512
|
-
@resource.flush
|
513
|
-
@resource.stat.should == "stat2"
|
504
|
+
it "should return true if purge is set to true" do
|
505
|
+
file[:purge] = true
|
506
|
+
|
507
|
+
file.must be_purge
|
514
508
|
end
|
515
|
-
end
|
516
509
|
|
517
|
-
|
518
|
-
|
519
|
-
end
|
510
|
+
it "should return false if purge is set to false" do
|
511
|
+
file[:purge] = false
|
520
512
|
|
521
|
-
|
522
|
-
it "should use Metadata to do its recursion" do
|
523
|
-
Puppet::FileServing::Metadata.indirection.expects(:search)
|
524
|
-
@file.perform_recursion(@file[:path])
|
513
|
+
file.must_not be_purge
|
525
514
|
end
|
515
|
+
end
|
526
516
|
|
527
|
-
|
528
|
-
|
529
|
-
|
517
|
+
describe "#recurse" do
|
518
|
+
before do
|
519
|
+
file[:recurse] = true
|
520
|
+
@metadata = Puppet::FileServing::Metadata
|
530
521
|
end
|
531
522
|
|
532
|
-
|
533
|
-
|
534
|
-
|
523
|
+
describe "and a source is set" do
|
524
|
+
it "should pass the already-discovered resources to recurse_remote" do
|
525
|
+
file[:source] = File.expand_path(__FILE__)
|
526
|
+
file.stubs(:recurse_local).returns(:foo => "bar")
|
527
|
+
file.expects(:recurse_remote).with(:foo => "bar").returns []
|
528
|
+
file.recurse
|
529
|
+
end
|
535
530
|
end
|
536
531
|
|
537
|
-
|
538
|
-
|
539
|
-
|
540
|
-
|
532
|
+
describe "and a target is set" do
|
533
|
+
it "should use recurse_link" do
|
534
|
+
file[:target] = File.expand_path(__FILE__)
|
535
|
+
file.stubs(:recurse_local).returns(:foo => "bar")
|
536
|
+
file.expects(:recurse_link).with(:foo => "bar").returns []
|
537
|
+
file.recurse
|
538
|
+
end
|
541
539
|
end
|
542
540
|
|
543
|
-
it "should
|
544
|
-
|
545
|
-
|
546
|
-
@file.perform_recursion(@file[:path])
|
541
|
+
it "should use recurse_local if recurse is not remote" do
|
542
|
+
file.expects(:recurse_local).returns({})
|
543
|
+
file.recurse
|
547
544
|
end
|
548
545
|
|
549
|
-
it "should
|
550
|
-
|
551
|
-
|
552
|
-
|
546
|
+
it "should not use recurse_local if recurse is remote" do
|
547
|
+
file[:recurse] = :remote
|
548
|
+
file.expects(:recurse_local).never
|
549
|
+
file.recurse
|
553
550
|
end
|
554
551
|
|
555
|
-
it "should
|
556
|
-
|
557
|
-
|
558
|
-
|
552
|
+
it "should return the generated resources as an array sorted by file path" do
|
553
|
+
one = stub 'one', :[] => "/one"
|
554
|
+
two = stub 'two', :[] => "/one/two"
|
555
|
+
three = stub 'three', :[] => "/three"
|
556
|
+
file.expects(:recurse_local).returns(:one => one, :two => two, :three => three)
|
557
|
+
file.recurse.should == [one, two, three]
|
559
558
|
end
|
560
559
|
|
561
|
-
|
562
|
-
|
563
|
-
|
564
|
-
|
560
|
+
describe "and purging is enabled" do
|
561
|
+
before do
|
562
|
+
file[:purge] = true
|
563
|
+
end
|
564
|
+
|
565
|
+
it "should mark each file for removal" do
|
566
|
+
local = described_class.new(:path => path, :ensure => :present)
|
567
|
+
file.expects(:recurse_local).returns("local" => local)
|
568
|
+
|
569
|
+
file.recurse
|
570
|
+
local[:ensure].should == :absent
|
571
|
+
end
|
572
|
+
|
573
|
+
it "should not remove files that exist in the remote repository" do
|
574
|
+
file[:source] = File.expand_path(__FILE__)
|
575
|
+
file.expects(:recurse_local).returns({})
|
576
|
+
|
577
|
+
remote = described_class.new(:path => path, :source => File.expand_path(__FILE__), :ensure => :present)
|
578
|
+
|
579
|
+
file.expects(:recurse_remote).with { |hash| hash["remote"] = remote }
|
580
|
+
|
581
|
+
file.recurse
|
582
|
+
|
583
|
+
remote[:ensure].should_not == :absent
|
584
|
+
end
|
565
585
|
end
|
566
|
-
end
|
567
586
|
|
568
|
-
it "should have a method for performing local recursion" do
|
569
|
-
@file.must respond_to(:recurse_local)
|
570
587
|
end
|
571
588
|
|
572
|
-
describe "
|
573
|
-
|
574
|
-
|
575
|
-
|
589
|
+
describe "#remove_less_specific_files" do
|
590
|
+
it "should remove any nested files that are already in the catalog" do
|
591
|
+
foo = described_class.new :path => File.join(file[:path], 'foo')
|
592
|
+
bar = described_class.new :path => File.join(file[:path], 'bar')
|
593
|
+
baz = described_class.new :path => File.join(file[:path], 'baz')
|
576
594
|
|
577
|
-
|
578
|
-
|
579
|
-
@file.stubs(:newchild)
|
580
|
-
@file.recurse_local
|
581
|
-
end
|
595
|
+
catalog.add_resource(foo)
|
596
|
+
catalog.add_resource(bar)
|
582
597
|
|
583
|
-
|
584
|
-
@file.expects(:perform_recursion).returns nil
|
585
|
-
@file.recurse_local.should == {}
|
598
|
+
file.remove_less_specific_files([foo, bar, baz]).should == [baz]
|
586
599
|
end
|
600
|
+
end
|
587
601
|
|
588
|
-
|
589
|
-
|
590
|
-
|
591
|
-
|
592
|
-
|
602
|
+
describe "#remove_less_specific_files" do
|
603
|
+
it "should remove any nested files that are already in the catalog" do
|
604
|
+
foo = described_class.new :path => File.join(file[:path], 'foo')
|
605
|
+
bar = described_class.new :path => File.join(file[:path], 'bar')
|
606
|
+
baz = described_class.new :path => File.join(file[:path], 'baz')
|
593
607
|
|
594
|
-
|
595
|
-
|
608
|
+
catalog.add_resource(foo)
|
609
|
+
catalog.add_resource(bar)
|
596
610
|
|
597
|
-
|
598
|
-
@file.expects(:newchild).never
|
599
|
-
@file.recurse_local
|
611
|
+
file.remove_less_specific_files([foo, bar, baz]).should == [baz]
|
600
612
|
end
|
601
613
|
|
602
|
-
|
603
|
-
|
604
|
-
|
605
|
-
|
614
|
+
end
|
615
|
+
|
616
|
+
describe "#recurse?" do
|
617
|
+
it "should be true if recurse is true" do
|
618
|
+
file[:recurse] = true
|
619
|
+
file.must be_recurse
|
606
620
|
end
|
607
621
|
|
608
|
-
it "should
|
609
|
-
|
610
|
-
|
611
|
-
@file.expects(:newchild).with("my/file").returns "fiebar"
|
612
|
-
@file.recurse_local
|
622
|
+
it "should be true if recurse is remote" do
|
623
|
+
file[:recurse] = :remote
|
624
|
+
file.must be_recurse
|
613
625
|
end
|
614
|
-
end
|
615
626
|
|
616
|
-
|
617
|
-
|
627
|
+
it "should be false if recurse is false" do
|
628
|
+
file[:recurse] = false
|
629
|
+
file.must_not be_recurse
|
630
|
+
end
|
618
631
|
end
|
619
632
|
|
620
|
-
describe "
|
633
|
+
describe "#recurse_link" do
|
621
634
|
before do
|
622
635
|
@first = stub 'first', :relative_path => "first", :full_path => "/my/first", :ftype => "directory"
|
623
636
|
@second = stub 'second', :relative_path => "second", :full_path => "/my/second", :ftype => "file"
|
@@ -626,66 +639,102 @@ describe Puppet::Type.type(:file) do
|
|
626
639
|
end
|
627
640
|
|
628
641
|
it "should pass its target to the :perform_recursion method" do
|
629
|
-
|
630
|
-
|
631
|
-
|
632
|
-
|
642
|
+
file[:target] = "mylinks"
|
643
|
+
file.expects(:perform_recursion).with("mylinks").returns [@first]
|
644
|
+
file.stubs(:newchild).returns @resource
|
645
|
+
file.recurse_link({})
|
633
646
|
end
|
634
647
|
|
635
648
|
it "should ignore the recursively-found '.' file and configure the top-level file to create a directory" do
|
636
649
|
@first.stubs(:relative_path).returns "."
|
637
|
-
|
638
|
-
|
639
|
-
|
640
|
-
|
641
|
-
|
650
|
+
file[:target] = "mylinks"
|
651
|
+
file.expects(:perform_recursion).with("mylinks").returns [@first]
|
652
|
+
file.stubs(:newchild).never
|
653
|
+
file.expects(:[]=).with(:ensure, :directory)
|
654
|
+
file.recurse_link({})
|
642
655
|
end
|
643
656
|
|
644
657
|
it "should create a new child resource for each generated metadata instance's relative path that doesn't already exist in the children hash" do
|
645
|
-
|
646
|
-
|
647
|
-
|
658
|
+
file.expects(:perform_recursion).returns [@first, @second]
|
659
|
+
file.expects(:newchild).with(@first.relative_path).returns @resource
|
660
|
+
file.recurse_link("second" => @resource)
|
648
661
|
end
|
649
662
|
|
650
663
|
it "should not create a new child resource for paths that already exist in the children hash" do
|
651
|
-
|
652
|
-
|
653
|
-
|
664
|
+
file.expects(:perform_recursion).returns [@first]
|
665
|
+
file.expects(:newchild).never
|
666
|
+
file.recurse_link("first" => @resource)
|
654
667
|
end
|
655
668
|
|
656
669
|
it "should set the target to the full path of discovered file and set :ensure to :link if the file is not a directory" do
|
657
|
-
file
|
658
|
-
file.
|
659
|
-
file.expects(:[]=).with(:ensure, :link)
|
670
|
+
file.stubs(:perform_recursion).returns [@first, @second]
|
671
|
+
file.recurse_link("first" => @resource, "second" => file)
|
660
672
|
|
661
|
-
|
662
|
-
|
673
|
+
file[:ensure].should == :link
|
674
|
+
file[:target].should == "/my/second"
|
663
675
|
end
|
664
676
|
|
665
677
|
it "should :ensure to :directory if the file is a directory" do
|
666
|
-
file
|
667
|
-
file.
|
678
|
+
file.stubs(:perform_recursion).returns [@first, @second]
|
679
|
+
file.recurse_link("first" => file, "second" => @resource)
|
680
|
+
|
681
|
+
file[:ensure].should == :directory
|
682
|
+
end
|
683
|
+
|
684
|
+
it "should return a hash with both created and existing resources with the relative paths as the hash keys" do
|
685
|
+
file.expects(:perform_recursion).returns [@first, @second]
|
686
|
+
file.stubs(:newchild).returns file
|
687
|
+
file.recurse_link("second" => @resource).should == {"second" => @resource, "first" => file}
|
688
|
+
end
|
689
|
+
end
|
690
|
+
|
691
|
+
describe "#recurse_local" do
|
692
|
+
before do
|
693
|
+
@metadata = stub 'metadata', :relative_path => "my/file"
|
694
|
+
end
|
695
|
+
|
696
|
+
it "should pass its path to the :perform_recursion method" do
|
697
|
+
file.expects(:perform_recursion).with(file[:path]).returns [@metadata]
|
698
|
+
file.stubs(:newchild)
|
699
|
+
file.recurse_local
|
700
|
+
end
|
701
|
+
|
702
|
+
it "should return an empty hash if the recursion returns nothing" do
|
703
|
+
file.expects(:perform_recursion).returns nil
|
704
|
+
file.recurse_local.should == {}
|
705
|
+
end
|
706
|
+
|
707
|
+
it "should create a new child resource with each generated metadata instance's relative path" do
|
708
|
+
file.expects(:perform_recursion).returns [@metadata]
|
709
|
+
file.expects(:newchild).with(@metadata.relative_path).returns "fiebar"
|
710
|
+
file.recurse_local
|
711
|
+
end
|
712
|
+
|
713
|
+
it "should not create a new child resource for the '.' directory" do
|
714
|
+
@metadata.stubs(:relative_path).returns "."
|
668
715
|
|
669
|
-
|
670
|
-
|
716
|
+
file.expects(:perform_recursion).returns [@metadata]
|
717
|
+
file.expects(:newchild).never
|
718
|
+
file.recurse_local
|
671
719
|
end
|
672
720
|
|
673
|
-
it "should return a hash
|
674
|
-
file
|
675
|
-
|
676
|
-
|
677
|
-
@file.stubs(:newchild).returns file
|
678
|
-
@file.recurse_link("second" => @resource).should == {"second" => @resource, "first" => file}
|
721
|
+
it "should return a hash of the created resources with the relative paths as the hash keys" do
|
722
|
+
file.expects(:perform_recursion).returns [@metadata]
|
723
|
+
file.expects(:newchild).with("my/file").returns "fiebar"
|
724
|
+
file.recurse_local.should == {"my/file" => "fiebar"}
|
679
725
|
end
|
680
|
-
end
|
681
726
|
|
682
|
-
|
683
|
-
|
727
|
+
it "should set checksum_type to none if this file checksum is none" do
|
728
|
+
file[:checksum] = :none
|
729
|
+
Puppet::FileServing::Metadata.indirection.expects(:search).with { |path,params| params[:checksum_type] == :none }.returns [@metadata]
|
730
|
+
file.expects(:newchild).with("my/file").returns "fiebar"
|
731
|
+
file.recurse_local
|
732
|
+
end
|
684
733
|
end
|
685
734
|
|
686
|
-
describe "
|
735
|
+
describe "#recurse_remote" do
|
687
736
|
before do
|
688
|
-
|
737
|
+
file[:source] = "puppet://foo/bar"
|
689
738
|
|
690
739
|
@first = Puppet::FileServing::Metadata.new("/my", :relative_path => "first")
|
691
740
|
@second = Puppet::FileServing::Metadata.new("/my", :relative_path => "second")
|
@@ -698,497 +747,728 @@ describe Puppet::Type.type(:file) do
|
|
698
747
|
|
699
748
|
it "should pass its source to the :perform_recursion method" do
|
700
749
|
data = Puppet::FileServing::Metadata.new("/whatever", :relative_path => "foobar")
|
701
|
-
|
702
|
-
|
703
|
-
|
750
|
+
file.expects(:perform_recursion).with("puppet://foo/bar").returns [data]
|
751
|
+
file.stubs(:newchild).returns @resource
|
752
|
+
file.recurse_remote({})
|
704
753
|
end
|
705
754
|
|
706
755
|
it "should not recurse when the remote file is not a directory" do
|
707
756
|
data = Puppet::FileServing::Metadata.new("/whatever", :relative_path => ".")
|
708
757
|
data.stubs(:ftype).returns "file"
|
709
|
-
|
710
|
-
|
711
|
-
|
758
|
+
file.expects(:perform_recursion).with("puppet://foo/bar").returns [data]
|
759
|
+
file.expects(:newchild).never
|
760
|
+
file.recurse_remote({})
|
712
761
|
end
|
713
762
|
|
714
763
|
it "should set the source of each returned file to the searched-for URI plus the found relative path" do
|
715
764
|
@first.expects(:source=).with File.join("puppet://foo/bar", @first.relative_path)
|
716
|
-
|
717
|
-
|
718
|
-
|
765
|
+
file.expects(:perform_recursion).returns [@first]
|
766
|
+
file.stubs(:newchild).returns @resource
|
767
|
+
file.recurse_remote({})
|
719
768
|
end
|
720
769
|
|
721
770
|
it "should create a new resource for any relative file paths that do not already have a resource" do
|
722
|
-
|
723
|
-
|
724
|
-
|
771
|
+
file.stubs(:perform_recursion).returns [@first]
|
772
|
+
file.expects(:newchild).with("first").returns @resource
|
773
|
+
file.recurse_remote({}).should == {"first" => @resource}
|
725
774
|
end
|
726
775
|
|
727
776
|
it "should not create a new resource for any relative file paths that do already have a resource" do
|
728
|
-
|
729
|
-
|
730
|
-
|
777
|
+
file.stubs(:perform_recursion).returns [@first]
|
778
|
+
file.expects(:newchild).never
|
779
|
+
file.recurse_remote("first" => @resource)
|
731
780
|
end
|
732
781
|
|
733
782
|
it "should set the source of each resource to the source of the metadata" do
|
734
|
-
|
783
|
+
file.stubs(:perform_recursion).returns [@first]
|
735
784
|
@resource.stubs(:[]=)
|
736
785
|
@resource.expects(:[]=).with(:source, File.join("puppet://foo/bar", @first.relative_path))
|
737
|
-
|
786
|
+
file.recurse_remote("first" => @resource)
|
738
787
|
end
|
739
788
|
|
740
789
|
# LAK:FIXME This is a bug, but I can't think of a fix for it. Fortunately it's already
|
741
790
|
# filed, and when it's fixed, we'll just fix the whole flow.
|
742
791
|
it "should set the checksum type to :md5 if the remote file is a file" do
|
743
792
|
@first.stubs(:ftype).returns "file"
|
744
|
-
|
793
|
+
file.stubs(:perform_recursion).returns [@first]
|
745
794
|
@resource.stubs(:[]=)
|
746
795
|
@resource.expects(:[]=).with(:checksum, :md5)
|
747
|
-
|
796
|
+
file.recurse_remote("first" => @resource)
|
748
797
|
end
|
749
798
|
|
750
799
|
it "should store the metadata in the source property for each resource so the source does not have to requery the metadata" do
|
751
|
-
|
800
|
+
file.stubs(:perform_recursion).returns [@first]
|
752
801
|
@resource.expects(:parameter).with(:source).returns @parameter
|
753
802
|
|
754
803
|
@parameter.expects(:metadata=).with(@first)
|
755
804
|
|
756
|
-
|
805
|
+
file.recurse_remote("first" => @resource)
|
757
806
|
end
|
758
807
|
|
759
808
|
it "should not create a new resource for the '.' file" do
|
760
809
|
@first.stubs(:relative_path).returns "."
|
761
|
-
|
810
|
+
file.stubs(:perform_recursion).returns [@first]
|
762
811
|
|
763
|
-
|
812
|
+
file.expects(:newchild).never
|
764
813
|
|
765
|
-
|
814
|
+
file.recurse_remote({})
|
766
815
|
end
|
767
816
|
|
768
817
|
it "should store the metadata in the main file's source property if the relative path is '.'" do
|
769
818
|
@first.stubs(:relative_path).returns "."
|
770
|
-
|
819
|
+
file.stubs(:perform_recursion).returns [@first]
|
771
820
|
|
772
|
-
|
821
|
+
file.parameter(:source).expects(:metadata=).with @first
|
773
822
|
|
774
|
-
|
823
|
+
file.recurse_remote("first" => @resource)
|
775
824
|
end
|
776
825
|
|
777
826
|
describe "and multiple sources are provided" do
|
827
|
+
let(:sources) do
|
828
|
+
h = {}
|
829
|
+
%w{/one /two /three /four}.each do |key|
|
830
|
+
h[key] = URI.unescape(Puppet::Util.path_to_uri(File.expand_path(key)).to_s)
|
831
|
+
end
|
832
|
+
h
|
833
|
+
end
|
834
|
+
|
778
835
|
describe "and :sourceselect is set to :first" do
|
779
836
|
it "should create file instances for the results for the first source to return any values" do
|
780
837
|
data = Puppet::FileServing::Metadata.new("/whatever", :relative_path => "foobar")
|
781
|
-
|
782
|
-
|
783
|
-
|
784
|
-
|
785
|
-
|
786
|
-
|
787
|
-
|
838
|
+
file[:source] = sources.keys.map { |key| File.expand_path(key) }
|
839
|
+
file.expects(:perform_recursion).with(sources['/one']).returns nil
|
840
|
+
file.expects(:perform_recursion).with(sources['/two']).returns []
|
841
|
+
file.expects(:perform_recursion).with(sources['/three']).returns [data]
|
842
|
+
file.expects(:perform_recursion).with(sources['/four']).never
|
843
|
+
file.expects(:newchild).with("foobar").returns @resource
|
844
|
+
file.recurse_remote({})
|
788
845
|
end
|
789
846
|
end
|
790
847
|
|
791
848
|
describe "and :sourceselect is set to :all" do
|
792
849
|
before do
|
793
|
-
|
850
|
+
file[:sourceselect] = :all
|
794
851
|
end
|
795
852
|
|
796
853
|
it "should return every found file that is not in a previous source" do
|
797
854
|
klass = Puppet::FileServing::Metadata
|
798
|
-
|
799
|
-
|
855
|
+
file[:source] = %w{/one /two /three /four}.map {|f| File.expand_path(f) }
|
856
|
+
file.stubs(:newchild).returns @resource
|
800
857
|
|
801
858
|
one = [klass.new("/one", :relative_path => "a")]
|
802
|
-
|
803
|
-
|
859
|
+
file.expects(:perform_recursion).with(sources['/one']).returns one
|
860
|
+
file.expects(:newchild).with("a").returns @resource
|
804
861
|
|
805
862
|
two = [klass.new("/two", :relative_path => "a"), klass.new("/two", :relative_path => "b")]
|
806
|
-
|
807
|
-
|
863
|
+
file.expects(:perform_recursion).with(sources['/two']).returns two
|
864
|
+
file.expects(:newchild).with("b").returns @resource
|
808
865
|
|
809
866
|
three = [klass.new("/three", :relative_path => "a"), klass.new("/three", :relative_path => "c")]
|
810
|
-
|
811
|
-
|
867
|
+
file.expects(:perform_recursion).with(sources['/three']).returns three
|
868
|
+
file.expects(:newchild).with("c").returns @resource
|
812
869
|
|
813
|
-
|
870
|
+
file.expects(:perform_recursion).with(sources['/four']).returns []
|
814
871
|
|
815
|
-
|
872
|
+
file.recurse_remote({})
|
816
873
|
end
|
817
874
|
end
|
818
875
|
end
|
819
876
|
end
|
820
877
|
|
821
|
-
describe "
|
822
|
-
|
823
|
-
|
824
|
-
|
878
|
+
describe "#perform_recursion" do
|
879
|
+
it "should use Metadata to do its recursion" do
|
880
|
+
Puppet::FileServing::Metadata.indirection.expects(:search)
|
881
|
+
file.perform_recursion(file[:path])
|
825
882
|
end
|
826
883
|
|
827
|
-
it "should
|
828
|
-
|
884
|
+
it "should use the provided path as the key to the search" do
|
885
|
+
Puppet::FileServing::Metadata.indirection.expects(:search).with { |key, options| key == "/foo" }
|
886
|
+
file.perform_recursion("/foo")
|
829
887
|
end
|
830
|
-
end
|
831
888
|
|
832
|
-
|
833
|
-
|
834
|
-
|
889
|
+
it "should return the results of the metadata search" do
|
890
|
+
Puppet::FileServing::Metadata.indirection.expects(:search).returns "foobar"
|
891
|
+
file.perform_recursion(file[:path]).should == "foobar"
|
835
892
|
end
|
836
|
-
Puppet::Type::File::ParameterChecksum.value_collection.values.reject {|v| v == :none}.each do |checksum_type|
|
837
|
-
describe "with checksum '#{checksum_type}'" do
|
838
|
-
before do
|
839
|
-
@file[:checksum] = checksum_type
|
840
|
-
end
|
841
893
|
|
842
|
-
|
894
|
+
it "should pass its recursion value to the search" do
|
895
|
+
file[:recurse] = true
|
896
|
+
Puppet::FileServing::Metadata.indirection.expects(:search).with { |key, options| options[:recurse] == true }
|
897
|
+
file.perform_recursion(file[:path])
|
898
|
+
end
|
843
899
|
|
844
|
-
|
845
|
-
|
846
|
-
|
900
|
+
it "should pass true if recursion is remote" do
|
901
|
+
file[:recurse] = :remote
|
902
|
+
Puppet::FileServing::Metadata.indirection.expects(:search).with { |key, options| options[:recurse] == true }
|
903
|
+
file.perform_recursion(file[:path])
|
847
904
|
end
|
848
905
|
|
849
|
-
|
850
|
-
|
851
|
-
|
852
|
-
|
906
|
+
it "should pass its recursion limit value to the search" do
|
907
|
+
file[:recurselimit] = 10
|
908
|
+
Puppet::FileServing::Metadata.indirection.expects(:search).with { |key, options| options[:recurselimit] == 10 }
|
909
|
+
file.perform_recursion(file[:path])
|
910
|
+
end
|
853
911
|
|
854
|
-
|
855
|
-
|
856
|
-
|
912
|
+
it "should configure the search to ignore or manage links" do
|
913
|
+
file[:links] = :manage
|
914
|
+
Puppet::FileServing::Metadata.indirection.expects(:search).with { |key, options| options[:links] == :manage }
|
915
|
+
file.perform_recursion(file[:path])
|
916
|
+
end
|
917
|
+
|
918
|
+
it "should pass its 'ignore' setting to the search if it has one" do
|
919
|
+
file[:ignore] = %w{.svn CVS}
|
920
|
+
Puppet::FileServing::Metadata.indirection.expects(:search).with { |key, options| options[:ignore] == %w{.svn CVS} }
|
921
|
+
file.perform_recursion(file[:path])
|
857
922
|
end
|
858
923
|
end
|
859
924
|
|
860
|
-
describe "
|
861
|
-
|
862
|
-
|
925
|
+
describe "#remove_existing" do
|
926
|
+
it "should do nothing if the file doesn't exist" do
|
927
|
+
file.remove_existing(:file).should == nil
|
863
928
|
end
|
864
929
|
|
865
|
-
|
866
|
-
|
867
|
-
|
868
|
-
@file[:checksum] = checksum_type
|
869
|
-
end
|
930
|
+
it "should fail if it can't backup the file" do
|
931
|
+
file.stubs(:stat).returns stub('stat')
|
932
|
+
file.stubs(:perform_backup).returns false
|
870
933
|
|
871
|
-
|
872
|
-
lambda { @file.validate }.should_not raise_error
|
873
|
-
end
|
874
|
-
end
|
934
|
+
expect { file.remove_existing(:file) }.to raise_error(Puppet::Error, /Could not back up; will not replace/)
|
875
935
|
end
|
876
936
|
|
877
|
-
|
878
|
-
|
879
|
-
it 'should raise an exception when validating' do
|
880
|
-
@file[:checksum] = checksum_type
|
937
|
+
it "should not do anything if the file is already the right type and not a link" do
|
938
|
+
file.stubs(:stat).returns stub('stat', :ftype => 'file')
|
881
939
|
|
882
|
-
|
883
|
-
|
884
|
-
|
940
|
+
file.remove_existing(:file).should == nil
|
941
|
+
end
|
942
|
+
|
943
|
+
it "should not remove directories and should not invalidate the stat unless force is set" do
|
944
|
+
# Actually call stat to set @needs_stat to nil
|
945
|
+
file.stat
|
946
|
+
file.stubs(:stat).returns stub('stat', :ftype => 'directory')
|
947
|
+
|
948
|
+
file.remove_existing(:file)
|
949
|
+
|
950
|
+
file.instance_variable_get(:@stat).should == nil
|
951
|
+
@logs.should be_any {|log| log.level == :notice and log.message =~ /Not removing directory; use 'force' to override/}
|
952
|
+
end
|
953
|
+
|
954
|
+
it "should remove a directory if force is set" do
|
955
|
+
file[:force] = true
|
956
|
+
file.stubs(:stat).returns stub('stat', :ftype => 'directory')
|
957
|
+
|
958
|
+
FileUtils.expects(:rmtree).with(file[:path])
|
959
|
+
|
960
|
+
file.remove_existing(:file).should == true
|
961
|
+
end
|
962
|
+
|
963
|
+
it "should remove an existing file" do
|
964
|
+
file.stubs(:perform_backup).returns true
|
965
|
+
FileUtils.touch(path)
|
966
|
+
|
967
|
+
file.remove_existing(:directory).should == true
|
968
|
+
|
969
|
+
File.exists?(file[:path]).should == false
|
970
|
+
end
|
971
|
+
|
972
|
+
it "should remove an existing link", :unless => Puppet.features.microsoft_windows? do
|
973
|
+
file.stubs(:perform_backup).returns true
|
974
|
+
|
975
|
+
target = tmpfile('link_target')
|
976
|
+
FileUtils.touch(target)
|
977
|
+
FileUtils.symlink(target, path)
|
978
|
+
file[:target] = target
|
979
|
+
|
980
|
+
file.remove_existing(:directory).should == true
|
981
|
+
|
982
|
+
File.exists?(file[:path]).should == false
|
983
|
+
end
|
984
|
+
|
985
|
+
it "should fail if the file is not a file, link, or directory" do
|
986
|
+
file.stubs(:stat).returns stub('stat', :ftype => 'socket')
|
987
|
+
|
988
|
+
expect { file.remove_existing(:file) }.to raise_error(Puppet::Error, /Could not back up files of type socket/)
|
989
|
+
end
|
990
|
+
|
991
|
+
it "should invalidate the existing stat of the file" do
|
992
|
+
# Actually call stat to set @needs_stat to nil
|
993
|
+
file.stat
|
994
|
+
file.stubs(:stat).returns stub('stat', :ftype => 'file')
|
995
|
+
|
996
|
+
File.stubs(:unlink)
|
997
|
+
|
998
|
+
file.remove_existing(:directory).should == true
|
999
|
+
file.instance_variable_get(:@stat).should == :needs_stat
|
885
1000
|
end
|
886
1001
|
end
|
887
1002
|
|
888
|
-
describe "
|
889
|
-
|
890
|
-
|
891
|
-
|
1003
|
+
describe "#retrieve" do
|
1004
|
+
it "should copy the source values if the 'source' parameter is set" do
|
1005
|
+
file[:source] = File.expand_path('/foo/bar')
|
1006
|
+
file.parameter(:source).expects(:copy_source_values)
|
1007
|
+
file.retrieve
|
1008
|
+
end
|
1009
|
+
end
|
892
1010
|
|
893
|
-
|
894
|
-
|
1011
|
+
describe "#should_be_file?" do
|
1012
|
+
it "should have a method for determining if the file should be a normal file" do
|
1013
|
+
file.must respond_to(:should_be_file?)
|
895
1014
|
end
|
896
1015
|
|
897
|
-
it "should
|
898
|
-
|
899
|
-
|
900
|
-
@file.expects(:recurse).returns [resource]
|
901
|
-
@file.eval_generate.should == [resource]
|
1016
|
+
it "should be a file if :ensure is set to :file" do
|
1017
|
+
file[:ensure] = :file
|
1018
|
+
file.must be_should_be_file
|
902
1019
|
end
|
903
1020
|
|
904
|
-
it "should
|
905
|
-
|
906
|
-
|
907
|
-
|
1021
|
+
it "should be a file if :ensure is set to :present and the file exists as a normal file" do
|
1022
|
+
file.stubs(:stat).returns(mock('stat', :ftype => "file"))
|
1023
|
+
file[:ensure] = :present
|
1024
|
+
file.must be_should_be_file
|
1025
|
+
end
|
1026
|
+
|
1027
|
+
it "should not be a file if :ensure is set to something other than :file" do
|
1028
|
+
file[:ensure] = :directory
|
1029
|
+
file.must_not be_should_be_file
|
1030
|
+
end
|
1031
|
+
|
1032
|
+
it "should not be a file if :ensure is set to :present and the file exists but is not a normal file" do
|
1033
|
+
file.stubs(:stat).returns(mock('stat', :ftype => "directory"))
|
1034
|
+
file[:ensure] = :present
|
1035
|
+
file.must_not be_should_be_file
|
908
1036
|
end
|
909
1037
|
|
910
|
-
it "should
|
911
|
-
|
912
|
-
|
913
|
-
|
1038
|
+
it "should be a file if :ensure is not set and :content is" do
|
1039
|
+
file[:content] = "foo"
|
1040
|
+
file.must be_should_be_file
|
1041
|
+
end
|
914
1042
|
|
915
|
-
|
1043
|
+
it "should be a file if neither :ensure nor :content is set but the file exists as a normal file" do
|
1044
|
+
file.stubs(:stat).returns(mock("stat", :ftype => "file"))
|
1045
|
+
file.must be_should_be_file
|
1046
|
+
end
|
916
1047
|
|
917
|
-
|
1048
|
+
it "should not be a file if neither :ensure nor :content is set but the file exists but not as a normal file" do
|
1049
|
+
file.stubs(:stat).returns(mock("stat", :ftype => "directory"))
|
1050
|
+
file.must_not be_should_be_file
|
918
1051
|
end
|
919
1052
|
end
|
920
1053
|
|
921
|
-
describe "
|
1054
|
+
describe "#stat", :unless => Puppet.features.microsoft_windows? do
|
922
1055
|
before do
|
923
|
-
|
924
|
-
|
1056
|
+
target = tmpfile('link_target')
|
1057
|
+
FileUtils.touch(target)
|
1058
|
+
FileUtils.symlink(target, path)
|
1059
|
+
|
1060
|
+
file[:target] = target
|
1061
|
+
file[:links] = :manage # so we always use :lstat
|
925
1062
|
end
|
926
1063
|
|
927
|
-
|
928
|
-
|
1064
|
+
it "should stat the target if it is following links" do
|
1065
|
+
file[:links] = :follow
|
929
1066
|
|
930
|
-
|
931
|
-
@file.stubs(:recurse_local).returns(:foo => "bar")
|
932
|
-
@file.expects(:recurse_remote).with(:foo => "bar").returns []
|
933
|
-
@file.recurse
|
934
|
-
end
|
1067
|
+
file.stat.ftype.should == 'file'
|
935
1068
|
end
|
936
1069
|
|
937
|
-
|
938
|
-
|
1070
|
+
it "should stat the link if is it not following links" do
|
1071
|
+
file[:links] = :manage
|
939
1072
|
|
940
|
-
|
941
|
-
@file.stubs(:recurse_local).returns(:foo => "bar")
|
942
|
-
@file.expects(:recurse_link).with(:foo => "bar").returns []
|
943
|
-
@file.recurse
|
944
|
-
end
|
1073
|
+
file.stat.ftype.should == 'link'
|
945
1074
|
end
|
946
1075
|
|
947
|
-
it "should
|
948
|
-
|
949
|
-
@file.recurse
|
950
|
-
end
|
1076
|
+
it "should return nil if the file does not exist" do
|
1077
|
+
file[:path] = '/foo/bar/baz/non-existent'
|
951
1078
|
|
952
|
-
|
953
|
-
@file[:recurse] = :remote
|
954
|
-
@file.expects(:recurse_local).never
|
955
|
-
@file.recurse
|
1079
|
+
file.stat.should be_nil
|
956
1080
|
end
|
957
1081
|
|
958
|
-
it "should return
|
959
|
-
|
960
|
-
|
961
|
-
|
962
|
-
|
963
|
-
|
1082
|
+
it "should return nil if the file cannot be stat'ed" do
|
1083
|
+
dir = tmpfile('link_test_dir')
|
1084
|
+
child = File.join(dir, 'some_file')
|
1085
|
+
Dir.mkdir(dir)
|
1086
|
+
File.chmod(0, dir)
|
1087
|
+
|
1088
|
+
file[:path] = child
|
1089
|
+
|
1090
|
+
file.stat.should be_nil
|
1091
|
+
|
1092
|
+
# chmod it back so we can clean it up
|
1093
|
+
File.chmod(0777, dir)
|
964
1094
|
end
|
965
1095
|
|
966
|
-
|
967
|
-
|
968
|
-
|
969
|
-
end
|
1096
|
+
it "should return the stat instance" do
|
1097
|
+
file.stat.should be_a(File::Stat)
|
1098
|
+
end
|
970
1099
|
|
971
|
-
|
972
|
-
|
973
|
-
|
974
|
-
|
975
|
-
@file.expects(:recurse_local).returns("local" => local)
|
976
|
-
local.expects(:[]=).with(:ensure, :absent)
|
1100
|
+
it "should cache the stat instance" do
|
1101
|
+
file.stat.should equal(file.stat)
|
1102
|
+
end
|
1103
|
+
end
|
977
1104
|
|
978
|
-
|
979
|
-
|
1105
|
+
describe "#write" do
|
1106
|
+
it "should propagate failures encountered when renaming the temporary file" do
|
1107
|
+
File.stubs(:open)
|
1108
|
+
File.expects(:rename).raises ArgumentError
|
980
1109
|
|
981
|
-
|
982
|
-
@file["source"] = "/my/file"
|
983
|
-
@file.expects(:recurse_local).returns({})
|
1110
|
+
file[:backup] = 'puppet'
|
984
1111
|
|
985
|
-
|
986
|
-
remote.stubs(:[]).with(:source).returns "/whatever" # Thus, a remote file
|
987
|
-
remote.stubs(:[]).with(:path).returns "foo"
|
1112
|
+
file.stubs(:validate_checksum?).returns(false)
|
988
1113
|
|
989
|
-
|
990
|
-
|
1114
|
+
property = stub('content_property', :actual_content => "something", :length => "something".length)
|
1115
|
+
file.stubs(:property).with(:content).returns(property)
|
991
1116
|
|
992
|
-
|
993
|
-
end
|
1117
|
+
lambda { file.write(:content) }.should raise_error(Puppet::Error)
|
994
1118
|
end
|
995
1119
|
|
996
|
-
|
997
|
-
|
998
|
-
|
999
|
-
|
1000
|
-
|
1120
|
+
it "should delegate writing to the content property" do
|
1121
|
+
filehandle = stub_everything 'fh'
|
1122
|
+
File.stubs(:open).yields(filehandle)
|
1123
|
+
File.stubs(:rename)
|
1124
|
+
property = stub('content_property', :actual_content => "something", :length => "something".length)
|
1125
|
+
file[:backup] = 'puppet'
|
1001
1126
|
|
1002
|
-
|
1003
|
-
|
1004
|
-
@file = Puppet::Type::File.new(:name => @path, param => value, :catalog => @catalog)
|
1127
|
+
file.stubs(:validate_checksum?).returns(false)
|
1128
|
+
file.stubs(:property).with(:content).returns(property)
|
1005
1129
|
|
1006
|
-
|
1130
|
+
property.expects(:write).with(filehandle)
|
1007
1131
|
|
1008
|
-
|
1009
|
-
|
1010
|
-
end
|
1132
|
+
file.write(:content)
|
1133
|
+
end
|
1011
1134
|
|
1012
|
-
|
1013
|
-
|
1014
|
-
|
1015
|
-
|
1016
|
-
|
1017
|
-
|
1135
|
+
describe "when validating the checksum" do
|
1136
|
+
before { file.stubs(:validate_checksum?).returns(true) }
|
1137
|
+
|
1138
|
+
it "should fail if the checksum parameter and content checksums do not match" do
|
1139
|
+
checksum = stub('checksum_parameter', :sum => 'checksum_b', :sum_file => 'checksum_b')
|
1140
|
+
file.stubs(:parameter).with(:checksum).returns(checksum)
|
1018
1141
|
|
1019
|
-
|
1020
|
-
|
1021
|
-
|
1142
|
+
property = stub('content_property', :actual_content => "something", :length => "something".length, :write => 'checksum_a')
|
1143
|
+
file.stubs(:property).with(:content).returns(property)
|
1144
|
+
|
1145
|
+
lambda { file.write :NOTUSED }.should raise_error(Puppet::Error)
|
1022
1146
|
end
|
1147
|
+
end
|
1148
|
+
|
1149
|
+
describe "when not validating the checksum" do
|
1150
|
+
before { file.stubs(:validate_checksum?).returns(false) }
|
1023
1151
|
|
1024
|
-
it "should not
|
1025
|
-
|
1026
|
-
|
1027
|
-
@file.parameter(:source).stubs(:metadata).returns metadata
|
1152
|
+
it "should not fail if the checksum property and content checksums do not match" do
|
1153
|
+
checksum = stub('checksum_parameter', :sum => 'checksum_b')
|
1154
|
+
file.stubs(:parameter).with(:checksum).returns(checksum)
|
1028
1155
|
|
1029
|
-
|
1156
|
+
property = stub('content_property', :actual_content => "something", :length => "something".length, :write => 'checksum_a')
|
1157
|
+
file.stubs(:property).with(:content).returns(property)
|
1030
1158
|
|
1031
|
-
|
1032
|
-
@file.newchild("my/path")
|
1159
|
+
lambda { file.write :NOTUSED }.should_not raise_error(Puppet::Error)
|
1033
1160
|
end
|
1034
1161
|
end
|
1035
1162
|
end
|
1036
1163
|
|
1037
|
-
describe "
|
1038
|
-
it "should
|
1039
|
-
|
1164
|
+
describe "#fail_if_checksum_is_wrong" do
|
1165
|
+
it "should fail if the checksum of the file doesn't match the expected one" do
|
1166
|
+
expect do
|
1167
|
+
file.instance_eval do
|
1168
|
+
parameter(:checksum).stubs(:sum_file).returns('wrong!!')
|
1169
|
+
fail_if_checksum_is_wrong(self[:path], 'anything!')
|
1170
|
+
end
|
1171
|
+
end.to raise_error(Puppet::Error, /File written to disk did not match checksum/)
|
1040
1172
|
end
|
1041
1173
|
|
1042
|
-
it "should
|
1043
|
-
|
1174
|
+
it "should not fail if the checksum is correct" do
|
1175
|
+
file.instance_eval do
|
1176
|
+
parameter(:checksum).stubs(:sum_file).returns('anything!')
|
1177
|
+
fail_if_checksum_is_wrong(self[:path], 'anything!').should == nil
|
1178
|
+
end
|
1044
1179
|
end
|
1045
1180
|
|
1046
|
-
it "should
|
1047
|
-
|
1181
|
+
it "should not fail if the checksum is absent" do
|
1182
|
+
file.instance_eval do
|
1183
|
+
parameter(:checksum).stubs(:sum_file).returns(nil)
|
1184
|
+
fail_if_checksum_is_wrong(self[:path], 'anything!').should == nil
|
1185
|
+
end
|
1048
1186
|
end
|
1187
|
+
end
|
1049
1188
|
|
1050
|
-
|
1051
|
-
|
1052
|
-
|
1189
|
+
describe "#write_content" do
|
1190
|
+
it "should delegate writing the file to the content property" do
|
1191
|
+
io = stub('io')
|
1192
|
+
file[:content] = "some content here"
|
1193
|
+
file.property(:content).expects(:write).with(io)
|
1053
1194
|
|
1054
|
-
|
1055
|
-
|
1056
|
-
|
1057
|
-
catalog.add_resource bucket_resource
|
1195
|
+
file.send(:write_content, io)
|
1196
|
+
end
|
1197
|
+
end
|
1058
1198
|
|
1059
|
-
|
1060
|
-
|
1199
|
+
describe "#write_temporary_file?" do
|
1200
|
+
it "should be true if the file has specified content" do
|
1201
|
+
file[:content] = 'some content'
|
1061
1202
|
|
1062
|
-
file
|
1063
|
-
file.bucket.should == bucket_resource.bucket
|
1203
|
+
file.send(:write_temporary_file?).should be_true
|
1064
1204
|
end
|
1065
1205
|
|
1066
|
-
it "should
|
1067
|
-
|
1206
|
+
it "should be true if the file has specified source" do
|
1207
|
+
file[:source] = File.expand_path('/tmp/foo')
|
1068
1208
|
|
1069
|
-
file
|
1070
|
-
|
1209
|
+
file.send(:write_temporary_file?).should be_true
|
1210
|
+
end
|
1071
1211
|
|
1072
|
-
|
1073
|
-
|
1212
|
+
it "should be false if the file has neither content nor source" do
|
1213
|
+
file.send(:write_temporary_file?).should be_false
|
1214
|
+
end
|
1215
|
+
end
|
1074
1216
|
|
1075
|
-
|
1217
|
+
describe "#property_fix" do
|
1218
|
+
{
|
1219
|
+
:mode => 0777,
|
1220
|
+
:owner => 'joeuser',
|
1221
|
+
:group => 'joeusers',
|
1222
|
+
:seluser => 'seluser',
|
1223
|
+
:selrole => 'selrole',
|
1224
|
+
:seltype => 'seltype',
|
1225
|
+
:selrange => 'selrange'
|
1226
|
+
}.each do |name,value|
|
1227
|
+
it "should sync the #{name} property if it's not in sync" do
|
1228
|
+
file[name] = value
|
1229
|
+
|
1230
|
+
prop = file.property(name)
|
1231
|
+
prop.expects(:retrieve)
|
1232
|
+
prop.expects(:safe_insync?).returns false
|
1233
|
+
prop.expects(:sync)
|
1234
|
+
|
1235
|
+
file.send(:property_fix)
|
1236
|
+
end
|
1076
1237
|
end
|
1238
|
+
end
|
1077
1239
|
|
1078
|
-
|
1079
|
-
|
1080
|
-
|
1081
|
-
|
1240
|
+
describe "when autorequiring" do
|
1241
|
+
describe "directories" do
|
1242
|
+
it "should autorequire its parent directory" do
|
1243
|
+
dir = described_class.new(:path => File.dirname(path))
|
1244
|
+
catalog.add_resource file
|
1245
|
+
catalog.add_resource dir
|
1246
|
+
reqs = file.autorequire
|
1247
|
+
reqs[0].source.must == dir
|
1248
|
+
reqs[0].target.must == file
|
1249
|
+
end
|
1250
|
+
|
1251
|
+
it "should autorequire its nearest ancestor directory" do
|
1252
|
+
dir = described_class.new(:path => File.dirname(path))
|
1253
|
+
grandparent = described_class.new(:path => File.dirname(File.dirname(path)))
|
1254
|
+
catalog.add_resource file
|
1255
|
+
catalog.add_resource dir
|
1256
|
+
catalog.add_resource grandparent
|
1257
|
+
reqs = file.autorequire
|
1258
|
+
reqs.length.must == 1
|
1259
|
+
reqs[0].source.must == dir
|
1260
|
+
reqs[0].target.must == file
|
1261
|
+
end
|
1262
|
+
|
1263
|
+
it "should not autorequire anything when there is no nearest ancestor directory" do
|
1264
|
+
catalog.add_resource file
|
1265
|
+
file.autorequire.should be_empty
|
1266
|
+
end
|
1082
1267
|
|
1083
|
-
|
1084
|
-
|
1268
|
+
it "should not autorequire its parent dir if its parent dir is itself" do
|
1269
|
+
file[:path] = File.expand_path('/')
|
1270
|
+
catalog.add_resource file
|
1271
|
+
file.autorequire.should be_empty
|
1272
|
+
end
|
1085
1273
|
|
1086
|
-
|
1274
|
+
describe "on Windows systems", :if => Puppet.features.microsoft_windows? do
|
1275
|
+
describe "when using UNC filenames" do
|
1276
|
+
it "should autorequire its parent directory" do
|
1277
|
+
file[:path] = '//server/foo/bar/baz'
|
1278
|
+
dir = described_class.new(:path => "//server/foo/bar")
|
1279
|
+
catalog.add_resource file
|
1280
|
+
catalog.add_resource dir
|
1281
|
+
reqs = file.autorequire
|
1282
|
+
reqs[0].source.must == dir
|
1283
|
+
reqs[0].target.must == file
|
1284
|
+
end
|
1285
|
+
|
1286
|
+
it "should autorequire its nearest ancestor directory" do
|
1287
|
+
file = described_class.new(:path => "//server/foo/bar/baz/qux")
|
1288
|
+
dir = described_class.new(:path => "//server/foo/bar/baz")
|
1289
|
+
grandparent = described_class.new(:path => "//server/foo/bar")
|
1290
|
+
catalog.add_resource file
|
1291
|
+
catalog.add_resource dir
|
1292
|
+
catalog.add_resource grandparent
|
1293
|
+
reqs = file.autorequire
|
1294
|
+
reqs.length.must == 1
|
1295
|
+
reqs[0].source.must == dir
|
1296
|
+
reqs[0].target.must == file
|
1297
|
+
end
|
1298
|
+
|
1299
|
+
it "should not autorequire anything when there is no nearest ancestor directory" do
|
1300
|
+
file = described_class.new(:path => "//server/foo/bar/baz/qux")
|
1301
|
+
catalog.add_resource file
|
1302
|
+
file.autorequire.should be_empty
|
1303
|
+
end
|
1304
|
+
|
1305
|
+
it "should not autorequire its parent dir if its parent dir is itself" do
|
1306
|
+
file = described_class.new(:path => "//server/foo")
|
1307
|
+
catalog.add_resource file
|
1308
|
+
puts file.autorequire
|
1309
|
+
file.autorequire.should be_empty
|
1310
|
+
end
|
1311
|
+
end
|
1312
|
+
end
|
1087
1313
|
end
|
1314
|
+
end
|
1315
|
+
|
1316
|
+
describe "when managing links" do
|
1317
|
+
require 'tempfile'
|
1088
1318
|
|
1089
|
-
|
1090
|
-
|
1091
|
-
|
1092
|
-
|
1319
|
+
if @real_posix
|
1320
|
+
describe "on POSIX systems" do
|
1321
|
+
before do
|
1322
|
+
Dir.mkdir(path)
|
1323
|
+
@target = File.join(path, "target")
|
1324
|
+
@link = File.join(path, "link")
|
1093
1325
|
|
1094
|
-
|
1095
|
-
|
1326
|
+
File.open(@target, "w", 0644) { |f| f.puts "yayness" }
|
1327
|
+
File.symlink(@target, @link)
|
1096
1328
|
|
1097
|
-
|
1098
|
-
|
1329
|
+
file[:path] = @link
|
1330
|
+
file[:mode] = 0755
|
1099
1331
|
|
1100
|
-
|
1101
|
-
|
1332
|
+
catalog.add_resource file
|
1333
|
+
end
|
1334
|
+
|
1335
|
+
it "should default to managing the link" do
|
1336
|
+
catalog.apply
|
1337
|
+
# I convert them to strings so they display correctly if there's an error.
|
1338
|
+
(File.stat(@target).mode & 007777).to_s(8).should == '644'
|
1339
|
+
end
|
1340
|
+
|
1341
|
+
it "should be able to follow links" do
|
1342
|
+
file[:links] = :follow
|
1343
|
+
catalog.apply
|
1102
1344
|
|
1103
|
-
|
1345
|
+
(File.stat(@target).mode & 007777).to_s(8).should == '755'
|
1346
|
+
end
|
1347
|
+
end
|
1348
|
+
else # @real_posix
|
1349
|
+
# should recode tests using expectations instead of using the filesystem
|
1104
1350
|
end
|
1105
1351
|
|
1106
|
-
|
1107
|
-
|
1108
|
-
|
1109
|
-
|
1352
|
+
describe "on Microsoft Windows systems" do
|
1353
|
+
before do
|
1354
|
+
Puppet.features.stubs(:posix?).returns(false)
|
1355
|
+
Puppet.features.stubs(:microsoft_windows?).returns(true)
|
1356
|
+
end
|
1110
1357
|
|
1111
|
-
|
1358
|
+
it "should refuse to work with links"
|
1112
1359
|
end
|
1360
|
+
end
|
1113
1361
|
|
1114
|
-
|
1115
|
-
|
1116
|
-
file.
|
1362
|
+
describe "when using source" do
|
1363
|
+
before do
|
1364
|
+
file[:source] = File.expand_path('/one')
|
1117
1365
|
end
|
1366
|
+
Puppet::Type::File::ParameterChecksum.value_collection.values.reject {|v| v == :none}.each do |checksum_type|
|
1367
|
+
describe "with checksum '#{checksum_type}'" do
|
1368
|
+
before do
|
1369
|
+
file[:checksum] = checksum_type
|
1370
|
+
end
|
1118
1371
|
|
1119
|
-
|
1120
|
-
|
1121
|
-
|
1122
|
-
|
1372
|
+
it 'should validate' do
|
1373
|
+
|
1374
|
+
lambda { file.validate }.should_not raise_error
|
1375
|
+
end
|
1376
|
+
end
|
1123
1377
|
end
|
1124
|
-
end
|
1125
1378
|
|
1126
|
-
|
1127
|
-
|
1128
|
-
|
1129
|
-
|
1130
|
-
|
1379
|
+
describe "with checksum 'none'" do
|
1380
|
+
before do
|
1381
|
+
file[:checksum] = :none
|
1382
|
+
end
|
1383
|
+
|
1384
|
+
it 'should raise an exception when validating' do
|
1385
|
+
lambda { file.validate }.should raise_error(/You cannot specify source when using checksum 'none'/)
|
1386
|
+
end
|
1131
1387
|
end
|
1132
1388
|
end
|
1133
1389
|
|
1134
|
-
describe "
|
1390
|
+
describe "when using content" do
|
1135
1391
|
before do
|
1136
|
-
|
1392
|
+
file[:content] = 'file contents'
|
1393
|
+
end
|
1394
|
+
|
1395
|
+
(Puppet::Type::File::ParameterChecksum.value_collection.values - SOURCE_ONLY_CHECKSUMS).each do |checksum_type|
|
1396
|
+
describe "with checksum '#{checksum_type}'" do
|
1397
|
+
before do
|
1398
|
+
file[:checksum] = checksum_type
|
1399
|
+
end
|
1400
|
+
|
1401
|
+
it 'should validate' do
|
1402
|
+
lambda { file.validate }.should_not raise_error
|
1403
|
+
end
|
1404
|
+
end
|
1137
1405
|
end
|
1138
1406
|
|
1139
|
-
|
1140
|
-
|
1141
|
-
|
1142
|
-
|
1143
|
-
|
1407
|
+
SOURCE_ONLY_CHECKSUMS.each do |checksum_type|
|
1408
|
+
describe "with checksum '#{checksum_type}'" do
|
1409
|
+
it 'should raise an exception when validating' do
|
1410
|
+
file[:checksum] = checksum_type
|
1411
|
+
|
1412
|
+
lambda { file.validate }.should raise_error(/You cannot specify content when using checksum '#{checksum_type}'/)
|
1413
|
+
end
|
1414
|
+
end
|
1144
1415
|
end
|
1145
1416
|
end
|
1146
1417
|
|
1147
1418
|
describe "when auditing" do
|
1419
|
+
before :each do
|
1420
|
+
# to prevent the catalog from trying to write state.yaml
|
1421
|
+
Puppet::Util::Storage.stubs(:store)
|
1422
|
+
end
|
1423
|
+
|
1148
1424
|
it "should not fail if creating a new file if group is not set" do
|
1149
|
-
|
1150
|
-
file = Puppet::Type::File.new(:name => @path, :audit => "all", :content => "content")
|
1151
|
-
catalog = Puppet::Resource::Catalog.new
|
1425
|
+
file = described_class.new(:path => path, :audit => 'all', :content => 'content')
|
1152
1426
|
catalog.add_resource(file)
|
1153
1427
|
|
1154
|
-
|
1155
|
-
transaction = catalog.apply
|
1428
|
+
report = catalog.apply.report
|
1156
1429
|
|
1157
|
-
|
1158
|
-
File.
|
1430
|
+
report.resource_statuses["File[#{path}]"].should_not be_failed
|
1431
|
+
File.read(path).should == 'content'
|
1159
1432
|
end
|
1160
1433
|
|
1161
1434
|
it "should not log errors if creating a new file with ensure present and no content" do
|
1162
|
-
|
1163
|
-
file
|
1164
|
-
catalog = Puppet::Resource::Catalog.new
|
1435
|
+
file[:audit] = 'content'
|
1436
|
+
file[:ensure] = 'present'
|
1165
1437
|
catalog.add_resource(file)
|
1166
1438
|
|
1167
|
-
Puppet::Util::Storage.stubs(:store) # to prevent the catalog from trying to write state.yaml
|
1168
|
-
|
1169
1439
|
catalog.apply
|
1170
|
-
|
1440
|
+
|
1441
|
+
File.should be_exist(path)
|
1442
|
+
@logs.should_not be_any {|l| l.level != :notice }
|
1171
1443
|
end
|
1172
1444
|
end
|
1173
1445
|
|
1174
1446
|
describe "when specifying both source and checksum" do
|
1175
1447
|
it 'should use the specified checksum when source is first' do
|
1176
|
-
|
1177
|
-
|
1448
|
+
file[:source] = File.expand_path('/foo')
|
1449
|
+
file[:checksum] = :md5lite
|
1178
1450
|
|
1179
|
-
|
1451
|
+
file[:checksum].should == :md5lite
|
1180
1452
|
end
|
1453
|
+
|
1181
1454
|
it 'should use the specified checksum when source is last' do
|
1182
|
-
|
1183
|
-
|
1455
|
+
file[:checksum] = :md5lite
|
1456
|
+
file[:source] = File.expand_path('/foo')
|
1184
1457
|
|
1185
|
-
|
1458
|
+
file[:checksum].should == :md5lite
|
1186
1459
|
end
|
1187
1460
|
end
|
1188
1461
|
|
1189
|
-
describe "
|
1190
|
-
|
1191
|
-
|
1462
|
+
describe "when validating" do
|
1463
|
+
[[:source, :target], [:source, :content], [:target, :content]].each do |prop1,prop2|
|
1464
|
+
it "should fail if both #{prop1} and #{prop2} are specified" do
|
1465
|
+
file[prop1] = prop1 == :source ? File.expand_path("prop1 value") : "prop1 value"
|
1466
|
+
file[prop2] = "prop2 value"
|
1467
|
+
expect do
|
1468
|
+
file.validate
|
1469
|
+
end.to raise_error(Puppet::Error, /You cannot specify more than one of/)
|
1470
|
+
end
|
1192
1471
|
end
|
1193
1472
|
end
|
1473
|
+
|
1194
1474
|
end
|