puppet 3.0.2 → 3.1.0.rc1

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 (320) hide show
  1. data/Gemfile +13 -11
  2. data/README.md +9 -7
  3. data/README_DEVELOPER.md +21 -30
  4. data/bin/extlookup2hiera +0 -0
  5. data/conf/auth.conf +42 -26
  6. data/conf/fileserver.conf +41 -0
  7. data/conf/tagmail.conf +16 -0
  8. data/examples/hiera/modules/data/manifests/common.pp +2 -1
  9. data/examples/hiera/modules/ntp/manifests/config.pp +4 -3
  10. data/examples/hiera/modules/ntp/manifests/data.pp +2 -1
  11. data/examples/hiera/modules/users/manifests/common.pp +2 -1
  12. data/examples/hiera/modules/users/manifests/dc1.pp +2 -1
  13. data/examples/hiera/modules/users/manifests/development.pp +2 -1
  14. data/examples/hiera/site.pp +1 -1
  15. data/ext/debian/fileserver.conf +39 -15
  16. data/ext/envpuppet +2 -0
  17. data/ext/gentoo/puppet/fileserver.conf +41 -12
  18. data/ext/ips/puppet-agent +1 -6
  19. data/ext/ips/puppetagent.xml +0 -4
  20. data/ext/osx/postflight.erb +109 -0
  21. data/ext/project_data.yaml +2 -2
  22. data/ext/redhat/fileserver.conf +41 -12
  23. data/ext/redhat/puppet.spec.erb +8 -13
  24. data/install.rb +2 -5
  25. data/lib/puppet.rb +30 -13
  26. data/lib/puppet/application.rb +34 -16
  27. data/lib/puppet/application/agent.rb +4 -4
  28. data/lib/puppet/application/master.rb +25 -5
  29. data/lib/puppet/defaults.rb +11 -7
  30. data/lib/puppet/dsl.rb +7 -3
  31. data/lib/puppet/dsl/actions.rb +283 -0
  32. data/lib/puppet/dsl/blank_slate.rb +55 -0
  33. data/lib/puppet/dsl/context.rb +393 -0
  34. data/lib/puppet/dsl/parser.rb +57 -0
  35. data/lib/puppet/dsl/resource_decorator.rb +56 -0
  36. data/lib/puppet/dsl/resource_reference.rb +95 -0
  37. data/lib/puppet/dsl/type_reference.rb +102 -0
  38. data/lib/puppet/error.rb +1 -1
  39. data/lib/puppet/face/help.rb +2 -4
  40. data/lib/puppet/face/man.rb +8 -2
  41. data/lib/puppet/feature/pson.rb +1 -3
  42. data/lib/puppet/indirector/catalog/active_record.rb +3 -0
  43. data/lib/puppet/indirector/catalog/compiler.rb +1 -2
  44. data/lib/puppet/indirector/catalog/queue.rb +4 -0
  45. data/lib/puppet/indirector/catalog/static_compiler.rb +30 -0
  46. data/lib/puppet/indirector/catalog/store_configs.rb +3 -0
  47. data/lib/puppet/indirector/certificate_request/rest.rb +1 -0
  48. data/lib/puppet/indirector/certificate_revocation_list/rest.rb +1 -0
  49. data/lib/puppet/indirector/certificate_status/file.rb +4 -0
  50. data/lib/puppet/indirector/certificate_status/rest.rb +1 -0
  51. data/lib/puppet/indirector/facts/active_record.rb +3 -0
  52. data/lib/puppet/indirector/facts/couch.rb +3 -0
  53. data/lib/puppet/indirector/facts/inventory_active_record.rb +4 -0
  54. data/lib/puppet/indirector/facts/store_configs.rb +3 -0
  55. data/lib/puppet/indirector/file_metadata/rest.rb +2 -0
  56. data/lib/puppet/indirector/instrumentation_data/local.rb +3 -0
  57. data/lib/puppet/indirector/instrumentation_data/rest.rb +3 -0
  58. data/lib/puppet/indirector/instrumentation_listener/local.rb +3 -0
  59. data/lib/puppet/indirector/instrumentation_listener/rest.rb +3 -0
  60. data/lib/puppet/indirector/instrumentation_probe/local.rb +3 -0
  61. data/lib/puppet/indirector/instrumentation_probe/rest.rb +3 -0
  62. data/lib/puppet/indirector/node/active_record.rb +3 -0
  63. data/lib/puppet/indirector/node/rest.rb +2 -2
  64. data/lib/puppet/indirector/node/store_configs.rb +3 -0
  65. data/lib/puppet/indirector/node/write_only_yaml.rb +32 -0
  66. data/lib/puppet/indirector/queue.rb +0 -1
  67. data/lib/puppet/indirector/request.rb +1 -2
  68. data/lib/puppet/indirector/resource/active_record.rb +4 -0
  69. data/lib/puppet/indirector/resource/ral.rb +3 -0
  70. data/lib/puppet/indirector/resource/rest.rb +3 -0
  71. data/lib/puppet/indirector/resource/store_configs.rb +3 -0
  72. data/lib/puppet/indirector/run/local.rb +3 -0
  73. data/lib/puppet/indirector/ssl_file.rb +16 -14
  74. data/lib/puppet/indirector/status/local.rb +3 -0
  75. data/lib/puppet/indirector/status/rest.rb +4 -0
  76. data/lib/puppet/interface.rb +78 -3
  77. data/lib/puppet/interface/action.rb +39 -3
  78. data/lib/puppet/interface/action_builder.rb +74 -1
  79. data/lib/puppet/interface/action_manager.rb +33 -3
  80. data/lib/puppet/interface/documentation.rb +116 -5
  81. data/lib/puppet/interface/face_collection.rb +6 -7
  82. data/lib/puppet/interface/option.rb +10 -1
  83. data/lib/puppet/interface/option_builder.rb +29 -1
  84. data/lib/puppet/interface/option_manager.rb +21 -6
  85. data/lib/puppet/metatype/manager.rb +47 -9
  86. data/lib/puppet/module_tool.rb +0 -1
  87. data/lib/puppet/network/formats.rb +0 -2
  88. data/lib/puppet/node.rb +2 -3
  89. data/lib/puppet/node/environment.rb +14 -1
  90. data/lib/puppet/parameter.rb +309 -44
  91. data/lib/puppet/parameter/package_options.rb +5 -0
  92. data/lib/puppet/parameter/path.rb +26 -3
  93. data/lib/puppet/parameter/value.rb +30 -6
  94. data/lib/puppet/parameter/value_collection.rb +82 -20
  95. data/lib/puppet/parser.rb +3 -0
  96. data/lib/puppet/parser/ast/definition.rb +2 -5
  97. data/lib/puppet/parser/ast/hostclass.rb +2 -3
  98. data/lib/puppet/parser/ast/node.rb +2 -5
  99. data/lib/puppet/parser/ast/resourceparam.rb +1 -1
  100. data/lib/puppet/parser/compiler.rb +10 -0
  101. data/lib/puppet/parser/functions.rb +111 -7
  102. data/lib/puppet/parser/functions/create_resources.rb +23 -2
  103. data/lib/puppet/parser/functions/defined.rb +1 -1
  104. data/lib/puppet/parser/functions/extlookup.rb +2 -1
  105. data/lib/puppet/parser/functions/fail.rb +1 -1
  106. data/lib/puppet/parser/functions/file.rb +1 -1
  107. data/lib/puppet/parser/functions/fqdn_rand.rb +1 -1
  108. data/lib/puppet/parser/functions/generate.rb +1 -1
  109. data/lib/puppet/parser/functions/hiera.rb +1 -1
  110. data/lib/puppet/parser/functions/hiera_array.rb +1 -1
  111. data/lib/puppet/parser/functions/hiera_hash.rb +1 -1
  112. data/lib/puppet/parser/functions/hiera_include.rb +1 -1
  113. data/lib/puppet/parser/functions/include.rb +1 -1
  114. data/lib/puppet/parser/functions/inline_template.rb +1 -1
  115. data/lib/puppet/parser/functions/md5.rb +1 -1
  116. data/lib/puppet/parser/functions/realize.rb +1 -1
  117. data/lib/puppet/parser/functions/regsubst.rb +54 -57
  118. data/lib/puppet/parser/functions/require.rb +1 -0
  119. data/lib/puppet/parser/functions/search.rb +1 -1
  120. data/lib/puppet/parser/functions/sha1.rb +1 -1
  121. data/lib/puppet/parser/functions/shellquote.rb +1 -1
  122. data/lib/puppet/parser/functions/split.rb +1 -2
  123. data/lib/puppet/parser/functions/sprintf.rb +7 -10
  124. data/lib/puppet/parser/functions/tag.rb +1 -1
  125. data/lib/puppet/parser/functions/tagged.rb +1 -1
  126. data/lib/puppet/parser/functions/template.rb +1 -1
  127. data/lib/puppet/parser/functions/versioncmp.rb +1 -5
  128. data/lib/puppet/parser/parser_support.rb +11 -27
  129. data/lib/puppet/parser/scope.rb +48 -4
  130. data/lib/puppet/parser/type_loader.rb +31 -7
  131. data/lib/puppet/property.rb +304 -70
  132. data/lib/puppet/property/ensure.rb +14 -1
  133. data/lib/puppet/property/keyvalue.rb +17 -8
  134. data/lib/puppet/property/list.rb +3 -0
  135. data/lib/puppet/property/ordered_list.rb +7 -0
  136. data/lib/puppet/provider.rb +275 -53
  137. data/lib/puppet/provider/augeas/augeas.rb +17 -3
  138. data/lib/puppet/provider/confiner.rb +30 -1
  139. data/lib/puppet/provider/group/pw.rb +2 -2
  140. data/lib/puppet/provider/package/pip.rb +0 -1
  141. data/lib/puppet/provider/package/pkgin.rb +2 -0
  142. data/lib/puppet/provider/service/bsd.rb +1 -1
  143. data/lib/puppet/provider/service/freebsd.rb +10 -6
  144. data/lib/puppet/provider/service/init.rb +1 -1
  145. data/lib/puppet/provider/service/service.rb +1 -1
  146. data/lib/puppet/provider/user/pw.rb +2 -2
  147. data/lib/puppet/provider/user/useradd.rb +2 -3
  148. data/lib/puppet/reference/configuration.rb +6 -0
  149. data/lib/puppet/reports.rb +44 -4
  150. data/lib/puppet/reports/tagmail.rb +1 -1
  151. data/lib/puppet/resource.rb +38 -25
  152. data/lib/puppet/resource/type.rb +14 -6
  153. data/lib/puppet/settings.rb +66 -142
  154. data/lib/puppet/settings/config_file.rb +99 -0
  155. data/lib/puppet/settings/file_setting.rb +92 -24
  156. data/lib/puppet/settings/value_translator.rb +15 -0
  157. data/lib/puppet/ssl/certificate_authority/interface.rb +2 -2
  158. data/lib/puppet/test/test_helper.rb +8 -3
  159. data/lib/puppet/transaction.rb +1 -2
  160. data/lib/puppet/transaction/report.rb +122 -13
  161. data/lib/puppet/type.rb +763 -150
  162. data/lib/puppet/type/augeas.rb +4 -0
  163. data/lib/puppet/type/file/ensure.rb +1 -1
  164. data/lib/puppet/type/file/group.rb +1 -1
  165. data/lib/puppet/type/file/mode.rb +2 -0
  166. data/lib/puppet/type/file/selcontext.rb +1 -0
  167. data/lib/puppet/type/group.rb +12 -0
  168. data/lib/puppet/type/mount.rb +2 -2
  169. data/lib/puppet/type/notify.rb +1 -1
  170. data/lib/puppet/type/router.rb +1 -1
  171. data/lib/puppet/type/service.rb +1 -0
  172. data/lib/puppet/type/ssh_authorized_key.rb +3 -1
  173. data/lib/puppet/type/user.rb +8 -1
  174. data/lib/puppet/util.rb +8 -0
  175. data/lib/puppet/util/autoload.rb +7 -10
  176. data/lib/puppet/util/classgen.rb +58 -33
  177. data/lib/puppet/util/command_line.rb +120 -77
  178. data/lib/puppet/util/constant_inflector.rb +2 -0
  179. data/lib/puppet/util/execution.rb +63 -33
  180. data/lib/puppet/util/filetype.rb +1 -1
  181. data/lib/puppet/util/manifest_filetype_helper.rb +22 -0
  182. data/lib/puppet/util/methodhelper.rb +19 -0
  183. data/lib/puppet/util/monkey_patches.rb +46 -0
  184. data/lib/puppet/util/plugins.rb +2 -2
  185. data/lib/puppet/util/provider_features.rb +24 -8
  186. data/lib/puppet/util/rubygems.rb +8 -1
  187. data/lib/puppet/util/zaml.rb +1 -1
  188. data/lib/puppet/version.rb +74 -3
  189. data/spec/integration/application/apply_spec.rb +1 -1
  190. data/spec/integration/defaults_spec.rb +1 -0
  191. data/spec/integration/dsl/classes_spec.rb +191 -0
  192. data/spec/integration/dsl/defaults_spec.rb +38 -0
  193. data/spec/integration/dsl/definitions_spec.rb +73 -0
  194. data/spec/integration/dsl/functions_spec.rb +95 -0
  195. data/spec/integration/dsl/nodes_spec.rb +96 -0
  196. data/spec/integration/dsl/params_spec.rb +146 -0
  197. data/spec/integration/dsl/relationships_spec.rb +46 -0
  198. data/spec/integration/dsl/resources_spec.rb +202 -0
  199. data/spec/integration/dsl/type_loading_spec.rb +64 -0
  200. data/spec/integration/indirector/catalog/queue_spec.rb +1 -1
  201. data/spec/integration/network/formats_spec.rb +32 -45
  202. data/spec/integration/parser/collector_spec.rb +105 -25
  203. data/spec/integration/parser/scope_spec.rb +64 -1
  204. data/spec/integration/resource/catalog_spec.rb +2 -4
  205. data/spec/integration/type/package_spec.rb +1 -1
  206. data/spec/lib/matchers/catalog.rb +50 -0
  207. data/spec/lib/puppet_spec/compiler.rb +11 -0
  208. data/spec/lib/puppet_spec/dsl.rb +29 -0
  209. data/spec/spec_helper.rb +17 -3
  210. data/spec/unit/application/agent_spec.rb +0 -1
  211. data/spec/unit/application/apply_spec.rb +1 -1
  212. data/spec/unit/application/face_base_spec.rb +11 -4
  213. data/spec/unit/application/indirection_base_spec.rb +4 -8
  214. data/spec/unit/application/kick_spec.rb +5 -2
  215. data/spec/unit/application/master_spec.rb +0 -6
  216. data/spec/unit/application_spec.rb +38 -14
  217. data/spec/unit/dsl/actions_spec.rb +402 -0
  218. data/spec/unit/dsl/blank_slate_spec.rb +27 -0
  219. data/spec/unit/dsl/context_spec.rb +678 -0
  220. data/spec/unit/dsl/parser_spec.rb +56 -0
  221. data/spec/unit/dsl/resource_decorator_spec.rb +94 -0
  222. data/spec/unit/dsl/resource_reference_spec.rb +150 -0
  223. data/spec/unit/dsl/type_reference_spec.rb +164 -0
  224. data/spec/unit/face/help_spec.rb +5 -7
  225. data/spec/unit/indirector/certificate_request/rest_spec.rb +4 -0
  226. data/spec/unit/indirector/certificate_revocation_list/rest_spec.rb +4 -0
  227. data/spec/unit/indirector/certificate_status/rest_spec.rb +4 -0
  228. data/spec/unit/indirector/file_metadata/rest_spec.rb +5 -0
  229. data/spec/unit/indirector/hiera_spec.rb +3 -1
  230. data/spec/unit/indirector/queue_spec.rb +1 -7
  231. data/spec/unit/indirector/ssl_file_spec.rb +66 -39
  232. data/spec/unit/module_spec.rb +1 -1
  233. data/spec/unit/network/authstore_spec.rb +22 -1
  234. data/spec/unit/network/formats_spec.rb +1 -1
  235. data/spec/unit/node/environment_spec.rb +13 -0
  236. data/spec/unit/parser/collector_spec.rb +1 -1
  237. data/spec/unit/parser/compiler_spec.rb +26 -0
  238. data/spec/unit/parser/functions/create_resources_spec.rb +12 -1
  239. data/spec/unit/parser/functions/extlookup_spec.rb +4 -4
  240. data/spec/unit/parser/functions/hiera_array_spec.rb +1 -1
  241. data/spec/unit/parser/functions/hiera_hash_spec.rb +1 -1
  242. data/spec/unit/parser/functions/hiera_include_spec.rb +1 -1
  243. data/spec/unit/parser/functions/hiera_spec.rb +1 -1
  244. data/spec/unit/parser/functions/regsubst_spec.rb +4 -4
  245. data/spec/unit/parser/functions/split_spec.rb +4 -4
  246. data/spec/unit/parser/functions/sprintf_spec.rb +2 -2
  247. data/spec/unit/parser/functions/versioncmp_spec.rb +4 -4
  248. data/spec/unit/parser/functions_spec.rb +51 -1
  249. data/spec/unit/parser/parser_spec.rb +0 -14
  250. data/spec/unit/parser/type_loader_spec.rb +15 -1
  251. data/spec/unit/provider/augeas/augeas_spec.rb +31 -0
  252. data/spec/unit/provider/package/apt_spec.rb +0 -2
  253. data/spec/unit/provider/package/pip_spec.rb +12 -2
  254. data/spec/unit/provider/service/freebsd_spec.rb +8 -0
  255. data/spec/unit/provider/service/gentoo_spec.rb +20 -20
  256. data/spec/unit/provider/service/openrc_spec.rb +20 -20
  257. data/spec/unit/provider/service/src_spec.rb +4 -4
  258. data/spec/unit/provider/service/systemd_spec.rb +0 -8
  259. data/spec/unit/provider/service/windows_spec.rb +1 -1
  260. data/spec/unit/provider/user/useradd_spec.rb +2 -9
  261. data/spec/unit/relationship_spec.rb +2 -2
  262. data/spec/unit/resource/catalog_spec.rb +2 -2
  263. data/spec/unit/resource/type_spec.rb +49 -25
  264. data/spec/unit/resource_spec.rb +34 -2
  265. data/spec/unit/settings/config_file_spec.rb +100 -0
  266. data/spec/unit/settings/file_setting_spec.rb +87 -84
  267. data/spec/unit/settings/value_translator_spec.rb +77 -0
  268. data/spec/unit/settings_spec.rb +96 -29
  269. data/spec/unit/type/file/ensure_spec.rb +75 -36
  270. data/spec/unit/type/file_spec.rb +0 -68
  271. data/spec/unit/type/group_spec.rb +10 -0
  272. data/spec/unit/util/autoload_spec.rb +6 -0
  273. data/spec/unit/util/command_line_spec.rb +54 -62
  274. data/spec/unit/util/manifest_filetype_helper_spec.rb +29 -0
  275. data/spec/unit/util/metric_spec.rb +0 -9
  276. data/spec/unit/util/posix_spec.rb +0 -4
  277. data/spec/unit/util/rdoc_spec.rb +0 -12
  278. data/spec/unit/util/zaml_spec.rb +188 -130
  279. data/spec/unit/version_spec.rb +42 -0
  280. metadata +123 -90
  281. data/README_HIERA.md +0 -148
  282. data/conf/epm.list +0 -8
  283. data/conf/namespaceauth.conf +0 -20
  284. data/conf/puppet-queue.conf +0 -10
  285. data/examples/allatonce +0 -13
  286. data/examples/assignments +0 -11
  287. data/examples/components +0 -73
  288. data/examples/etc/init.d/sleeper +0 -70
  289. data/examples/etc/otherfile +0 -0
  290. data/examples/etc/puppet/fileserver.conf +0 -13
  291. data/examples/etc/puppet/namespaceauth.conf +0 -20
  292. data/examples/etc/puppet/puppet.conf +0 -10
  293. data/examples/etc/puppet/tagmail.conf +0 -1
  294. data/examples/execs +0 -16
  295. data/examples/file.bl +0 -11
  296. data/examples/filedefaults +0 -10
  297. data/examples/fileparsing +0 -116
  298. data/examples/filerecursion +0 -15
  299. data/examples/functions +0 -3
  300. data/examples/groups +0 -7
  301. data/examples/head +0 -30
  302. data/examples/importing +0 -8
  303. data/examples/mac_dscl.pp +0 -28
  304. data/examples/mac_dscl_revert.pp +0 -26
  305. data/examples/mac_pkgdmg.pp +0 -7
  306. data/examples/modules/sample_module.pp +0 -10
  307. data/examples/modules/sample_module/lib/puppet/parser/functions/hostname_to_dn.rb +0 -36
  308. data/examples/modules/sample_module/manifests/init.pp +0 -12
  309. data/examples/modules/sample_module/templates/sample.erb +0 -5
  310. data/examples/nodes +0 -20
  311. data/examples/one +0 -8
  312. data/examples/relationships +0 -34
  313. data/examples/selectors +0 -28
  314. data/examples/simpletests +0 -11
  315. data/examples/svncommit +0 -13
  316. data/lib/puppet/dsl/resource_api.rb +0 -120
  317. data/lib/puppet/dsl/resource_type_api.rb +0 -34
  318. data/spec/integration/parser/ruby_manifest_spec.rb +0 -127
  319. data/spec/unit/dsl/resource_api_spec.rb +0 -180
  320. data/spec/unit/dsl/resource_type_api_spec.rb +0 -53
