puppet 6.18.0-x64-mingw32 → 6.21.1-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 (276) hide show
  1. checksums.yaml +4 -4
  2. data/CODEOWNERS +2 -16
  3. data/Gemfile +2 -0
  4. data/Gemfile.lock +37 -34
  5. data/README.md +1 -2
  6. data/Rakefile +4 -12
  7. data/lib/puppet/agent/locker.rb +0 -7
  8. data/lib/puppet/application.rb +10 -6
  9. data/lib/puppet/application/agent.rb +9 -3
  10. data/lib/puppet/application/apply.rb +3 -2
  11. data/lib/puppet/application/device.rb +1 -0
  12. data/lib/puppet/application/doc.rb +1 -1
  13. data/lib/puppet/application/filebucket.rb +2 -2
  14. data/lib/puppet/application/lookup.rb +5 -5
  15. data/lib/puppet/application/script.rb +1 -0
  16. data/lib/puppet/application_support.rb +7 -0
  17. data/lib/puppet/configurer.rb +50 -8
  18. data/lib/puppet/defaults.rb +67 -35
  19. data/lib/puppet/environments.rb +84 -59
  20. data/lib/puppet/face/catalog.rb +1 -1
  21. data/lib/puppet/face/config.rb +56 -16
  22. data/lib/puppet/face/epp.rb +12 -2
  23. data/lib/puppet/face/facts.rb +60 -0
  24. data/lib/puppet/face/node.rb +3 -3
  25. data/lib/puppet/face/node/clean.rb +2 -2
  26. data/lib/puppet/face/status.rb +1 -1
  27. data/lib/puppet/ffi/posix.rb +10 -0
  28. data/lib/puppet/ffi/posix/constants.rb +14 -0
  29. data/lib/puppet/ffi/posix/functions.rb +24 -0
  30. data/lib/puppet/file_bucket/dipper.rb +1 -1
  31. data/lib/puppet/functions/epp.rb +1 -0
  32. data/lib/puppet/functions/inline_epp.rb +1 -0
  33. data/lib/puppet/functions/new.rb +8 -3
  34. data/lib/puppet/http.rb +1 -0
  35. data/lib/puppet/http/client.rb +1 -1
  36. data/lib/puppet/http/resolver.rb +5 -8
  37. data/lib/puppet/http/resolver/server_list.rb +18 -36
  38. data/lib/puppet/http/resolver/settings.rb +4 -4
  39. data/lib/puppet/http/resolver/srv.rb +5 -5
  40. data/lib/puppet/http/service.rb +3 -1
  41. data/lib/puppet/http/service/compiler.rb +1 -1
  42. data/lib/puppet/http/service/file_server.rb +1 -1
  43. data/lib/puppet/http/service/puppetserver.rb +39 -0
  44. data/lib/puppet/http/session.rb +5 -4
  45. data/lib/puppet/indirector/catalog/compiler.rb +1 -1
  46. data/lib/puppet/indirector/fact_search.rb +60 -0
  47. data/lib/puppet/indirector/facts/json.rb +27 -0
  48. data/lib/puppet/indirector/facts/yaml.rb +4 -59
  49. data/lib/puppet/indirector/json.rb +5 -1
  50. data/lib/puppet/indirector/msgpack.rb +1 -1
  51. data/lib/puppet/indirector/node/json.rb +8 -0
  52. data/lib/puppet/indirector/report/json.rb +34 -0
  53. data/lib/puppet/indirector/request.rb +4 -4
  54. data/lib/puppet/indirector/yaml.rb +1 -1
  55. data/lib/puppet/module_tool/applications/installer.rb +48 -2
  56. data/lib/puppet/module_tool/errors/shared.rb +17 -2
  57. data/lib/puppet/network/formats.rb +2 -1
  58. data/lib/puppet/network/http/api/master/v3/environments.rb +0 -1
  59. data/lib/puppet/node/facts.rb +17 -0
  60. data/lib/puppet/pal/pal_impl.rb +70 -17
  61. data/lib/puppet/parser/ast/leaf.rb +3 -2
  62. data/lib/puppet/parser/templatewrapper.rb +1 -1
  63. data/lib/puppet/pops/evaluator/collectors/abstract_collector.rb +1 -3
  64. data/lib/puppet/pops/evaluator/deferred_resolver.rb +5 -3
  65. data/lib/puppet/pops/evaluator/evaluator_impl.rb +22 -3
  66. data/lib/puppet/pops/evaluator/runtime3_converter.rb +2 -2
  67. data/lib/puppet/pops/model/ast_transformer.rb +1 -1
  68. data/lib/puppet/pops/types/p_meta_type.rb +1 -1
  69. data/lib/puppet/pops/types/p_type_set_type.rb +4 -0
  70. data/lib/puppet/property/list.rb +1 -1
  71. data/lib/puppet/provider/group/groupadd.rb +13 -8
  72. data/lib/puppet/provider/package/apt.rb +34 -2
  73. data/lib/puppet/provider/package/aptitude.rb +6 -0
  74. data/lib/puppet/provider/package/dpkg.rb +1 -1
  75. data/lib/puppet/provider/package/pip2.rb +17 -0
  76. data/lib/puppet/provider/package/puppetserver_gem.rb +180 -0
  77. data/lib/puppet/provider/package/yum.rb +1 -0
  78. data/lib/puppet/provider/service/debian.rb +2 -0
  79. data/lib/puppet/provider/user/aix.rb +2 -2
  80. data/lib/puppet/provider/user/useradd.rb +62 -8
  81. data/lib/puppet/reference/configuration.rb +6 -5
  82. data/lib/puppet/resource/type.rb +2 -1
  83. data/lib/puppet/rest/route.rb +2 -2
  84. data/lib/puppet/settings.rb +62 -20
  85. data/lib/puppet/settings/alias_setting.rb +37 -0
  86. data/lib/puppet/settings/base_setting.rb +26 -2
  87. data/lib/puppet/transaction/report.rb +11 -7
  88. data/lib/puppet/type/file/source.rb +1 -1
  89. data/lib/puppet/type/filebucket.rb +1 -1
  90. data/lib/puppet/type/package.rb +3 -3
  91. data/lib/puppet/util/autoload.rb +1 -8
  92. data/lib/puppet/util/connection.rb +8 -8
  93. data/lib/puppet/util/fact_dif.rb +62 -0
  94. data/lib/puppet/util/posix.rb +54 -5
  95. data/lib/puppet/util/rubygems.rb +5 -1
  96. data/lib/puppet/util/run_mode.rb +5 -1
  97. data/lib/puppet/util/windows/service.rb +1 -1
  98. data/lib/puppet/version.rb +1 -1
  99. data/locales/puppet.pot +289 -268
  100. data/man/man5/puppet.conf.5 +33 -17
  101. data/man/man8/puppet-agent.8 +7 -4
  102. data/man/man8/puppet-apply.8 +2 -2
  103. data/man/man8/puppet-catalog.8 +1 -1
  104. data/man/man8/puppet-config.8 +6 -6
  105. data/man/man8/puppet-describe.8 +1 -1
  106. data/man/man8/puppet-device.8 +2 -2
  107. data/man/man8/puppet-doc.8 +1 -1
  108. data/man/man8/puppet-epp.8 +1 -1
  109. data/man/man8/puppet-facts.8 +32 -1
  110. data/man/man8/puppet-filebucket.8 +3 -3
  111. data/man/man8/puppet-generate.8 +1 -1
  112. data/man/man8/puppet-help.8 +1 -1
  113. data/man/man8/puppet-key.8 +1 -1
  114. data/man/man8/puppet-lookup.8 +1 -1
  115. data/man/man8/puppet-man.8 +1 -1
  116. data/man/man8/puppet-module.8 +1 -1
  117. data/man/man8/puppet-node.8 +7 -4
  118. data/man/man8/puppet-parser.8 +1 -1
  119. data/man/man8/puppet-plugin.8 +1 -1
  120. data/man/man8/puppet-report.8 +4 -1
  121. data/man/man8/puppet-resource.8 +1 -1
  122. data/man/man8/puppet-script.8 +2 -2
  123. data/man/man8/puppet-ssl.8 +1 -1
  124. data/man/man8/puppet-status.8 +2 -2
  125. data/man/man8/puppet.8 +2 -2
  126. data/spec/fixtures/integration/application/agent/cached_deferred_catalog.json +91 -0
  127. data/spec/fixtures/unit/provider/package/puppetserver_gem/gem-list-local-packages +30 -0
  128. data/spec/fixtures/unit/provider/user/aix/aix_passwd_file.out +4 -0
  129. data/spec/integration/application/agent_spec.rb +183 -22
  130. data/spec/integration/application/apply_spec.rb +19 -0
  131. data/spec/integration/application/filebucket_spec.rb +7 -7
  132. data/spec/integration/application/plugin_spec.rb +3 -3
  133. data/spec/integration/configurer_spec.rb +14 -0
  134. data/spec/integration/defaults_spec.rb +19 -1
  135. data/spec/integration/environments/setting_hooks_spec.rb +1 -1
  136. data/spec/integration/resource/type_collection_spec.rb +2 -6
  137. data/spec/integration/transaction_spec.rb +4 -9
  138. data/spec/integration/util/windows/adsi_spec.rb +5 -3
  139. data/spec/integration/util/windows/registry_spec.rb +0 -10
  140. data/spec/lib/puppet_spec/settings.rb +6 -1
  141. data/spec/shared_contexts/types_setup.rb +2 -0
  142. data/spec/spec_helper.rb +1 -4
  143. data/spec/unit/agent_spec.rb +8 -6
  144. data/spec/unit/application/agent_spec.rb +0 -1
  145. data/spec/unit/application/config_spec.rb +224 -4
  146. data/spec/unit/application/doc_spec.rb +2 -2
  147. data/spec/unit/application/facts_spec.rb +3 -1
  148. data/spec/unit/application/filebucket_spec.rb +0 -2
  149. data/spec/unit/application_spec.rb +60 -13
  150. data/spec/unit/configurer_spec.rb +39 -6
  151. data/spec/unit/confine/feature_spec.rb +1 -1
  152. data/spec/unit/confine_spec.rb +8 -2
  153. data/spec/unit/defaults_spec.rb +20 -1
  154. data/spec/unit/environments_spec.rb +176 -32
  155. data/spec/unit/face/config_spec.rb +62 -11
  156. data/spec/unit/face/node_spec.rb +2 -13
  157. data/spec/unit/file_serving/configuration/parser_spec.rb +0 -1
  158. data/spec/unit/file_serving/metadata_spec.rb +3 -3
  159. data/spec/unit/file_serving/terminus_helper_spec.rb +11 -4
  160. data/spec/unit/file_system_spec.rb +1 -2
  161. data/spec/unit/forge/module_release_spec.rb +2 -7
  162. data/spec/unit/functions/inline_epp_spec.rb +26 -1
  163. data/spec/unit/http/resolver_spec.rb +24 -4
  164. data/spec/unit/http/service/ca_spec.rb +2 -2
  165. data/spec/unit/http/service/compiler_spec.rb +51 -2
  166. data/spec/unit/http/service/file_server_spec.rb +2 -2
  167. data/spec/unit/http/service/puppetserver_spec.rb +82 -0
  168. data/spec/unit/http/service/report_spec.rb +2 -2
  169. data/spec/unit/http/service_spec.rb +1 -1
  170. data/spec/unit/http/session_spec.rb +8 -20
  171. data/spec/unit/indirector/catalog/json_spec.rb +1 -1
  172. data/spec/unit/indirector/catalog/rest_spec.rb +1 -1
  173. data/spec/unit/indirector/face_spec.rb +0 -1
  174. data/spec/unit/indirector/facts/facter_spec.rb +0 -1
  175. data/spec/unit/indirector/facts/json_spec.rb +255 -0
  176. data/spec/unit/indirector/facts/rest_spec.rb +1 -1
  177. data/spec/unit/indirector/file_bucket_file/selector_spec.rb +26 -8
  178. data/spec/unit/indirector/indirection_spec.rb +8 -12
  179. data/spec/unit/indirector/json_spec.rb +8 -8
  180. data/spec/unit/indirector/key/file_spec.rb +0 -1
  181. data/spec/unit/indirector/msgpack_spec.rb +8 -8
  182. data/spec/unit/indirector/node/json_spec.rb +33 -0
  183. data/spec/unit/indirector/node/rest_spec.rb +1 -1
  184. data/spec/{integration/indirector/report/yaml.rb → unit/indirector/report/json_spec.rb} +13 -24
  185. data/spec/unit/indirector/report/yaml_spec.rb +72 -8
  186. data/spec/unit/indirector/request_spec.rb +4 -4
  187. data/spec/unit/indirector/rest_spec.rb +1 -1
  188. data/spec/unit/indirector/status/rest_spec.rb +1 -1
  189. data/spec/unit/indirector/yaml_spec.rb +7 -7
  190. data/spec/unit/indirector_spec.rb +2 -2
  191. data/spec/unit/module_tool/applications/installer_spec.rb +66 -0
  192. data/spec/unit/network/authconfig_spec.rb +0 -3
  193. data/spec/unit/network/http/api/indirected_routes_spec.rb +0 -9
  194. data/spec/unit/network/http/api/master/v3/environments_spec.rb +12 -23
  195. data/spec/unit/network/http/handler_spec.rb +0 -5
  196. data/spec/unit/parser/compiler_spec.rb +3 -19
  197. data/spec/unit/parser/resource_spec.rb +14 -8
  198. data/spec/unit/parser/templatewrapper_spec.rb +4 -3
  199. data/spec/unit/pops/evaluator/deferred_resolver_spec.rb +20 -0
  200. data/spec/unit/property_spec.rb +1 -0
  201. data/spec/unit/provider/exec_spec.rb +4 -3
  202. data/spec/unit/provider/group/groupadd_spec.rb +5 -2
  203. data/spec/unit/provider/nameservice_spec.rb +66 -65
  204. data/spec/unit/provider/package/apt_spec.rb +28 -23
  205. data/spec/unit/provider/package/aptitude_spec.rb +1 -1
  206. data/spec/unit/provider/package/base_spec.rb +6 -5
  207. data/spec/unit/provider/package/dpkg_spec.rb +22 -7
  208. data/spec/unit/provider/package/openbsd_spec.rb +2 -0
  209. data/spec/unit/provider/package/pacman_spec.rb +18 -12
  210. data/spec/unit/provider/package/pip2_spec.rb +36 -0
  211. data/spec/unit/provider/package/pip_spec.rb +6 -11
  212. data/spec/unit/provider/package/pkgdmg_spec.rb +0 -4
  213. data/spec/unit/provider/package/puppetserver_gem_spec.rb +137 -0
  214. data/spec/unit/provider/package/yum_spec.rb +31 -0
  215. data/spec/unit/provider/service/base_spec.rb +2 -4
  216. data/spec/unit/provider/service/bsd_spec.rb +5 -1
  217. data/spec/unit/provider/service/daemontools_spec.rb +1 -1
  218. data/spec/unit/provider/service/debian_spec.rb +3 -5
  219. data/spec/unit/provider/service/freebsd_spec.rb +1 -1
  220. data/spec/unit/provider/service/gentoo_spec.rb +4 -5
  221. data/spec/unit/provider/service/init_spec.rb +4 -5
  222. data/spec/unit/provider/service/launchd_spec.rb +5 -6
  223. data/spec/unit/provider/service/openrc_spec.rb +4 -5
  224. data/spec/unit/provider/service/openwrt_spec.rb +1 -1
  225. data/spec/unit/provider/service/redhat_spec.rb +1 -1
  226. data/spec/unit/provider/service/runit_spec.rb +2 -1
  227. data/spec/unit/provider/service/smf_spec.rb +1 -1
  228. data/spec/unit/provider/service/src_spec.rb +3 -5
  229. data/spec/unit/provider/service/systemd_spec.rb +3 -1
  230. data/spec/unit/provider/service/upstart_spec.rb +4 -5
  231. data/spec/unit/provider/user/aix_spec.rb +5 -0
  232. data/spec/unit/provider/user/hpux_spec.rb +1 -1
  233. data/spec/unit/provider/user/pw_spec.rb +2 -0
  234. data/spec/unit/provider/user/useradd_spec.rb +56 -3
  235. data/spec/unit/provider_spec.rb +8 -10
  236. data/spec/unit/puppet_pal_catalog_spec.rb +45 -0
  237. data/spec/unit/resource/capability_finder_spec.rb +6 -1
  238. data/spec/unit/resource/type_spec.rb +1 -1
  239. data/spec/unit/resource_spec.rb +11 -10
  240. data/spec/unit/rest/route_spec.rb +4 -4
  241. data/spec/unit/settings_spec.rb +576 -239
  242. data/spec/unit/ssl/base_spec.rb +0 -1
  243. data/spec/unit/ssl/host_spec.rb +0 -5
  244. data/spec/unit/ssl/ssl_provider_spec.rb +14 -8
  245. data/spec/unit/transaction/additional_resource_generator_spec.rb +3 -7
  246. data/spec/unit/transaction/event_manager_spec.rb +14 -11
  247. data/spec/unit/transaction/report_spec.rb +2 -0
  248. data/spec/unit/transaction_spec.rb +13 -4
  249. data/spec/unit/type/file/content_spec.rb +0 -1
  250. data/spec/unit/type/file/selinux_spec.rb +0 -2
  251. data/spec/unit/type/file/source_spec.rb +1 -1
  252. data/spec/unit/type/file_spec.rb +0 -6
  253. data/spec/unit/type/filebucket_spec.rb +1 -1
  254. data/spec/unit/type/group_spec.rb +13 -6
  255. data/spec/unit/type/resources_spec.rb +7 -7
  256. data/spec/unit/type/service_spec.rb +1 -1
  257. data/spec/unit/type/tidy_spec.rb +0 -1
  258. data/spec/unit/type_spec.rb +2 -2
  259. data/spec/unit/util/at_fork_spec.rb +2 -2
  260. data/spec/unit/util/autoload_spec.rb +5 -1
  261. data/spec/unit/util/backups_spec.rb +1 -2
  262. data/spec/unit/util/execution_spec.rb +15 -11
  263. data/spec/unit/util/inifile_spec.rb +6 -14
  264. data/spec/unit/util/log_spec.rb +8 -7
  265. data/spec/unit/util/logging_spec.rb +3 -3
  266. data/spec/unit/util/posix_spec.rb +363 -15
  267. data/spec/unit/util/rubygems_spec.rb +2 -2
  268. data/spec/unit/util/run_mode_spec.rb +6 -6
  269. data/spec/unit/util/selinux_spec.rb +76 -52
  270. data/spec/unit/util/storage_spec.rb +3 -1
  271. data/spec/unit/util/suidmanager_spec.rb +44 -41
  272. data/spec/unit/util_spec.rb +13 -6
  273. metadata +32 -10
  274. data/spec/integration/application/config_spec.rb +0 -74
  275. data/spec/unit/face/catalog_spec.rb +0 -6
  276. data/spec/unit/face/module_spec.rb +0 -3
