puppet 4.0.0 → 4.1.0

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 (219) hide show
  1. checksums.yaml +4 -4
  2. data/ext/build_defaults.yaml +8 -35
  3. data/ext/debian/puppet.default +0 -5
  4. data/ext/debian/puppet.init +1 -15
  5. data/lib/hiera/puppet_function.rb +15 -4
  6. data/lib/puppet/application/agent.rb +5 -0
  7. data/lib/puppet/application/apply.rb +23 -2
  8. data/lib/puppet/application/device.rb +8 -3
  9. data/lib/puppet/application/master.rb +16 -5
  10. data/lib/puppet/configurer.rb +7 -5
  11. data/lib/puppet/defaults.rb +18 -0
  12. data/lib/puppet/environments.rb +1 -1
  13. data/lib/puppet/error.rb +27 -1
  14. data/lib/puppet/file_serving/metadata.rb +13 -8
  15. data/lib/puppet/file_serving/terminus_helper.rb +7 -8
  16. data/lib/puppet/file_system.rb +13 -0
  17. data/lib/puppet/file_system/file_impl.rb +4 -0
  18. data/lib/puppet/file_system/memory_impl.rb +4 -0
  19. data/lib/puppet/file_system/windows.rb +8 -0
  20. data/lib/puppet/functions.rb +33 -3
  21. data/lib/puppet/functions/defined.rb +130 -0
  22. data/lib/puppet/functions/regsubst.rb +1 -1
  23. data/lib/puppet/functions/split.rb +1 -1
  24. data/lib/puppet/indirector/catalog/compiler.rb +1 -1
  25. data/lib/puppet/indirector/facts/facter.rb +11 -0
  26. data/lib/puppet/loaders.rb +1 -0
  27. data/lib/puppet/node.rb +17 -1
  28. data/lib/puppet/node/environment.rb +4 -0
  29. data/lib/puppet/parser/ast/pops_bridge.rb +4 -0
  30. data/lib/puppet/parser/compiler.rb +9 -0
  31. data/lib/puppet/parser/functions/defined.rb +25 -1
  32. data/lib/puppet/parser/functions/file.rb +3 -1
  33. data/lib/puppet/parser/scope.rb +11 -2
  34. data/lib/puppet/parser/templatewrapper.rb +2 -1
  35. data/lib/puppet/pops.rb +4 -0
  36. data/lib/puppet/pops/evaluator/access_operator.rb +25 -5
  37. data/lib/puppet/pops/evaluator/closure.rb +28 -2
  38. data/lib/puppet/pops/evaluator/collector_transformer.rb +1 -11
  39. data/lib/puppet/pops/evaluator/collectors/catalog_collector.rb +4 -0
  40. data/lib/puppet/pops/evaluator/collectors/exported_collector.rb +4 -0
  41. data/lib/puppet/pops/evaluator/compare_operator.rb +43 -0
  42. data/lib/puppet/pops/evaluator/epp_evaluator.rb +7 -2
  43. data/lib/puppet/pops/evaluator/evaluator_impl.rb +48 -14
  44. data/lib/puppet/pops/evaluator/runtime3_support.rb +10 -5
  45. data/lib/puppet/pops/functions/dispatch.rb +6 -1
  46. data/lib/puppet/pops/functions/dispatcher.rb +7 -1
  47. data/lib/puppet/pops/issue_reporter.rb +42 -16
  48. data/lib/puppet/pops/issues.rb +116 -2
  49. data/lib/puppet/pops/loader/loader.rb +11 -0
  50. data/lib/puppet/pops/loader/loader_paths.rb +67 -6
  51. data/lib/puppet/pops/loader/module_loaders.rb +19 -8
  52. data/lib/puppet/pops/loader/puppet_function_instantiator.rb +78 -0
  53. data/lib/puppet/pops/loaders.rb +6 -4
  54. data/lib/puppet/pops/migration/migration_checker.rb +54 -0
  55. data/lib/puppet/pops/model/factory.rb +5 -1
  56. data/lib/puppet/pops/model/model_label_provider.rb +2 -0
  57. data/lib/puppet/pops/model/model_meta.rb +5 -1
  58. data/lib/puppet/pops/parser/egrammar.ra +9 -10
  59. data/lib/puppet/pops/parser/eparser.rb +1061 -1047
  60. data/lib/puppet/pops/parser/epp_support.rb +18 -9
  61. data/lib/puppet/pops/parser/evaluating_parser.rb +7 -1
  62. data/lib/puppet/pops/parser/heredoc_support.rb +12 -11
  63. data/lib/puppet/pops/parser/interpolation_support.rb +7 -1
  64. data/lib/puppet/pops/parser/lexer2.rb +29 -12
  65. data/lib/puppet/pops/parser/lexer_support.rb +52 -23
  66. data/lib/puppet/pops/parser/parser_support.rb +11 -14
  67. data/lib/puppet/pops/parser/slurp_support.rb +22 -6
  68. data/lib/puppet/pops/types/type_calculator.rb +156 -55
  69. data/lib/puppet/pops/types/type_factory.rb +66 -13
  70. data/lib/puppet/pops/types/type_parser.rb +22 -13
  71. data/lib/puppet/pops/types/types.rb +23 -4
  72. data/lib/puppet/pops/types/types_meta.rb +13 -2
  73. data/lib/puppet/pops/validation.rb +25 -2
  74. data/lib/puppet/pops/validation/checker4_0.rb +63 -31
  75. data/lib/puppet/provider/group/windows_adsi.rb +8 -4
  76. data/lib/puppet/provider/mount/parsed.rb +145 -2
  77. data/lib/puppet/provider/package/apt.rb +1 -1
  78. data/lib/puppet/provider/package/pip.rb +11 -2
  79. data/lib/puppet/provider/package/pkgng.rb +134 -0
  80. data/lib/puppet/provider/package/portage.rb +1 -1
  81. data/lib/puppet/provider/package/ports.rb +0 -3
  82. data/lib/puppet/provider/package/windows/exe_package.rb +0 -1
  83. data/lib/puppet/provider/package/windows/msi_package.rb +0 -1
  84. data/lib/puppet/provider/package/zypper.rb +50 -15
  85. data/lib/puppet/provider/scheduled_task/win32_taskscheduler.rb +32 -7
  86. data/lib/puppet/provider/service/debian.rb +1 -1
  87. data/lib/puppet/provider/service/init.rb +7 -0
  88. data/lib/puppet/provider/user/openbsd.rb +1 -0
  89. data/lib/puppet/provider/user/windows_adsi.rb +45 -2
  90. data/lib/puppet/reference/indirection.rb +1 -1
  91. data/lib/puppet/resource.rb +1 -1
  92. data/lib/puppet/resource/catalog.rb +0 -4
  93. data/lib/puppet/settings.rb +19 -0
  94. data/lib/puppet/type/file.rb +1 -0
  95. data/lib/puppet/type/file/ensure.rb +1 -1
  96. data/lib/puppet/type/mount.rb +9 -1
  97. data/lib/puppet/type/scheduled_task.rb +13 -0
  98. data/lib/puppet/type/tidy.rb +3 -1
  99. data/lib/puppet/type/user.rb +32 -0
  100. data/lib/puppet/type/yumrepo.rb +5 -5
  101. data/lib/puppet/util/log.rb +50 -8
  102. data/lib/puppet/util/log/destinations.rb +23 -2
  103. data/lib/puppet/util/logging.rb +37 -1
  104. data/lib/puppet/util/run_mode.rb +1 -14
  105. data/lib/puppet/util/windows/adsi.rb +130 -58
  106. data/lib/puppet/version.rb +1 -1
  107. data/man/man5/puppet.conf.5 +48 -6
  108. data/man/man8/extlookup2hiera.8 +1 -1
  109. data/man/man8/puppet-agent.8 +4 -1
  110. data/man/man8/puppet-apply.8 +4 -1
  111. data/man/man8/puppet-ca.8 +1 -1
  112. data/man/man8/puppet-catalog.8 +1 -1
  113. data/man/man8/puppet-cert.8 +1 -1
  114. data/man/man8/puppet-certificate.8 +1 -1
  115. data/man/man8/puppet-certificate_request.8 +1 -1
  116. data/man/man8/puppet-certificate_revocation_list.8 +1 -1
  117. data/man/man8/puppet-config.8 +1 -1
  118. data/man/man8/puppet-describe.8 +1 -1
  119. data/man/man8/puppet-device.8 +6 -3
  120. data/man/man8/puppet-doc.8 +1 -1
  121. data/man/man8/puppet-epp.8 +1 -1
  122. data/man/man8/puppet-facts.8 +1 -1
  123. data/man/man8/puppet-file.8 +1 -1
  124. data/man/man8/puppet-filebucket.8 +1 -1
  125. data/man/man8/puppet-help.8 +1 -1
  126. data/man/man8/puppet-inspect.8 +1 -1
  127. data/man/man8/puppet-key.8 +1 -1
  128. data/man/man8/puppet-man.8 +1 -1
  129. data/man/man8/puppet-master.8 +4 -1
  130. data/man/man8/puppet-module.8 +1 -1
  131. data/man/man8/puppet-node.8 +1 -1
  132. data/man/man8/puppet-parser.8 +1 -1
  133. data/man/man8/puppet-plugin.8 +1 -1
  134. data/man/man8/puppet-report.8 +1 -1
  135. data/man/man8/puppet-resource.8 +1 -1
  136. data/man/man8/puppet-resource_type.8 +1 -1
  137. data/man/man8/puppet-status.8 +1 -1
  138. data/man/man8/puppet.8 +1 -1
  139. data/spec/fixtures/unit/data_providers/environments/production/lib/puppet/functions/environment/data.rb +3 -1
  140. data/spec/fixtures/unit/data_providers/environments/production/modules/xyz/functions/data.pp +6 -0
  141. data/spec/fixtures/unit/data_providers/environments/production/modules/xyz/lib/puppet/bindings/xyz/default.rb +9 -0
  142. data/spec/fixtures/unit/data_providers/environments/production/modules/xyz/manifests/init.pp +9 -0
  143. data/spec/fixtures/unit/pops/loaders/loaders/mix_4x_and_3x_functions/user/functions/puppetcalled.pp +3 -0
  144. data/spec/fixtures/unit/pops/loaders/loaders/mix_4x_and_3x_functions/user/functions/puppetcaller.pp +3 -0
  145. data/spec/fixtures/unit/pops/loaders/loaders/mix_4x_and_3x_functions/user/functions/puppetcaller4.pp +3 -0
  146. data/spec/fixtures/unit/pops/loaders/loaders/mix_4x_and_3x_functions/user/lib/puppet/functions/user/callingpuppet.rb +5 -0
  147. data/spec/fixtures/unit/pops/loaders/loaders/module_no_lib/modules/modulea/functions/hello.pp +3 -0
  148. data/spec/fixtures/unit/pops/loaders/loaders/module_no_lib/modules/modulea/manifests/init.pp +3 -0
  149. data/spec/fixtures/unit/pops/loaders/loaders/module_no_lib/modules/modulea/metadata.json +10 -0
  150. data/spec/fixtures/unit/pops/loaders/loaders/single_module/modules/modulea/functions/hello.pp +3 -0
  151. data/spec/fixtures/unit/pops/loaders/loaders/single_module/modules/modulea/functions/subspace/hello.pp +3 -0
  152. data/spec/fixtures/unit/pops/loaders/loaders/single_module/modules/modulea/metadata.json +1 -10
  153. data/spec/fixtures/unit/provider/mount/parsed/aix.filesystems +93 -85
  154. data/spec/fixtures/unit/provider/mount/parsed/aix.mount +11 -7
  155. data/spec/fixtures/unit/provider/package/pkgng/pkg.info +8 -0
  156. data/spec/fixtures/unit/provider/package/pkgng/pkg.query +1 -0
  157. data/spec/fixtures/unit/provider/package/pkgng/pkg.query_absent +1 -0
  158. data/spec/fixtures/unit/provider/package/pkgng/pkg.version +3 -0
  159. data/spec/fixtures/unit/provider/package/zypper/zypper-list-updates-empty.out +3 -0
  160. data/spec/integration/application/apply_spec.rb +49 -0
  161. data/spec/integration/faces/plugin_spec.rb +0 -4
  162. data/spec/integration/indirector/facts/facter_spec.rb +59 -0
  163. data/spec/integration/parser/compiler_spec.rb +850 -0
  164. data/spec/integration/parser/resource_expressions_spec.rb +3 -0
  165. data/spec/integration/parser/scope_spec.rb +26 -5
  166. data/spec/integration/transaction_spec.rb +1 -1
  167. data/spec/integration/type/file_spec.rb +318 -41
  168. data/spec/integration/util/windows/security_spec.rb +14 -5
  169. data/spec/lib/matchers/resource.rb +22 -1
  170. data/spec/lib/puppet_spec/matchers.rb +6 -4
  171. data/spec/unit/application/master_spec.rb +33 -7
  172. data/spec/unit/data_providers/function_data_provider_spec.rb +10 -1
  173. data/spec/unit/file_serving/metadata_spec.rb +1 -1
  174. data/spec/unit/file_serving/terminus_helper_spec.rb +2 -3
  175. data/spec/unit/file_system_spec.rb +38 -0
  176. data/spec/unit/functions/defined_spec.rb +289 -0
  177. data/spec/unit/functions/hiera_spec.rb +8 -6
  178. data/spec/unit/functions/regsubst_spec.rb +4 -0
  179. data/spec/unit/functions/split_spec.rb +8 -0
  180. data/spec/unit/functions4_spec.rb +97 -2
  181. data/spec/unit/indirector/facts/facter_spec.rb +7 -0
  182. data/spec/unit/node_spec.rb +6 -0
  183. data/spec/unit/parser/functions/file_spec.rb +7 -1
  184. data/spec/unit/parser/functions/template_spec.rb +1 -1
  185. data/spec/unit/parser/scope_spec.rb +2 -2
  186. data/spec/unit/parser/templatewrapper_spec.rb +1 -1
  187. data/spec/unit/pops/evaluator/access_ops_spec.rb +19 -0
  188. data/spec/unit/pops/evaluator/evaluating_parser_spec.rb +84 -18
  189. data/spec/unit/pops/evaluator/variables_spec.rb +1 -1
  190. data/spec/unit/pops/issues_spec.rb +16 -16
  191. data/spec/unit/pops/loaders/loaders_spec.rb +106 -48
  192. data/spec/unit/pops/migration_spec.rb +53 -0
  193. data/spec/unit/pops/parser/lexer2_spec.rb +142 -1
  194. data/spec/unit/pops/parser/parse_heredoc_spec.rb +26 -0
  195. data/spec/unit/pops/types/type_calculator_spec.rb +205 -12
  196. data/spec/unit/pops/validation_spec.rb +66 -0
  197. data/spec/unit/pops/validator/validator_spec.rb +1 -1
  198. data/spec/unit/provider/group/windows_adsi_spec.rb +57 -9
  199. data/spec/unit/provider/mount/parsed_spec.rb +31 -5
  200. data/spec/unit/provider/package/apt_spec.rb +5 -0
  201. data/spec/unit/provider/package/pip_spec.rb +9 -0
  202. data/spec/unit/provider/package/pkgng_spec.rb +172 -0
  203. data/spec/unit/provider/package/windows/exe_package_spec.rb +0 -1
  204. data/spec/unit/provider/package/windows/msi_package_spec.rb +0 -1
  205. data/spec/unit/provider/package/zypper_spec.rb +50 -19
  206. data/spec/unit/provider/scheduled_task/win32_taskscheduler_spec.rb +312 -70
  207. data/spec/unit/provider/service/base_spec.rb +38 -27
  208. data/spec/unit/provider/service/debian_spec.rb +8 -0
  209. data/spec/unit/provider/service/freebsd_spec.rb +1 -0
  210. data/spec/unit/provider/service/gentoo_spec.rb +1 -0
  211. data/spec/unit/provider/service/init_spec.rb +18 -0
  212. data/spec/unit/provider/service/openbsd_spec.rb +1 -0
  213. data/spec/unit/provider/service/redhat_spec.rb +1 -0
  214. data/spec/unit/provider/user/windows_adsi_spec.rb +134 -5
  215. data/spec/unit/settings_spec.rb +11 -0
  216. data/spec/unit/util/log_spec.rb +113 -0
  217. data/spec/unit/util/windows/adsi_spec.rb +135 -41
  218. data/spec/unit/util/windows/sid_spec.rb +0 -10
  219. metadata +48 -2