@@ -51,4 +51,14 @@ describe Puppet::Type.type(:group) do
51
51
  group.provider.expects(:delete)
52
52
  group.parameter(:ensure).sync
53
53
  end
54
+
55
+ it "delegates the existance check to its provider" do
56
+ provider = @class.provide(:testing) {}
57
+ provider_instance = provider.new
58
+ provider_instance.expects(:exists?).returns true
59
+
60
+ type = @class.new(:name => "group", :provider => provider_instance)
61
+
62
+ type.exists?.should == true
63
+ end
54
64
  end
@@ -262,4 +262,10 @@ describe Puppet::Util::Autoload do
262
262
  end
263
263
  end
264
264
  end
265
+
266
+ describe "#expand" do
267
+ it "should expand relative to the autoloader's prefix" do
268
+ @autoload.expand('bar').should == 'tmp/bar'
269
+ end
270
+ end
265
271
  end
@@ -6,64 +6,62 @@ require 'puppet/util/command_line'
6
6
 
7
7
  describe Puppet::Util::CommandLine do
8
8
  include PuppetSpec::Files
9
- let :tty do stub("tty", :tty? => true) end
10
- let :pipe do stub("pipe", :tty? => false) end
11
9
 
12
10
  context "#initialize" do
13
11
  it "should pull off the first argument if it looks like a subcommand" do