@@ -6,9 +6,6 @@ describe Puppet::Network::DefaultAuthProvider do
6
6
  before :each do
7
7
  allow(Puppet::FileSystem).to receive(:stat).and_return(double('stat', :ctime => :now))
8
8
  allow(Time).to receive(:now).and_return(Time.now)
9
-
10
- allow_any_instance_of(Puppet::Network::DefaultAuthProvider).to receive(:exists?).and_return(true)
11
- # FIXME @authprovider = Puppet::Network::DefaultAuthProvider.new("dummy")
12
9
  end
13
10
 
14
11
  describe "when initializing" do
@@ -17,7 +17,6 @@ describe Puppet::Network::HTTP::API::IndirectedRoutes do
17
17
  before do
18
18
  Puppet::IndirectorTesting.indirection.terminus_class = :memory
19
19
  Puppet::IndirectorTesting.indirection.terminus.clear
20
- allow(handler).to receive(:warn_if_near_expiration)
21
20
  end
22
21
 
23
22
  describe "when converting a URI into a request" do
@@ -25,10 +24,6 @@ describe Puppet::Network::HTTP::API::IndirectedRoutes do
25
24
  let(:env_loaders) { Puppet::Environments::Static.new(environment) }
26
25
  let(:params) { { :environment => "env" } }
