puppet 5.5.17-universal-darwin → 5.5.22-universal-darwin

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 (340) hide show
  1. checksums.yaml +4 -4
  2. data/CODEOWNERS +1 -1
  3. data/Gemfile +4 -5
  4. data/Gemfile.lock +59 -55
  5. data/ext/build_defaults.yaml +1 -0
  6. data/ext/cert_inspector +3 -3
  7. data/ext/puppet-test +2 -2
  8. data/ext/regexp_nodes/regexp_nodes.rb +4 -4
  9. data/ext/windows/service/daemon.rb +54 -8
  10. data/install.rb +6 -6
  11. data/lib/puppet.rb +5 -2
  12. data/lib/puppet/agent.rb +5 -13
  13. data/lib/puppet/application.rb +1 -1
  14. data/lib/puppet/application/agent.rb +3 -1
  15. data/lib/puppet/application/apply.rb +2 -2
  16. data/lib/puppet/application/describe.rb +3 -9
  17. data/lib/puppet/application/doc.rb +1 -1
  18. data/lib/puppet/application/filebucket.rb +13 -0
  19. data/lib/puppet/application/lookup.rb +1 -1
  20. data/lib/puppet/application/script.rb +2 -2
  21. data/lib/puppet/configurer.rb +106 -31
  22. data/lib/puppet/configurer/downloader.rb +33 -16
  23. data/lib/puppet/daemon.rb +1 -1
  24. data/lib/puppet/defaults.rb +86 -40
  25. data/lib/puppet/error.rb +9 -1
  26. data/lib/puppet/external/nagios/base.rb +1 -1
  27. data/lib/puppet/face/ca.rb +1 -1
  28. data/lib/puppet/face/module/list.rb +5 -5
  29. data/lib/puppet/face/module/search.rb +1 -1
  30. data/lib/puppet/face/module/uninstall.rb +1 -1
  31. data/lib/puppet/face/module/upgrade.rb +1 -1
  32. data/lib/puppet/file_serving/http_metadata.rb +1 -1
  33. data/lib/puppet/file_serving/mount/locales.rb +1 -2
  34. data/lib/puppet/file_serving/mount/pluginfacts.rb +1 -2
  35. data/lib/puppet/file_serving/mount/plugins.rb +1 -2
  36. data/lib/puppet/file_system.rb +0 -8
  37. data/lib/puppet/file_system/memory_file.rb +1 -1
  38. data/lib/puppet/file_system/posix.rb +3 -2
  39. data/lib/puppet/file_system/uniquefile.rb +4 -0
  40. data/lib/puppet/forge.rb +3 -3
  41. data/lib/puppet/functions/epp.rb +4 -4
  42. data/lib/puppet/functions/inline_epp.rb +5 -5
  43. data/lib/puppet/functions/new.rb +8 -3
  44. data/lib/puppet/functions/reduce.rb +2 -4
  45. data/lib/puppet/functions/reverse_each.rb +1 -1
  46. data/lib/puppet/functions/step.rb +1 -1
  47. data/lib/puppet/gettext/module_translations.rb +1 -1
  48. data/lib/puppet/graph/rb_tree_map.rb +2 -2
  49. data/lib/puppet/graph/simple_graph.rb +6 -5
  50. data/lib/puppet/indirector/catalog/compiler.rb +8 -0
  51. data/lib/puppet/indirector/file_bucket_file/file.rb +1 -1
  52. data/lib/puppet/indirector/hiera.rb +6 -0
  53. data/lib/puppet/indirector/resource/ral.rb +1 -3
  54. data/lib/puppet/indirector/resource/validator.rb +1 -1
  55. data/lib/puppet/interface.rb +2 -1
  56. data/lib/puppet/loaders.rb +0 -1
  57. data/lib/puppet/metatype/manager.rb +1 -1
  58. data/lib/puppet/module.rb +1 -1
  59. data/lib/puppet/module_tool/applications/builder.rb +1 -1
  60. data/lib/puppet/module_tool/applications/installer.rb +1 -1
  61. data/lib/puppet/module_tool/applications/uninstaller.rb +3 -3
  62. data/lib/puppet/module_tool/metadata.rb +1 -1
  63. data/lib/puppet/module_tool/shared_behaviors.rb +4 -4
  64. data/lib/puppet/module_tool/tar/mini.rb +1 -1
  65. data/lib/puppet/network/http/api/indirected_routes.rb +13 -12
  66. data/lib/puppet/network/http/api/master/v3/environment.rb +3 -0
  67. data/lib/puppet/network/http/connection.rb +14 -12
  68. data/lib/puppet/network/http/pool.rb +7 -1
  69. data/lib/puppet/network/http/rack/rest.rb +2 -2
  70. data/lib/puppet/network/http/site.rb +1 -1
  71. data/lib/puppet/network/resolver.rb +2 -2
  72. data/lib/puppet/node/environment.rb +11 -3
  73. data/lib/puppet/parser/ast.rb +1 -1
  74. data/lib/puppet/parser/ast/resourceparam.rb +1 -1
  75. data/lib/puppet/parser/compiler/catalog_validator/env_relationship_validator.rb +2 -0
  76. data/lib/puppet/parser/compiler/catalog_validator/site_validator.rb +2 -0
  77. data/lib/puppet/parser/environment_compiler.rb +3 -0
  78. data/lib/puppet/parser/functions.rb +14 -10
  79. data/lib/puppet/parser/functions/epp.rb +3 -3
  80. data/lib/puppet/parser/functions/inline_epp.rb +5 -5
  81. data/lib/puppet/parser/resource.rb +3 -2
  82. data/lib/puppet/parser/resource/param.rb +6 -0
  83. data/lib/puppet/pops/adaptable.rb +7 -13
  84. data/lib/puppet/pops/adapters.rb +8 -4
  85. data/lib/puppet/pops/evaluator/access_operator.rb +2 -2
  86. data/lib/puppet/pops/evaluator/collectors/abstract_collector.rb +1 -3
  87. data/lib/puppet/pops/evaluator/collectors/catalog_collector.rb +1 -1
  88. data/lib/puppet/pops/evaluator/collectors/exported_collector.rb +1 -1
  89. data/lib/puppet/pops/evaluator/evaluator_impl.rb +1 -1
  90. data/lib/puppet/pops/evaluator/external_syntax_support.rb +3 -2
  91. data/lib/puppet/pops/evaluator/runtime3_support.rb +4 -4
  92. data/lib/puppet/pops/issues.rb +5 -0
  93. data/lib/puppet/pops/loaders.rb +1 -1
  94. data/lib/puppet/pops/lookup/hiera_config.rb +1 -0
  95. data/lib/puppet/pops/lookup/sub_lookup.rb +1 -1
  96. data/lib/puppet/pops/merge_strategy.rb +22 -18
  97. data/lib/puppet/pops/parser/heredoc_support.rb +1 -1
  98. data/lib/puppet/pops/parser/interpolation_support.rb +4 -4
  99. data/lib/puppet/pops/parser/locator.rb +1 -1
  100. data/lib/puppet/pops/parser/pn_parser.rb +17 -16
  101. data/lib/puppet/pops/puppet_stack.rb +51 -48
  102. data/lib/puppet/pops/resource/resource_type_impl.rb +2 -0
  103. data/lib/puppet/pops/types/iterable.rb +34 -8
  104. data/lib/puppet/pops/types/p_meta_type.rb +1 -1
  105. data/lib/puppet/pops/types/p_sensitive_type.rb +1 -1
  106. data/lib/puppet/pops/types/p_type_set_type.rb +4 -0
  107. data/lib/puppet/pops/types/string_converter.rb +10 -10
  108. data/lib/puppet/pops/types/type_calculator.rb +24 -0
  109. data/lib/puppet/pops/types/types.rb +3 -3
  110. data/lib/puppet/pops/validation/checker4_0.rb +29 -15
  111. data/lib/puppet/pops/validation/validator_factory_4_0.rb +1 -0
  112. data/lib/puppet/property.rb +1 -1
  113. data/lib/puppet/property/ensure.rb +1 -1
  114. data/lib/puppet/provider/augeas/augeas.rb +1 -1
  115. data/lib/puppet/provider/cron/crontab.rb +1 -1
  116. data/lib/puppet/provider/exec.rb +6 -2
  117. data/lib/puppet/provider/group/groupadd.rb +19 -19
  118. data/lib/puppet/provider/group/windows_adsi.rb +3 -3
  119. data/lib/puppet/provider/mailalias/aliases.rb +1 -1
  120. data/lib/puppet/provider/mount.rb +1 -1
  121. data/lib/puppet/provider/mount/parsed.rb +8 -8
  122. data/lib/puppet/provider/nameservice/directoryservice.rb +1 -1
  123. data/lib/puppet/provider/nameservice/pw.rb +2 -2
  124. data/lib/puppet/provider/package/aix.rb +17 -2
  125. data/lib/puppet/provider/package/apt.rb +14 -3
  126. data/lib/puppet/provider/package/dnfmodule.rb +141 -0
  127. data/lib/puppet/provider/package/dpkg.rb +16 -18
  128. data/lib/puppet/provider/package/fink.rb +20 -3
  129. data/lib/puppet/provider/package/gem.rb +4 -2
  130. data/lib/puppet/provider/package/openbsd.rb +14 -2
  131. data/lib/puppet/provider/package/pip.rb +37 -10
  132. data/lib/puppet/provider/package/pkg.rb +18 -5
  133. data/lib/puppet/provider/package/pkgdmg.rb +1 -1
  134. data/lib/puppet/provider/package/pkgng.rb +16 -4
  135. data/lib/puppet/provider/package/portage.rb +4 -4
  136. data/lib/puppet/provider/package/puppet_gem.rb +5 -0
  137. data/lib/puppet/provider/package/rpm.rb +6 -6
  138. data/lib/puppet/provider/package/windows/package.rb +1 -1
  139. data/lib/puppet/provider/package/yum.rb +28 -20
  140. data/lib/puppet/provider/package/zypper.rb +1 -0
  141. data/lib/puppet/provider/package_targetable.rb +5 -4
  142. data/lib/puppet/provider/parsedfile.rb +1 -1
  143. data/lib/puppet/provider/scheduled_task/win32_taskscheduler.rb +3 -3
  144. data/lib/puppet/provider/selmodule/semodule.rb +43 -26
  145. data/lib/puppet/provider/service/daemontools.rb +9 -9
  146. data/lib/puppet/provider/service/openbsd.rb +1 -1
  147. data/lib/puppet/provider/service/rcng.rb +2 -2
  148. data/lib/puppet/provider/service/runit.rb +2 -8
  149. data/lib/puppet/provider/service/systemd.rb +31 -13
  150. data/lib/puppet/provider/user/directoryservice.rb +31 -6
  151. data/lib/puppet/provider/user/hpux.rb +1 -1
  152. data/lib/puppet/provider/user/user_role_add.rb +1 -1
  153. data/lib/puppet/provider/user/useradd.rb +39 -20
  154. data/lib/puppet/provider/user/windows_adsi.rb +4 -5
  155. data/lib/puppet/provider/yumrepo/inifile.rb +2 -2
  156. data/lib/puppet/reference/indirection.rb +2 -2
  157. data/lib/puppet/reference/metaparameter.rb +1 -3
  158. data/lib/puppet/reference/providers.rb +1 -1
  159. data/lib/puppet/reference/type.rb +3 -9
  160. data/lib/puppet/reports.rb +1 -1
  161. data/lib/puppet/resource.rb +1 -1
  162. data/lib/puppet/resource/catalog.rb +1 -1
  163. data/lib/puppet/resource/type.rb +10 -1
  164. data/lib/puppet/settings.rb +3 -3
  165. data/lib/puppet/settings/environment_conf.rb +1 -0
  166. data/lib/puppet/ssl/certificate.rb +2 -1
  167. data/lib/puppet/ssl/certificate_authority.rb +6 -5
  168. data/lib/puppet/ssl/certificate_authority/interface.rb +1 -1
  169. data/lib/puppet/ssl/certificate_factory.rb +2 -2
  170. data/lib/puppet/ssl/host.rb +3 -3
  171. data/lib/puppet/ssl/oids.rb +1 -1
  172. data/lib/puppet/test/test_helper.rb +20 -12
  173. data/lib/puppet/transaction/report.rb +1 -1
  174. data/lib/puppet/transaction/resource_harness.rb +1 -1
  175. data/lib/puppet/type.rb +8 -4
  176. data/lib/puppet/type/cron.rb +1 -1
  177. data/lib/puppet/type/exec.rb +7 -3
  178. data/lib/puppet/type/file.rb +14 -2
  179. data/lib/puppet/type/file/data_sync.rb +5 -1
  180. data/lib/puppet/type/group.rb +4 -2
  181. data/lib/puppet/type/interface.rb +1 -1
  182. data/lib/puppet/type/notify.rb +3 -2
  183. data/lib/puppet/type/package.rb +97 -8
  184. data/lib/puppet/type/schedule.rb +1 -1
  185. data/lib/puppet/type/selboolean.rb +17 -3
  186. data/lib/puppet/type/service.rb +2 -8
  187. data/lib/puppet/type/user.rb +5 -9
  188. data/lib/puppet/util.rb +35 -12
  189. data/lib/puppet/util/autoload.rb +9 -7
  190. data/lib/puppet/util/command_line/trollop.rb +1 -1
  191. data/lib/puppet/util/http_proxy.rb +8 -14
  192. data/lib/puppet/util/instance_loader.rb +1 -1
  193. data/lib/puppet/util/log.rb +1 -1
  194. data/lib/puppet/util/log/destinations.rb +3 -12
  195. data/lib/puppet/util/logging.rb +30 -18
  196. data/lib/puppet/util/metric.rb +2 -2
  197. data/lib/puppet/util/monkey_patches.rb +1 -1
  198. data/lib/puppet/util/nagios_maker.rb +2 -2
  199. data/lib/puppet/util/network_device/cisco/device.rb +1 -1
  200. data/lib/puppet/util/network_device/cisco/interface.rb +2 -2
  201. data/lib/puppet/util/network_device/transport/ssh.rb +1 -1
  202. data/lib/puppet/util/pidlock.rb +12 -6
  203. data/lib/puppet/util/plist.rb +6 -0
  204. data/lib/puppet/util/provider_features.rb +2 -4
  205. data/lib/puppet/util/rdoc.rb +1 -1
  206. data/lib/puppet/util/reference.rb +1 -1
  207. data/lib/puppet/util/resource_template.rb +1 -1
  208. data/lib/puppet/util/selinux.rb +3 -1
  209. data/lib/puppet/util/windows/adsi.rb +60 -30
  210. data/lib/puppet/util/windows/api_types.rb +45 -32
  211. data/lib/puppet/util/windows/eventlog.rb +1 -6
  212. data/lib/puppet/util/windows/principal.rb +8 -6
  213. data/lib/puppet/util/windows/process.rb +16 -15
  214. data/lib/puppet/util/windows/registry.rb +17 -15
  215. data/lib/puppet/util/windows/security.rb +1 -0
  216. data/lib/puppet/util/windows/sid.rb +3 -3
  217. data/lib/puppet/vendor.rb +1 -1
  218. data/lib/puppet/version.rb +1 -1
  219. data/lib/puppet_pal.rb +2 -2
  220. data/locales/puppet.pot +362 -318
  221. data/man/man5/puppet.conf.5 +39 -9
  222. data/man/man8/puppet-agent.8 +2 -2
  223. data/man/man8/puppet-apply.8 +1 -1
  224. data/man/man8/puppet-ca.8 +1 -1
  225. data/man/man8/puppet-catalog.8 +1 -1
  226. data/man/man8/puppet-cert.8 +1 -1
  227. data/man/man8/puppet-certificate.8 +1 -1
  228. data/man/man8/puppet-certificate_request.8 +1 -1
  229. data/man/man8/puppet-certificate_revocation_list.8 +1 -1
  230. data/man/man8/puppet-config.8 +1 -1
  231. data/man/man8/puppet-describe.8 +1 -1
  232. data/man/man8/puppet-device.8 +1 -1
  233. data/man/man8/puppet-doc.8 +1 -1
  234. data/man/man8/puppet-epp.8 +1 -1
  235. data/man/man8/puppet-facts.8 +1 -1
  236. data/man/man8/puppet-filebucket.8 +16 -1
  237. data/man/man8/puppet-generate.8 +1 -1
  238. data/man/man8/puppet-help.8 +1 -1
  239. data/man/man8/puppet-key.8 +1 -1
  240. data/man/man8/puppet-lookup.8 +1 -1
  241. data/man/man8/puppet-man.8 +1 -1
  242. data/man/man8/puppet-master.8 +1 -1
  243. data/man/man8/puppet-module.8 +1 -1
  244. data/man/man8/puppet-node.8 +1 -1
  245. data/man/man8/puppet-parser.8 +1 -1
  246. data/man/man8/puppet-plugin.8 +1 -1
  247. data/man/man8/puppet-report.8 +1 -1
  248. data/man/man8/puppet-resource.8 +1 -1
  249. data/man/man8/puppet-script.8 +1 -1
  250. data/man/man8/puppet-status.8 +1 -1
  251. data/man/man8/puppet.8 +2 -2
  252. data/spec/fixtures/integration/provider/mailalias/aliases/test1 +1 -0
  253. data/spec/fixtures/unit/provider/package/dnfmodule/dnf-module-list.txt +19 -0
  254. data/spec/fixtures/unit/provider/package/pkgng/pkg.version +2 -0
  255. data/spec/fixtures/unit/provider/package/yum/yum-check-update-subscription-manager.txt +9 -0
  256. data/spec/fixtures/unit/provider/service/systemd/list_unit_files_services +9 -0
  257. data/spec/integration/configurer_spec.rb +66 -0
  258. data/spec/integration/data_binding_spec.rb +1 -0
  259. data/spec/integration/defaults_spec.rb +1 -2
  260. data/spec/integration/faces/plugin_spec.rb +29 -47
  261. data/spec/integration/indirector/facts/facter_spec.rb +4 -0
  262. data/spec/integration/parser/compiler_spec.rb +11 -0
  263. data/spec/integration/type/notify_spec.rb +46 -0
  264. data/spec/integration/util/windows/adsi_spec.rb +6 -1
  265. data/spec/integration/util/windows/registry_spec.rb +7 -7
  266. data/spec/shared_contexts/types_setup.rb +2 -0
  267. data/spec/unit/agent_spec.rb +34 -26
  268. data/spec/unit/application/apply_spec.rb +2 -12
  269. data/spec/unit/configurer/downloader_spec.rb +10 -0
  270. data/spec/unit/configurer/fact_handler_spec.rb +0 -4
  271. data/spec/unit/configurer_spec.rb +430 -415
  272. data/spec/unit/daemon_spec.rb +0 -1
  273. data/spec/unit/file_serving/mount/locales_spec.rb +2 -2
  274. data/spec/unit/file_serving/mount/pluginfacts_spec.rb +2 -2
  275. data/spec/unit/file_serving/mount/plugins_spec.rb +2 -2
  276. data/spec/unit/file_system/uniquefile_spec.rb +11 -0
  277. data/spec/unit/forge/forge_spec.rb +1 -3
  278. data/spec/unit/forge/repository_spec.rb +1 -3
  279. data/spec/unit/indirector/catalog/compiler_spec.rb +45 -26
  280. data/spec/unit/indirector/resource/ral_spec.rb +4 -4
  281. data/spec/unit/network/http/api/indirected_routes_spec.rb +2 -1
  282. data/spec/unit/network/http/connection_spec.rb +43 -1
  283. data/spec/unit/network/http/pool_spec.rb +32 -0
  284. data/spec/unit/node_spec.rb +7 -4
  285. data/spec/unit/parser/environment_compiler_spec.rb +7 -0
  286. data/spec/unit/pops/evaluator/evaluating_parser_spec.rb +8 -3
  287. data/spec/unit/provider/exec_spec.rb +209 -0
  288. data/spec/unit/provider/group/groupadd_spec.rb +30 -1
  289. data/spec/unit/provider/group/windows_adsi_spec.rb +43 -10
  290. data/spec/unit/provider/package/aix_spec.rb +29 -0
  291. data/spec/unit/provider/package/apt_spec.rb +13 -2
  292. data/spec/unit/provider/package/aptitude_spec.rb +1 -0
  293. data/spec/unit/provider/package/dnfmodule_spec.rb +247 -0
  294. data/spec/unit/provider/package/dpkg_spec.rb +35 -7
  295. data/spec/unit/provider/package/openbsd_spec.rb +17 -0
  296. data/spec/unit/provider/package/pip_spec.rb +93 -22
  297. data/spec/unit/provider/package/pkg_spec.rb +13 -1
  298. data/spec/unit/provider/package/pkgdmg_spec.rb +1 -1
  299. data/spec/unit/provider/package/pkgng_spec.rb +36 -0
  300. data/spec/unit/provider/package/portage_spec.rb +4 -4
  301. data/spec/unit/provider/package/puppet_gem_spec.rb +4 -1
  302. data/spec/unit/provider/package/yum_spec.rb +90 -0
  303. data/spec/unit/provider/package/zypper_spec.rb +13 -0
  304. data/spec/unit/provider/package_targetable_spec.rb +60 -0
  305. data/spec/unit/provider/selmodule_spec.rb +118 -47
  306. data/spec/unit/provider/service/daemontools_spec.rb +24 -0
  307. data/spec/unit/provider/service/runit_spec.rb +24 -0
  308. data/spec/unit/provider/service/systemd_spec.rb +109 -36
  309. data/spec/unit/provider/user/directoryservice_spec.rb +41 -0
  310. data/spec/unit/provider/user/hpux_spec.rb +2 -2
  311. data/spec/unit/provider/user/openbsd_spec.rb +1 -0
  312. data/spec/unit/provider/user/useradd_spec.rb +81 -16
  313. data/spec/unit/provider/user/windows_adsi_spec.rb +3 -3
  314. data/spec/unit/puppet_pal_2pec.rb +3 -0
  315. data/spec/unit/ssl/certificate_authority_spec.rb +2 -3
  316. data/spec/unit/ssl/certificate_spec.rb +7 -0
  317. data/spec/unit/ssl/host_spec.rb +2 -0
  318. data/spec/unit/test/test_helper_spec.rb +17 -0
  319. data/spec/unit/type/exec_spec.rb +6 -12
  320. data/spec/unit/type/file/content_spec.rb +9 -3
  321. data/spec/unit/type/file_spec.rb +9 -4
  322. data/spec/unit/type/package_spec.rb +8 -0
  323. data/spec/unit/type/selboolean_spec.rb +4 -6
  324. data/spec/unit/type/service_spec.rb +9 -8
  325. data/spec/unit/type/user_spec.rb +19 -13
  326. data/spec/unit/util/execution_spec.rb +16 -0
  327. data/spec/unit/util/http_proxy_spec.rb +97 -0
  328. data/spec/unit/util/log/destinations_spec.rb +2 -26
  329. data/spec/unit/util/log_spec.rb +0 -138
  330. data/spec/unit/util/logging_spec.rb +200 -0
  331. data/spec/unit/util/pidlock_spec.rb +67 -40
  332. data/spec/unit/util/plist_spec.rb +20 -0
  333. data/spec/unit/util/windows/adsi_spec.rb +55 -4
  334. data/spec/unit/util/windows/api_types_spec.rb +104 -40
  335. data/spec/unit/util/windows/sid_spec.rb +2 -2
  336. data/tasks/manpages.rake +1 -0
  337. metadata +16 -7
  338. data/lib/puppet/pops/loader/null_loader.rb +0 -60
  339. data/locales/ja/puppet.po +0 -12114
  340. data/spec/integration/test/test_helper_spec.rb +0 -31