14
- command_line = Puppet::Util::CommandLine.new("puppet", %w{ client --help whatever.pp }, tty)
12
+ command_line = Puppet::Util::CommandLine.new("puppet", %w{ client --help whatever.pp })
15
13
 
16
14
  command_line.subcommand_name.should == "client"
17
15
  command_line.args.should == %w{ --help whatever.pp }
18
16
  end
19
17
 
20
18
  it "should return nil if the first argument looks like a .pp file" do
21
- command_line = Puppet::Util::CommandLine.new("puppet", %w{ whatever.pp }, tty)
19
+ command_line = Puppet::Util::CommandLine.new("puppet", %w{ whatever.pp })
22
20
 
23
21
  command_line.subcommand_name.should == nil
24
22
  command_line.args.should == %w{ whatever.pp }
25
23
  end
26
24
 
27
25
  it "should return nil if the first argument looks like a .rb file" do
28
- command_line = Puppet::Util::CommandLine.new("puppet", %w{ whatever.rb }, tty)
26
+ command_line = Puppet::Util::CommandLine.new("puppet", %w{ whatever.rb })
29
27
 
30
28
  command_line.subcommand_name.should == nil
31
29
  command_line.args.should == %w{ whatever.rb }
32
30
  end
33
31
 
34
32
  it "should return nil if the first argument looks like a flag" do
