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.

Files changed (140) hide show
  1. data/CHANGELOG +121 -0
  2. data/conf/redhat/puppet.spec +16 -7
  3. data/lib/puppet.rb +1 -1
  4. data/lib/puppet/application/cert.rb +17 -3
  5. data/lib/puppet/application/device.rb +1 -0
  6. data/lib/puppet/application/kick.rb +0 -2
  7. data/lib/puppet/application/resource.rb +73 -66
  8. data/lib/puppet/configurer/plugin_handler.rb +6 -2
  9. data/lib/puppet/defaults.rb +60 -5
  10. data/lib/puppet/face/ca.rb +11 -2
  11. data/lib/puppet/face/certificate.rb +33 -4
  12. data/lib/puppet/file_serving/fileset.rb +1 -1
  13. data/lib/puppet/file_serving/indirection_hooks.rb +2 -2
  14. data/lib/puppet/file_serving/metadata.rb +43 -4
  15. data/lib/puppet/indirector.rb +0 -1
  16. data/lib/puppet/indirector/request.rb +3 -4
  17. data/lib/puppet/indirector/resource/active_record.rb +3 -10
  18. data/lib/puppet/indirector/resource/ral.rb +2 -2
  19. data/lib/puppet/indirector/rest.rb +1 -1
  20. data/lib/puppet/network/handler/ca.rb +16 -106
  21. data/lib/puppet/network/handler/master.rb +0 -3
  22. data/lib/puppet/network/handler/runner.rb +1 -0
  23. data/lib/puppet/parser/scope.rb +10 -0
  24. data/lib/puppet/provider/file/posix.rb +72 -34
  25. data/lib/puppet/provider/file/windows.rb +100 -0
  26. data/lib/puppet/provider/group/windows_adsi.rb +2 -2
  27. data/lib/puppet/provider/user/windows_adsi.rb +19 -4
  28. data/lib/puppet/resource.rb +16 -0
  29. data/lib/puppet/resource/catalog.rb +1 -1
  30. data/lib/puppet/ssl/certificate.rb +2 -2
  31. data/lib/puppet/ssl/certificate_authority.rb +86 -10
  32. data/lib/puppet/ssl/certificate_authority/interface.rb +64 -19
  33. data/lib/puppet/ssl/certificate_factory.rb +112 -91
  34. data/lib/puppet/ssl/certificate_request.rb +88 -1
  35. data/lib/puppet/ssl/host.rb +20 -3
  36. data/lib/puppet/type/file.rb +15 -34
  37. data/lib/puppet/type/file/group.rb +11 -91
  38. data/lib/puppet/type/file/mode.rb +11 -41
  39. data/lib/puppet/type/file/owner.rb +18 -34
  40. data/lib/puppet/type/file/source.rb +22 -7
  41. data/lib/puppet/type/group.rb +4 -3
  42. data/lib/puppet/type/user.rb +4 -1
  43. data/lib/puppet/util.rb +59 -6
  44. data/lib/puppet/util/adsi.rb +11 -0
  45. data/lib/puppet/util/log.rb +4 -0
  46. data/lib/puppet/util/log/destinations.rb +7 -1
  47. data/lib/puppet/util/monkey_patches.rb +19 -0
  48. data/lib/puppet/util/network_device/config.rb +4 -5
  49. data/lib/puppet/util/settings.rb +5 -0
  50. data/lib/puppet/util/suidmanager.rb +0 -1
  51. data/lib/puppet/util/windows.rb +4 -0
  52. data/lib/puppet/util/windows/error.rb +16 -0
  53. data/lib/puppet/util/windows/security.rb +593 -0
  54. data/spec/integration/defaults_spec.rb +27 -0
  55. data/spec/integration/network/handler_spec.rb +1 -1
  56. data/spec/integration/type/file_spec.rb +382 -145
  57. data/spec/integration/util/windows/security_spec.rb +468 -0
  58. data/spec/shared_behaviours/file_serving.rb +4 -3
  59. data/spec/unit/application/agent_spec.rb +1 -0
  60. data/spec/unit/application/device_spec.rb +5 -0
  61. data/spec/unit/application/resource_spec.rb +62 -101
  62. data/spec/unit/configurer/downloader_spec.rb +2 -2
  63. data/spec/unit/configurer/plugin_handler_spec.rb +15 -8
  64. data/spec/unit/configurer_spec.rb +2 -2
  65. data/spec/unit/face/ca_spec.rb +34 -0
  66. data/spec/unit/face/certificate_spec.rb +168 -1
  67. data/spec/unit/file_serving/fileset_spec.rb +1 -1
  68. data/spec/unit/file_serving/indirection_hooks_spec.rb +1 -1
  69. data/spec/unit/file_serving/metadata_spec.rb +151 -107
  70. data/spec/unit/indirector/certificate_request/ca_spec.rb +0 -3
  71. data/spec/unit/indirector/direct_file_server_spec.rb +10 -9
  72. data/spec/unit/indirector/file_metadata/file_spec.rb +6 -4
  73. data/spec/unit/indirector/request_spec.rb +13 -3
  74. data/spec/unit/indirector/resource/active_record_spec.rb +4 -10
  75. data/spec/unit/indirector/resource/ral_spec.rb +6 -4
  76. data/spec/unit/indirector/rest_spec.rb +5 -6
  77. data/spec/unit/network/handler/ca_spec.rb +86 -0
  78. data/spec/unit/parser/collector_spec.rb +7 -7
  79. data/spec/unit/parser/scope_spec.rb +20 -0
  80. data/spec/unit/provider/file/posix_spec.rb +226 -0
  81. data/spec/unit/provider/file/windows_spec.rb +136 -0
  82. data/spec/unit/provider/group/windows_adsi_spec.rb +7 -2
  83. data/spec/unit/provider/user/windows_adsi_spec.rb +36 -3
  84. data/spec/unit/resource/catalog_spec.rb +20 -10
  85. data/spec/unit/resource_spec.rb +55 -8
  86. data/spec/unit/ssl/certificate_authority/interface_spec.rb +97 -54
  87. data/spec/unit/ssl/certificate_authority_spec.rb +133 -23
  88. data/spec/unit/ssl/certificate_factory_spec.rb +90 -70
  89. data/spec/unit/ssl/certificate_request_spec.rb +62 -1
  90. data/spec/unit/ssl/certificate_spec.rb +20 -14
  91. data/spec/unit/ssl/host_spec.rb +52 -6
  92. data/spec/unit/type/file/content_spec.rb +4 -4
  93. data/spec/unit/type/file/group_spec.rb +34 -96
  94. data/spec/unit/type/file/mode_spec.rb +88 -0
  95. data/spec/unit/type/file/owner_spec.rb +32 -123
  96. data/spec/unit/type/file/source_spec.rb +120 -41
  97. data/spec/unit/type/file_spec.rb +1033 -753
  98. data/spec/unit/type_spec.rb +19 -1
  99. data/spec/unit/util/adsi_spec.rb +19 -0
  100. data/spec/unit/util/log/destinations_spec.rb +75 -0
  101. data/spec/unit/util/log_spec.rb +15 -0
  102. data/spec/unit/util/network_device/config_spec.rb +7 -0
  103. data/spec/unit/util/settings_spec.rb +10 -0
  104. data/spec/unit/util_spec.rb +126 -13
  105. data/test/language/functions.rb +0 -1
  106. data/test/language/snippets.rb +0 -9
  107. data/test/lib/puppettest/exetest.rb +1 -1
  108. data/test/lib/puppettest/servertest.rb +0 -1
  109. data/test/rails/rails.rb +0 -1
  110. data/test/ral/type/filesources.rb +0 -60
  111. metadata +13 -33
  112. data/lib/puppet/network/client.rb +0 -174
  113. data/lib/puppet/network/client/ca.rb +0 -56
  114. data/lib/puppet/network/client/file.rb +0 -6
  115. data/lib/puppet/network/client/proxy.rb +0 -27
  116. data/lib/puppet/network/client/report.rb +0 -26
  117. data/lib/puppet/network/client/runner.rb +0 -10
  118. data/lib/puppet/network/client/status.rb +0 -4
  119. data/lib/puppet/network/http_server.rb +0 -3
  120. data/lib/puppet/network/http_server/mongrel.rb +0 -130
  121. data/lib/puppet/network/http_server/webrick.rb +0 -155
  122. data/lib/puppet/network/xmlrpc/client.rb +0 -211
  123. data/lib/puppet/provider/file/win32.rb +0 -72
  124. data/lib/puppet/sslcertificates.rb +0 -146
  125. data/lib/puppet/sslcertificates/ca.rb +0 -375
  126. data/lib/puppet/sslcertificates/certificate.rb +0 -255
  127. data/lib/puppet/sslcertificates/inventory.rb +0 -38
  128. data/lib/puppet/sslcertificates/support.rb +0 -146
  129. data/spec/integration/network/client_spec.rb +0 -18
  130. data/spec/unit/network/xmlrpc/client_spec.rb +0 -172
  131. data/spec/unit/sslcertificates/ca_spec.rb +0 -106
  132. data/test/certmgr/certmgr.rb +0 -308
  133. data/test/certmgr/inventory.rb +0 -69
  134. data/test/certmgr/support.rb +0 -105
  135. data/test/network/client/ca.rb +0 -69
  136. data/test/network/client/dipper.rb +0 -34
  137. data/test/network/handler/ca.rb +0 -273
  138. data/test/network/server/mongrel_test.rb +0 -99
  139. data/test/network/server/webrick.rb +0 -111
  140. data/test/network/xmlrpc/client.rb +0 -45