@@ -22,23 +22,6 @@ describe Puppet::Util::Pidlock do
22
22
 
23
23
  it "should become locked" do
24
24
  @lock.lock
25
- if Puppet::Util::Platform.windows?
26
- allow(Puppet::Util::Windows::Process).to receive(:get_process_image_name_by_pid).with(@lock.lock_pid).and_return('C:\Program Files\Puppet Labs\Puppet\puppet\bin\ruby.exe')
27
- else
28
- allow(Puppet::Util::Execution).to receive(:execute).with(['ps', '-p', @lock.lock_pid, '-o', 'comm=']).and_return('puppet')
29
- allow(Puppet::Util::Execution).to receive(:execute).with(['ps', '-p', @lock.lock_pid, '-o', 'args=']).and_return('puppet')
30
- end
31
- expect(@lock).to be_locked
32
- end
33
-
34
- it "should become locked if puppet is a gem" do
35
- @lock.lock
36
- unless Puppet::Util::Platform.windows?
37
- expect(Puppet::Util::Execution).to receive(:execute).with(['ps', '-p', @lock.lock_pid, '-o', 'comm=']).and_return('ruby')
38
- expect(Puppet::Util::Execution).to receive(:execute).with(['ps', '-p', @lock.lock_pid, '-o', 'args=']).and_return('ruby /root/puppet/.bundle/ruby/2.3.0/bin/puppet agent --no-daemonize -v')
39
- else
40
- allow(Puppet::Util::Windows::Process).to receive(:get_process_image_name_by_pid).with(@lock.lock_pid).and_return('C:\tools\ruby25\bin\ruby.exe')
41
- end
42
25
  expect(@lock).to be_locked