@@ -10,39 +10,52 @@ describe "base service provider" do
10
10
 
11
11
  let :type do Puppet::Type.type(:service) end
12
12
  let :provider do type.provider(:base) end
13
+ let(:executor) { Puppet::Util::Execution }
14
+ let(:start_command) { 'start' }
15
+ let(:status_command) { 'status' }
16
+ let(:stop_command) { 'stop' }
13
17
 
14
18
  subject { provider }
15
19
 
16
20
  context "basic operations" do
17
- # Cross-platform file interactions. Fun times.
18
- Ruby = File.join(RbConfig::CONFIG["bindir"],
19
- RbConfig::CONFIG["RUBY_INSTALL_NAME"] +
20
- RbConfig::CONFIG["EXEEXT"])
21
-
22
- Start = [Ruby, '-rfileutils', '-e', 'FileUtils.touch(ARGV[0])']
23
- Status = [Ruby, '-e' 'exit File.file?(ARGV[0])']
24
- Stop = [Ruby, '-e', 'File.exist?(ARGV[0]) and File.unlink(ARGV[0])']
25
-
26
- let :flag do tmpfile('base-service-test') end
27
-
28
21
  subject do
29
- type.new(:name => "test", :provider => :base,
30
- :start => Start + [flag],
31
- :status => Status + [flag],
32
- :stop => Stop + [flag]
22
+ type.new(
23
+ :name => "test",
24
+ :provider => :base,
25
+ :start => start_command,
26
+ :status => status_command,
27
+ :stop => stop_command
33
28
  ).provider
34
29
  end
35
30
 
36
- before :each do
37
- Puppet::FileSystem.unlink(flag) if Puppet::FileSystem.exist?(flag)
31
+ def execute_command(command, options)
32
+ case command.shift
33
+ when start_command
34
+ expect(options[:failonfail]).to eq(true)
35
+ raise(Puppet::ExecutionFailure, 'failed to start') if @running
36
+ @running = true
37
+ return 'started'
38
+ when status_command
39
+ expect(options[:failonfail]).to eq(false)
40
+ $CHILD_STATUS.expects(:exitstatus).at_least(1).returns(@running ? 0 : 1)
41
+ return @running ? 'running' : 'not running'
42
+ when stop_command
43
+ expect(options[:failonfail]).to eq(true)
44
+ raise(Puppet::ExecutionFailure, 'failed to stop') unless @running
45
+ @running = false
46
+ return 'stopped'
47
+ else
48
+ raise "unexpected command execution: #{command}"
49
+ end
38
50
  end
39
51
 
40
- it { is_expected.to be }
52
+ before :each do
53
+ @running = false
54
+ executor.expects(:execute).at_least(1).with { |command, options| execute_command(command, options) }
55
+ end
41
56
 
42
57
  it "should invoke the start command if not running" do
43
- expect(File).not_to be_file(flag)
44
58
  subject.start
45
- expect(File).to be_file(flag)
46
59
  end
47
60
 
48
61
  it "should be stopped before being started" do
@@ -59,19 +72,17 @@ describe "base service provider" do
59
72
  expect(subject.status).to eq(:running)
60
73
  subject.stop
61
74
  expect(subject.status).to eq(:stopped)
62
- expect(File).not_to be_file(flag)
63
75
  end
64
76
 
65
- it "should start again even if already running" do
66
- subject.start
67
- subject.expects(:ucommand).with(:start)
77
+ it "should raise an error if started twice" do
68
78
  subject.start
79
+ expect {subject.start }.to raise_error(Puppet::Error, 'Could not start Service[test]: failed to start')
69
80
  end
70
81
 
71
- it "should stop again even if already stopped" do
72
- subject.stop
73
- subject.expects(:ucommand).with(:stop)
82
+ it "should raise an error if stopped twice" do
83
+ subject.start
74
84
  subject.stop
85
+ expect {subject.stop }.to raise_error(Puppet::Error, 'Could not stop Service[test]: failed to stop')
75
86
  end
76
87
  end
77
88
  end
@@ -32,6 +32,14 @@ describe provider_class do
32
32
  @provider.stubs(:invoke_rc)
33
33
  end
34
34
 
35
+ operatingsystem = [ 'Debian', 'CumulusLinux' ]
36
+ operatingsystem.each do |os|
37
+ it "should be the default provider on #{os}" do
38
+ Facter.expects(:value).with(:operatingsystem).returns(os)
39
+ expect(provider_class.default?).to be_truthy
40
+ end
41
+ end
42
+
35
43
  it "should have an enabled? method" do
36
44
  expect(@provider).to respond_to(:enabled?)
37
45
  end
@@ -7,6 +7,7 @@ describe provider_class do
7
7
  before :each do
8
8
  @provider = provider_class.new
9
9
  @provider.stubs(:initscript)
10
+ Facter.stubs(:value).with(:osfamily).returns 'FreeBSD'
10
11
  end
11
12
 
12
13
  it "should correctly parse rcvar for FreeBSD < 7" do
@@ -9,6 +9,7 @@ describe Puppet::Type.type(:service).provider(:gentoo) do
9
9
  FileTest.stubs(:file?).with('/sbin/rc-update').returns true
10
10
  FileTest.stubs(:executable?).with('/sbin/rc-update').returns true
11
11
  Facter.stubs(:value).with(:operatingsystem).returns 'Gentoo'
12
+ Facter.stubs(:value).with(:osfamily).returns 'Gentoo'
12
13
 
13
14
  # The initprovider (parent of the gentoo provider) does a stat call
14
15
  # before it even tries to execute an initscript. We use sshd in all the
@@ -213,5 +213,23 @@ describe Puppet::Type.type(:service).provider(:init) do
213
213
  provider.restart
214
214
  end
215
215
  end
216
+
217
+ describe "when starting a service on Solaris" do
218
+ it "should use ctrun" do
219
+ Facter.stubs(:value).with(:osfamily).returns 'Solaris'
220
+ provider.expects(:execute).with('/usr/bin/ctrun -l none /service/path/myservice start', {:failonfail => true, :override_locale => false, :squelch => false, :combine => true}).returns("")
221
+ $CHILD_STATUS.stubs(:exitstatus).returns(0)
222
+ provider.start
223
+ end
224
+ end
225
+
226
+ describe "when starting a service on RedHat" do
227
+ it "should not use ctrun" do
228
+ Facter.stubs(:value).with(:osfamily).returns 'RedHat'
229
+ provider.expects(:execute).with(['/service/path/myservice', :start], {:failonfail => true, :override_locale => false, :squelch => false, :combine => true}).returns("")
230
+ $CHILD_STATUS.stubs(:exitstatus).returns(0)
231
+ provider.start
232
+ end
233
+ end
216
234
  end
217
235
  end
@@ -10,6 +10,7 @@ describe provider_class, :unless => Puppet.features.microsoft_windows? do
10
10
  before :each do
11
11
  Puppet::Type.type(:service).stubs(:defaultprovider).returns described_class
12
12
  Facter.stubs(:value).with(:operatingsystem).returns :openbsd
13
+ Facter.stubs(:value).with(:osfamily).returns 'OpenBSD'
13
14
  FileTest.stubs(:file?).with('/usr/sbin/rcctl').returns true
14
15
  FileTest.stubs(:executable?).with('/usr/sbin/rcctl').returns true
15
16
  end
@@ -20,6 +20,7 @@ describe provider_class, :if => Puppet.features.posix? do
20
20
  FileTest.stubs(:file?).with('/sbin/service').returns true
21
21
  FileTest.stubs(:executable?).with('/sbin/service').returns true
22
22
  Facter.stubs(:value).with(:operatingsystem).returns('CentOS')
23
+ Facter.stubs(:value).with(:osfamily).returns 'RedHat'
23
24
  end
24
25
 
25
26
  osfamily = [ 'RedHat', 'Suse' ]
@@ -35,16 +35,18 @@ describe Puppet::Type.type(:user).provider(:windows_adsi), :if => Puppet.feature
35
35
  end
36
36
 
37
37
  describe "when managing groups" do
38
- it 'should return the list of groups as a comma-separated list' do
39
- provider.user.stubs(:groups).returns ['group1', 'group2', 'group3']
38
+ it 'should return the list of groups as an array of strings' do
39
+ provider.user.stubs(:groups).returns nil
40
+ groups = {'group1' => nil, 'group2' => nil, 'group3' => nil}
41
+ Puppet::Util::Windows::ADSI::Group.expects(:name_sid_hash).returns(groups)
40
42
 
41
- expect(provider.groups).to eq('group1,group2,group3')
43
+ expect(provider.groups).to eq(groups.keys)
42
44
  end
43
45
 
44
- it "should return absent if there are no groups" do
46
+ it "should return an empty array if there are no groups" do
45
47
  provider.user.stubs(:groups).returns []
46
48
 
47
- expect(provider.groups).to eq('')
49
+ expect(provider.groups).to eq([])
48
50
  end
49
51
 
50
52
  it 'should be able to add a user to a set of groups' do
@@ -60,6 +62,112 @@ describe Puppet::Type.type(:user).provider(:windows_adsi), :if => Puppet.feature
60
62
  end
61
63
  end
62
64
 
65
+ describe "#groups_insync?" do
66
+
67
+ let(:group1) { stub(:account => 'group1', :domain => '.', :to_s => 'group1sid') }
68
+ let(:group2) { stub(:account => 'group2', :domain => '.', :to_s => 'group2sid') }
69
+ let(:group3) { stub(:account => 'group3', :domain => '.', :to_s => 'group3sid') }
70
+
71
+ before :each do
72
+ Puppet::Util::Windows::SID.stubs(:name_to_sid_object).with('group1').returns(group1)
73
+ Puppet::Util::Windows::SID.stubs(:name_to_sid_object).with('group2').returns(group2)
74
+ Puppet::Util::Windows::SID.stubs(:name_to_sid_object).with('group3').returns(group3)
75
+ end
76
+
77
+ it "should return true for same lists of members" do
78
+ expect(provider.groups_insync?(['group1', 'group2'], ['group1', 'group2'])).to be_truthy
79
+ end
80
+
81
+ it "should return true for same lists of unordered members" do
82
+ expect(provider.groups_insync?(['group1', 'group2'], ['group2', 'group1'])).to be_truthy
83
+ end
84
+
85
+ it "should return true for same lists of members irrespective of duplicates" do
86
+ expect(provider.groups_insync?(['group1', 'group2', 'group2'], ['group2', 'group1', 'group1'])).to be_truthy
87
+ end
88
+
89
+ it "should return true when current group(s) and should group(s) are empty lists" do
90
+ expect(provider.groups_insync?([], [])).to be_truthy
91
+ end
92
+
93
+ it "should return true when current groups is empty and should groups is nil" do
94
+ expect(provider.groups_insync?([], nil)).to be_truthy
95
+ end
96
+
97
+ context "when membership => inclusive" do
98
+ before :each do
99
+ resource[:membership] = :inclusive
100
+ end
101
+
102
+ it "should return false when current contains different groups than should" do
103
+ expect(provider.groups_insync?(['group1'], ['group2'])).to be_falsey
104
+ end
105
+
106
+ it "should return false when current is nil" do
107
+ expect(provider.groups_insync?(nil, ['group2'])).to be_falsey
108
+ end
109
+
110
+ it "should return false when should is nil" do
111
+ expect(provider.groups_insync?(['group1'], nil)).to be_falsey
112
+ end
113
+
114
+ it "should return false when current contains members and should is empty" do
115
+ expect(provider.groups_insync?(['group1'], [])).to be_falsey
116
+ end
117
+
118
+ it "should return false when current is empty and should contains members" do
119
+ expect(provider.groups_insync?([], ['group2'])).to be_falsey
120
+ end
121
+
122
+ it "should return false when should groups(s) are not the only items in the current" do
123
+ expect(provider.groups_insync?(['group1', 'group2'], ['group1'])).to be_falsey
124
+ end
125
+
126
+ it "should return false when current group(s) is not empty and should is an empty list" do
127
+ expect(provider.groups_insync?(['group1','group2'], [])).to be_falsey
128
+ end
129
+ end
130
+
131
+ context "when membership => minimum" do
132
+ before :each do
133
+ # this is also the default
134
+ resource[:membership] = :minimum
135
+ end
136
+
137
+ it "should return false when current contains different groups than should" do
138
+ expect(provider.groups_insync?(['group1'], ['group2'])).to be_falsey
139
+ end
140
+
141
+ it "should return false when current is nil" do
142
+ expect(provider.groups_insync?(nil, ['group2'])).to be_falsey
143
+ end
144
+
145
+ it "should return true when should is nil" do
146
+ expect(provider.groups_insync?(['group1'], nil)).to be_truthy
147
+ end
148
+
149
+ it "should return true when current contains members and should is empty" do
150
+ expect(provider.groups_insync?(['group1'], [])).to be_truthy
151
+ end
152
+
153
+ it "should return false when current is empty and should contains members" do
154
+ expect(provider.groups_insync?([], ['group2'])).to be_falsey
155
+ end
156
+
157
+ it "should return true when current group(s) contains at least the should list" do
158
+ expect(provider.groups_insync?(['group1','group2'], ['group1'])).to be_truthy
159
+ end
160
+
161
+ it "should return true when current group(s) is not empty and should is an empty list" do
162
+ expect(provider.groups_insync?(['group1','group2'], [])).to be_truthy
163
+ end
164
+
165
+ it "should return true when current group(s) contains at least the should list, even unordered" do
166
+ expect(provider.groups_insync?(['group3','group1','group2'], ['group2','group1'])).to be_truthy
167
+ end
168
+ end
169
+ end
170
+
63
171
  describe "when creating a user" do
64
172
  it "should create the user on the system and set its other properties" do
65
173
  resource[:groups] = ['group1', 'group2']
@@ -119,6 +227,19 @@ describe Puppet::Type.type(:user).provider(:windows_adsi), :if => Puppet.feature
119
227
  expect{ provider.create }.to raise_error( Puppet::Error,
120
228
  /Cannot create user if group 'testuser' exists./ )
121
229
  end
230
+
231
+ it "should fail with an actionable message when trying to create an active directory user" do
232
+ resource[:name] = 'DOMAIN\testdomainuser'
233
+ Puppet::Util::Windows::ADSI::Group.expects(:exists?).with(resource[:name]).returns(false)
234
+ connection.expects(:Create)
235
+ connection.expects(:SetPassword)
236
+ connection.expects(:SetInfo).raises( WIN32OLERuntimeError.new("(in OLE method `SetInfo': )\n OLE error code:8007089A in Active Directory\n The specified username is invalid.\r\n\n HRESULT error code:0x80020009\n Exception occurred."))
237
+
238
+ expect{ provider.create }.to raise_error(
239
+ Puppet::Error,
240
+ /not able to create\/delete domain users/
241
+ )
242
+ end
122
243
  end
123
244
 
124
245
  it 'should be able to test whether a user exists' do
@@ -136,6 +257,14 @@ describe Puppet::Type.type(:user).provider(:windows_adsi), :if => Puppet.feature
136
257
  provider.delete
137
258
  end
138
259
 
260
+ it 'should not run commit on a deleted user' do
261
+ connection.expects(:Delete).with('user', 'testuser')
262
+ connection.expects(:SetInfo).never
263
+
264
+ provider.delete
265
+ provider.flush
266
+ end
267
+
139
268
  it 'should delete the profile if managehome is set' do
140
269
  resource[:managehome] = true
141
270
 
@@ -118,6 +118,17 @@ describe Puppet::Settings do
118
118
 
119
119
  expect(@settings.preferred_run_mode).to eq(:master)
120
120
  end
121
+
122
+ it "creates ancestor directories for all required app settings" do
123
+ # initialize_app_defaults is called in spec_helper, before we even
124
+ # get here, but call it here to make it explicit what we're trying
125
+ # to do.
126
+ @settings.initialize_app_defaults(default_values)
127
+
128
+ Puppet::Settings::REQUIRED_APP_SETTINGS.each do |key|
129
+ expect(File).to exist(File.dirname(Puppet[key]))
130
+ end
131
+ end
121
132
  end
122
133
 
123
134
  describe "#call_hooks_deferred_to_application_initialization" do
@@ -93,7 +93,120 @@ describe Puppet::Util::Log do
93
93
 
94
94
  expect(logs.collect(&:message)).to include("Inner block", "Outer block")
95
95
  end
96
+
97
+ it 'includes backtrace for RuntimeError in log message when trace is enabled' do
98
+ logs = []
99
+ destination = Puppet::Test::LogCollector.new(logs)
100
+
101
+ Puppet::Util::Log.newdestination(destination)
102
+ Puppet::Util::Log.with_destination(destination) do
103
+ begin
104
+ raise RuntimeError, 'Oops'
105
+ rescue RuntimeError => e
106
+ Puppet.log_exception(e, :default, :trace => true)
107
+ end
108
+ end
109
+ expect(logs.size).to eq(1)
110
+ log = logs[0]
111
+ expect(log.message).to match('/log_spec.rb')
112
+ expect(log.backtrace).to be_nil
113
+ end
114
+
115
+ it 'excludes backtrace for RuntimeError in log message when trace is disabled' do
116
+ logs = []
117
+ destination = Puppet::Test::LogCollector.new(logs)
118
+
119
+ Puppet::Util::Log.newdestination(destination)
120
+ Puppet::Util::Log.with_destination(destination) do
121
+ begin
122
+ raise RuntimeError, 'Oops'
123
+ rescue RuntimeError => e
124
+ Puppet.log_exception(e)
125
+ end
126
+ end
127
+ expect(logs.size).to eq(1)
128
+ log = logs[0]
129
+ expect(log.message).to_not match('/log_spec.rb')
130
+ expect(log.backtrace).to be_nil
131
+ end
132
+
133
+ it "backtrace is Array in 'backtrace' and excluded from 'message' when logging ParseErrorWithIssue with trace enabled" do
134
+ logs = []
135
+ destination = Puppet::Test::LogCollector.new(logs)
136
+
137
+ Puppet::Util::Log.newdestination(destination)
138
+ Puppet::Util::Log.with_destination(destination) do
139
+ begin
140
+ raise Puppet::ParseErrorWithIssue.new('Oops', '/tmp/test.pp', 30, 15, nil, :SYNTAX_ERROR)
141
+ rescue RuntimeError => e
142
+ Puppet.log_exception(e, :default, :trace => true)
143
+ end
144
+ end
145
+ expect(logs.size).to eq(1)
146
+ log = logs[0]
147
+ expect(log.message).to_not match('/log_spec.rb')
148
+ expect(log.backtrace).to be_a(Array)
149
+ end
150
+
151
+ it "backtrace is excluded when logging ParseErrorWithIssue with trace disabled" do
152
+ logs = []
153
+ destination = Puppet::Test::LogCollector.new(logs)
154
+
155
+ Puppet::Util::Log.newdestination(destination)
156
+ Puppet::Util::Log.with_destination(destination) do
157
+ begin
158
+ raise Puppet::ParseErrorWithIssue.new('Oops', '/tmp/test.pp', 30, 15, nil, :SYNTAX_ERROR)
159
+ rescue RuntimeError => e
160
+ Puppet.log_exception(e)
161
+ end
162
+ end
163
+ expect(logs.size).to eq(1)
164
+ log = logs[0]
165
+ expect(log.message).to_not match('/log_spec.rb')
166
+ expect(log.backtrace).to be_nil
167
+ end
168
+
169
+ it 'includes position details for ParseError in log message' do
170
+ logs = []
171
+ destination = Puppet::Test::LogCollector.new(logs)
172
+
173
+ Puppet::Util::Log.newdestination(destination)
174
+ Puppet::Util::Log.with_destination(destination) do
175
+ begin
176
+ raise Puppet::ParseError.new('Oops', '/tmp/test.pp', 30, 15)
177
+ rescue RuntimeError => e
178
+ Puppet.log_exception(e)
179
+ end
180
+ end
181
+ expect(logs.size).to eq(1)
182
+ log = logs[0]
183
+ expect(log.message).to match(/ at \/tmp\/test\.pp:30:15/)
184
+ expect(log.message).to be(log.to_s)
185
+ end
186
+
187
+ it 'excludes position details for ParseErrorWithIssue from log message' do
188
+ logs = []
189
+ destination = Puppet::Test::LogCollector.new(logs)
190
+
191
+ Puppet::Util::Log.newdestination(destination)
192
+ Puppet::Util::Log.with_destination(destination) do
193
+ begin
194
+ raise Puppet::ParseErrorWithIssue.new('Oops', '/tmp/test.pp', 30, 15, nil, :SYNTAX_ERROR)
195
+ rescue RuntimeError => e
196
+ Puppet.log_exception(e)
197
+ end
198
+ end
199
+ expect(logs.size).to eq(1)
200
+ log = logs[0]
201
+ expect(log.message).to_not match(/ at \/tmp\/test\.pp:30:15/)
202
+ expect(log.to_s).to match(/ at \/tmp\/test\.pp:30:15/)
203
+ expect(log.issue_code).to eq(:SYNTAX_ERROR)
204
+ expect(log.file).to eq('/tmp/test.pp')
205
+ expect(log.line).to eq(30)
206
+ expect(log.pos).to eq(15)
207
+ end
96
208
  end
209
+
97
210
  describe Puppet::Util::Log::DestConsole do
98
211
  before do
99
212
  @console = Puppet::Util::Log::DestConsole.new