Add missing new files from commit 131e09855e06
[mirror/dsa-puppet.git] / 3rdparty / modules / stdlib / spec / unit / puppet / provider / file_line / ruby_spec_alter.rb
1 require 'spec_helper'
2
3 provider_class = Puppet::Type.type(:file_line).provider(:ruby)
4 #  These tests fail on windows when run as part of the rake task. Individually they pass
5 describe provider_class, :unless => Puppet::Util::Platform.windows? do
6   include PuppetlabsSpec::Files
7
8   let :tmpfile do
9     tmpfilename('file_line_test')
10   end
11   let :content do
12     ''
13   end
14   let :params do
15     {}
16   end
17   let :resource do
18     Puppet::Type::File_line.new({
19       :name => 'foo',
20       :path => tmpfile,
21       :line => 'foo',
22     }.merge(params))
23   end
24   let :provider do
25     provider_class.new(resource)
26   end
27
28   before :each do
29     File.open(tmpfile, 'w') do |fh|
30       fh.write(content)
31     end
32   end
33
34   describe '#create' do
35     context 'when adding' do
36       pending('To be added.')
37     end
38     context 'when replacing' do
39       let :params do
40         {
41           :line => 'foo = bar',
42           :match => '^foo\s*=.*$',
43           :replace => false,
44         }
45       end
46       let(:content) { "foo1\nfoo=blah\nfoo2\nfoo3" }
47
48       it "providor 'be_exists'" do
49         expect(provider).to be_exists
50       end
51       it 'does not replace the matching line' do
52         provider.create
53         expect(File.read(tmpfile).chomp).to eql("foo1\nfoo=blah\nfoo2\nfoo3")
54       end
55       it 'appends the line if no matches are found' do
56         File.open(tmpfile, 'w') { |fh| fh.write("foo1\nfoo2") }
57         expect(provider.exists?).to be false
58         provider.create
59         expect(File.read(tmpfile).chomp).to eql("foo1\nfoo2\nfoo = bar")
60       end
61       it 'raises an error with invalid values' do
62         expect {
63           @resource = Puppet::Type::File_line.new(
64             :name => 'foo', :path => tmpfile, :line => 'foo = bar', :match => '^foo\s*=.*$', :replace => 'asgadga',
65           )
66         }.to raise_error(Puppet::Error, %r{Invalid value "asgadga"\. Valid values are true, false\.})
67       end
68     end
69   end
70   describe '#destroy' do
71     pending('To be added?')
72   end
73   context 'when matching' do
74     # rubocop:disable RSpec/InstanceVariable : replacing before with let breaks the tests, variables need to be altered within it block : multi
75     before :each do
76       @resource = Puppet::Type::File_line.new(
77         :name => 'foo',
78         :path => tmpfile,
79         :line => 'foo = bar',
80         :match => '^foo\s*=.*$',
81       )
82       @provider = provider_class.new(@resource)
83     end
84     describe 'using match' do
85       it 'raises an error if more than one line matches, and should not have modified the file' do
86         File.open(tmpfile, 'w') { |fh| fh.write("foo1\nfoo=blah\nfoo2\nfoo=baz") }
87         expect { @provider.create }.to raise_error(Puppet::Error, %r{More than one line.*matches})
88         expect(File.read(tmpfile)).to eql("foo1\nfoo=blah\nfoo2\nfoo=baz")
89       end
90
91       it 'replaces all lines that matches' do
92         @resource = Puppet::Type::File_line.new(:name => 'foo', :path => tmpfile, :line => 'foo = bar', :match => '^foo\s*=.*$', :multiple => true)
93         @provider = provider_class.new(@resource)
94         File.open(tmpfile, 'w') { |fh| fh.write("foo1\nfoo=blah\nfoo2\nfoo=baz") }
95         @provider.create
96         expect(File.read(tmpfile).chomp).to eql("foo1\nfoo = bar\nfoo2\nfoo = bar")
97       end
98
99       it 'replaces all lines that match, even when some lines are correct' do
100         @resource = Puppet::Type::File_line.new(:name => 'neil', :path => tmpfile, :line => "\thard\tcore\t0\n", :match => '^[ \t]hard[ \t]+core[ \t]+.*', :multiple => true)
101         @provider = provider_class.new(@resource)
102         File.open(tmpfile, 'w') { |fh| fh.write("\thard\tcore\t90\n\thard\tcore\t0\n") }
103         @provider.create
104         expect(File.read(tmpfile).chomp).to eql("\thard\tcore\t0\n\thard\tcore\t0")
105       end
106
107       it 'raises an error with invalid values' do
108         expect {
109           @resource = Puppet::Type::File_line.new(
110             :name => 'foo', :path => tmpfile, :line => 'foo = bar', :match => '^foo\s*=.*$', :multiple => 'asgadga',
111           )
112         }.to raise_error(Puppet::Error, %r{Invalid value "asgadga"\. Valid values are true, false\.})
113       end
114
115       it 'replaces a line that matches' do
116         File.open(tmpfile, 'w') { |fh| fh.write("foo1\nfoo=blah\nfoo2") }
117         @provider.create
118         expect(File.read(tmpfile).chomp).to eql("foo1\nfoo = bar\nfoo2")
119       end
120       it 'adds a new line if no lines match' do
121         File.open(tmpfile, 'w') { |fh| fh.write("foo1\nfoo2") }
122         @provider.create
123         expect(File.read(tmpfile)).to eql("foo1\nfoo2\nfoo = bar\n")
124       end
125       it 'does nothing if the exact line already exists' do
126         File.open(tmpfile, 'w') { |fh| fh.write("foo1\nfoo = bar\nfoo2") }
127         @provider.create
128         expect(File.read(tmpfile).chomp).to eql("foo1\nfoo = bar\nfoo2")
129       end
130     end
131     describe 'using match+append_on_no_match - when there is a match' do
132       it 'replaces line' do
133         @resource = Puppet::Type::File_line.new(:name => 'foo', :path => tmpfile, :line => 'inserted = line', :match => '^foo3$', :append_on_no_match => false)
134         @provider = provider_class.new(@resource)
135         File.open(tmpfile, 'w') { |fh| fh.write("foo1\nfoo = blah\nfoo2\nfoo = baz") }
136         expect(File.read(tmpfile).chomp).to eql("foo1\nfoo = blah\nfoo2\nfoo = baz")
137       end
138     end
139     describe 'using match+append_on_no_match - when there is no match' do
140       it 'does not add line after no matches found' do
141         @resource = Puppet::Type::File_line.new(:name => 'foo', :path => tmpfile, :line => 'inserted = line', :match => '^foo3$', :append_on_no_match => false)
142         @provider = provider_class.new(@resource)
143         File.open(tmpfile, 'w') { |fh| fh.write("foo1\nfoo = blah\nfoo2\nfoo = baz") }
144         expect(File.read(tmpfile).chomp).to eql("foo1\nfoo = blah\nfoo2\nfoo = baz")
145       end
146     end
147   end
148   context 'when match+replace+append_on_no_match' do
149     pending('to do')
150   end
151   context 'when after' do
152     let :resource do
153       Puppet::Type::File_line.new(
154         :name => 'foo',
155         :path => tmpfile,
156         :line => 'inserted = line',
157         :after => '^foo1',
158       )
159     end
160
161     let :provider do
162       provider_class.new(resource)
163     end
164
165     context 'when match and after set' do
166       shared_context 'when resource_create' do
167         let(:match) { '^foo2$' }
168         let(:after) { '^foo1$' }
169         let(:resource) do
170           Puppet::Type::File_line.new(
171             :name => 'foo',
172             :path => tmpfile,
173             :line => 'inserted = line',
174             :after => after,
175             :match => match,
176           )
177         end
178       end
179       before :each do
180         File.open(tmpfile, 'w') { |fh| fh.write("foo1\nfoo2\nfoo = baz") }
181       end
182       describe 'inserts at match' do
183         include_context 'resource_create'
184         it {
185           provider.create
186           expect(File.read(tmpfile).chomp).to eq("foo1\ninserted = line\nfoo = baz")
187         }
188       end
189       describe 'inserts a new line after when no match' do
190         include_context 'resource_create' do
191           let(:match) { '^nevergoingtomatch$' }
192         end
193         it {
194           provider.create
195           expect(File.read(tmpfile).chomp).to eq("foo1\ninserted = line\nfoo2\nfoo = baz")
196         }
197       end
198       describe 'append to end of file if no match for both after and match' do
199         include_context 'resource_create' do
200           let(:match) { '^nevergoingtomatch$' }
201           let(:after) { '^stillneverafter' }
202         end
203         it {
204           provider.create
205           expect(File.read(tmpfile).chomp).to eq("foo1\nfoo2\nfoo = baz\ninserted = line")
206         }
207       end
208     end
209     context 'with one line matching the after expression' do
210       before :each do
211         File.open(tmpfile, 'w') { |fh| fh.write("foo1\nfoo = blah\nfoo2\nfoo = baz") }
212       end
213
214       it 'inserts the specified line after the line matching the "after" expression' do
215         provider.create
216         expect(File.read(tmpfile).chomp).to eql("foo1\ninserted = line\nfoo = blah\nfoo2\nfoo = baz")
217       end
218     end
219     context 'with multiple lines matching the after expression' do
220       before :each do
221         File.open(tmpfile, 'w') { |fh| fh.write("foo1\nfoo = blah\nfoo2\nfoo1\nfoo = baz") }
222       end
223
224       it 'errors out stating "One or no line must match the pattern"' do
225         expect { provider.create }.to raise_error(Puppet::Error, %r{One or no line must match the pattern})
226       end
227
228       it 'adds the line after all lines matching the after expression' do
229         @resource = Puppet::Type::File_line.new(:name => 'foo', :path => tmpfile, :line => 'inserted = line', :after => '^foo1$', :multiple => true)
230         @provider = provider_class.new(@resource)
231         @provider.create
232         expect(File.read(tmpfile).chomp).to eql("foo1\ninserted = line\nfoo = blah\nfoo2\nfoo1\ninserted = line\nfoo = baz")
233       end
234     end
235     context 'with no lines matching the after expression' do
236       let :content do
237         "foo3\nfoo = blah\nfoo2\nfoo = baz\n"
238       end
239
240       before :each do
241         File.open(tmpfile, 'w') { |fh| fh.write(content) }
242       end
243
244       it 'appends the specified line to the file' do
245         provider.create
246         expect(File.read(tmpfile)).to eq(content << resource[:line] << "\n")
247       end
248     end
249   end
250   context 'when removing with a line' do
251     before :each do
252       # TODO: these should be ported over to use the PuppetLabs spec_helper
253       #  file fixtures once the following pull request has been merged:
254       # https://github.com/puppetlabs/puppetlabs-stdlib/pull/73/files
255       @resource = Puppet::Type::File_line.new(
256         :name => 'foo',
257         :path => tmpfile,
258         :line => 'foo',
259         :ensure => 'absent',
260       )
261       @provider = provider_class.new(@resource)
262     end
263     it 'removes the line if it exists' do
264       File.open(tmpfile, 'w') { |fh| fh.write("foo1\nfoo\nfoo2") }
265       @provider.destroy
266       expect(File.read(tmpfile)).to eql("foo1\nfoo2")
267     end
268     it 'removes the line without touching the last new line' do
269       File.open(tmpfile, 'w') { |fh| fh.write("foo1\nfoo\nfoo2\n") }
270       @provider.destroy
271       expect(File.read(tmpfile)).to eql("foo1\nfoo2\n")
272     end
273     it 'removes any occurence of the line' do
274       File.open(tmpfile, 'w') { |fh| fh.write("foo1\nfoo\nfoo2\nfoo\nfoo") }
275       @provider.destroy
276       expect(File.read(tmpfile)).to eql("foo1\nfoo2\n")
277     end
278     it 'example in the docs' do
279       @resource = Puppet::Type::File_line.new(:name => 'bashrc_proxy', :ensure => 'absent', :path => tmpfile, :line => 'export HTTP_PROXY=http://squid.puppetlabs.vm:3128')
280       @provider = provider_class.new(@resource)
281       File.open(tmpfile, 'w') { |fh| fh.write("foo1\nfoo2\nexport HTTP_PROXY=http://squid.puppetlabs.vm:3128\nfoo4\n") }
282       @provider.destroy
283       expect(File.read(tmpfile)).to eql("foo1\nfoo2\nfoo4\n")
284     end
285   end
286   context 'when removing with a match' do
287     before :each do
288       @resource = Puppet::Type::File_line.new(
289         :name => 'foo',
290         :path => tmpfile,
291         :line => 'foo2',
292         :ensure => 'absent',
293         :match => 'o$',
294         :match_for_absence => true,
295       )
296       @provider = provider_class.new(@resource)
297     end
298
299     it 'finds a line to match' do
300       File.open(tmpfile, 'w') { |fh| fh.write("foo1\nfoo\nfoo2") }
301       expect(@provider.exists?).to be true
302     end
303
304     it 'removes one line if it matches' do
305       File.open(tmpfile, 'w') { |fh| fh.write("foo1\nfoo\nfoo2") }
306       @provider.destroy
307       expect(File.read(tmpfile)).to eql("foo1\nfoo2")
308     end
309
310     it 'the line parameter is actually not used at all but is silently ignored if here' do
311       @resource = Puppet::Type::File_line.new(:name => 'foo', :path => tmpfile, :line => 'supercalifragilisticexpialidocious', :ensure => 'absent', :match => 'o$', :match_for_absence => true)
312       @provider = provider_class.new(@resource)
313       File.open(tmpfile, 'w') { |fh| fh.write("foo1\nfoo\nfoo2") }
314       @provider.destroy
315       expect(File.read(tmpfile)).to eql("foo1\nfoo2")
316     end
317
318     it 'and may not be here and does not need to be here' do
319       @resource = Puppet::Type::File_line.new(:name => 'foo', :path => tmpfile, :ensure => 'absent', :match => 'o$', :match_for_absence => true)
320       @provider = provider_class.new(@resource)
321       File.open(tmpfile, 'w') { |fh| fh.write("foo1\nfoo\nfoo2") }
322       @provider.destroy
323       expect(File.read(tmpfile)).to eql("foo1\nfoo2")
324     end
325
326     it 'raises an error if more than one line matches' do
327       File.open(tmpfile, 'w') { |fh| fh.write("foo1\nfoo\nfoo2\nfoo\nfoo") }
328       expect { @provider.destroy }.to raise_error(Puppet::Error, %r{More than one line})
329     end
330
331     it 'removes multiple lines if :multiple is true' do
332       @resource = Puppet::Type::File_line.new(:name => 'foo', :path => tmpfile, :line => 'foo2', :ensure => 'absent', :match => 'o$', :multiple => true, :match_for_absence => true)
333       @provider = provider_class.new(@resource)
334       File.open(tmpfile, 'w') { |fh| fh.write("foo1\nfoo\nfoo2\nfoo\nfoo") }
335       @provider.destroy
336       expect(File.read(tmpfile)).to eql("foo1\nfoo2\n")
337     end
338
339     it 'ignores the match if match_for_absence is not specified' do
340       @resource = Puppet::Type::File_line.new(:name => 'foo', :path => tmpfile, :line => 'foo2', :ensure => 'absent', :match => 'o$')
341       @provider = provider_class.new(@resource)
342       File.open(tmpfile, 'w') { |fh| fh.write("foo1\nfoo\nfoo2") }
343       @provider.destroy
344       expect(File.read(tmpfile)).to eql("foo1\nfoo\n")
345     end
346
347     it 'ignores the match if match_for_absence is false' do
348       @resource = Puppet::Type::File_line.new(:name => 'foo', :path => tmpfile, :line => 'foo2', :ensure => 'absent', :match => 'o$', :match_for_absence => false)
349       @provider = provider_class.new(@resource)
350       File.open(tmpfile, 'w') { |fh| fh.write("foo1\nfoo\nfoo2") }
351       @provider.destroy
352       expect(File.read(tmpfile)).to eql("foo1\nfoo\n")
353     end
354
355     it 'example in the docs' do
356       @resource = Puppet::Type::File_line.new(
357         :name => 'bashrc_proxy', :ensure => 'absent', :path => tmpfile, :line => 'export HTTP_PROXY=http://squid.puppetlabs.vm:3128',
358         :match => '^export\ HTTP_PROXY\=', :match_for_absence => true
359       )
360       @provider = provider_class.new(@resource)
361       File.open(tmpfile, 'w') { |fh| fh.write("foo1\nfoo2\nexport HTTP_PROXY=foo\nfoo4\n") }
362       @provider.destroy
363       expect(File.read(tmpfile)).to eql("foo1\nfoo2\nfoo4\n")
364     end
365
366     it 'example in the docs showing line is redundant' do
367       @resource = Puppet::Type::File_line.new(:name => 'bashrc_proxy', :ensure => 'absent', :path => tmpfile, :match => '^export\ HTTP_PROXY\=', :match_for_absence => true)
368       @provider = provider_class.new(@resource)
369       File.open(tmpfile, 'w') { |fh| fh.write("foo1\nfoo2\nexport HTTP_PROXY=foo\nfoo4\n") }
370       @provider.destroy
371       expect(File.read(tmpfile)).to eql("foo1\nfoo2\nfoo4\n")
372     end
373   end
374 end