43
26
  end
44
27
 
@@ -117,23 +100,6 @@ describe Puppet::Util::Pidlock do
117
100
  describe "#locked?" do
118
101
  it "should return true if locked" do
119
102
  @lock.lock
120
- if Puppet::Util::Platform.windows?
121
- allow(Puppet::Util::Windows::Process).to receive(:get_process_image_name_by_pid).with(@lock.lock_pid).and_return('C:\Program Files\Puppet Labs\Puppet\puppet\bin\ruby.exe')
122
- else
123
- allow(Puppet::Util::Execution).to receive(:execute).with(['ps', '-p', @lock.lock_pid, '-o', 'comm=']).and_return('puppet')
124
- allow(Puppet::Util::Execution).to receive(:execute).with(['ps', '-p', @lock.lock_pid, '-o', 'args=']).and_return('puppet')
125
- end
126
- expect(@lock).to be_locked
127
- end
128
-
129
- it "should return true if locked when puppet as gem" do
130
- @lock.lock
131
- unless Puppet::Util::Platform.windows?
132
- expect(Puppet::Util::Execution).to receive(:execute).with(['ps', '-p', @lock.lock_pid, '-o', 'comm=']).and_return('ruby')
133
- expect(Puppet::Util::Execution).to receive(:execute).with(['ps', '-p', @lock.lock_pid, '-o', 'args=']).and_return('ruby /root/puppet/.bundle/ruby/2.3.0/bin/puppet agent --no-daemonize -v')
134
- else
135
- allow(Puppet::Util::Windows::Process).to receive(:get_process_image_name_by_pid).with(@lock.lock_pid).and_return('C:\tools\ruby25\bin\ruby.exe')
136
- end
137
103
  expect(@lock).to be_locked