35
- command_line = Puppet::Util::CommandLine.new("puppet", %w{ --debug }, tty)
33
+ command_line = Puppet::Util::CommandLine.new("puppet", %w{ --debug })
36
34
 
37
35
  command_line.subcommand_name.should == nil
38
36
  command_line.args.should == %w{ --debug }
39
37
  end
40
38
 
41
39
  it "should return nil if the first argument is -" do
42
- command_line = Puppet::Util::CommandLine.new("puppet", %w{ - }, tty)
40
+ command_line = Puppet::Util::CommandLine.new("puppet", %w{ - })
43
41
 
44
42
  command_line.subcommand_name.should == nil
45
43
  command_line.args.should == %w{ - }
46
44
  end
47
45
 
48
46
  it "should return nil if the first argument is --help" do
49
- command_line = Puppet::Util::CommandLine.new("puppet", %w{ --help }, tty)
47
+ command_line = Puppet::Util::CommandLine.new("puppet", %w{ --help })
50
48
 
51
49
  command_line.subcommand_name.should == nil
52
50
  end
53
51
 
54
52
 
55
- it "should return nil if there are no arguments on a tty" do
56
- command_line = Puppet::Util::CommandLine.new("puppet", [], tty)
53
+ it "should return nil if there are no arguments" do
54
+ command_line = Puppet::Util::CommandLine.new("puppet", [])
57
55
 
58
56
  command_line.subcommand_name.should == nil
59
57
  command_line.args.should == []
60
58
  end
61
59
 
62
- it "should return nil if there are no arguments on a pipe" do
63
- command_line = Puppet::Util::CommandLine.new("puppet", [], pipe)
64
-
65
- command_line.subcommand_name.should == nil
66
- command_line.args.should == []
60
+ it "should pick up changes to the array of arguments" do
61
+ args = %w{subcommand}
62
+ command_line = Puppet::Util::CommandLine.new("puppet", args)
63
+ args[0] = 'different_subcommand'
64
+ command_line.subcommand_name.should == 'different_subcommand'
67
65
  end
68
66
  end
69
67
 
@@ -71,40 +69,32 @@ describe Puppet::Util::CommandLine do
71
69
  %w{--version -V}.each do |arg|
72
70
  it "should print the version and exit if #{arg} is given" do
73
71
  expect do
