puppet 4.1.0-x64-mingw32 → 4.2.0-x64-mingw32

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 (117) hide show
  1. data/ext/osx/puppet.plist +32 -0
  2. data/ext/redhat/client.init +3 -6
  3. data/ext/redhat/client.sysconfig +1 -10
  4. data/ext/suse/client.init +3 -6
  5. data/ext/systemd/puppet.service +2 -1
  6. data/lib/puppet.rb +1 -1
  7. data/lib/puppet/agent.rb +4 -19
  8. data/lib/puppet/application/apply.rb +22 -6
  9. data/lib/puppet/configurer.rb +3 -2
  10. data/lib/puppet/configurer/plugin_handler.rb +6 -2
  11. data/lib/puppet/face/plugin.rb +7 -14
  12. data/lib/puppet/forge/repository.rb +1 -2
  13. data/lib/puppet/indirector/catalog/compiler.rb +4 -3
  14. data/lib/puppet/indirector/facts/facter.rb +8 -0
  15. data/lib/puppet/module.rb +17 -12
  16. data/lib/puppet/network/http/factory.rb +8 -4
  17. data/lib/puppet/node/environment.rb +11 -7
  18. data/lib/puppet/parser/ast/pops_bridge.rb +5 -0
  19. data/lib/puppet/parser/functions/fqdn_rand.rb +2 -2
  20. data/lib/puppet/parser/scope.rb +39 -13
  21. data/lib/puppet/pops.rb +1 -0
  22. data/lib/puppet/pops/evaluator/runtime3_converter.rb +1 -1
  23. data/lib/puppet/pops/evaluator/runtime3_support.rb +31 -0
  24. data/lib/puppet/pops/parser/epp_support.rb +4 -2
  25. data/lib/puppet/property/ensure.rb +1 -1
  26. data/lib/puppet/provider.rb +5 -0
  27. data/lib/puppet/provider/augeas/augeas.rb +5 -0
  28. data/lib/puppet/provider/group/pw.rb +1 -0
  29. data/lib/puppet/provider/group/windows_adsi.rb +9 -0
  30. data/lib/puppet/provider/mount/parsed.rb +15 -1
  31. data/lib/puppet/provider/package.rb +6 -2
  32. data/lib/puppet/provider/package/gem.rb +16 -0
  33. data/lib/puppet/provider/package/openbsd.rb +7 -7
  34. data/lib/puppet/provider/package/pacman.rb +9 -8
  35. data/lib/puppet/provider/package/pip.rb +1 -1
  36. data/lib/puppet/provider/package/pip3.rb +18 -0
  37. data/lib/puppet/provider/package/pkgdmg.rb +4 -2
  38. data/lib/puppet/provider/package/pkgin.rb +3 -3
  39. data/lib/puppet/provider/package/rpm.rb +8 -14
  40. data/lib/puppet/provider/package/yum.rb +5 -4
  41. data/lib/puppet/provider/service/base.rb +3 -2
  42. data/lib/puppet/provider/service/bsd.rb +7 -7
  43. data/lib/puppet/provider/service/debian.rb +2 -1
  44. data/lib/puppet/provider/service/freebsd.rb +1 -1
  45. data/lib/puppet/provider/service/systemd.rb +75 -6
  46. data/lib/puppet/provider/service/upstart.rb +1 -1
  47. data/lib/puppet/provider/user/pw.rb +1 -0
  48. data/lib/puppet/resource/catalog.rb +1 -1
  49. data/lib/puppet/resource/status.rb +9 -0
  50. data/lib/puppet/resource/type.rb +4 -2
  51. data/lib/puppet/settings.rb +43 -16
  52. data/lib/puppet/transaction.rb +27 -13
  53. data/lib/puppet/type/augeas.rb +1 -0
  54. data/lib/puppet/type/exec.rb +11 -2
  55. data/lib/puppet/type/group.rb +9 -1
  56. data/lib/puppet/type/mount.rb +2 -0
  57. data/lib/puppet/type/package.rb +13 -2
  58. data/lib/puppet/type/service.rb +9 -0
  59. data/lib/puppet/util.rb +8 -3
  60. data/lib/puppet/util/execution.rb +2 -2
  61. data/lib/puppet/util/http_proxy.rb +60 -0
  62. data/lib/puppet/util/log.rb +1 -1
  63. data/lib/puppet/util/splayer.rb +18 -0
  64. data/lib/puppet/version.rb +1 -1
  65. data/spec/fixtures/unit/provider/package/yum/yum-check-update-obsoletes.txt +195 -0
  66. data/spec/integration/application/apply_spec.rb +72 -30
  67. data/spec/integration/indirector/facts/facter_spec.rb +38 -0
  68. data/spec/integration/parser/scope_spec.rb +20 -2
  69. data/spec/integration/provider/mount_spec.rb +23 -36
  70. data/spec/integration/transaction_spec.rb +40 -1
  71. data/spec/integration/type/file_spec.rb +36 -0
  72. data/spec/integration/type/package_spec.rb +65 -0
  73. data/spec/lib/matchers/include_in_order.rb +0 -1
  74. data/spec/lib/puppet_spec/files.rb +14 -0
  75. data/spec/unit/agent_spec.rb +0 -38
  76. data/spec/unit/application/apply_spec.rb +13 -0
  77. data/spec/unit/configurer/plugin_handler_spec.rb +42 -13
  78. data/spec/unit/configurer_spec.rb +5 -0
  79. data/spec/unit/face/plugin_spec.rb +33 -4
  80. data/spec/unit/file_serving/configuration/parser_spec.rb +25 -30
  81. data/spec/unit/indirector/catalog/compiler_spec.rb +16 -0
  82. data/spec/unit/indirector/facts/facter_spec.rb +2 -1
  83. data/spec/unit/module_spec.rb +0 -23
  84. data/spec/unit/network/http/factory_spec.rb +14 -0
  85. data/spec/unit/parser/functions/fqdn_rand_spec.rb +6 -2
  86. data/spec/unit/parser/functions/generate_spec.rb +3 -12
  87. data/spec/unit/parser/scope_spec.rb +9 -0
  88. data/spec/unit/pops/evaluator/runtime3_converter_spec.rb +19 -0
  89. data/spec/unit/pops/evaluator/variables_spec.rb +1 -1
  90. data/spec/unit/pops/parser/lexer2_spec.rb +35 -3
  91. data/spec/unit/provider/augeas/augeas_spec.rb +9 -0
  92. data/spec/unit/provider/group/windows_adsi_spec.rb +5 -0
  93. data/spec/unit/provider/package/aptrpm_spec.rb +2 -2
  94. data/spec/unit/provider/package/base_spec.rb +18 -0
  95. data/spec/unit/provider/package/gem_spec.rb +70 -0
  96. data/spec/unit/provider/package/pacman_spec.rb +55 -0
  97. data/spec/unit/provider/package/pip3_spec.rb +257 -0
  98. data/spec/unit/provider/package/pip_spec.rb +1 -1
  99. data/spec/unit/provider/package/pkgdmg_spec.rb +18 -0
  100. data/spec/unit/provider/package/pkgin_spec.rb +23 -13
  101. data/spec/unit/provider/package/yum_spec.rb +11 -0
  102. data/spec/unit/provider/service/bsd_spec.rb +130 -0
  103. data/spec/unit/provider/service/debian_spec.rb +12 -1
  104. data/spec/unit/provider/service/freebsd_spec.rb +16 -0
  105. data/spec/unit/provider/service/systemd_spec.rb +84 -7
  106. data/spec/unit/provider/service/upstart_spec.rb +1 -0
  107. data/spec/unit/provider/zone/solaris_spec.rb +45 -12
  108. data/spec/unit/puppet_spec.rb +1 -1
  109. data/spec/unit/resource/catalog_spec.rb +5 -0
  110. data/spec/unit/type/mount_spec.rb +8 -0
  111. data/spec/unit/type/service_spec.rb +5 -0
  112. data/spec/unit/util/http_proxy_spec.rb +87 -0
  113. data/spec/unit/util/log_spec.rb +12 -1
  114. data/spec/unit/util/splayer_spec.rb +45 -0
  115. metadata +3071 -3035
  116. checksums.yaml +0 -7
  117. data/ext/systemd/puppetmaster.service +0 -11