27
26
 
28
- before do
29
- allow(handler).to receive(:handler).and_return("foo")
30
- end
31
-
32
27
  around do |example|
33
28
  Puppet.override(:environments => env_loaders) do
34
29
  example.run
@@ -180,10 +175,6 @@ describe Puppet::Network::HTTP::API::IndirectedRoutes do
180
175
  let(:environment) { Puppet::Node::Environment.create(:myenv, []) }
181
176
  let(:request) { Puppet::Indirector::Request.new(:foo, :find, "with spaces", nil, :foo => :bar, :environment => environment) }
182
177
 
183
- before do
184
- allow(handler).to receive(:handler).and_return("foo")
185
- end
186
-
187
178
  it "should include the environment in the query string of the URI" do
188
179
  expect(handler.class.request_to_uri(request)).to eq("#{master_url_prefix}/foo/with%20spaces?environment=myenv&foo=bar")
189
180
  end
@@ -7,13 +7,14 @@ require 'matchers/json'
7
7
  describe Puppet::Network::HTTP::API::Master::V3::Environments do
8
8
  include JSONMatchers
9
9
 
10
- it "responds with all of the available environments" do
11
- environment = Puppet::Node::Environment.create(:production, ["/first", "/second"], '/manifests')
12
- loader = Puppet::Environments::Static.new(environment)
13
- handler = Puppet::Network::HTTP::API::Master::V3::Environments.new(loader)
14
- response = Puppet::Network::HTTP::MemoryResponse.new
10
+ let(:environment) { Puppet::Node::Environment.create(:production, ["/first", "/second"], '/manifests') }
11
+ let(:loader) { Puppet::Environments::Static.new(environment) }
12
+ let(:handler) { Puppet::Network::HTTP::API::Master::V3::Environments.new(loader) }
13
+ let(:request) { Puppet::Network::HTTP::Request.from_hash(:headers => { 'accept' => 'application/json' }) }
14
+ let(:response) { Puppet::Network::HTTP::MemoryResponse.new }
15
15
 