138
104
  end
139
105
 
@@ -179,12 +145,6 @@ describe Puppet::Util::Pidlock do
179
145
  end
180
146
 
181
147
  it "should replace with new locks" do
182
- if Puppet::Util::Platform.windows?
183
- allow(Puppet::Util::Windows::Process).to receive(:get_process_image_name_by_pid).with(6789).and_return('C:\Program Files\Puppet Labs\Puppet\puppet\bin\ruby.exe')
184
- else
185
- allow(Puppet::Util::Execution).to receive(:execute).with(['ps', '-p', 6789, '-o', 'comm=']).and_return('puppet')
186
- allow(Puppet::Util::Execution).to receive(:execute).with(['ps', '-p', 6789, '-o', 'args=']).and_return('puppet')
187
- end
188
148
  @lock.lock
189
149
  expect(Puppet::FileSystem.exist?(@lockfile)).to be_truthy
190
150
  expect(@lock.lock_pid).to eq(6789)
@@ -205,6 +165,49 @@ describe Puppet::Util::Pidlock do
205
165
  end
206
166
  end
207
167
 
168
+ describe "with no access to open the process on Windows", :if => Puppet.features.microsoft_windows? do
169
+ before(:each) do
170
+ allow(Process).to receive(:pid).and_return(6789)
171
+ @lock.lock
172
+ allow(Process).to receive(:pid).and_return(1234)
173
+ exception = Puppet::Util::Windows::Error.new('Access Denied', 5) # ERROR_ACCESS_DENIED
174
+ allow(Puppet::Util::Windows::Process).to receive(:get_process_image_name_by_pid).with(6789).and_raise(exception)
175
+ allow(Process).to receive(:kill).with(0, 6789)
176
+ allow(Process).to receive(:kill).with(0, 1234)
177
+ end
178
+
179
+ it "should be locked" do
180
+ expect(@lock).to be_locked
181
+ end
182
+
183
+ describe "#lock" do
184
+ it "should not be possible" do
185
+ expect(@lock.lock).to be_falsey
186
+ end
187
+
188
+ it "should not overwrite the lock" do
189
+ @lock.lock
190
+ expect(@lock).not_to be_mine
191
+ end
192
+ end
193
+
194
+ describe "#unlock" do
195
+ it "should not be possible" do
196
+ expect(@lock.unlock).to be_falsey
197
+ end
198
+
199
+ it "should not remove the lock file" do
200
+ @lock.unlock
201
+ expect(Puppet::FileSystem.exist?(@lockfile)).to be_truthy
202
+ end
203
+
204
+ it "should still not be our lock" do
205
+ @lock.unlock
206
+ expect(@lock).not_to be_mine
207
+ end
208
+ end
209
+ end
210
+
208
211
  describe "with another process lock" do