@@ -5,13 +5,32 @@ require 'puppet/face'
5
5
  require 'puppet/ssl/host'
6
6
 
7
7
  describe Puppet::Face[:certificate, '0.0.1'] do
8
+ include PuppetSpec::Files
9
+
10
+ let(:ca) { Puppet::SSL::CertificateAuthority.instance }
11
+
12
+ before :each do
13
+ Puppet[:confdir] = tmpdir('conf')
14
+ Puppet::SSL::CertificateAuthority.stubs(:ca?).returns true
15
+
16
+ Puppet::SSL::Host.ca_location = :local
17
+
18
+ # We can't cache the CA between tests, because each one has its own SSL dir.
19
+ ca = Puppet::SSL::CertificateAuthority.new
20
+ Puppet::SSL::CertificateAuthority.stubs(:new).returns ca
21
+ Puppet::SSL::CertificateAuthority.stubs(:instance).returns ca
22
+ end
23
+
8
24
  it "should have a ca-location option" do
9
25
  subject.should be_option :ca_location
10
26
  end
11
27
 
12
28
  it "should set the ca location when invoked" do
13
29
  Puppet::SSL::Host.expects(:ca_location=).with(:local)
14
- Puppet::SSL::Host.indirection.expects(:save)
30
+ ca.expects(:sign).with do |name,options|
31
+ name == "hello, friend"
32
+ end
33
+
15
34
  subject.sign "hello, friend", :ca_location => :local