16
- handler.call(Puppet::Network::HTTP::Request.from_hash(:headers => { 'accept' => 'application/json' }), response)
16
+ it "responds with all of the available environments" do
17
+ handler.call(request, response)
17
18
 
18
19
  expect(response.code).to eq(200)
19
20
  expect(response.type).to eq("application/json")
@@ -33,29 +34,17 @@ describe Puppet::Network::HTTP::API::Master::V3::Environments do
33
34
  end
34
35
 
35
36
  it "the response conforms to the environments schema for unlimited timeout" do
36
- conf_stub = double('conf_stub')
37
- expect(conf_stub).to receive(:environment_timeout).and_return(Float::INFINITY)
38
- environment = Puppet::Node::Environment.create(:production, [])
39
- env_loader = Puppet::Environments::Static.new(environment)
40
- expect(env_loader).to receive(:get_conf).with(:production).and_return(conf_stub)
41
- handler = Puppet::Network::HTTP::API::Master::V3::Environments.new(env_loader)
42
- response = Puppet::Network::HTTP::MemoryResponse.new
37
+ Puppet[:environment_timeout] = 'unlimited'
43
38
 
44
- handler.call(Puppet::Network::HTTP::Request.from_hash(:headers => { 'accept' => 'application/json' }), response)
39
+ handler.call(request, response)
45
40
 
46
41
  expect(response.body).to validate_against('api/schemas/environments.json')
47
42
  end
48
43
 
49
44
  it "the response conforms to the environments schema for integer timeout" do
50
- conf_stub = double('conf_stub')
51
- expect(conf_stub).to receive(:environment_timeout).and_return(1)
52
- environment = Puppet::Node::Environment.create(:production, [])
53
- env_loader = Puppet::Environments::Static.new(environment)
54
- expect(env_loader).to receive(:get_conf).with(:production).and_return(conf_stub)
55
- handler = Puppet::Network::HTTP::API::Master::V3::Environments.new(env_loader)
56
- response = Puppet::Network::HTTP::MemoryResponse.new
57
-
58
- handler.call(Puppet::Network::HTTP::Request.from_hash(:headers => { 'accept' => 'application/json' }), response)
45
+ Puppet[:environment_timeout] = 1
46
+
47
+ handler.call(request, response)
59
48
 
60
49
  expect(response.body).to validate_against('api/schemas/environments.json')
61
50
  end
@@ -102,11 +102,6 @@ describe Puppet::Network::HTTP::Handler do
102
102
  { :status => 200 }
103
103
  end
104
104
 
105
- before do
106
- allow(handler).to receive(:check_authorization)
107
- allow(handler).to receive(:warn_if_near_expiration)
108
- end
109
-
110
105
  it "should setup a profiler when the puppet-profiling header exists" do
111
106
  request = a_request
112
107
  request[:headers][Puppet::Network::HTTP::HEADER_ENABLE_PROFILING.downcase] = "true"
@@ -240,20 +240,9 @@ describe Puppet::Parser::Compiler do
240
240
  end
241
241
 