@@ -55,16 +55,17 @@ describe "apply" do
55
55
 
56
56
  it "applies a given file even when an ENC is configured", :if => !Puppet.features.microsoft_windows? do
57
57
  manifest = file_containing("manifest.pp", "notice('specific manifest applied')")
58
- site_manifest = file_containing("site_manifest.pp", "notice('the site manifest was applied instead')")
59
- enc = file_containing("enc_script", "#!/bin/sh\necho 'classes: []'")
60
- File.chmod(0755, enc)
58
+ enc = script_containing('enc_script',
59
+ :windows => '@echo classes: []' + "\n" + '@echo environment: special',
60
+ :posix => '#!/bin/sh' + "\n" + 'echo "classes: []"' + "\n" + 'echo "environment: special"')
61
+
62
+ Dir.mkdir(File.join(Puppet[:environmentpath], "special"), 0755)
61
63
 
62
64
  special = Puppet::Node::Environment.create(:special, [])
63
65
  Puppet.override(:current_environment => special) do
64
66
  Puppet[:environment] = 'special'
65
67
  Puppet[:node_terminus] = 'exec'
66
68
  Puppet[:external_nodes] = enc
67
- Puppet[:manifest] = site_manifest
68
69
  puppet = Puppet::Application[:apply]
69
70
  puppet.stubs(:command_line).returns(stub('command_line', :args => [manifest]))