74
- described_class.new("puppet", [arg], tty).execute
75
- end.to have_printed(Puppet.version)
72
+ described_class.new("puppet", [arg]).execute
73
+ end.to have_printed(/^#{Puppet.version}$/)
76
74
  end
77
75
  end
78
76
  end
79
77
 
80
78
  describe "when dealing with puppet commands" do
81
79
  it "should return the executable name if it is not puppet" do
82
- command_line = Puppet::Util::CommandLine.new("puppetmasterd", [], tty)
80
+ command_line = Puppet::Util::CommandLine.new("puppetmasterd", [])
83
81
  command_line.subcommand_name.should == "puppetmasterd"
84
82
  end
85
83
 
86
84
  describe "when the subcommand is not implemented" do
87
85
  it "should find and invoke an executable with a hyphenated name" do
88
- commandline = Puppet::Util::CommandLine.new("puppet", ['whatever', 'argument'], tty)
86
+ commandline = Puppet::Util::CommandLine.new("puppet", ['whatever', 'argument'])
89
87
  Puppet::Util.expects(:which).with('puppet-whatever').
90
88
  returns('/dev/null/puppet-whatever')
91
89
 
92
- # It is important that we abort at the point exec is called, because
93
- # the code (reasonably) assumes that if `exec` is called processing
94
- # immediately terminates, and we are replaced by the executed process.
95
- #
96
- # This raise isn't a perfect simulation of that, but it is enough to
97
- # validate that the system works, and ... well, if exec is broken we
98
- # have two problems, y'know.
99
- commandline.expects(:exec).with('/dev/null/puppet-whatever', 'argument').
100
- raises(SystemExit)
101
-
102
- expect { commandline.execute }.to raise_error SystemExit
90
+ Kernel.expects(:exec).with('/dev/null/puppet-whatever', 'argument')
91
+
92
+ commandline.execute
103
93
  end
104
94
 
105
95
  describe "and an external implementation cannot be found" do
106
96
  it "should abort and show the usage message" do
107
- commandline = Puppet::Util::CommandLine.new("puppet", ['whatever', 'argument'], tty)
97
+ commandline = Puppet::Util::CommandLine.new("puppet", ['whatever', 'argument'])
108
98
  Puppet::Util.expects(:which).with('puppet-whatever').returns(nil)
109
99
  commandline.expects(:exec).never
110
100
 
@@ -112,43 +102,45 @@ describe Puppet::Util::CommandLine do
112
102
  commandline.execute
113
103
  }.to have_printed(/Unknown Puppet subcommand 'whatever'/)
114
104
  end