16
35
  end
17
36
 
@@ -32,4 +51,152 @@ describe Puppet::Face[:certificate, '0.0.1'] do
32
51
  subject.find 'hello, friend', :ca_location => :foo
33
52
  end.to raise_exception ArgumentError, /valid values/i
34
53
  end
54
+
55
+ describe "#generate" do
56
+ let(:options) { {:ca_location => 'local'} }
57
+ let(:host) { Puppet::SSL::Host.new(hostname) }
58
+ let(:csr) { host.certificate_request }
59
+
60
+ describe "for the current host" do
61
+ let(:hostname) { Puppet[:certname] }
62
+
63
+ it "should generate a CSR for this host" do
64
+ subject.generate(hostname, options)
65
+
66
+ csr.content.subject.to_s.should == "/CN=#{Puppet[:certname]}"
67
+ csr.name.should == Puppet[:certname]
68
+ end
69
+
70
+ it "should add dns_alt_names from the global config if not otherwise specified" do
71
+ Puppet[:dns_alt_names] = 'from,the,config'
72
+
73
+ subject.generate(hostname, options)
74
+
75
+ expected = %W[DNS:from DNS:the DNS:config DNS:#{hostname}]
76
+
77
+ csr.subject_alt_names.should =~ expected
78
+ end
79
+
80
+ it "should add the provided dns_alt_names if they are specified" do
81
+ Puppet[:dns_alt_names] = 'from,the,config'
82
+
83
+ subject.generate(hostname, options.merge(:dns_alt_names => 'explicit,alt,names'))
84
+
85
+ expected = %W[DNS:explicit DNS:alt DNS:names DNS:#{hostname}]
86
+
87
+ csr.subject_alt_names.should =~ expected
88
+ end
89
+ end
90
+
91
+ describe "for another host" do
92
+ let(:hostname) { Puppet[:certname] + 'different' }
93
+
94
+ it "should generate a CSR for the specified host" do
95
+ subject.generate(hostname, options)
96
+
97
+ csr.content.subject.to_s.should == "/CN=#{hostname}"
98
+ csr.name.should == hostname
99
+ end
100
+
101
+ it "should fail if a CSR already exists for the host" do
102
+ subject.generate(hostname, options)
103
+
104
+ expect do
105
+ subject.generate(hostname, options)
106
+ end.to raise_error(RuntimeError, /#{hostname} already has a requested certificate; ignoring certificate request/)
107
+ end
108
+
109
+ it "should add not dns_alt_names from the config file" do
110
+ Puppet[:dns_alt_names] = 'from,the,config'
111
+
112
+ subject.generate(hostname, options)
113
+
114
+ csr.subject_alt_names.should be_empty
115
+ end
116
+
117
+ it "should add the provided dns_alt_names if they are specified" do
118
+ Puppet[:dns_alt_names] = 'from,the,config'
119
+
120
+ subject.generate(hostname, options.merge(:dns_alt_names => 'explicit,alt,names'))
121
+
122
+ expected = %W[DNS:explicit DNS:alt DNS:names DNS:#{hostname}]
123
+
124
+ csr.subject_alt_names.should =~ expected
125
+ end
126
+ end
127
+ end
128
+
129
+ describe "#sign" do
130
+ let(:options) { {:ca_location => 'local'} }
131
+ let(:host) { Puppet::SSL::Host.new(hostname) }
132
+ let(:hostname) { "foobar" }
133
+
134
+ it "should sign the certificate request if one is waiting" do
135
+ subject.generate(hostname, options)
136
+
137
+ subject.sign(hostname, options)
138
+
139
+ host.certificate_request.should be_nil
140
+ host.certificate.should be_a(Puppet::SSL::Certificate)
141
+ host.state.should == 'signed'
142
+ end
143
+
144
+ it "should fail if there is no waiting certificate request" do
145
+ expect do
146
+ subject.sign(hostname, options)
147
+ end.to raise_error(ArgumentError, /Could not find certificate request for #{hostname}/)
148
+ end
149
+
150
+ describe "when ca_location is local" do
151
+ describe "when the request has dns alt names" do
152
+ before :each do
153
+ subject.generate(hostname, options.merge(:dns_alt_names => 'some,alt,names'))
154
+ end
155
+
156
+ it "should refuse to sign the request if allow_dns_alt_names is not set" do
157
+ expect do
158
+ subject.sign(hostname, options)
159
+ end.to raise_error(Puppet::SSL::CertificateAuthority::CertificateSigningError,
160
+ /CSR '#{hostname}' contains subject alternative names \(.*?\), which are disallowed. Use `puppet cert --allow-dns-alt-names sign #{hostname}` to sign this request./i)
161
+
162
+ host.state.should == 'requested'
163
+ end
164
+
165
+ it "should sign the request if allow_dns_alt_names is set" do
166
+ expect do
167
+ subject.sign(hostname, options.merge(:allow_dns_alt_names => true))
168
+ end.not_to raise_error
169
+
170
+ host.state.should == 'signed'
171
+ end
172
+ end
173
+
174
+ describe "when the request has no dns alt names" do
175
+ before :each do
176
+ subject.generate(hostname, options)
177
+ end
178
+
179
+ it "should sign the request if allow_dns_alt_names is set" do
180
+ expect { subject.sign(hostname, options.merge(:allow_dns_alt_names => true)) }.not_to raise_error
181
+
182
+ host.state.should == 'signed'
183
+ end
184
+
185
+ it "should sign the request if allow_dns_alt_names is not set" do
186
+ expect { subject.sign(hostname, options) }.not_to raise_error
187
+
188
+ host.state.should == 'signed'
189
+ end
190
+ end
191
+ end
192
+
193
+ describe "when ca_location is remote" do
194
+ let(:options) { {:ca_location => :remote} }
195
+ it "should fail if allow-dns-alt-names is specified" do
196
+ expect do
197
+ subject.sign(hostname, options.merge(:allow_dns_alt_names => true))
198
+ end
199
+ end
200
+ end
201
+ end
35
202
  end
@@ -26,7 +26,7 @@ describe Puppet::FileServing::Fileset, " when initializing" do
26
26
  end
27
27
 
28
28
  it "should not fail if the path is just the file separator" do
29
- path = make_absolute(File::SEPARATOR)
29
+ path = File.expand_path(File::SEPARATOR)
30
30
  File.stubs(:lstat).with(path).returns stub('stat')
31
31
  fileset = Puppet::FileServing::Fileset.new(path)
32
32
  fileset.path.should == path
@@ -13,7 +13,7 @@ describe Puppet::FileServing::IndirectionHooks do
13
13
 
14
14
  describe "when being used to select termini" do
15
15
  it "should return :file if the request key is fully qualified" do
16
- @request.expects(:key).returns "#{File::SEPARATOR}foo"
16
+ @request.expects(:key).returns File.expand_path('/foo')
17
17
  @object.select_terminus(@request).should == :file
18
18
  end
19
19
 
@@ -99,148 +99,192 @@ describe Puppet::FileServing::Metadata do
99
99
  end
100
100
  end
101
101
 
102
- describe Puppet::FileServing::Metadata, " when finding the file to use for setting attributes" do
103
- before do
104
- @path = "/my/path"
105
- @metadata = Puppet::FileServing::Metadata.new(@path)
102
+ describe Puppet::FileServing::Metadata do
103
+ include PuppetSpec::Files
104
+
105
+ shared_examples_for "metadata collector" do
106
+ let(:metadata) do
107
+ data = described_class.new(path)
108
+ data.collect
109
+ data
110
+ end
111
+
112
+ describe "when collecting attributes" do
113
+ describe "when managing files" do
114
+ let(:path) { tmpfile('file_serving_metadata') }
115
+
116
+ before :each do
117
+ FileUtils.touch(path)
118
+ end
119
+
120
+ it "should be able to produce xmlrpc-style attribute information" do
121
+ metadata.should respond_to(:attributes_with_tabs)
122
+ end
123
+
124
+ it "should set the owner to the file's current owner" do
125
+ metadata.owner.should == owner
126
+ end
127
+
128
+ it "should set the group to the file's current group" do
129
+ metadata.group.should == group
130
+ end
131
+
132
+ it "should set the mode to the file's masked mode" do
133
+ set_mode(33261, path)
134
+
135
+ metadata.mode.should == 0755
136
+ end
106
137
 
107
- # Use a link because it's easier to test -- no checksumming
108
- @stat = stub "stat", :uid => 10, :gid => 20, :mode => 0755, :ftype => "link"
138
+ describe "#checksum" do
139
+ let(:checksum) { Digest::MD5.hexdigest("some content\n") }
109
140
 
110
- # Not quite. We don't want to checksum links, but we must because they might be being followed.
111
- @checksum = Digest::MD5.hexdigest("some content\n") # Remove these when :managed links are no longer checksumed.
112
- @metadata.stubs(:md5_file).returns(@checksum) #
113
- end
141
+ before :each do
142
+ File.open(path, "w") {|f| f.print("some content\n")}
143
+ end
114
144
 
115
- it "should accept a base path path to which the file should be relative" do
116
- File.expects(:lstat).with(@path).returns @stat
117
- File.expects(:readlink).with(@path).returns "/what/ever"
118
- @metadata.collect
119
- end
145
+ it "should default to a checksum of type MD5 with the file's current checksum" do
146
+ metadata.checksum.should == "{md5}#{checksum}"
147
+ end
120
148
 
121
- it "should use the set base path if one is not provided" do
122
- File.expects(:lstat).with(@path).returns @stat
123
- File.expects(:readlink).with(@path).returns "/what/ever"
124
- @metadata.collect
125
- end
149
+ it "should give a mtime checksum when checksum_type is set" do
150
+ time = Time.now
151
+ metadata.checksum_type = "mtime"
152
+ metadata.expects(:mtime_file).returns(@time)
153
+ metadata.collect
154
+ metadata.checksum.should == "{mtime}#{@time}"
155
+ end
126
156
 
127
- it "should raise an exception if the file does not exist" do
128
- File.expects(:lstat).with(@path).raises(Errno::ENOENT)
129
- proc { @metadata.collect}.should raise_error(Errno::ENOENT)
130
- end
131
- end
157
+ it "should produce tab-separated mode, type, owner, group, and checksum for xmlrpc" do
158
+ set_mode(0755, path)
132
159
 
133
- describe Puppet::FileServing::Metadata, " when collecting attributes" do
134
- before do
135
- @path = "/my/file"
136
- # Use a real file mode, so we can validate the masking is done.
137
- @stat = stub 'stat', :uid => 10, :gid => 20, :mode => 33261, :ftype => "file"
138
- File.stubs(:lstat).returns(@stat)
139
- @checksum = Digest::MD5.hexdigest("some content\n")
140
- @metadata = Puppet::FileServing::Metadata.new("/my/file")
141
- @metadata.stubs(:md5_file).returns(@checksum)
142
- @metadata.collect
143
- end
160
+ metadata.attributes_with_tabs.should == "#{0755.to_s}\tfile\t#{owner}\t#{group}\t{md5}#{checksum}"
161
+ end
162
+ end
163
+ end
144
164
 
145
- it "should be able to produce xmlrpc-style attribute information" do
146
- @metadata.should respond_to(:attributes_with_tabs)
147
- end
165
+ describe "when managing directories" do
166
+ let(:path) { tmpdir('file_serving_metadata_dir') }
167
+ let(:time) { Time.now }
148
168
 
149
- # LAK:FIXME This should actually change at some point
150
- it "should set the owner by id" do
151
- @metadata.owner.should be_instance_of(Fixnum)
152
- end
169
+ before :each do
170
+ metadata.expects(:ctime_file).returns(time)
171
+ end
153
172
 
154
- # LAK:FIXME This should actually change at some point
155
- it "should set the group by id" do
156
- @metadata.group.should be_instance_of(Fixnum)
157
- end
173
+ it "should only use checksums of type 'ctime' for directories" do
174
+ metadata.collect
175
+ metadata.checksum.should == "{ctime}#{time}"
176
+ end
158
177
 
159
- it "should set the owner to the file's current owner" do
160
- @metadata.owner.should == 10
161
- end
178
+ it "should only use checksums of type 'ctime' for directories even if checksum_type set" do
179
+ metadata.checksum_type = "mtime"
180
+ metadata.expects(:mtime_file).never
181
+ metadata.collect
182
+ metadata.checksum.should == "{ctime}#{time}"
183
+ end
162
184
 
163
- it "should set the group to the file's current group" do
164
- @metadata.group.should == 20
165
- end
185
+ it "should produce tab-separated mode, type, owner, group, and checksum for xmlrpc" do
186
+ set_mode(0755, path)
187
+ metadata.collect
166
188
 
167
- it "should set the mode to the file's masked mode" do
168
- @metadata.mode.should == 0755
169
- end
189
+ metadata.attributes_with_tabs.should == "#{0755.to_s}\tdirectory\t#{owner}\t#{group}\t{ctime}#{time.to_s}"
190
+ end
191
+ end
170
192
 
171
- it "should set the checksum to the file's current checksum" do
172
- @metadata.checksum.should == "{md5}#{@checksum}"
173
- end
193
+ describe "when managing links", :unless => Puppet.features.microsoft_windows? do
194
+ # 'path' is a link that points to 'target'
195
+ let(:path) { tmpfile('file_serving_metadata_link') }
196
+ let(:target) { tmpfile('file_serving_metadata_target') }
197
+ let(:checksum) { Digest::MD5.hexdigest("some content\n") }
198
+ let(:fmode) { File.lstat(path).mode & 0777 }
174
199
 
175
- describe "when managing files" do
176
- it "should default to a checksum of type MD5" do
177
- @metadata.checksum.should == "{md5}#{@checksum}"
178
- end
200
+ before :each do
201
+ File.open(target, "w") {|f| f.print("some content\n")}
202
+ set_mode(0644, target)
179
203
 
180
- it "should give a mtime checksum when checksum_type is set" do
181
- time = Time.now
182
- @metadata.checksum_type = "mtime"
183
- @metadata.expects(:mtime_file).returns(@time)
184
- @metadata.collect
185
- @metadata.checksum.should == "{mtime}#{@time}"
186
- end
204
+ FileUtils.symlink(target, path)
205
+ end
187
206
 
188
- it "should produce tab-separated mode, type, owner, group, and checksum for xmlrpc" do
189
- @metadata.attributes_with_tabs.should == "#{0755.to_s}\tfile\t10\t20\t{md5}#{@checksum}"
190
- end
191
- end
207
+ it "should read links instead of returning their checksums" do
208
+ metadata.destination.should == target
209
+ end
192
210
 
193
- describe "when managing directories" do
194
- before do
195
- @stat.stubs(:ftype).returns("directory")
196
- @time = Time.now
197
- @metadata.expects(:ctime_file).returns(@time)
198
- end
211
+ pending "should produce tab-separated mode, type, owner, group, and destination for xmlrpc" do
212
+ # "We'd like this to be true, but we need to always collect the checksum because in the server/client/server round trip we lose the distintion between manage and follow."
213
+ metadata.attributes_with_tabs.should == "#{0755}\tlink\t#{owner}\t#{group}\t#{target}"
214
+ end
199
215
 
200
- it "should only use checksums of type 'ctime' for directories" do
201
- @metadata.collect
202
- @metadata.checksum.should == "{ctime}#{@time}"
216
+ it "should produce tab-separated mode, type, owner, group, checksum, and destination for xmlrpc" do
217
+ metadata.attributes_with_tabs.should == "#{fmode}\tlink\t#{owner}\t#{group}\t{md5}eb9c2bf0eb63f3a7bc0ea37ef18aeba5\t#{target}"
218
+ end
219
+ end
203
220
  end
204
221
 
205
- it "should only use checksums of type 'ctime' for directories even if checksum_type set" do
206
- @metadata.checksum_type = "mtime"
207
- @metadata.expects(:mtime_file).never
208
- @metadata.collect
209
- @metadata.checksum.should == "{ctime}#{@time}"
210
- end
222
+ describe Puppet::FileServing::Metadata, " when finding the file to use for setting attributes" do
223
+ let(:path) { tmpfile('file_serving_metadata_find_file') }
224
+
225
+ before :each do
226
+ File.open(path, "w") {|f| f.print("some content\n")}
227
+ set_mode(0755, path)
228
+ end
229
+
230
+ it "should accept a base path to which the file should be relative" do
231
+ dir = tmpdir('metadata_dir')
232
+ metadata = described_class.new(dir)
233
+ metadata.relative_path = 'relative_path'
234
+
235
+ FileUtils.touch(metadata.full_path)
236
+
237
+ metadata.collect
238
+ end
239
+
240
+ it "should use the set base path if one is not provided" do
241
+ metadata.collect
242
+ end
211
243
 
212
- it "should produce tab-separated mode, type, owner, group, and checksum for xmlrpc" do
213
- @metadata.collect
214
- @metadata.attributes_with_tabs.should == "#{0755.to_s}\tdirectory\t10\t20\t{ctime}#{@time.to_s}"
244
+ it "should raise an exception if the file does not exist" do
245
+ File.delete(path)
246
+
247
+ proc { metadata.collect}.should raise_error(Errno::ENOENT)
248
+ end
215
249
  end
216
250
  end
217
251
 
218
- describe "when managing links" do
219
- before do
220
- @stat.stubs(:ftype).returns("link")
221
- File.expects(:readlink).with("/my/file").returns("/path/to/link")
222
- @metadata.collect
252
+ describe "on POSIX systems", :if => Puppet.features.posix? do
253
+ let(:owner) {10}
254
+ let(:group) {20}
223
255
 
224
- @checksum = Digest::MD5.hexdigest("some content\n") # Remove these when :managed links are no longer checksumed.
225
- @file.stubs(:md5_file).returns(@checksum) #
256
+ before :each do
257
+ File::Stat.any_instance.stubs(:uid).returns owner
258
+ File::Stat.any_instance.stubs(:gid).returns group
226
259
  end
227
260
 
228
- it "should read links instead of returning their checksums" do
229
- @metadata.destination.should == "/path/to/link"
261
+ it_should_behave_like "metadata collector"
262
+
263
+ def set_mode(mode, path)
264
+ File.chmod(mode, path)
230
265
  end
266
+ end
267
+
268
+ describe "on Windows systems", :if => Puppet.features.microsoft_windows? do
269
+ let(:owner) {'S-1-1-50'}
270
+ let(:group) {'S-1-1-51'}
231
271
 
232
- pending "should produce tab-separated mode, type, owner, group, and destination for xmlrpc" do
233
- # "We'd like this to be true, but we need to always collect the checksum because in the server/client/server round trip we lose the distintion between manage and follow."
234
- @metadata.attributes_with_tabs.should == "#{0755}\tlink\t10\t20\t/path/to/link"
272
+ before :each do
273
+ require 'puppet/util/windows/security'
274
+ Puppet::Util::Windows::Security.stubs(:get_owner).returns owner
275
+ Puppet::Util::Windows::Security.stubs(:get_group).returns group
235
276
  end
236
277
 
237
- it "should produce tab-separated mode, type, owner, group, checksum, and destination for xmlrpc" do
238
- @metadata.attributes_with_tabs.should == "#{0755}\tlink\t10\t20\t{md5}eb9c2bf0eb63f3a7bc0ea37ef18aeba5\t/path/to/link"
278
+ it_should_behave_like "metadata collector"
279
+
280
+ def set_mode(mode, path)
281
+ Puppet::Util::Windows::Security.set_mode(mode, path)
239
282
  end
240
283
  end
241
284
  end
242
285
 
243
- describe Puppet::FileServing::Metadata, " when pointing to a link" do
286
+
287
+ describe Puppet::FileServing::Metadata, " when pointing to a link", :unless => Puppet.features.microsoft_windows? do
244
288
  describe "when links are managed" do
245
289
  before do
246
290
  @file = Puppet::FileServing::Metadata.new("/base/path/my/file", :links => :manage)