70
71
  expect { puppet.run_command }.to exit_with(0)
@@ -110,21 +111,25 @@ describe "apply" do
110
111
  end
111
112
  end
112
113
 
113
- context "with a module" do
114
- let(:modulepath) { tmpdir('modulepath') }
114
+ context "with a module in an environment" do
115
+ let(:envdir) { tmpdir('environments') }
116
+ let(:modulepath) { File.join(envdir, 'spec', 'modules') }
115
117
  let(:execute) { 'include amod' }
116
- let(:args) { ['-e', execute, '--modulepath', modulepath] }
117
118
 
118
119
  before(:each) do
119
- dir_contained_in(modulepath, {
120
- "amod" => {
121
- "manifests" => {
122
- "init.pp" => "class amod{ notice('amod class included') }"
120
+ dir_contained_in(envdir, {
121
+ "spec" => {
122
+ "modules" => {
123
+ "amod" => {
124
+ "manifests" => {
125
+ "init.pp" => "class amod{ notice('amod class included') }"
126
+ }
127
+ }
123
128
  }
124
129
  }
125
130
  })
126
131
 
127
- Puppet[:environmentpath] = dir_containing("environments", { Puppet[:environment] => {} })
132
+ Puppet[:environmentpath] = envdir
128
133
  end
129
134
 
130
135
  def init_cli_args_and_apply_app(args, execute)
@@ -134,31 +139,68 @@ describe "apply" do
134
139
  return puppet
135
140
  end
136
141
 
137
- it "looks in --modulepath even when the default directory environment exists" do
138
- apply = init_cli_args_and_apply_app(args, execute)
142
+ context "given the --modulepath option" do
143
+ let(:args) { ['-e', execute, '--modulepath', modulepath] }
139
144
 
140
- expect do
141
- expect { apply.run }.to exit_with(0)
142
- end.to have_printed('amod class included')
143
- end
145
+ it "looks in --modulepath even when the default directory environment exists" do
146
+ apply = init_cli_args_and_apply_app(args, execute)
144
147
 
145
- it "looks in --modulepath even when given a specific directory --environment" do
146
- args << '--environment' << 'production'
147
- apply = init_cli_args_and_apply_app(args, execute)
148
+ expect do
149
+ expect { apply.run }.to exit_with(0)
150
+ end.to have_printed('amod class included')
151
+ end
148
152
 
149
- expect do
150
- expect { apply.run }.to exit_with(0)
151
- end.to have_printed('amod class included')
153
+ it "looks in --modulepath even when given a specific directory --environment" do
154
+ args << '--environment' << 'production'
155
+ apply = init_cli_args_and_apply_app(args, execute)
156
+
157
+ expect do
158
+ expect { apply.run }.to exit_with(0)
159
+ end.to have_printed('amod class included')
160
+ end
161
+
162
+ it "looks in --modulepath when given multiple paths in --modulepath" do
163
+ args = ['-e', execute, '--modulepath', [tmpdir('notmodulepath'), modulepath].join(File::PATH_SEPARATOR)]
164
+ apply = init_cli_args_and_apply_app(args, execute)
165
+
166
+ expect do
167
+ expect { apply.run }.to exit_with(0)
168
+ end.to have_printed('amod class included')
169
+ end
152
170
  end
153
171
 
154
- it "looks in --modulepath when given multiple paths in --modulepath" do
155
- args = ['-e', execute, '--modulepath', [tmpdir('notmodulepath'), modulepath].join(File::PATH_SEPARATOR)]
156
- apply = init_cli_args_and_apply_app(args, execute)
172
+ # When executing an ENC script, output cannot be captured using
173
+ # expect { }.to have_printed(...)
174
+ # External node script execution will fail, likely due to the tampering
175
+ # with the basic file descriptors.
176
+ # Workaround: Define a log destination and merely inspect logs.
177
+ context "with an ENC" do
178
+ let(:logdest) { tmpfile('logdest') }
179
+ let(:args) { ['-e', execute, '--logdest', logdest ] }
180
+ let(:enc) do
181
+ script_containing('enc_script',
182
+ :windows => '@echo environment: spec',
183
+ :posix => '#!/bin/sh' + "\n" + 'echo "environment: spec"')
184
+ end
157
185
 
158
- expect do
186
+ before :each do
187
+ Puppet[:node_terminus] = 'exec'
188
+ Puppet[:external_nodes] = enc
189
+ end
190
+
191
+ it "should use the environment that the ENC mandates" do
192
+ apply = init_cli_args_and_apply_app(args, execute)
159
193
  expect { apply.run }.to exit_with(0)
160
- end.to have_printed('amod class included')
194
+ expect(@logs.map(&:to_s)).to include('amod class included')
195
+ end
196
+
197
+ it "should prefer the ENC environment over the configured one and emit a warning" do
198
+ apply = init_cli_args_and_apply_app(args + [ '--environment', 'production' ], execute)
199
+ expect { apply.run }.to exit_with(0)
200
+ logs = @logs.map(&:to_s)
201
+ expect(logs).to include('amod class included')
202
+ expect(logs).to include(match(/doesn't match server specified environment/))
203
+ end
161
204
  end
162
205
  end
163
-
164
206
  end
@@ -78,4 +78,42 @@ describe Puppet::Node::Facts::Facter do
78
78
  Puppet::Node.indirection.find('foo'))
79
79
  expect(cat.resource("Notify[#{Puppet.version.to_s}]")).to be
80
80
  end
81
+
82
+ it "the agent_specified_environment fact is nil when not set" do
83
+ expect do
84
+ compile_to_catalog('notify { $::agent_specified_environment: }',
85
+ Puppet::Node.indirection.find('foo'))
86
+ end.to raise_error(Puppet::PreformattedError)
87
+ end
88
+
89
+ it "adds the agent_specified_environment fact when set in puppet.conf" do
90
+ FileUtils.mkdir_p(Puppet[:confdir])
91
+ File.open(File.join(Puppet[:confdir], 'puppet.conf'), 'w') do |f|
92
+ f.puts("environment=bar")
93
+ end
94
+
95
+ Puppet.initialize_settings
96
+ cat = compile_to_catalog('notify { $::agent_specified_environment: }',
97
+ Puppet::Node.indirection.find('foo'))
98
+ expect(cat.resource("Notify[bar]")).to be
99
+ end
100
+
101
+ it "adds the agent_specified_environment fact when set via command-line" do
102
+ Puppet.initialize_settings(['--environment', 'bar'])
103
+ cat = compile_to_catalog('notify { $::agent_specified_environment: }',
104
+ Puppet::Node.indirection.find('foo'))
105
+ expect(cat.resource("Notify[bar]")).to be
106
+ end
107
+
108
+ it "adds the agent_specified_environment fact, preferring cli, when set in puppet.conf and via command-line" do
109
+ FileUtils.mkdir_p(Puppet[:confdir])
110
+ File.open(File.join(Puppet[:confdir], 'puppet.conf'), 'w') do |f|
111
+ f.puts("environment=bar")
112
+ end
113
+
114
+ Puppet.initialize_settings(['--environment', 'baz'])
115
+ cat = compile_to_catalog('notify { $::agent_specified_environment: }',
116
+ Puppet::Node.indirection.find('foo'))
117
+ expect(cat.resource("Notify[baz]")).to be
118
+ end
81
119
  end
@@ -34,7 +34,6 @@ describe "Two step scoping for variables" do
34
34
  MANIFEST
35
35
  end.to raise_error(/The operator '-=' is no longer supported/)
36
36
  end
37
- end
38
37
 
39
38
  it "issues error about built-in variable when reassigning to name" do
40
39
  enc_node = Puppet::Node.new("the_node", { :parameters => { } })
@@ -112,7 +111,26 @@ describe "Two step scoping for variables" do
112
111
  class bar inherits bar_bamama {
113
112
  notify { 'something': message => inline_template("<%= @var %>"), }
114
113
  }
115
- MANIFEST
114
+ MANIFEST
115
+ end
116
+ end
117
+
118
+ describe 'handles 3.x/4.x functions' do
119
+ it 'can call a 3.x function via call_function' do
120
+ expect_the_message_to_be('yes') do <<-MANIFEST
121
+ $msg = inline_template('<%= scope().call_function("fqdn_rand", [30]).to_i <= 30 ? "yes" : "no" %>')
122
+ notify { 'something': message => $msg }
123
+ MANIFEST
124
+ end
125
+ end
126
+
127
+ it 'it can call a 4.x function via call_function' do
128
+ expect_the_message_to_be('yes') do <<-MANIFEST
129
+ $msg = inline_template('<%= scope().call_function("with", ["yes"]) { |x| x } %>')
130
+ notify { 'something': message => $msg }
131
+ MANIFEST
132
+ end
133
+ end
116
134
  end
117
135
  end
118
136
 
@@ -22,9 +22,9 @@ describe "mount provider (integration)", :unless => Puppet.features.microsoft_wi
22
22
  Puppet::Type.type(:mount).defaultprovider.stubs(:default_target).returns(@fake_fstab)
23
23
  Facter.stubs(:value).with(:hostname).returns('some_host')
24
24
  Facter.stubs(:value).with(:domain).returns('some_domain')
25
- Facter.stubs(:value).with(:kernel).returns('Darwin')
26
- Facter.stubs(:value).with(:operatingsystem).returns('Darwin')
27
- Facter.stubs(:value).with(:osfamily).returns('Darwin')
25
+ Facter.stubs(:value).with(:kernel).returns('Linux')
26
+ Facter.stubs(:value).with(:operatingsystem).returns('RedHat')
27
+ Facter.stubs(:value).with(:osfamily).returns('RedHat')
28
28
  Puppet::Util::ExecutionStub.set do |command, options|
29
29
  case command[0]
30
30
  when %r{/s?bin/mount}
@@ -35,24 +35,7 @@ describe "mount provider (integration)", :unless => Puppet.features.microsoft_wi
35
35
  ''
36
36
  end
37
37
  else
38
- expect(command.length).to eq(4)
39
- expect(command[1]).to eq('-o')
40
-
41
- # update is a special option, used on bsd's
42
- # strip it out and track as a local bool here
43
- update = false
44
- tmp_options = command[2].split(",")
45
-
46
- if tmp_options.include?("update")
47
- update = true
48
- tmp_options.delete("update")
49
- end
50
- @current_options = tmp_options.join(",")
51
-
52
- if !update
53
- expect(@mounted).to eq(false) # verify that we don't try to call "mount" redundantly
54
- end
55
- expect(command[3]).to eq('/Volumes/foo_disk')
38
+ expect(command.last).to eq('/Volumes/foo_disk')
56
39
  @current_device = check_fstab(true)
57
40
  @mounted = true
58
41
  ''
@@ -123,27 +106,31 @@ describe "mount provider (integration)", :unless => Puppet.features.microsoft_wi
123
106
  end
124
107
  expected_fstab_data = (ensure_setting != :absent)
125
108
  describe "When setting ensure => #{ensure_setting}" do
126
- ["local", "journaled"].each do |options_setting|
127
- describe "When setting options => #{options_setting}" do
109
+ ["local", "journaled", "", nil].each do |options_setting|
110
+ describe "When setting options => '#{options_setting}'" do
128
111
  it "should leave the system in the #{expected_final_state ? 'mounted' : 'unmounted'} state, #{expected_fstab_data ? 'with' : 'without'} data in /etc/fstab" do
129
112
  if family == "Solaris"
130
113
  skip("Solaris: The mock :operatingsystem value does not get changed in lib/puppet/provider/mount/parsed.rb")
131
114
  else
132
- @desired_options = options_setting
133
- run_in_catalog(:ensure=>ensure_setting, :options => options_setting)
134
- expect(@mounted).to eq(expected_final_state)
135
- if expected_fstab_data
136
- expect(check_fstab(expected_fstab_data)).to eq("/dev/disk1s1")
115
+ if options_setting && options_setting.empty?
116
+ expect { run_in_catalog(:ensure=>ensure_setting, :options => options_setting) }.to raise_error Puppet::ResourceError
137
117
  else
138
- expect(check_fstab(expected_fstab_data)).to eq(nil)
139
- end
140
- if @mounted
141
- if ![:defined, :present].include?(ensure_setting)
142
- expect(@current_options).to eq(@desired_options)
143
- elsif initial_fstab_entry
144
- expect(@current_options).to eq(@desired_options)
118
+ if options_setting
119
+ @desired_options = options_setting
120
+ run_in_catalog(:ensure=>ensure_setting, :options => options_setting)
121
+ else
122
+ if initial_fstab_entry
123
+ @desired_options = @current_options
124
+ else
125
+ @desired_options = 'defaults'
126
+ end
127
+ run_in_catalog(:ensure=>ensure_setting)
128
+ end
129
+ expect(@mounted).to eq(expected_final_state)
130
+ if expected_fstab_data
131
+ expect(check_fstab(expected_fstab_data)).to eq("/dev/disk1s1")
145
132
  else
146
- expect(@current_options).to eq('local') #Workaround for #6645
133
+ expect(check_fstab(expected_fstab_data)).to eq(nil)
147
134
  end
148
135
  end
149
136
  end
@@ -352,10 +352,49 @@ describe Puppet::Transaction do
352
352
  )
353
353
 
354
354
  catalog = mk_catalog(exec, file1, file2)
355
- catalog.apply
355
+ transaction = catalog.apply
356
356
 
357
357
  expect(Puppet::FileSystem.exist?(file1[:path])).to be_falsey
358
358
  expect(Puppet::FileSystem.exist?(file2[:path])).to be_falsey
359
+
360
+ expect(transaction.resource_status(file1).skipped).to be_truthy
361
+ expect(transaction.resource_status(file2).skipped).to be_truthy
362
+
363
+ expect(transaction.resource_status(file1).failed_dependencies).to eq([exec])
364
+ expect(transaction.resource_status(file2).failed_dependencies).to eq([exec])
365
+ end
366
+
367
+ it "on failure, skips dynamically-generated dependents" do
368
+ exec = Puppet::Type.type(:exec).new(
369
+ :command => "#{File.expand_path('/bin/mkdir')} /this/path/cannot/possibly/exist",
370
+ :title => "mkdir"
371
+ )
372
+
373
+ tmp = tmpfile("dir1")
374
+ FileUtils.mkdir_p(tmp)
375
+ FileUtils.mkdir_p(File.join(tmp, "foo"))
376
+
377
+ purge_dir = Puppet::Type.type(:file).new(
378
+ :title => "dir1",
379
+ :path => tmp,
380
+ :require => exec,
381
+ :ensure => :directory,
382
+ :recurse => true,
383
+ :purge => true
384
+ )
385
+
386
+ catalog = mk_catalog(exec, purge_dir)
387
+ txn = catalog.apply
388
+
389
+ expect(txn.resource_status(purge_dir).skipped).to be_truthy
390
+
391
+ children = catalog.relationship_graph.direct_dependents_of(purge_dir)
392
+
393
+ children.each do |child|
394
+ expect(txn.resource_status(child).skipped).to be_truthy
395
+ end
396
+
397
+ expect(Puppet::FileSystem.exist?(File.join(tmp, "foo"))).to be_truthy
359
398
  end
360
399
 
361
400
  it "should not trigger subscribing resources on failure" do
@@ -716,6 +716,42 @@ describe Puppet::Type.type(:file), :uses_checksums => true do
716
716
  end
717
717
  end
718
718
 
719
+ it "should not recursively manage files set to be ignored" do
720
+ srcdir = tmpfile("ignore_vs_recurse_1")
721
+ dstdir = tmpfile("ignore_vs_recurse_2")
722
+
723
+ FileUtils.mkdir_p(srcdir)
724
+ FileUtils.mkdir_p(dstdir)
725
+
726
+ srcfile = File.join(srcdir, "file.src")
727
+ cpyfile = File.join(dstdir, "file.src")
728
+ ignfile = File.join(srcdir, "file.ign")
729
+
730
+ File.open(srcfile, "w") { |f| f.puts "don't ignore me" }
731
+ File.open(ignfile, "w") { |f| f.puts "you better ignore me" }
732
+
733
+
734
+ catalog.add_resource described_class.new(
735
+ :name => srcdir,
736
+ :ensure => 'directory',
737
+ :mode => '0755',)
738
+
739
+ catalog.add_resource described_class.new(
740
+ :name => dstdir,
741
+ :ensure => 'directory',
742
+ :mode => "755",
743
+ :source => srcdir,
744
+ :recurse => true,
745
+ :ignore => '*.ign',)
746
+
747
+ catalog.apply
748
+ expect(Puppet::FileSystem.exist?(srcdir)).to be_truthy
749
+ expect(Puppet::FileSystem.exist?(dstdir)).to be_truthy
750
+ expect(File.read(srcfile).strip).to eq("don't ignore me")
751
+ expect(File.read(cpyfile).strip).to eq("don't ignore me")
752
+ expect(Puppet::FileSystem.exist?("#{dstdir}/file.ign")).to be_falsey
753
+ end
754
+
719
755
  it "should not recursively manage files managed by a more specific explicit file" do
720
756
  dir = tmpfile("recursion_vs_explicit_1")
721
757
 
@@ -125,3 +125,68 @@ describe Puppet::Type.type(:package), "when packages with the same name are sour
125
125
  end
126
126
  end
127
127
 
128
+ describe Puppet::Type.type(:package), 'logging package state transitions' do
129
+
130
+ let(:catalog) { Puppet::Resource::Catalog.new }
131
+ let(:provider) { stub('provider', :class => Puppet::Type.type(:package).defaultprovider, :clear => nil, :validate_source => nil) }
132
+
133
+ before :each do
134
+ provider.stubs(:satisfies?).with([:purgeable]).returns(true)
135
+ provider.class.stubs(:instances).returns([])
136
+ provider.stubs(:install).returns nil
137
+ provider.stubs(:uninstall).returns nil
138
+ provider.stubs(:purge).returns nil
139
+ Puppet::Type.type(:package).defaultprovider.stubs(:new).returns(provider)
140
+ end
141
+
142
+ after :each do
143
+ Puppet::Type.type(:package).defaultprovider = nil
144
+ end
145
+
146
+ # Map of old state -> {new state -> change}
147
+ states = {
148
+ # 'installed' transitions to 'removed' or 'purged'
149
+ :installed => {
150
+ :installed => nil,
151
+ :absent => 'removed',
152
+ :purged => 'purged'
153
+ },
154
+ # 'absent' transitions to 'created' or 'purged'
155
+ :absent => {
156
+ :installed => 'created',
157
+ :absent => nil,
158
+ :purged => 'purged'
159
+ },
160
+ # 'purged' transitions to 'created'
161
+ :purged => {
162
+ :installed => 'created',
163
+ :absent => nil,
164
+ :purged => nil
165
+ }
166
+ }
167
+
168
+ states.each do |old, new_states|
169
+ describe "#{old} package" do
170
+
171
+ before :each do
172
+ provider.stubs(:properties).returns(:ensure => old)
173
+ end
174
+
175
+ new_states.each do |new, status|
176
+ it "ensure => #{new} should log #{status ? status : 'nothing'}" do
177
+ catalog.add_resource(described_class.new(:name => 'yay', :ensure => new))
178
+ catalog.apply
179
+
180
+ logs = catalog.apply.report.logs
181
+ if status
182
+ expect(logs.first.source).to eq("/Package[yay]/ensure")
183
+ expect(logs.first.message).to eq(status)
184
+ else
185
+ expect(logs.first).to be_nil
186
+ end
187
+ end
188
+ end
189
+ end
190
+ end
191
+ end
192
+