105
+
106
+ it "should abort and show the help message" do
107
+ commandline = Puppet::Util::CommandLine.new("puppet", ['whatever', 'argument'])
108
+ Puppet::Util.expects(:which).with('puppet-whatever').returns(nil)
109
+ commandline.expects(:exec).never
110
+
111
+ expect {
112
+ commandline.execute
113
+ }.to have_printed(/See 'puppet help' for help on available puppet subcommands/)
114
+ end
115
+
116
+ %w{--version -V}.each do |arg|
117
+ it "should abort and display #{arg} information" do
118
+ commandline = Puppet::Util::CommandLine.new("puppet", ['whatever', arg])
119
+ Puppet::Util.expects(:which).with('puppet-whatever').returns(nil)
120
+ commandline.expects(:exec).never
121
+
122
+ expect {
123
+ commandline.execute
124
+ }.to have_printed(/^#{Puppet.version}$/)
125
+ end
126
+ end
115
127
  end
116
128
  end
129
+
117
130
  describe 'when loading commands' do
118
- let :core_apps do
119
- %w{describe filebucket kick queue resource agent cert apply doc master}
120
- end
131
+ it "should deprecate the available_subcommands instance method" do
132
+ Puppet::Application.expects(:available_application_names)
133
+ Puppet.expects(:deprecation_warning).with("Puppet::Util::CommandLine#available_subcommands is deprecated; please use Puppet::Application.available_application_names instead.")
121
134
 
122
- let :command_line do
123
- Puppet::Util::CommandLine.new("foo", %w{ client --help whatever.pp }, tty)
135
+ command_line = Puppet::Util::CommandLine.new("foo", %w{ client --help whatever.pp })
136
+ command_line.available_subcommands
124
137
  end
125
138
 
126
- it "should expose available_subcommands as a class method" do
127
- core_apps.each do |command|
128
- command_line.available_subcommands.should include command
129
- end
130
- end
131
- it 'should be able to find all existing commands' do
132
- core_apps.each do |command|
133
- command_line.available_subcommands.should include command
134
- end
135
- end
136
- describe 'when multiple paths have applications' do
137
- before do
138
- @dir=tmpdir('command_line_plugin_test')
139
- @appdir="#{@dir}/puppet/application"
140
- FileUtils.mkdir_p(@appdir)
141
- FileUtils.touch("#{@appdir}/foo.rb")
142
- $LOAD_PATH.unshift(@dir) # WARNING: MUST MATCH THE AFTER ACTIONS!
143
- end
144
- it 'should be able to find commands from both paths' do
145
- found = command_line.available_subcommands
146
- found.should include 'foo'
147
- core_apps.each { |cmd| found.should include cmd }
148
- end
149
- after do
150
- $LOAD_PATH.shift # WARNING: MUST MATCH THE BEFORE ACTIONS!
151
- end
139
+ it "should deprecate the available_subcommands class method" do
140
+ Puppet::Application.expects(:available_application_names)
141
+ Puppet.expects(:deprecation_warning).with("Puppet::Util::CommandLine.available_subcommands is deprecated; please use Puppet::Application.available_application_names instead.")
142
+
143
+ Puppet::Util::CommandLine.available_subcommands
152
144
  end
153
145
  end
154
146
  end
@@ -0,0 +1,29 @@
1
+ require 'spec_helper'
2
+
3
+ require 'puppet/util/manifest_filetype_helper'
4
+
5
+ describe Puppet::Util::ManifestFiletypeHelper do
6
+ subject { Object.new.extend Puppet::Util::ManifestFiletypeHelper }
7
+
8
+ describe "#is_ruby_filename?" do
9
+ it "returns true when Ruby filename is passed as an argument" do
10
+ subject.is_ruby_filename?("test.rb").should be true
11
+ end
12
+
13
+ it "returns false when not Ruby filename is passed as an argument" do
14
+ subject.is_ruby_filename?("test").should be false
15
+ end
16
+ end
17
+
18
+ describe "#is_puppet_filename?" do
19
+ it "returns true when Puppet filename is passed as an argument" do
20
+ subject.is_puppet_filename?("test.pp").should be true
21
+ end
22
+
23
+ it "returns false when non-Puppet filename is passed as an argument" do
24
+ subject.is_puppet_filename?("test").should be false
25
+ end
26
+ end
27
+
28
+ end
29
+
@@ -83,13 +83,4 @@ describe Puppet::Util::Metric do
83
83
  it "should return nil if the named value cannot be found" do
84
84
  @metric["foo"].should == 0
85
85
  end
86
-
87
- # LAK: I'm not taking the time to develop these tests right now.
88
- # I expect they should actually be extracted into a separate class
89
- # anyway.
90
- it "should be able to graph metrics using RRDTool"
91
-
92
- it "should be able to create a new RRDTool database"
93
-
94
- it "should be able to store metrics into an RRDTool database"
95
86
  end
@@ -248,8 +248,4 @@ describe Puppet::Util::POSIX do
248
248
  it "should be able to iteratively search for posix values" do
249
249
  @posix.should respond_to(:search_posix_field)
250
250
  end
251
-
252
- describe "when searching for posix values iteratively" do
253
- it "should iterate across all of the structs returned by Etc and return the appropriate field from the first matching value"
254
- end
255
251
  end
@@ -142,18 +142,6 @@ describe Puppet::Util::RDoc do
142
142
  # any other output must fail
143
143
  Puppet::Util::RDoc.manifestdoc([my_fixture('basic.pp')])
144
144
  end
145
-
146
- it "should output resource documentation if needed" do
147
- pending "#6634 being fixed"
148
- Puppet.settings[:document_all] = true
149
- byline = sequence('documentation outputs in line order')
150
- Puppet::Util::RDoc.expects(:puts).with("im a class\n").in_sequence(byline)
151
- Puppet::Util::RDoc.expects(:puts).with("im a node\n").in_sequence(byline)
152
- Puppet::Util::RDoc.expects(:puts).with("im a define\n").in_sequence(byline)
153
- Puppet::Util::RDoc.expects(:puts).with("im a resource\n").in_sequence(byline)
154
- # any other output must fail
155
- Puppet::Util::RDoc.manifestdoc([my_fixture('basic.pp')])
156
- end
157
145
  end
158
146
  end
159
147
  end
@@ -16,8 +16,24 @@ require 'spec_helper'
16
16
  require 'puppet/util/monkey_patches'
17
17
 
18
18
  describe "Pure ruby yaml implementation" do
19
- def can_round_trip(value)
20
- YAML.load(value.to_yaml).should == value
19
+ RSpec::Matchers.define :round_trip_through_yaml do
20
+ match do |object|
21
+ YAML.load(object.to_yaml) == object
22
+ end
23
+ end
24
+
25
+ RSpec::Matchers.define :be_equivalent_to do |expected_yaml|
26
+ match do |object|
27
+ object.to_yaml == expected_yaml and YAML.load(expected_yaml) == object
28
+ end
29
+
30
+ failure_message_for_should do |object|
31
+ if object.to_yaml != expected_yaml
32
+ "#{object} serialized to #{object.to_yaml}"
33
+ else
34
+ "#{expected_yaml} deserialized as #{YAML.load(expected_yaml)}"
35
+ end
36
+ end
21
37
  end
22
38
 
23
39
  {
@@ -34,14 +50,67 @@ describe "Pure ruby yaml implementation" do
34
50
  [] => "--- []",
35
51
  :symbol => "--- !ruby/sym symbol",
36
52
  {:a => "A"} => "--- \n !ruby/sym a: A",
37
- {:a => "x\ny"} => "--- \n !ruby/sym a: |-\n x\n y"
53
+ {:a => "x\ny"} => "--- \n !ruby/sym a: |-\n x\n y",
38
54
  }.each do |data, serialized|
39
55
  it "should convert the #{data.class} #{data.inspect} to yaml" do
40
- data.to_yaml.should == serialized
56
+ data.should be_equivalent_to serialized
57
+ end
58
+ end
59
+
60
+ context Time do
61
+ def the_time_in(timezone)
62
+ Puppet::Util.withenv("TZ" => timezone) do
63
+ Time.local(2012, "dec", 11, 15, 59, 2)
64
+ end
65
+ end
66
+
67
+ def the_time_in_yaml_offset_by(offset)
68
+ "--- 2012-12-11 15:59:02.000000 #{offset}"
69
+ end
70
+
71
+ it "serializes a time in UTC" do
72
+ pending("not supported on Windows", :if => Puppet.features.microsoft_windows?) do
73
+ the_time_in("Europe/London").should be_equivalent_to(the_time_in_yaml_offset_by("+00:00"))
74
+ end
75
+ end
76
+
77
+ it "serializes a time behind UTC" do
78
+ pending("not supported on Windows", :if => Puppet.features.microsoft_windows?) do
79
+ the_time_in("America/Chicago").should be_equivalent_to(the_time_in_yaml_offset_by("-06:00"))
80
+ end
41
81
  end
42
82
 
43
- it "should produce yaml for the #{data.class} #{data.inspect} that can be reconstituted" do
44
- can_round_trip data
83
+ it "serializes a time behind UTC that is not a complete hour (Bug #15496)" do
84
+ pending("not supported on Windows", :if => Puppet.features.microsoft_windows?) do
85
+ the_time_in("America/Caracas").should be_equivalent_to(the_time_in_yaml_offset_by("-04:30"))
86
+ end
87
+ end
88
+
89
+ it "serializes a time ahead of UTC" do
90
+ pending("not supported on Windows", :if => Puppet.features.microsoft_windows?) do
91
+ the_time_in("Europe/Berlin").should be_equivalent_to(the_time_in_yaml_offset_by("+01:00"))
92
+ end
93
+ end
94
+
95
+ it "serializes a time ahead of UTC that is not a complete hour" do
96
+ pending("not supported on Windows", :if => Puppet.features.microsoft_windows?) do
97
+ the_time_in("Asia/Kathmandu").should be_equivalent_to(the_time_in_yaml_offset_by("+05:45"))
98
+ end
99
+ end
100
+
101
+ it "serializes a time more than 12 hours ahead of UTC" do
102
+ pending("not supported on Windows", :if => Puppet.features.microsoft_windows?) do
103
+ the_time_in("Pacific/Kiritimati").should be_equivalent_to(the_time_in_yaml_offset_by("+14:00"))
104
+ end
105
+ end
106
+
107
+ it "should roundtrip Time.now" do
108
+ tm = Time.now
109
+ # yaml only emits 6 digits of precision, but on some systems with ruby 1.9
110
+ # the original time object may contain nanoseconds, which will cause
111
+ # the equality check to fail. So truncate the time object to only microsecs
112
+ tm = Time.at(tm.to_i, tm.usec)
113
+ tm.should round_trip_through_yaml
45
114
  end
46
115
  end
47
116
 
@@ -63,7 +132,7 @@ describe "Pure ruby yaml implementation" do
63
132
  { "b:" => { "a" => [] } }
64
133
  ].each do |value|
65
134
  it "properly escapes #{value.inspect}, which contains YAML characters" do
66
- can_round_trip value
135
+ value.should round_trip_through_yaml
67
136
  end
68
137
  end
69
138
 
@@ -88,11 +157,7 @@ describe "Pure ruby yaml implementation" do
88
157
  x = [1, 2]
89
158
  y = [3, 4]
90
159
  z = [x, y, x, y]