209
212
  before(:each) do
210
213
  # fake our pid to be 1234
@@ -233,6 +236,30 @@ describe Puppet::Util::Pidlock do
233
236
  expect(@lock).not_to be_mine
234
237
  end
235
238
 
239
+ it "should be locked if the other process is a puppet gem" do
240
+ File.write(@lockfile, "1234")
241
+
242
+ if Puppet::Util::Platform.windows?
243
+ allow(Puppet::Util::Windows::Process).to receive(:get_process_image_name_by_pid).with(1234).and_return('C:\Program Files\Puppet Labs\Puppet\puppet\bin\ruby.exe')
244
+ else
245
+ allow(Puppet::Util::Execution).to receive(:execute).with(['ps', '-p', 1234, '-o', 'comm=']).and_return('ruby')
246
+ allow(Puppet::Util::Execution).to receive(:execute).with(['ps', '-p', 1234, '-o', 'args=']).and_return('ruby /root/puppet/.bundle/ruby/2.3.0/bin/puppet agent --no-daemonize -v')
247
+ end
248
+ expect(@lock).to be_locked
249
+ end
250
+
251
+ it "should not be mine if the other process is a puppet gem" do
252
+ File.write(@lockfile, "1234")
253
+
254
+ if Puppet::Util::Platform.windows?
255
+ allow(Puppet::Util::Windows::Process).to receive(:get_process_image_name_by_pid).with(1234).and_return('C:\Program Files\Puppet Labs\Puppet\puppet\bin\ruby.exe')
256
+ else
257
+ allow(Puppet::Util::Execution).to receive(:execute).with(['ps', '-p', 1234, '-o', 'comm=']).and_return('ruby')
258
+ allow(Puppet::Util::Execution).to receive(:execute).with(['ps', '-p', 1234, '-o', 'args=']).and_return('ruby /root/puppet/.bundle/ruby/2.3.0/bin/puppet agent --no-daemonize -v')
259
+ end
260
+ expect(@lock).to_not be_mine
261
+ end
262
+
236
263
  describe "#lock" do
237
264
  it "should not be possible" do
238
265
  expect(@lock.lock).to be_falsey
@@ -1,3 +1,5 @@
1
+ # coding: utf-8
2
+
1
3
  require 'spec_helper'
2
4
  require 'puppet/util/plist'
3
5
  require 'puppet_spec/files'
@@ -52,6 +54,19 @@ describe Puppet::Util::Plist, :if => Puppet.features.cfpropertylist? do
52
54
  </dict>
53
55
  </plist>'
54
56
  end
57
+ let(:ascii_xml_plist) do
58
+ '<?xml version="1.0" encoding="UTF-8"?>
59
+ <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
60
+ <plist version="1.0">
61
+ <dict>
62
+ <key>RecordName</key>
63
+ <array>
64
+ <string>Timișoara</string>
65
+ <string>Tōkyō</string>
66
+ </array>
67
+ </dict>
68
+ </plist>'.force_encoding(Encoding::US_ASCII)
69
+ end
55
70
  let(:non_plist_data) do
56
71
  "Take my love, take my land
57
72
  Take me where I cannot stand