242
242
  describe "when compiling" do
243
- def compile_methods
244
- [:set_node_parameters, :evaluate_main, :evaluate_ast_node, :evaluate_node_classes, :evaluate_generators, :fail_on_unevaluated,
245
- :finish, :store, :extract, :evaluate_relationships]
246
- end
247
-
248
- # Stub all of the main compile methods except the ones we're specifically interested in.
249
- def compile_stub(*except)
250
- (compile_methods - except).each { |m| allow(@compiler).to receive(m) }
251
- end
252
-
253
243
  it "should set node parameters as variables in the top scope" do
254
244
  params = {"a" => "b", "c" => "d"}
255
245
  allow(@node).to receive(:parameters).and_return(params)
256
- compile_stub(:set_node_parameters)
257
246
  @compiler.compile
258
247
  expect(@compiler.topscope['a']).to eq("b")
259
248
  expect(@compiler.topscope['c']).to eq("d")
@@ -262,13 +251,11 @@ describe Puppet::Parser::Compiler do
262
251
  it "should set node parameters that are of Symbol type as String variables in the top scope" do
263
252
  params = {"a" => :b}
264
253
  allow(@node).to receive(:parameters).and_return(params)
265
- compile_stub(:set_node_parameters)
266
254
  @compiler.compile
267
255
  expect(@compiler.topscope['a']).to eq("b")
268
256
  end
269
257
 
270
258
  it "should set the node's environment as a string variable in top scope" do
271
- compile_stub(:set_node_parameters)
272
259
  @node.merge({'wat' => 'this is how the sausage is made'})
273
260
  @compiler.compile
274
261
  expect(@compiler.topscope['environment']).to eq("testing")
@@ -276,7 +263,6 @@ describe Puppet::Parser::Compiler do
276
263
  end
277
264
 
278
265
  it "sets the environment based on node.environment instead of the parameters" do
279
- compile_stub(:set_node_parameters)
280
266
  @node.parameters['environment'] = "Not actually #{@node.environment.name}"
281
267
 
282
268
  @compiler.compile
@@ -286,23 +272,21 @@ describe Puppet::Parser::Compiler do
286
272
  it "should set the client and server versions on the catalog" do
287
273
  params = {"clientversion" => "2", "serverversion" => "3"}
288
274
  allow(@node).to receive(:parameters).and_return(params)
289
- compile_stub(:set_node_parameters)
290
275
  @compiler.compile
291
276
  expect(@compiler.catalog.client_version).to eq("2")
292
277
  expect(@compiler.catalog.server_version).to eq("3")
293
278
  end
294
279
 
295
280
  it "should evaluate the main class if it exists" do
296
- compile_stub(:evaluate_main)
297
281
  main_class = @known_resource_types.add Puppet::Resource::Type.new(:hostclass, "")
282
+ @compiler.topscope.source = main_class
283
+
298
284
  expect(main_class).to receive(:evaluate_code).with(be_a(Puppet::Parser::Resource))
299
- expect(@compiler.topscope).to receive(:source=).with(main_class)
300
285
 
301
286
  @compiler.compile
302
287
  end
303
288
 
304
289
  it "should create a new, empty 'main' if no main class exists" do
305
- compile_stub(:evaluate_main)
306
290
  @compiler.compile
307
291
  expect(@known_resource_types.find_hostclass("")).to be_instance_of(Puppet::Resource::Type)
308
292
  end
@@ -325,7 +309,7 @@ describe Puppet::Parser::Compiler do
325
309
  @compiler.add_collection(colls[0])
326
310
  @compiler.add_collection(colls[1])
327
311
 
328
- compile_stub(:evaluate_generators)
312
+ allow(@compiler).to receive(:fail_on_unevaluated)
329
313
  @compiler.compile
330
314
  end
331
315
 
@@ -418,22 +418,27 @@ describe Puppet::Parser::Resource do
418
418
  end
419
419
 
420
420
  describe "when merging overrides" do
421
+ def resource_type(name)
422
+ double(name, :child_of? => false)
423
+ end
424
+
421
425
  before do
422
- @source = "source1"
426
+ @source = resource_type("source1")
423
427
  @resource = mkresource :source => @source
424
428
  @override = mkresource :source => @source
425
429
  end
426
430
 
427
431
  it "should fail when the override was not created by a parent class" do
428
- @override.source = "source2"
429
- expect(@override.source).to receive(:child_of?).with("source1").and_return(false)
432
+ @override.source = resource_type("source2")
433
+ expect(@override.source).to receive(:child_of?).with(@source).and_return(false)
430
434
  expect { @resource.merge(@override) }.to raise_error(Puppet::ParseError)
431
435
  end
432
436
 
433
437
  it "should succeed when the override was created in the current scope" do
434
- @resource.source = "source3"
438
+ @source3 = resource_type("source3")
439
+ @resource.source = @source3
435
440
  @override.source = @resource.source
436
- expect(@override.source).not_to receive(:child_of?).with("source3")
441
+ expect(@override.source).not_to receive(:child_of?).with(@source3)
437
442
  params = {:a => :b, :c => :d}
438
443
  expect(@override).to receive(:parameters).and_return(params)
439
444
  expect(@resource).to receive(:override_parameter).with(:b)
@@ -442,9 +447,10 @@ describe Puppet::Parser::Resource do
442
447
  end
443
448
 
444
449
  it "should succeed when a parent class created the override" do
445
- @resource.source = "source3"
446
- @override.source = "source4"
447
- expect(@override.source).to receive(:child_of?).with("source3").and_return(true)
450
+ @source3 = resource_type("source3")
451
+ @resource.source = @source3
452
+ @override.source = resource_type("source4")
453
+ expect(@override.source).to receive(:child_of?).with(@source3).and_return(true)
448
454
  params = {:a => :b, :c => :d}
449
455
  expect(@override).to receive(:parameters).and_return(params)
450
456
  expect(@resource).to receive(:override_parameter).with(:b)
@@ -57,9 +57,10 @@ describe Puppet::Parser::TemplateWrapper do
57
57
  expect(tw.all_tags).to eq(["tag1","tag2"])
58
58
  end
59
59
 
60
- it "provides the tags defined in the current scope with #tags" do
61
- expect(scope).to receive(:tags).and_return(["tag1", "tag2"])
62
- expect(tw.tags).to eq(["tag1","tag2"])
60
+ it "raises not implemented error" do
61
+ expect {
62
+ tw.tags
63
+ }.to raise_error(NotImplementedError, /Call 'all_tags' instead/)
63
64
  end