91
- z.to_yaml.should == "--- \n - &id001\n - 1\n - 2\n - &id002\n - 3\n - 4\n - *id001\n - *id002"
92
- z2 = YAML.load(z.to_yaml)
93
- z2.should == z
94
- z2[0].should equal(z2[2])
95
- z2[1].should equal(z2[3])
160
+ z.should be_equivalent_to("--- \n - &id001\n - 1\n - 2\n - &id002\n - 3\n - 4\n - *id001\n - *id002")
96
161
  end
97
162
 
98
163
  it "should emit proper labels and backreferences for recursive objects" do
@@ -106,141 +171,134 @@ describe "Pure ruby yaml implementation" do
106
171
  x2[1].should == 2
107
172
  x2[2].should equal(x2)
108
173
  end
109
- end
110
-
111
- # Note, many of these tests will pass on Ruby 1.8 but fail on 1.9 if the patch
112
- # fix is not applied to Puppet or there's a regression. These version
113
- # dependant failures are intentional since the string encoding behavior changed
114
- # significantly in 1.9.
115
- describe "UTF-8 encoded String#to_yaml (Bug #11246)" do
116
- # JJM All of these snowmen are different representations of the same
117
- # UTF-8 encoded string.
118
- let(:snowman) { 'Snowman: [☃]' }
119
- let(:snowman_escaped) { "Snowman: [\xE2\x98\x83]" }
120
174
 
121
- describe "UTF-8 String Literal" do
122
- subject { snowman }
175
+ # Note, many of these tests will pass on Ruby 1.8 but fail on 1.9 if the patch
176
+ # fix is not applied to Puppet or there's a regression. These version
177
+ # dependant failures are intentional since the string encoding behavior changed
178
+ # significantly in 1.9.
179
+ context "UTF-8 encoded String#to_yaml (Bug #11246)" do
180
+ # JJM All of these snowmen are different representations of the same
181
+ # UTF-8 encoded string.
182
+ let(:snowman) { 'Snowman: [☃]' }
183
+ let(:snowman_escaped) { "Snowman: [\xE2\x98\x83]" }
123
184
 
124
- it "should serialize to YAML" do
125
- subject.to_yaml
126
- end
127
185
  it "should serialize and deserialize to the same thing" do
128
- YAML.load(subject.to_yaml).should == subject
186
+ snowman.should round_trip_through_yaml
129
187
  end
188
+
130
189
  it "should serialize and deserialize to a String compatible with a UTF-8 encoded Regexp" do
131
- YAML.load(subject.to_yaml).should =~ /☃/u
190
+ YAML.load(snowman.to_yaml).should =~ /☃/u
132
191
  end
133
192
  end
134
- end
135
193
 
136
- describe "binary data" do
137
- subject { "M\xC0\xDF\xE5tt\xF6" }
194
+ context "binary data" do
195
+ subject { "M\xC0\xDF\xE5tt\xF6" }
138
196
 
139
- if String.method_defined?(:encoding)
140
- def binary(str)
141
- str.force_encoding('binary')
197
+ if String.method_defined?(:encoding)
198
+ def binary(str)
199
+ str.force_encoding('binary')
200
+ end
201
+ else
202
+ def binary(str)
203
+ str
204
+ end
142
205
  end
143
- else
144
- def binary(str)
145
- str
146
- end
147
- end
148
206
 
149
- it "should not explode encoding binary data" do
150
- expect { subject.to_yaml }.not_to raise_error
151
- end
207
+ it "should not explode encoding binary data" do
208
+ expect { subject.to_yaml }.not_to raise_error
209
+ end
152
210
 
153
- it "should mark the binary data as binary" do
154
- subject.to_yaml.should =~ /!binary/
155
- end
211
+ it "should mark the binary data as binary" do
212
+ subject.to_yaml.should =~ /!binary/
213
+ end
156
214
 
157
- it "should round-trip the data" do
158
- yaml = subject.to_yaml
159
- read = YAML.load(yaml)
160
- binary(read).should == binary(subject)
161
- end
215
+ it "should round-trip the data" do
216
+ yaml = subject.to_yaml
217
+ read = YAML.load(yaml)
218
+ binary(read).should == binary(subject)
219
+ end
162
220
 