@@ -62,6 +77,7 @@ describe Puppet::Util::Plist, :if => Puppet.features.cfpropertylist? do
62
77
  "\xCF\xFA\xED\xFE\a\u0000\u0000\u0001\u0003\u0000\u0000\x80\u0002\u0000\u0000\u0000\u0012\u0000\u0000\u0000\b"
63
78
  end
64
79
  let(:valid_xml_plist_hash) { {"LastUsedPrinters"=>[{"Network"=>"10.85.132.1", "PrinterID"=>"baskerville_corp_puppetlabs_net"}, {"Network"=>"10.14.96.1", "PrinterID"=>"Statler"}]} }
80
+ let(:ascii_xml_plist_hash) { {"RecordName"=>["Timișoara", "Tōkyō"]} }
65
81
  let(:plist_path) { file_containing('sample.plist', valid_xml_plist) }
66
82
  let(:binary_plist_magic_number) { 'bplist00' }
67
83
  let(:bad_xml_doctype) { '<!DOCTYPE plist PUBLIC -//Apple Computer' }
@@ -132,6 +148,10 @@ describe Puppet::Util::Plist, :if => Puppet.features.cfpropertylist? do
132
148
  expect(subject.parse_plist(valid_xml_plist)).to eq(valid_xml_plist_hash)
133
149
  end
134
150
 
151
+ it "returns a valid hash when an ASCII XML plist is provided" do
152
+ expect(subject.parse_plist(ascii_xml_plist)).to eq(ascii_xml_plist_hash)
153
+ end
154
+
135
155
  it "raises a debug message and replaces a bad XML plist doctype should one be encountered" do
136
156
  expect(subject).to receive(:new_cfpropertylist).with({:data => good_xml_doctype}).and_return('plist_object')
137
157
  allow(subject).to receive(:convert_cfpropertylist_to_native_types).with('plist_object')
@@ -41,6 +41,19 @@ describe Puppet::Util::Windows::ADSI, :if => Puppet.features.microsoft_windows?
41
41
  end
42
42
  end
43
43
 
44
+ describe ".domain_role" do
45
+ DOMAIN_ROLES = Puppet::Util::Platform.windows? ? Puppet::Util::Windows::ADSI::DOMAIN_ROLES : {}
46
+
47
+ DOMAIN_ROLES.each do |id, role|
48
+ it "should be able to return #{role} as the domain role of the computer" do
49
+ Puppet::Util::Windows::ADSI.instance_variable_set(:@domain_role, nil)
50
+ domain_role = [double('WMI', :DomainRole => id)]
51
+ allow(Puppet::Util::Windows::ADSI).to receive(:execquery).with('select DomainRole from Win32_ComputerSystem').and_return(domain_role)
52
+ expect(Puppet::Util::Windows::ADSI.domain_role).to eq(role)
53
+ end
54
+ end
55
+ end
56
+
44
57
  describe ".sid_uri" do
45
58
  it "should raise an error when the input is not a SID Principal" do
46
59
  [Object.new, {}, 1, :symbol, '', nil].each do |input|
@@ -56,6 +69,32 @@ describe Puppet::Util::Windows::ADSI, :if => Puppet.features.microsoft_windows?
56
69
  end
57
70
  end
58
71
 
72
+ shared_examples 'a local only resource query' do |klass, account_type|
73
+ before(:each) do
74
+ allow(Puppet::Util::Windows::ADSI).to receive(:domain_role).and_return(:MEMBER_SERVER)
75
+ end
76
+
77
+ it "should be able to check for a local resource" do
78
+ local_domain = 'testcomputername'
79
+ principal = double('Principal', :account => resource_name, :domain => local_domain, :account_type => account_type)
80
+ allow(Puppet::Util::Windows::SID).to receive(:name_to_principal).with(resource_name).and_return(principal)
81
+ expect(klass.exists?(resource_name)).to eq(true)
82
+ end
83
+
84
+ it "should be case insensitive when comparing the domain with the computer name" do
85
+ local_domain = 'TESTCOMPUTERNAME'
86
+ principal = double('Principal', :account => resource_name, :domain => local_domain, :account_type => account_type)
87
+ allow(Puppet::Util::Windows::SID).to receive(:name_to_principal).with(resource_name).and_return(principal)
88
+ expect(klass.exists?(resource_name)).to eq(true)
89
+ end
90
+
91
+ it "should return false if no local resource exists" do
92
+ principal = double('Principal', :account => resource_name, :domain => 'AD_DOMAIN', :account_type => account_type)
93
+ allow(Puppet::Util::Windows::SID).to receive(:name_to_principal).with(resource_name).and_return(principal)
94
+ expect(klass.exists?(resource_name)).to eq(false)
95
+ end
96
+ end
97
+
59
98
  describe Puppet::Util::Windows::ADSI::User do
60
99
  let(:username) { 'testuser' }
61
100
  let(:domain) { 'DOMAIN' }
@@ -103,6 +142,12 @@ describe Puppet::Util::Windows::ADSI, :if => Puppet.features.microsoft_windows?
103
142
  expect(user.native_object).to eq(adsi_user)
104
143
  end
105
144
 
145
+ context "when domain-joined" do
146
+ it_should_behave_like 'a local only resource query', Puppet::Util::Windows::ADSI::User, :SidTypeUser do
147
+ let(:resource_name) { username }
148
+ end
149
+ end
150
+
106
151
  it "should be able to check the existence of a user" do
107
152
  expect(Puppet::Util::Windows::SID).to receive(:name_to_principal).with(username).and_return(nil)
108
153
  expect(Puppet::Util::Windows::ADSI).to receive(:connect).with("WinNT://./#{username},user").and_return(connection)
@@ -421,8 +466,8 @@ describe Puppet::Util::Windows::ADSI, :if => Puppet.features.microsoft_windows?
421
466
  expect(Puppet::Util::Windows::SID).to receive(:octet_string_to_principal).with([0]).and_return(sids[0])
422
467
  expect(Puppet::Util::Windows::SID).to receive(:octet_string_to_principal).with([1]).and_return(sids[1])
423
468
 
424
- expect(Puppet::Util::Windows::SID).to receive(:name_to_principal).with('user2').and_return(sids[1])
425
- expect(Puppet::Util::Windows::SID).to receive(:name_to_principal).with('DOMAIN2\user3').and_return(sids[2])
469
+ expect(Puppet::Util::Windows::SID).to receive(:name_to_principal).with('user2', false).and_return(sids[1])
470
+ expect(Puppet::Util::Windows::SID).to receive(:name_to_principal).with('DOMAIN2\user3', false).and_return(sids[2])
426
471
 
427
472
  expect(Puppet::Util::Windows::ADSI).to receive(:sid_uri).with(sids[0]).and_return("WinNT://DOMAIN/user1,user")