64
65
 
65
66
  it "raises error on access to removed in-scope variables via method calls" do
@@ -0,0 +1,20 @@
1
+ require 'spec_helper'
2
+ require 'puppet_spec/compiler'
3
+
4
+ describe Puppet::Pops::Evaluator::DeferredResolver do
5
+ include PuppetSpec::Compiler
6
+
7
+ let(:environment) { Puppet::Node::Environment.create(:testing, []) }
8
+ let(:facts) { Puppet::Node::Facts.new('node.example.com') }
9
+
10
+ it 'resolves deferred values in a catalog' do
11
+ catalog = compile_to_catalog(<<~END)
12
+ notify { "deferred":
13
+ message => Deferred("join", [[1,2,3], ":"])
14
+ }
15
+ END
16
+ described_class.resolve_and_replace(facts, catalog)
17
+
18
+ expect(catalog.resource(:notify, 'deferred')[:message]).to eq('1:2:3')
19
+ end
20
+ end
@@ -5,6 +5,7 @@ Puppet::Type.newtype(:property_test) do
5
5
  newparam(:name, isnamevar: true)
6
6
  end
7
7
  Puppet::Type.type(:property_test).provide(:property_test) do
8
+ attr_accessor :foo
8
9
  end
9
10
 
10
11
  describe Puppet::Property do
@@ -49,9 +49,10 @@ describe Puppet::Provider::Exec do
49
49
  # we can't reference that in our manifest. Windows PATHs can contain
50
50
  # double quotes and trailing backslashes, which confuse HEREDOC
51
51
  # interpolation below. So sanitize it:
52
- ENV['PATH'].split(File::PATH_SEPARATOR).map do |dir|
53
- dir.gsub(/"/, '\"').gsub(/\\$/, '')
54
- end.join(File::PATH_SEPARATOR)
52
+ ENV['PATH'].split(File::PATH_SEPARATOR)
53
+ .map { |dir| dir.gsub(/"/, '\"').gsub(/\\$/, '') }
54
+ .map { |dir| Pathname.new(dir).cleanpath.to_s }
55
+ .join(File::PATH_SEPARATOR)
55
56
  else
56
57
  ENV['PATH']
57
58
  end
@@ -198,7 +198,10 @@ describe Puppet::Type.type(:group).provider(:groupadd) do
198
198
  end
199
199
 
200
200
  describe "#findgroup" do
201
- before { allow(File).to receive(:read).with('/etc/group').and_return(content) }
201
+ before do
202
+ allow(Puppet::FileSystem).to receive(:exist?).with('/etc/group').and_return(true)
203
+ allow(Puppet::FileSystem).to receive(:each_line).with('/etc/group').and_yield(content)
204
+ end
202
205
 
203
206
  let(:content) { "sample_group_name:sample_password:sample_gid:sample_user_list" }
204
207
  let(:output) do
@@ -221,7 +224,7 @@ describe Puppet::Type.type(:group).provider(:groupadd) do
221
224
  end
222
225
 
223
226
  it "reads the group file only once per resource" do
224
- expect(File).to receive(:read).with('/etc/group').once
227
+ expect(Puppet::FileSystem).to receive(:each_line).with('/etc/group').once
225
228
  5.times { provider.send(:findgroup, :group_name, 'sample_group_name') }
226
229
  end
227
230
  end
@@ -3,11 +3,28 @@ require 'puppet/provider/nameservice'
3
3
  require 'puppet/etc'
4
4
  require 'puppet_spec/character_encoding'
5
5
 
6
+ Puppet::Type.newtype(:nameservice_dummytype) do
7
+ newparam(:name)
8
+ ensurable
9
+ newproperty(:foo)
10
+ newproperty(:bar)
11
+ end
12
+
13
+ Puppet::Type.type(:nameservice_dummytype).provide(:nameservice_dummyprovider, parent: Puppet::Provider::NameService) do
14
+ def posixmethod(param)
15
+ param
16
+ end
17
+
18
+ def modifycmd(param, value)
19
+ []
20
+ end
21
+ end
22
+
6
23
  describe Puppet::Provider::NameService do
7
24
 
8
25
  before :each do
9
- described_class.initvars
10
- described_class.resource_type = faketype
26
+ provider.class.initvars
27
+ provider.class.resource_type = faketype
11
28
  end
12
29
 
13
30
  # These are values getpwent might give you
@@ -41,16 +58,12 @@ describe Puppet::Provider::NameService do
41
58
  # The provider sometimes relies on @resource for valid properties so let's
42
59
  # create a fake type with properties that match our fake struct.
43
60
  let :faketype do
44
- Puppet::Type.newtype(:nameservice_dummytype) do
45
- newparam(:name)
46
- ensurable
47
- newproperty(:foo)
48
- newproperty(:bar)
49
- end
61
+ Puppet::Type.type(:nameservice_dummytype)
50
62
  end
51
63
 
52
64
  let :provider do
53
- described_class.new(:name => 'bob', :foo => 'fooval', :bar => 'barval')
65
+ Puppet::Type.type(:nameservice_dummytype).provider(:nameservice_dummyprovider)
66
+ .new(:name => 'bob', :foo => 'fooval', :bar => 'barval')
54
67
  end
55
68
 
56
69
  let :resource do
@@ -91,61 +104,61 @@ describe Puppet::Provider::NameService do
91
104
 
92
105
  describe "#options" do
93
106
  it "should add options for a valid property" do
94
- described_class.options :foo, :key1 => 'val1', :key2 => 'val2'
95
- described_class.options :bar, :key3 => 'val3'
96
- expect(described_class.option(:foo, :key1)).to eq('val1')
97
- expect(described_class.option(:foo, :key2)).to eq('val2')
98
- expect(described_class.option(:bar, :key3)).to eq('val3')
107
+ provider.class.options :foo, :key1 => 'val1', :key2 => 'val2'
108
+ provider.class.options :bar, :key3 => 'val3'
109
+ expect(provider.class.option(:foo, :key1)).to eq('val1')
110
+ expect(provider.class.option(:foo, :key2)).to eq('val2')
111
+ expect(provider.class.option(:bar, :key3)).to eq('val3')
99
112
  end
100
113
 
101
114
  it "should raise an error for an invalid property" do
102
- expect { described_class.options :baz, :key1 => 'val1' }.to raise_error(
115
+ expect { provider.class.options :baz, :key1 => 'val1' }.to raise_error(
103
116
  Puppet::Error, 'baz is not a valid attribute for nameservice_dummytype')
104
117
  end
105
118
  end
106
119
 
107
120
  describe "#option" do
108
121
  it "should return the correct value" do
109
- described_class.options :foo, :key1 => 'val1', :key2 => 'val2'
110
- expect(described_class.option(:foo, :key2)).to eq('val2')
122
+ provider.class.options :foo, :key1 => 'val1', :key2 => 'val2'
123
+ expect(provider.class.option(:foo, :key2)).to eq('val2')
111
124
  end
112
125
 
113
126
  it "should symbolize the name first" do
114
- described_class.options :foo, :key1 => 'val1', :key2 => 'val2'
115
- expect(described_class.option('foo', :key2)).to eq('val2')
127
+ provider.class.options :foo, :key1 => 'val1', :key2 => 'val2'
128
+ expect(provider.class.option('foo', :key2)).to eq('val2')
116
129
  end
117
130
 
118
131
  it "should return nil if no option has been specified earlier" do
119
- expect(described_class.option(:foo, :key2)).to be_nil
132
+ expect(provider.class.option(:foo, :key2)).to be_nil
120
133
  end
121
134
 
122
135
  it "should return nil if no option for that property has been specified earlier" do
123
- described_class.options :bar, :key2 => 'val2'
124
- expect(described_class.option(:foo, :key2)).to be_nil
136
+ provider.class.options :bar, :key2 => 'val2'
137
+ expect(provider.class.option(:foo, :key2)).to be_nil
125
138
  end
126
139
 
127
140
  it "should return nil if no matching key can be found for that property" do
128
- described_class.options :foo, :key3 => 'val2'
129
- expect(described_class.option(:foo, :key2)).to be_nil
141
+ provider.class.options :foo, :key3 => 'val2'
142
+ expect(provider.class.option(:foo, :key2)).to be_nil
130
143
  end
131
144
  end
132
145
 
133
146
  describe "#section" do
134
147
  it "should raise an error if resource_type has not been set" do
135
- expect(described_class).to receive(:resource_type).and_return(nil)
136
- expect { described_class.section }.to raise_error Puppet::Error, 'Cannot determine Etc section without a resource type'
148
+ expect(provider.class).to receive(:resource_type).and_return(nil)
149
+ expect { provider.class.section }.to raise_error Puppet::Error, 'Cannot determine Etc section without a resource type'
137
150
  end
138
151
 
139
152
  # the return values are hard coded so I am using types that actually make
140
153
  # use of the nameservice provider
141
154
  it "should return pw for users" do
142
- described_class.resource_type = Puppet::Type.type(:user)
143
- expect(described_class.section).to eq('pw')
155
+ provider.class.resource_type = Puppet::Type.type(:user)
156
+ expect(provider.class.section).to eq('pw')
144
157
  end
145
158
 
146
159
  it "should return gr for groups" do
147
- described_class.resource_type = Puppet::Type.type(:group)
148
- expect(described_class.section).to eq('gr')
160
+ provider.class.resource_type = Puppet::Type.type(:group)
161
+ expect(provider.class.section).to eq('gr')
149
162
  end
150
163
  end
151
164
 
@@ -213,7 +226,7 @@ describe Puppet::Provider::NameService do
213
226
  # encoding
214
227
  allow(Etc).to receive(:getpwent).and_return(*utf_8_mixed_users)
215
228
  result = PuppetSpec::CharacterEncoding.with_external_encoding(Encoding::UTF_8) do
216
- described_class.instances
229
+ provider.class.instances
217
230
  end
218
231
  expect(result.map(&:name)).to eq(
219
232
  [
@@ -228,7 +241,7 @@ describe Puppet::Provider::NameService do
228
241
  it "should have object names in their original encoding/bytes if they would not be valid UTF-8" do
229
242
  allow(Etc).to receive(:getpwent).and_return(*latin_1_mixed_users)
230
243
  result = PuppetSpec::CharacterEncoding.with_external_encoding(Encoding::ISO_8859_1) do
231
- described_class.instances
244
+ provider.class.instances
232
245
  end
233
246
  expect(result.map(&:name)).to eq(
234
247
  [
@@ -243,40 +256,40 @@ describe Puppet::Provider::NameService do
243
256
  it "should pass the Puppet::Etc :canonical_name Struct member to the constructor" do
244
257
  users = [ Struct::Passwd.new(invalid_utf_8_jose, invalid_utf_8_jose, 1002, 2000), nil ]
245
258
  allow(Etc).to receive(:getpwent).and_return(*users)
246
- expect(described_class).to receive(:new).with(:name => escaped_utf_8_jose, :canonical_name => invalid_utf_8_jose, :ensure => :present)
247
- described_class.instances
259
+ expect(provider.class).to receive(:new).with(:name => escaped_utf_8_jose, :canonical_name => invalid_utf_8_jose, :ensure => :present)
260
+ provider.class.instances
248
261
  end
249
262
  end
250
263
 
251
264
  describe "validate" do
252
265
  it "should pass if no check is registered at all" do
253
- expect { described_class.validate(:foo, 300) }.to_not raise_error
254
- expect { described_class.validate('foo', 300) }.to_not raise_error
266
+ expect { provider.class.validate(:foo, 300) }.to_not raise_error
267
+ expect { provider.class.validate('foo', 300) }.to_not raise_error
255
268
  end
256
269
 
257
270
  it "should pass if no check for that property is registered" do
258
- described_class.verify(:bar, 'Must be 100') { |val| val == 100 }
259
- expect { described_class.validate(:foo, 300) }.to_not raise_error
260
- expect { described_class.validate('foo', 300) }.to_not raise_error
271
+ provider.class.verify(:bar, 'Must be 100') { |val| val == 100 }
272
+ expect { provider.class.validate(:foo, 300) }.to_not raise_error
273
+ expect { provider.class.validate('foo', 300) }.to_not raise_error
261
274
  end
262
275
 
263
276
  it "should pass if the value is valid" do
264
- described_class.verify(:foo, 'Must be 100') { |val| val == 100 }
265
- expect { described_class.validate(:foo, 100) }.to_not raise_error
266
- expect { described_class.validate('foo', 100) }.to_not raise_error
277
+ provider.class.verify(:foo, 'Must be 100') { |val| val == 100 }
278
+ expect { provider.class.validate(:foo, 100) }.to_not raise_error
279
+ expect { provider.class.validate('foo', 100) }.to_not raise_error
267
280
  end
268
281
 
269
282
  it "should raise an error if the value is invalid" do
270
- described_class.verify(:foo, 'Must be 100') { |val| val == 100 }
271
- expect { described_class.validate(:foo, 200) }.to raise_error(ArgumentError, 'Invalid value 200: Must be 100')
272
- expect { described_class.validate('foo', 200) }.to raise_error(ArgumentError, 'Invalid value 200: Must be 100')
283
+ provider.class.verify(:foo, 'Must be 100') { |val| val == 100 }
284
+ expect { provider.class.validate(:foo, 200) }.to raise_error(ArgumentError, 'Invalid value 200: Must be 100')
285
+ expect { provider.class.validate('foo', 200) }.to raise_error(ArgumentError, 'Invalid value 200: Must be 100')
273
286
  end
274
287
  end
275
288
 
276
289
  describe "getinfo" do
277
290
  before :each do
278
291
  # with section=foo we'll call Etc.getfoonam instead of getpwnam or getgrnam
279
- allow(described_class).to receive(:section).and_return('foo')
292
+ allow(provider.class).to receive(:section).and_return('foo')
280
293
  resource # initialize the resource so our provider has a @resource instance variable
281
294
  end
282
295
 
@@ -296,13 +309,13 @@ describe Puppet::Provider::NameService do
296
309
  # overriding to UTF-8, in @canonical_name for querying that state on disk
297
310
  # again if needed
298
311
  it "should use the instance's @canonical_name to query the system" do
299
- provider_instance = described_class.new(:name => 'foo', :canonical_name => 'original_foo', :ensure => :present)
312
+ provider_instance = provider.class.new(:name => 'foo', :canonical_name => 'original_foo', :ensure => :present)
300
313
  expect(Puppet::Etc).to receive(:send).with(:getfoonam, 'original_foo')
301
314
  provider_instance.getinfo(true)
302
315
  end
303
316
 
304
317
  it "should use the instance's name instead of canonical_name if not supplied during instantiation" do
305
- provider_instance = described_class.new(:name => 'foo', :ensure => :present)
318
+ provider_instance = provider.class.new(:name => 'foo', :ensure => :present)
306
319
  expect(Puppet::Etc).to receive(:send).with(:getfoonam, 'foo')
307
320
  provider_instance.getinfo(true)
308
321
  end
@@ -310,16 +323,6 @@ describe Puppet::Provider::NameService do
310
323
 
311
324
  describe "info2hash" do
312
325
  it "should return a hash with all properties" do
313
- # we have to have an implementation of posixmethod which has to
314
- # convert a propertyname (e.g. comment) into a fieldname of our
315
- # Struct (e.g. gecos). I do not want to test posixmethod here so
316
- # let's fake an implementation which does not do any translation. We
317
- # expect two method invocations because info2hash calls the method
318
- # twice if the Struct responds to the propertyname (our fake Struct
319
- # provides values for :foo and :bar) TODO: Fix that
320
- expect(provider).to receive(:posixmethod).with(:foo).and_return(:foo).twice
321
- expect(provider).to receive(:posixmethod).with(:bar).and_return(:bar).twice
322
- expect(provider).to receive(:posixmethod).with(:ensure).and_return(:ensure)
323
326
  expect(provider.info2hash(fakeetcobject)).to eq({ :foo => 'fooval', :bar => 'barval' })
324
327
  end
325
328
  end
@@ -330,7 +333,7 @@ describe Puppet::Provider::NameService do
330
333
  end
331
334
 
332
335
  it "should return the munged value otherwise" do
333
- described_class.options(:foo, :munge => proc { |x| x*2 })
336
+ provider.class.options(:foo, :munge => proc { |x| x*2 })
334
337
  expect(provider.munge(:foo, 100)).to eq(200)
335
338
  end
336
339
  end
@@ -341,7 +344,7 @@ describe Puppet::Provider::NameService do
341
344
  end
342
345
 
343
346
  it "should return the unmunged value otherwise" do
344
- described_class.options(:foo, :unmunge => proc { |x| x/2 })
347
+ provider.class.options(:foo, :unmunge => proc { |x| x/2 })
345
348
  expect(provider.unmunge(:foo, 200)).to eq(100)
346
349
  end
347
350
  end
@@ -359,15 +362,13 @@ describe Puppet::Provider::NameService do
359
362
  end
360
363
 
361
364
  describe "get" do
362
- before(:each) {described_class.resource_type = faketype }
363
-
364
365
  it "should return the correct getinfo value" do
365
366
  expect(provider).to receive(:getinfo).with(false).and_return(:foo => 'fooval', :bar => 'barval')
366
367
  expect(provider.get(:bar)).to eq('barval')
367
368
  end
368
369
 
369
370
  it "should unmunge the value first" do
370
- described_class.options(:bar, :munge => proc { |x| x*2}, :unmunge => proc {|x| x/2})
371
+ provider.class.options(:bar, :munge => proc { |x| x*2}, :unmunge => proc {|x| x/2})
371
372
  expect(provider).to receive(:getinfo).with(false).and_return(:foo => 200, :bar => 500)
372
373
  expect(provider.get(:bar)).to eq(250)
373
374
  end
@@ -382,7 +383,7 @@ describe Puppet::Provider::NameService do
382
383
  describe "set" do
383
384
  before :each do
384
385
  resource # initialize resource so our provider has a @resource object
385
- described_class.verify(:foo, 'Must be 100') { |val| val == 100 }
386
+ provider.class.verify(:foo, 'Must be 100') { |val| val == 100 }
386
387
  end
387
388
 
388
389
  it "should raise an error on invalid values" do
@@ -396,7 +397,7 @@ describe Puppet::Provider::NameService do
396
397
  end
397
398
 
398
399
  it "should munge the value first" do
399
- described_class.options(:foo, :munge => proc { |x| x*2}, :unmunge => proc {|x| x/2})
400
+ provider.class.options(:foo, :munge => proc { |x| x*2}, :unmunge => proc {|x| x/2})
400
401
  expect(provider).to receive(:modifycmd).with(:foo, 200).and_return(['/bin/modify', '-f', '200' ])
401
402
  expect(provider).to receive(:execute).with(['/bin/modify', '-f', '200'], hash_including(custom_environment: {}))
402
403
  provider.set(:foo, 100)