163
- [
164
- "\xC0\xAE", # over-long UTF-8 '.' character
165
- "\xC0\x80", # over-long NULL byte
166
- "\xC0\xFF",
167
- "\xC1\xAE",
168
- "\xC1\x80",
169
- "\xC1\xFF",
170
- "\x80", # first continuation byte
171
- "\xbf", # last continuation byte
172
- # all possible continuation bytes in one shot
173
- "\x80\x81\x82\x83\x84\x85\x86\x87\x88\x89\x8A\x8B\x8C\x8D\x8E\x8F" +
174
- "\x90\x91\x92\x93\x94\x95\x96\x97\x98\x99\x9A\x9B\x9C\x9D\x9E\x9F" +
175
- "\xA0\xA1\xA2\xA3\xA4\xA5\xA6\xA7\xA8\xA9\xAA\xAB\xAC\xAD\xAE\xAF" +
176
- "\xB0\xB1\xB2\xB3\xB4\xB5\xB6\xB7\xB8\xB9\xBA\xBB\xBC\xBD\xBE\xBF",
177
- # lonely start characters - first, all possible two byte sequences
178
- "\xC0 \xC1 \xC2 \xC3 \xC4 \xC5 \xC6 \xC7 \xC8 \xC9 \xCA \xCB \xCC \xCD \xCE \xCF " +
179
- "\xD0 \xD1 \xD2 \xD3 \xD4 \xD5 \xD6 \xD7 \xD8 \xD9 \xDA \xDB \xDC \xDD \xDE \xDF ",
180
- # and so for three byte sequences, four, five, and six, as follow.
181
- "\xE0 \xE1 \xE2 \xE3 \xE4 \xE5 \xE6 \xE7 \xE8 \xE9 \xEA \xEB \xEC \xED \xEE \xEF ",
182
- "\xF0 \xF1 \xF2 \xF3 \xF4 \xF5 \xF6 \xF7 ",
183
- "\xF8 \xF9 \xFA \xFB ",
184
- "\xFC \xFD ",
185
- # sequences with the last byte missing
186
- "\xC0", "\xE0", "\xF0\x80\x80", "\xF8\x80\x80\x80", "\xFC\x80\x80\x80\x80",
187
- "\xDF", "\xEF\xBF", "\xF7\xBF\xBF", "\xFB\xBF\xBF\xBF", "\xFD\xBF\xBF\xBF\xBF",
188
- # impossible bytes
189
- "\xFE", "\xFF", "\xFE\xFE\xFF\xFF",
190
- # over-long '/' character
191
- "\xC0\xAF",
192
- "\xE0\x80\xAF",
193
- "\xF0\x80\x80\xAF",
194
- "\xF8\x80\x80\x80\xAF",
195
- "\xFC\x80\x80\x80\x80\xAF",
196
- # maximum overlong sequences
197
- "\xc1\xbf",
198
- "\xe0\x9f\xbf",
199
- "\xf0\x8f\xbf\xbf",
200
- "\xf8\x87\xbf\xbf\xbf",
201
- "\xfc\x83\xbf\xbf\xbf\xbf",
202
- # overlong NUL
203
- "\xc0\x80",
204
- "\xe0\x80\x80",
205
- "\xf0\x80\x80\x80",
206
- "\xf8\x80\x80\x80\x80",
207
- "\xfc\x80\x80\x80\x80\x80",
208
- ].each do |input|
209
- # It might seem like we should more correctly reject these sequences in
210
- # the encoder, and I would personally agree, but the sad reality is that
211
- # we do not distinguish binary and textual data in our language, and so we
212
- # wind up with the same thing - a string - containing both.
213
- #
214
- # That leads to the position where we must treat these invalid sequences,
215
- # which are both legitimate binary content, and illegitimate potential
216
- # attacks on the system, as something that passes through correctly in
217
- # a string. --daniel 2012-07-14
218
- it "binary encode highly dubious non-compliant UTF-8 input #{input.inspect}" do
219
- encoded = ZAML.dump(binary(input))
220
- encoded.should =~ /!binary/
221
- YAML.load(encoded).should == input
221
+ [
222
+ "\xC0\xAE", # over-long UTF-8 '.' character
223
+ "\xC0\x80", # over-long NULL byte
224
+ "\xC0\xFF",
225
+ "\xC1\xAE",
226
+ "\xC1\x80",
227
+ "\xC1\xFF",
228
+ "\x80", # first continuation byte
229
+ "\xbf", # last continuation byte
230
+ # all possible continuation bytes in one shot
231
+ "\x80\x81\x82\x83\x84\x85\x86\x87\x88\x89\x8A\x8B\x8C\x8D\x8E\x8F" +
232
+ "\x90\x91\x92\x93\x94\x95\x96\x97\x98\x99\x9A\x9B\x9C\x9D\x9E\x9F" +
233
+ "\xA0\xA1\xA2\xA3\xA4\xA5\xA6\xA7\xA8\xA9\xAA\xAB\xAC\xAD\xAE\xAF" +
234
+ "\xB0\xB1\xB2\xB3\xB4\xB5\xB6\xB7\xB8\xB9\xBA\xBB\xBC\xBD\xBE\xBF",
235
+ # lonely start characters - first, all possible two byte sequences
236
+ "\xC0 \xC1 \xC2 \xC3 \xC4 \xC5 \xC6 \xC7 \xC8 \xC9 \xCA \xCB \xCC \xCD \xCE \xCF " +
237
+ "\xD0 \xD1 \xD2 \xD3 \xD4 \xD5 \xD6 \xD7 \xD8 \xD9 \xDA \xDB \xDC \xDD \xDE \xDF ",
238
+ # and so for three byte sequences, four, five, and six, as follow.
239
+ "\xE0 \xE1 \xE2 \xE3 \xE4 \xE5 \xE6 \xE7 \xE8 \xE9 \xEA \xEB \xEC \xED \xEE \xEF ",
240
+ "\xF0 \xF1 \xF2 \xF3 \xF4 \xF5 \xF6 \xF7 ",
241
+ "\xF8 \xF9 \xFA \xFB ",
242
+ "\xFC \xFD ",
243
+ # sequences with the last byte missing
244
+ "\xC0", "\xE0", "\xF0\x80\x80", "\xF8\x80\x80\x80", "\xFC\x80\x80\x80\x80",
245
+ "\xDF", "\xEF\xBF", "\xF7\xBF\xBF", "\xFB\xBF\xBF\xBF", "\xFD\xBF\xBF\xBF\xBF",
246
+ # impossible bytes
247
+ "\xFE", "\xFF", "\xFE\xFE\xFF\xFF",
248
+ # over-long '/' character
249
+ "\xC0\xAF",
250
+ "\xE0\x80\xAF",
251
+ "\xF0\x80\x80\xAF",
252
+ "\xF8\x80\x80\x80\xAF",
253
+ "\xFC\x80\x80\x80\x80\xAF",
254
+ # maximum overlong sequences
255
+ "\xc1\xbf",
256
+ "\xe0\x9f\xbf",
257
+ "\xf0\x8f\xbf\xbf",
258
+ "\xf8\x87\xbf\xbf\xbf",
259
+ "\xfc\x83\xbf\xbf\xbf\xbf",
260
+ # overlong NUL
261
+ "\xc0\x80",
262
+ "\xe0\x80\x80",
263
+ "\xf0\x80\x80\x80",
264
+ "\xf8\x80\x80\x80\x80",
265
+ "\xfc\x80\x80\x80\x80\x80",
266
+ ].each do |input|
267
+ # It might seem like we should more correctly reject these sequences in
268
+ # the encoder, and I would personally agree, but the sad reality is that
269
+ # we do not distinguish binary and textual data in our language, and so we
270
+ # wind up with the same thing - a string - containing both.
271
+ #
272
+ # That leads to the position where we must treat these invalid sequences,
273
+ # which are both legitimate binary content, and illegitimate potential
274
+ # attacks on the system, as something that passes through correctly in
275
+ # a string. --daniel 2012-07-14
276
+ it "binary encode highly dubious non-compliant UTF-8 input #{input.inspect}" do
277
+ encoded = ZAML.dump(binary(input))
278
+ encoded.should =~ /!binary/
279
+ YAML.load(encoded).should == input
280
+ end
222
281
  end
223
282
  end
224
- end
225
283
 
226
- describe "multi-line values" do
227
- [
228
- "none",
229
- "one\n",
230
- "two\n\n",
231
- ["one\n", "two"],
232
- ["two\n\n", "three"],
233
- { "\nkey" => "value" },
234
- { "key\n" => "value" },
235
- { "\nkey\n" => "value" },
236
- { "key\nkey" => "value" },
237
- { "\nkey\nkey" => "value" },
238
- { "key\nkey\n" => "value" },
239
- { "\nkey\nkey\n" => "value" },
240
- ].each do |input|
241
- it "handles #{input.inspect} without corruption" do
242
- zaml = ZAML.dump(input)
243
- YAML.load(zaml).should == input
284
+ context "multi-line values" do
285
+ [
286
+ "none",
287
+ "one\n",
288
+ "two\n\n",
289
+ ["one\n", "two"],
290
+ ["two\n\n", "three"],
291
+ { "\nkey" => "value" },
292
+ { "key\n" => "value" },
293
+ { "\nkey\n" => "value" },
294
+ { "key\nkey" => "value" },
295
+ { "\nkey\nkey" => "value" },
296
+ { "key\nkey\n" => "value" },
297
+ { "\nkey\nkey\n" => "value" },
298
+ ].each do |input|
299
+ it "handles #{input.inspect} without corruption" do
300
+ input.should round_trip_through_yaml
301
+ end
244
302
  end
245
303
  end
246
304
  end