428
473
  expect(Puppet::Util::Windows::ADSI).to receive(:sid_uri).with(sids[2]).and_return("WinNT://DOMAIN2/user3,user")
@@ -448,8 +493,8 @@ describe Puppet::Util::Windows::ADSI, :if => Puppet.features.microsoft_windows?
448
493
  expect(Puppet::Util::Windows::SID).to receive(:octet_string_to_principal).with([0]).and_return(sids[0])
449
494
  expect(Puppet::Util::Windows::SID).to receive(:octet_string_to_principal).with([1]).and_return(sids[1])
450
495
 
451
- expect(Puppet::Util::Windows::SID).to receive(:name_to_principal).with('user2').and_return(sids[1])
452
- expect(Puppet::Util::Windows::SID).to receive(:name_to_principal).with('DOMAIN2\user3').and_return(sids[2])
496
+ expect(Puppet::Util::Windows::SID).to receive(:name_to_principal).with('user2', any_args).and_return(sids[1])
497
+ expect(Puppet::Util::Windows::SID).to receive(:name_to_principal).with('DOMAIN2\user3', any_args).and_return(sids[2])
453
498
 
454
499
  expect(Puppet::Util::Windows::ADSI).to receive(:sid_uri).with(sids[2]).and_return("WinNT://DOMAIN2/user3,user")
455
500
 
@@ -543,6 +588,12 @@ describe Puppet::Util::Windows::ADSI, :if => Puppet.features.microsoft_windows?
543
588
  expect(Puppet::Util::Windows::ADSI::Group.uri(groupname, ntauthority_localized)).to eq("WinNT://./#{groupname},group")
544
589
  end
545
590
 
591
+ context "when domain-joined" do
592
+ it_should_behave_like 'a local only resource query', Puppet::Util::Windows::ADSI::Group, :SidTypeGroup do
593
+ let(:resource_name) { groupname }
594
+ end
595
+ end
596
+
546
597
  it "should be able to create a group" do
547
598
  adsi_group = double("adsi")
548
599
 
@@ -4,62 +4,86 @@ require 'spec_helper'
4
4
 
5
5
  describe "FFI::MemoryPointer", :if => Puppet.features.microsoft_windows? do
6
6
  # use 2 bad bytes at end so we have even number of bytes / characters
7
- let (:bad_string) { "hello invalid world".encode(Encoding::UTF_16LE) + "\xDD\xDD".force_encoding(Encoding::UTF_16LE) }
8
- let (:bad_string_bytes) { bad_string.bytes.to_a }
7
+ let(:bad_string) { "hello invalid world".encode(Encoding::UTF_16LE) + "\xDD\xDD".force_encoding(Encoding::UTF_16LE) }
8
+ let(:bad_string_bytes) { bad_string.bytes.to_a }
9
+ let(:a_wide_bytes) { "A".encode(Encoding::UTF_16LE).bytes.to_a }
10
+ let(:b_wide_bytes) { "B".encode(Encoding::UTF_16LE).bytes.to_a }
9
11
 
10
12
  context "read_wide_string" do
11
13
  let (:string) { "foo_bar" }
12
14
 
13
15
  it "should properly roundtrip a given string" do
14
- read_string = nil
15
16
  FFI::MemoryPointer.from_string_to_wide_string(string) do |ptr|
16
- read_string = ptr.read_wide_string(string.length)
17
+ expect(ptr.read_wide_string(string.length)).to eq(string)
17
18
  end
18
-
19
- expect(read_string).to eq(string)
20
19
  end
21
20
 
22
21
  it "should return a given string in UTF-8" do
23
- read_string = nil
24
22
  FFI::MemoryPointer.from_string_to_wide_string(string) do |ptr|
25
23
  read_string = ptr.read_wide_string(string.length)
24
+ expect(read_string.encoding).to eq(Encoding::UTF_8)
26
25
  end
27
-
28
- expect(read_string.encoding).to eq(Encoding::UTF_8)
29
26
  end
30
27
 
31
28
  it "should raise an error and emit a debug message when receiving a string containing invalid bytes in the destination encoding" do
32
- # enable a debug output sink to local string array
33
- Puppet.debug = true
34
- arraydest = []
35
- Puppet::Util::Log.newdestination(Puppet::Test::LogCollector.new(arraydest))
36
-
37
- read_string = nil
29
+ Puppet[:log_level] = 'debug'
38
30
 
39
31
  expect {
40
32
  FFI::MemoryPointer.new(:byte, bad_string_bytes.count) do |ptr|
41
33
  # uchar here is synonymous with byte
42
34
  ptr.put_array_of_uchar(0, bad_string_bytes)
43
35
 
44
- read_string = ptr.read_wide_string(bad_string.length)
36
+ ptr.read_wide_string(bad_string.length)
45
37
  end
46
38
  }.to raise_error(Encoding::InvalidByteSequenceError)
47
39
 
48
- expect(read_string).to be_nil
49
- expect(arraydest.last.message).to eq("Unable to convert value #{bad_string.dump} to encoding UTF-8 due to #<Encoding::InvalidByteSequenceError: \"\\xDD\\xDD\" on UTF-16LE>")
40
+ expect(@logs.last.message).to eq("Unable to convert value #{bad_string.dump} to encoding UTF-8 due to #<Encoding::InvalidByteSequenceError: \"\\xDD\\xDD\" on UTF-16LE>")
50
41
  end
51
42
 
52
43
  it "should not raise an error when receiving a string containing invalid bytes in the destination encoding, when specifying :invalid => :replace" do
53
- read_string = nil
54
-
55
44
  FFI::MemoryPointer.new(:byte, bad_string_bytes.count) do |ptr|
56
45
  # uchar here is synonymous with byte
57
46
  ptr.put_array_of_uchar(0, bad_string_bytes)
58
47
 
59
- read_string = ptr.read_wide_string(bad_string.length, Encoding::UTF_8, :invalid => :replace)
48
+ read_string = ptr.read_wide_string(bad_string.length, Encoding::UTF_8, false, :invalid => :replace)
49
+ expect(read_string).to eq("hello invalid world\uFFFD")
60
50
  end
51
+ end
61
52
 
62
- expect(read_string).to eq("hello invalid world\uFFFD")
53
+ it "raises an IndexError if asked to read more characters than there are bytes allocated" do
54
+ expect {
55
+ FFI::MemoryPointer.new(:byte, 1) do |ptr|
56
+ ptr.read_wide_string(1) # 1 wchar = 2 bytes
57
+ end
58
+ }.to raise_error(IndexError, /out of bounds/)
59
+ end
60
+
61
+ it "raises an IndexError if asked to read a negative number of characters" do
62
+ expect {
63
+ FFI::MemoryPointer.new(:byte, 1) do |ptr|
64
+ ptr.read_wide_string(-1)
65
+ end
66
+ }.to raise_error(IndexError, /out of bounds/)
67
+ end
68
+
69
+ it "returns an empty string if asked to read 0 characters" do
70
+ FFI::MemoryPointer.new(:byte, 1) do |ptr|
71
+ expect(ptr.read_wide_string(0)).to eq("")
72
+ end
73
+ end
74
+
75
+ it "returns a substring if asked to read fewer characters than are in the byte array" do
76
+ FFI::MemoryPointer.new(:byte, 4) do |ptr|
77
+ ptr.write_array_of_uint8("AB".encode('UTF-16LE').bytes.to_a)
78
+ expect(ptr.read_wide_string(1)).to eq("A")
79
+ end
80
+ end
81
+
82
+ it "preserves wide null characters in the string" do
83
+ FFI::MemoryPointer.new(:byte, 6) do |ptr|
84
+ ptr.write_array_of_uint8(a_wide_bytes + [0, 0] + b_wide_bytes)
85
+ expect(ptr.read_wide_string(3)).to eq("A\x00B")
86
+ end
63
87
  end
64
88
  end
65
89
 
@@ -69,52 +93,92 @@ describe "FFI::MemoryPointer", :if => Puppet.features.microsoft_windows? do
69
93
  let (:double_null_string) { string + "\x00\x00" }
70
94
 
71
95
  it "should read a short single null terminated string" do
72
- read_string = nil
73
96
  FFI::MemoryPointer.from_string_to_wide_string(single_null_string) do |ptr|
74
- read_string = ptr.read_arbitrary_wide_string_up_to()
97
+ expect(ptr.read_arbitrary_wide_string_up_to).to eq(string)
75
98
  end
76
-
77
- expect(read_string).to eq(string)
78
99
  end
79
100
 
80
101
  it "should read a short double null terminated string" do
81
- read_string = nil
82
102
  FFI::MemoryPointer.from_string_to_wide_string(double_null_string) do |ptr|
83
- read_string = ptr.read_arbitrary_wide_string_up_to(512, :double_null)
103
+ expect(ptr.read_arbitrary_wide_string_up_to(512, :double_null)).to eq(string)
84
104
  end
105
+ end
106
+
107
+ it "detects trailing single null wchar" do
108
+ FFI::MemoryPointer.from_string_to_wide_string(single_null_string) do |ptr|
109
+ expect(ptr).to receive(:read_wide_string).with(string.length, anything, anything, anything).and_call_original
85
110
 
86
- expect(read_string).to eq(string)
111
+ expect(ptr.read_arbitrary_wide_string_up_to).to eq(string)
112
+ end
87
113
  end
88
114
 
89
- it "should return a string of max_length characters when specified" do
90
- read_string = nil
115
+ it "detects trailing double null wchar" do
116
+ FFI::MemoryPointer.from_string_to_wide_string(double_null_string) do |ptr|
117
+ expect(ptr).to receive(:read_wide_string).with(string.length, anything, anything, anything).and_call_original
118
+
119
+ expect(ptr.read_arbitrary_wide_string_up_to(512, :double_null)).to eq(string)
120
+ end
121
+ end
122
+
123
+ it "should raises an IndexError if max_length is negative" do
124
+ FFI::MemoryPointer.from_string_to_wide_string(single_null_string) do |ptr|
125
+ expect {
126
+ ptr.read_arbitrary_wide_string_up_to(-1)
127
+ }.to raise_error(IndexError, /out of bounds/)
128
+ end
129
+ end
130
+
131
+ it "should return an empty string when the max_length is 0" do
91
132
  FFI::MemoryPointer.from_string_to_wide_string(single_null_string) do |ptr|
92
- read_string = ptr.read_arbitrary_wide_string_up_to(3)
133
+ expect(ptr.read_arbitrary_wide_string_up_to(0)).to eq("")
93
134
  end
135
+ end
94
136
 
95
- expect(read_string).to eq(string[0..2])
137
+ it "should return a string of max_length characters when specified" do
138
+ FFI::MemoryPointer.from_string_to_wide_string(single_null_string) do |ptr|
139
+ expect(ptr.read_arbitrary_wide_string_up_to(3)).to eq(string[0..2])
140
+ end
96
141
  end
97
142
 
98
143
  it "should return wide strings in UTF-8" do
99
- read_string = nil
100
144
  FFI::MemoryPointer.from_string_to_wide_string(string) do |ptr|
101
- read_string = ptr.read_arbitrary_wide_string_up_to()
145
+ read_string = ptr.read_arbitrary_wide_string_up_to
146
+ expect(read_string.encoding).to eq(Encoding::UTF_8)
102
147
  end
103
-
104
- expect(read_string.encoding).to eq(Encoding::UTF_8)
105
148
  end
106
149
 
107
150
  it "should not raise an error when receiving a string containing invalid bytes in the destination encoding, when specifying :invalid => :replace" do
108
- read_string = nil
109
-
110
151
  FFI::MemoryPointer.new(:byte, bad_string_bytes.count) do |ptr|
111
152
  # uchar here is synonymous with byte
112
153
  ptr.put_array_of_uchar(0, bad_string_bytes)
113
154
 
114
155
  read_string = ptr.read_arbitrary_wide_string_up_to(ptr.size / 2, :single_null, :invalid => :replace)
156
+ expect(read_string).to eq("hello invalid world\uFFFD")
157
+ end
158
+ end
159
+
160
+ it "should raise an IndexError if there isn't a null terminator" do
161
+ # This only works when using a memory pointer with a known number of cells
162
+ # and size per cell, but not arbitrary Pointers
163
+ FFI::MemoryPointer.new(:wchar, 1) do |ptr|
164
+ ptr.write_array_of_uint8(a_wide_bytes)
165
+
166
+ expect {
167
+ ptr.read_arbitrary_wide_string_up_to(42)
168
+ }.to raise_error(IndexError, /out of bounds/)
115
169
  end
170
+ end
171
+
172
+ it "should raise an IndexError if there isn't a double null terminator" do
173
+ # This only works when using a memory pointer with a known number of cells
174
+ # and size per cell, but not arbitrary Pointers
175
+ FFI::MemoryPointer.new(:wchar, 1) do |ptr|
176
+ ptr.write_array_of_uint8(a_wide_bytes)
116
177
 
117
- expect(read_string).to eq("hello invalid world\uFFFD")
178
+ expect {
179
+ ptr.read_arbitrary_wide_string_up_to(42, :double_null)
180
+ }.to raise_error(IndexError, /out of bounds/)
181
+ end
118
182
  end
119
183
  end
120
184
  end