chef 13.5.3 → 13.6.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (61) hide show
  1. checksums.yaml +4 -4
  2. data/VERSION +1 -1
  3. data/bin/chef-shell +2 -0
  4. data/distro/powershell/chef/chef.psm1 +23 -2
  5. data/lib/chef/application/client.rb +1 -1
  6. data/lib/chef/chef_fs/config.rb +1 -1
  7. data/lib/chef/chef_fs/data_handler/data_bag_item_data_handler.rb +5 -0
  8. data/lib/chef/client.rb +3 -0
  9. data/lib/chef/cookbook/synchronizer.rb +2 -4
  10. data/lib/chef/data_bag.rb +4 -0
  11. data/lib/chef/deprecated.rb +10 -0
  12. data/lib/chef/knife/client_delete.rb +1 -1
  13. data/lib/chef/knife/node_delete.rb +1 -1
  14. data/lib/chef/knife/node_run_list_add.rb +1 -1
  15. data/lib/chef/knife/node_run_list_remove.rb +1 -1
  16. data/lib/chef/knife/role_env_run_list_add.rb +1 -1
  17. data/lib/chef/knife/role_run_list_add.rb +1 -1
  18. data/lib/chef/mixin/user_context.rb +1 -1
  19. data/lib/chef/platform/rebooter.rb +7 -3
  20. data/lib/chef/provider/dsc_script.rb +5 -1
  21. data/lib/chef/provider/package.rb +35 -4
  22. data/lib/chef/provider/package/apt.rb +7 -0
  23. data/lib/chef/provider/package/chocolatey.rb +24 -8
  24. data/lib/chef/provider/package/dnf.rb +14 -5
  25. data/lib/chef/provider/package/dnf/dnf_helper.py +10 -0
  26. data/lib/chef/provider/package/dnf/python_helper.rb +15 -0
  27. data/lib/chef/provider/package/rpm.rb +5 -0
  28. data/lib/chef/provider/package/windows.rb +15 -0
  29. data/lib/chef/provider/package/yum.rb +4 -20
  30. data/lib/chef/provider/package/zypper.rb +5 -1
  31. data/lib/chef/provider/route.rb +1 -1
  32. data/lib/chef/provider/windows_task.rb +19 -4
  33. data/lib/chef/provider/zypper_repository.rb +100 -12
  34. data/lib/chef/resource/deploy.rb +6 -0
  35. data/lib/chef/resource/dnf_package.rb +9 -2
  36. data/lib/chef/resource/windows_task.rb +12 -7
  37. data/lib/chef/resource/zypper_package.rb +1 -0
  38. data/lib/chef/resource/zypper_repository.rb +1 -0
  39. data/lib/chef/util/dsc/lcm_output_parser.rb +57 -2
  40. data/lib/chef/util/dsc/local_configuration_manager.rb +16 -16
  41. data/lib/chef/version.rb +1 -1
  42. data/spec/functional/rebooter_spec.rb +22 -11
  43. data/spec/functional/resource/windows_task_spec.rb +25 -0
  44. data/spec/unit/chef_fs/data_handler/data_bag_item_data_handler.rb +79 -0
  45. data/spec/unit/client_spec.rb +11 -0
  46. data/spec/unit/cookbook/synchronizer_spec.rb +30 -0
  47. data/spec/unit/knife/data_bag_create_spec.rb +8 -0
  48. data/spec/unit/mixin/user_context_spec.rb +1 -2
  49. data/spec/unit/provider/package/chocolatey_spec.rb +3 -1
  50. data/spec/unit/provider/package/rubygems_spec.rb +5 -0
  51. data/spec/unit/provider/package/zypper_spec.rb +8 -0
  52. data/spec/unit/provider/remote_file/network_file_spec.rb +1 -1
  53. data/spec/unit/provider/route_spec.rb +2 -0
  54. data/spec/unit/provider/windows_task_spec.rb +28 -0
  55. data/spec/unit/provider/zypper_repository_spec.rb +124 -0
  56. data/spec/unit/provider_resolver_spec.rb +4 -1
  57. data/spec/unit/resource/windows_task_spec.rb +8 -2
  58. data/spec/unit/resource/zypper_repository_spec.rb +11 -9
  59. data/spec/unit/util/dsc/lcm_output_parser_spec.rb +102 -18
  60. data/spec/unit/util/dsc/local_configuration_manager_spec.rb +2 -1
  61. metadata +6 -4
@@ -383,6 +383,11 @@ describe Chef::Provider::Package::Rubygems do
383
383
  provider.load_current_resource
384
384
  expect(provider.target_version_already_installed?(provider.current_resource.version, new_resource.version)).to be_falsey
385
385
  end
386
+
387
+ it "version_equals? should return false so that we can search for candidates" do
388
+ provider.load_current_resource
389
+ expect(provider.version_equals?(provider.current_resource.version, new_resource.version)).to be_falsey
390
+ end
386
391
  end
387
392
 
388
393
  describe "when new_resource version is an rspec version" do
@@ -140,6 +140,14 @@ describe Chef::Provider::Package::Zypper do
140
140
  provider.install_package(["emacs"], ["1.0"])
141
141
  end
142
142
 
143
+ it "setting the property should allow downgrade" do
144
+ new_resource.allow_downgrade true
145
+ shell_out_expectation!(
146
+ "zypper", "--non-interactive", "install", "--auto-agree-with-licenses", "--oldpackage", "emacs=1.0"
147
+ )
148
+ provider.install_package(["emacs"], ["1.0"])
149
+ end
150
+
143
151
  it "should add user provided options to the command" do
144
152
  new_resource.options "--user-provided"
145
153
  shell_out_expectation!(
@@ -33,7 +33,7 @@ describe Chef::Provider::RemoteFile::NetworkFile do
33
33
  let(:source_file) { double("::File", :read => nil) }
34
34
 
35
35
  before do
36
- allow(fetcher).to receive(:node).and_return({ "platform_family" => "windows" })
36
+ allow(Chef::Platform).to receive(:windows?).and_return(true)
37
37
  end
38
38
 
39
39
  it "stages the local file to a temporary file" do
@@ -236,9 +236,11 @@ describe Chef::Provider::Route do
236
236
  @node.automatic_attrs[:platform] = platform
237
237
 
238
238
  route_file = StringIO.new
239
+ allow(File).to receive(:exist?).with("/etc/sysconfig/network").and_return(false)
239
240
  expect(File).to receive(:new).with("/etc/sysconfig/network", "w").and_return(route_file)
240
241
  @run_context.resource_collection << @default_resource
241
242
  @default_provider.generate_config
243
+ expect(route_file.string).to match(/GATEWAY=10\.0\.0\.9/)
242
244
  end
243
245
  end
244
246
 
@@ -143,6 +143,17 @@ describe Chef::Provider::WindowsTask do
143
143
  provider.run_action(:create)
144
144
  expect(new_resource).to be_updated_by_last_action
145
145
  end
146
+
147
+ it "updates the task XML if frequency is set as `:none`" do
148
+ new_resource.frequency :none
149
+ new_resource.random_delay ""
150
+ allow(provider).to receive(:task_need_update?).and_return(true)
151
+ allow(provider).to receive(:basic_validation).and_return(true)
152
+ allow(provider).to receive(:run_schtasks).and_return("CREATE", { "F" => "", "SC" => :once, "ST" => "00:00", "SD" => "12/12/2012", "TR" => nil, "RU" => "SYSTEM" })
153
+ expect(provider).to receive(:update_task_xml)
154
+ provider.run_action(:create)
155
+ expect(new_resource).to be_updated_by_last_action
156
+ end
146
157
  end
147
158
  end
148
159
 
@@ -507,6 +518,18 @@ describe Chef::Provider::WindowsTask do
507
518
  expect(provider).to receive(:run_schtasks).twice
508
519
  output = provider.send(:update_task_xml, ["random_delay"])
509
520
  end
521
+
522
+ it "updates the task XML if frequency is set as `:none`" do
523
+ new_resource.frequency :none
524
+ new_resource.random_delay ""
525
+ shell_out_obj = double("xml", :exitstatus => 0, :stdout => task_xml)
526
+ allow(provider).to receive(:powershell_out).and_return(shell_out_obj)
527
+ expect(::File).to receive(:delete)
528
+ expect(::File).to receive(:join)
529
+ expect(::File).to receive(:open)
530
+ expect(provider).to receive(:run_schtasks).twice
531
+ output = provider.send(:update_task_xml, ["random_delay"])
532
+ end
510
533
  end
511
534
 
512
535
  describe "#load_task_hash" do
@@ -541,5 +564,10 @@ describe Chef::Provider::WindowsTask do
541
564
  new_resource.frequency :once
542
565
  expect(provider.send(:frequency_modifier_allowed)).to be(false)
543
566
  end
567
+
568
+ it "returns false for frequency :none" do
569
+ new_resource.frequency :none
570
+ expect(provider.send(:frequency_modifier_allowed)).to be(false)
571
+ end
544
572
  end
545
573
  end
@@ -0,0 +1,124 @@
1
+ #
2
+ # Author:: Tim Smith (<tsmith@chef.io>)
3
+ # Copyright:: 2017, Chef Software, Inc.
4
+ # License:: Apache License, Version 2.0
5
+ #
6
+ # Licensed under the Apache License, Version 2.0 (the "License");
7
+ # you may not use this file except in compliance with the License.
8
+ # You may obtain a copy of the License at
9
+ #
10
+ # http://www.apache.org/licenses/LICENSE-2.0
11
+ #
12
+ # Unless required by applicable law or agreed to in writing, software
13
+ # distributed under the License is distributed on an "AS IS" BASIS,
14
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15
+ # See the License for the specific language governing permissions and
16
+ # limitations under the License.
17
+ #
18
+
19
+ require "spec_helper"
20
+
21
+ # Output of the command:
22
+ # => rpm -qa gpg-pubkey*
23
+ RPM_KEYS = <<-EOF
24
+ gpg-pubkey-307e3d54-4be01a65
25
+ gpg-pubkey-3dbdc284-53674dd4
26
+ EOF
27
+
28
+ # Output of the command:
29
+ # => gpg --with-fingerprint [FILE]
30
+ GPG_FINGER = <<-EOF
31
+ pub 2048R/3DBDC284 2011-08-19 [expires: 2024-06-14]
32
+ Key fingerprint = 573B FD6B 3D8F BC64 1079 A6AB ABF5 BD82 7BD9 BF62
33
+ uid nginx signing key <signing-key@nginx.com>
34
+ EOF
35
+
36
+ describe Chef::Provider::ZypperRepository do
37
+ let(:new_resource) { Chef::Resource::ZypperRepository.new("Nginx Repository") }
38
+ let(:provider) do
39
+ node = Chef::Node.new
40
+ events = Chef::EventDispatch::Dispatcher.new
41
+ run_context = Chef::RunContext.new(node, {}, events)
42
+ Chef::Provider::ZypperRepository.new(new_resource, run_context)
43
+ end
44
+
45
+ let(:rpm_key_finger) do
46
+ double("shell_out_with_systems_locale", stdout: RPM_KEYS, exitstatus: 0, error?: false)
47
+ end
48
+
49
+ let(:gpg_finger) do
50
+ double("shell_out_with_systems_locale", stdout: GPG_FINGER, exitstatus: 0, error?: false)
51
+ end
52
+
53
+ it "responds to load_current_resource" do
54
+ expect(provider).to respond_to(:load_current_resource)
55
+ end
56
+
57
+ describe "#action_create" do
58
+ it "skips key import if gpgautoimportkeys is false" do
59
+ new_resource.gpgautoimportkeys(false)
60
+ expect(provider).to receive(:declare_resource)
61
+ expect(Chef::Log).to receive(:debug)
62
+ provider.run_action(:create)
63
+ end
64
+ end
65
+
66
+ describe "#escaped_repo_name" do
67
+ it "returns an escaped repo name" do
68
+ expect(provider.escaped_repo_name).to eq('Nginx\\ Repository')
69
+ end
70
+ end
71
+
72
+ describe "#cookbook_name" do
73
+ it "returns 'test' when the cookbook property is set" do
74
+ new_resource.cookbook("test")
75
+ expect(provider.cookbook_name).to eq("test")
76
+ end
77
+ end
78
+
79
+ describe "#key_type" do
80
+ it "returns :remote_file with an http URL" do
81
+ expect(provider.key_type("https://www.chef.io/key")).to eq(:remote_file)
82
+ end
83
+
84
+ it "returns :cookbook_file with a chef managed file" do
85
+ expect(provider).to receive(:has_cookbook_file?).and_return(true)
86
+ expect(provider.key_type("/foo/nginx.key")).to eq(:cookbook_file)
87
+ end
88
+
89
+ it "throws exception if an unknown file specified" do
90
+ expect(provider).to receive(:has_cookbook_file?).and_return(false)
91
+ expect { provider.key_type("/foo/nginx.key") }.to raise_error(Chef::Exceptions::FileNotFound)
92
+ end
93
+ end
94
+
95
+ describe "#key_installed?" do
96
+ before do
97
+ expect(provider).to receive(:shell_out).with("rpm -qa gpg-pubkey*").and_return(rpm_key_finger)
98
+ end
99
+
100
+ it "returns true if the key is installed" do
101
+ expect(provider).to receive(:key_fingerprint).and_return("3dbdc284")
102
+ expect(provider.key_installed?("/foo/nginx.key")).to be_truthy
103
+ end
104
+
105
+ it "returns false if the key is not installed" do
106
+ expect(provider).to receive(:key_fingerprint).and_return("BOGUS")
107
+ expect(provider.key_installed?("/foo/nginx.key")).to be_falsey
108
+ end
109
+ end
110
+
111
+ describe "#key_fingerprint" do
112
+ it "returns the key's fingerprint" do
113
+ expect(provider).to receive(:shell_out!).with("gpg --with-fingerprint /foo/nginx.key").and_return(gpg_finger)
114
+ expect(provider.key_fingerprint("/foo/nginx.key")).to eq("3dbdc284")
115
+ end
116
+ end
117
+
118
+ describe "#install_gpg_key" do
119
+ it "skips installing the key if a nil value for key is passed" do
120
+ expect(Chef::Log).to receive(:debug)
121
+ provider.install_gpg_key(nil)
122
+ end
123
+ end
124
+ end
@@ -708,18 +708,21 @@ describe Chef::ProviderResolver do
708
708
 
709
709
  "rhel" => {
710
710
  # service: [ Chef::Resource::SystemdService, Chef::Provider::Service::Systemd ],
711
- package: [ Chef::Resource::YumPackage, Chef::Provider::Package::Yum ],
711
+ package: [ Chef::Resource::DnfPackage, Chef::Provider::Package::Dnf ],
712
712
  ifconfig: [ Chef::Resource::Ifconfig, Chef::Provider::Ifconfig::Redhat ],
713
713
 
714
714
  %w{amazon xcp xenserver ibm_powerkvm cloudlinux parallels} => {
715
715
  "3.1.4" => {
716
+ package: [ Chef::Resource::YumPackage, Chef::Provider::Package::Yum ],
716
717
  # service: [ Chef::Resource::RedhatService, Chef::Provider::Service::Redhat ],
717
718
  },
718
719
  },
719
720
  %w{redhat centos scientific oracle} => {
720
721
  "7.0" => {
722
+ package: [ Chef::Resource::YumPackage, Chef::Provider::Package::Yum ],
721
723
  },
722
724
  "6.0" => {
725
+ package: [ Chef::Resource::YumPackage, Chef::Provider::Package::Yum ],
723
726
  # service: [ Chef::Resource::RedhatService, Chef::Provider::Service::Redhat ],
724
727
  },
725
728
  },
@@ -102,8 +102,14 @@ describe Chef::Resource::WindowsTask do
102
102
  end
103
103
 
104
104
  context "#validate_start_time" do
105
- it "raises error if start_time is nil" do
106
- expect { resource.send(:validate_start_time, nil) }.to raise_error(Chef::Exceptions::ArgumentError, "`start_time` needs to be provided with `frequency :once`")
105
+ it "raises error if start_time is nil when frequency `:once`" do
106
+ resource.frequency :once
107
+ expect { resource.send(:validate_start_time, nil, :once) }.to raise_error(Chef::Exceptions::ArgumentError, "`start_time` needs to be provided with `frequency :once`")
108
+ end
109
+
110
+ it "raises error if start_time is given when frequency `:none`" do
111
+ resource.frequency :none
112
+ expect { resource.send(:validate_start_time, "12.00", :none) }.to raise_error(Chef::Exceptions::ArgumentError, "`start_time` property is not supported with `frequency :none`")
107
113
  end
108
114
  end
109
115
 
@@ -46,20 +46,22 @@ describe Chef::Resource::ZypperRepository do
46
46
  expect { resource.action :delete }.to raise_error(ArgumentError)
47
47
  end
48
48
 
49
- it "should resolve to a Noop class when zypper is not found" do
50
- expect(Chef::Provider::ZypperRepository).to receive(:which).with("zypper").and_return(false)
49
+ it "resolves to a Noop class when on non-linux OS" do
50
+ node.automatic[:os] = "windows"
51
+ node.automatic[:platform_family] = "windows"
51
52
  expect(resource.provider_for_action(:add)).to be_a(Chef::Provider::Noop)
52
53
  end
53
54
 
54
- it "should resolve to a ZypperRepository class when zypper is found" do
55
- expect(Chef::Provider::ZypperRepository).to receive(:which).with("zypper").and_return(true)
56
- expect(resource.provider_for_action(:add)).to be_a(Chef::Provider::ZypperRepository)
55
+ it "resolves to a Noop class when on non-suse linux" do
56
+ node.automatic[:os] = "linux"
57
+ node.automatic[:platform_family] = "debian"
58
+ expect(resource.provider_for_action(:add)).to be_a(Chef::Provider::Noop)
57
59
  end
58
- end
59
60
 
60
- context "on windows", :windows_only do
61
- it "should resolve to a NoOp provider" do
62
- expect(resource.provider_for_action(:add)).to be_a(Chef::Provider::Noop)
61
+ it "resolves to a ZypperRepository class when on a suse platform_family" do
62
+ node.automatic[:os] = "linux"
63
+ node.automatic[:platform_family] = "suse"
64
+ expect(resource.provider_for_action(:add)).to be_a(Chef::Provider::ZypperRepository)
63
65
  end
64
66
  end
65
67
  end
@@ -19,20 +19,33 @@
19
19
  require "chef/util/dsc/lcm_output_parser"
20
20
 
21
21
  describe Chef::Util::DSC::LocalConfigurationManager::Parser do
22
- context "empty input parameter" do
22
+ context "empty input parameter for WhatIfParser" do
23
23
  it "raises an exception when there are no valid lines" do
24
24
  str = <<-EOF
25
25
 
26
26
  EOF
27
- expect { Chef::Util::DSC::LocalConfigurationManager::Parser.parse(str) }.to raise_error(Chef::Exceptions::LCMParser)
27
+ expect { Chef::Util::DSC::LocalConfigurationManager::Parser.parse(str, false) }.to raise_error(Chef::Exceptions::LCMParser)
28
28
  end
29
29
 
30
30
  it "raises an exception for a nil input" do
31
- expect { Chef::Util::DSC::LocalConfigurationManager::Parser.parse(nil) }.to raise_error(Chef::Exceptions::LCMParser)
31
+ expect { Chef::Util::DSC::LocalConfigurationManager::Parser.parse(nil, false) }.to raise_error(Chef::Exceptions::LCMParser)
32
32
  end
33
33
  end
34
34
 
35
- context "correctly formatted output from lcm" do
35
+ context "empty input parameter for TestDSCParser" do
36
+ it "raises an exception when there are no valid lines" do
37
+ str = <<-EOF
38
+
39
+ EOF
40
+ expect { Chef::Util::DSC::LocalConfigurationManager::Parser.parse(str, true) }.to raise_error(Chef::Exceptions::LCMParser)
41
+ end
42
+
43
+ it "raises an exception for a nil input" do
44
+ expect { Chef::Util::DSC::LocalConfigurationManager::Parser.parse(nil, true) }.to raise_error(Chef::Exceptions::LCMParser)
45
+ end
46
+ end
47
+
48
+ context "correctly formatted output from lcm for WhatIfParser" do
36
49
  it "returns a single resource when only 1 logged with the correct name" do
37
50
  str = <<EOF
38
51
  logtype: [machinename]: LCM: [ Start Set ]
@@ -40,7 +53,7 @@ logtype: [machinename]: LCM: [ Start Resource ] [name]
40
53
  logtype: [machinename]: LCM: [ End Resource ] [name]
41
54
  logtype: [machinename]: LCM: [ End Set ]
42
55
  EOF
43
- resources = Chef::Util::DSC::LocalConfigurationManager::Parser.parse(str)
56
+ resources = Chef::Util::DSC::LocalConfigurationManager::Parser.parse(str, false)
44
57
  expect(resources.length).to eq(1)
45
58
  expect(resources[0].name).to eq("[name]")
46
59
  end
@@ -54,7 +67,7 @@ logtype: [machinename]: LCM: [ End Set ] [name]
54
67
  logtype: [machinename]: LCM: [ End Resource ] [name]
55
68
  logtype: [machinename]: LCM: [ End Set ]
56
69
  EOF
57
- resources = Chef::Util::DSC::LocalConfigurationManager::Parser.parse(str)
70
+ resources = Chef::Util::DSC::LocalConfigurationManager::Parser.parse(str, false)
58
71
  expect(resources[0].changes_state?).to be_truthy
59
72
  end
60
73
 
@@ -68,11 +81,11 @@ logtype: [machinename]: LCM: [ End Set ] [name]
68
81
  logtype: [machinename]: LCM: [ End Resource ] [name]
69
82
  logtype: [machinename]: LCM: [ End Set ]
70
83
  EOF
71
- resources = Chef::Util::DSC::LocalConfigurationManager::Parser.parse(str)
84
+ resources = Chef::Util::DSC::LocalConfigurationManager::Parser.parse(str, false)
72
85
  expect(resources[0].change_log).to match_array(["[name]", "[message]", "[name]"])
73
86
  end
74
87
 
75
- it "should return false for changes_state?" do
88
+ it "returns false for changes_state?" do
76
89
  str = <<EOF
77
90
  logtype: [machinename]: LCM: [ Start Set ]
78
91
  logtype: [machinename]: LCM: [ Start Resource ] [name]
@@ -80,11 +93,11 @@ logtype: [machinename]: LCM: [ Skip Set ] [name]
80
93
  logtype: [machinename]: LCM: [ End Resource ] [name]
81
94
  logtype: [machinename]: LCM: [ End Set ]
82
95
  EOF
83
- resources = Chef::Util::DSC::LocalConfigurationManager::Parser.parse(str)
96
+ resources = Chef::Util::DSC::LocalConfigurationManager::Parser.parse(str, false)
84
97
  expect(resources[0].changes_state?).to be_falsey
85
98
  end
86
99
 
87
- it "should return an empty array for change_log if changes_state? is false" do
100
+ it "returns an empty array for change_log if changes_state? is false" do
88
101
  str = <<EOF
89
102
  logtype: [machinename]: LCM: [ Start Set ]
90
103
  logtype: [machinename]: LCM: [ Start Resource ] [name]
@@ -92,13 +105,64 @@ logtype: [machinename]: LCM: [ Skip Set ] [name]
92
105
  logtype: [machinename]: LCM: [ End Resource ] [name]
93
106
  logtype: [machinename]: LCM: [ End Set ]
94
107
  EOF
95
- resources = Chef::Util::DSC::LocalConfigurationManager::Parser.parse(str)
108
+ resources = Chef::Util::DSC::LocalConfigurationManager::Parser.parse(str, false)
96
109
  expect(resources[0].change_log).to be_empty
97
110
  end
98
111
  end
99
112
 
100
- context "Incorrectly formatted output from LCM" do
101
- it "should allow missing a [End Resource] when its the last one and still find all the resource" do
113
+ context "correctly formatted output from lcm for TestDSCParser" do
114
+ it "returns a single resource when only 1 logged with the correct name" do
115
+ str = <<EOF
116
+ InDesiredState : False
117
+ ResourcesInDesiredState :
118
+ ResourcesNotInDesiredState: [name]
119
+ ReturnValue : 0
120
+ PSComputerName : .
121
+ EOF
122
+ resources = Chef::Util::DSC::LocalConfigurationManager::Parser.parse(str, true)
123
+ expect(resources.length).to eq(1)
124
+ expect(resources[0].name).to eq("[name]")
125
+ end
126
+
127
+ it "identifies when a resource changes the state of the system" do
128
+ str = <<EOF
129
+ InDesiredState : False
130
+ ResourcesInDesiredState :
131
+ ResourcesNotInDesiredState: [name]
132
+ ReturnValue : 0
133
+ PSComputerName : .
134
+ EOF
135
+ resources = Chef::Util::DSC::LocalConfigurationManager::Parser.parse(str, true)
136
+ expect(resources[0].changes_state?).to be_truthy
137
+ end
138
+
139
+ it "returns false for changes_state?" do
140
+ str = <<EOF
141
+ InDesiredState : True
142
+ ResourcesInDesiredState : [name]
143
+ ResourcesNotInDesiredState:
144
+ ReturnValue : 0
145
+ PSComputerName : .
146
+ EOF
147
+ resources = Chef::Util::DSC::LocalConfigurationManager::Parser.parse(str, true)
148
+ expect(resources[0].changes_state?).to be_falsey
149
+ end
150
+
151
+ it "returns an empty array for change_log if changes_state? is false" do
152
+ str = <<EOF
153
+ InDesiredState : True
154
+ ResourcesInDesiredState : [name]
155
+ ResourcesNotInDesiredState:
156
+ ReturnValue : 0
157
+ PSComputerName : .
158
+ EOF
159
+ resources = Chef::Util::DSC::LocalConfigurationManager::Parser.parse(str, true)
160
+ expect(resources[0].change_log).to be_empty
161
+ end
162
+ end
163
+
164
+ context "Incorrectly formatted output from LCM for WhatIfParser" do
165
+ it "allows missing [End Resource] when its the last one and still find all the resource" do
102
166
  str = <<-EOF
103
167
  logtype: [machinename]: LCM: [ Start Set ]
104
168
  logtype: [machinename]: LCM: [ Start Resource ] [name]
@@ -114,12 +178,12 @@ logtype: [machinename]: LCM: [ End Set ]
114
178
  logtype: [machinename]: LCM: [ End Set ]
115
179
  EOF
116
180
 
117
- resources = Chef::Util::DSC::LocalConfigurationManager::Parser.parse(str)
181
+ resources = Chef::Util::DSC::LocalConfigurationManager::Parser.parse(str, false)
118
182
  expect(resources[0].changes_state?).to be_falsey
119
183
  expect(resources[1].changes_state?).to be_truthy
120
184
  end
121
185
 
122
- it "should allow missing a [End Resource] when its the first one and still find all the resource" do
186
+ it "allow missing [End Resource] when its the first one and still find all the resource" do
123
187
  str = <<-EOF
124
188
  logtype: [machinename]: LCM: [ Start Set ]
125
189
  logtype: [machinename]: LCM: [ Start Resource ] [name]
@@ -135,12 +199,12 @@ logtype: [machinename]: LCM: [ End Resource ]
135
199
  logtype: [machinename]: LCM: [ End Set ]
136
200
  EOF
137
201
 
138
- resources = Chef::Util::DSC::LocalConfigurationManager::Parser.parse(str)
202
+ resources = Chef::Util::DSC::LocalConfigurationManager::Parser.parse(str, false)
139
203
  expect(resources[0].changes_state?).to be_falsey
140
204
  expect(resources[1].changes_state?).to be_truthy
141
205
  end
142
206
 
143
- it "should allow missing set and end resource and assume an unconverged resource in this case" do
207
+ it "allows missing set and end resource and assume an unconverged resource in this case" do
144
208
  str = <<-EOF
145
209
  logtype: [machinename]: LCM: [ Start Set ]
146
210
  logtype: [machinename]: LCM: [ Start Resource ] [name]
@@ -154,11 +218,31 @@ logtype: [machinename]: LCM: [ End Set ]
154
218
  logtype: [machinename]: LCM: [ End Resource ]
155
219
  logtype: [machinename]: LCM: [ End Set ]
156
220
  EOF
157
- resources = Chef::Util::DSC::LocalConfigurationManager::Parser.parse(str)
221
+ resources = Chef::Util::DSC::LocalConfigurationManager::Parser.parse(str, false)
158
222
  expect(resources[0].changes_state?).to be_truthy
159
223
  expect(resources[0].name).to eql("[name]")
160
224
  expect(resources[1].changes_state?).to be_truthy
161
225
  expect(resources[1].name).to eql("[name2]")
162
226
  end
163
227
  end
228
+
229
+ context "Incorrectly formatted output from LCM for TestDSCParser" do
230
+ it "allows missing [End Resource] when its the last one and still find all the resource" do
231
+ str = <<EOF
232
+ InDesiredState : True
233
+ ResourcesInDesiredState :
234
+ ResourcesNotInDesiredState: [name]
235
+ ReturnValue : 0
236
+ PSComputerName : .
237
+ InDesiredState : True
238
+ ResourcesInDesiredState :
239
+ ResourcesNotInDesiredState: [name2]
240
+ ReturnValue : 0
241
+ PSComputerName : .
242
+ EOF
243
+
244
+ resources = Chef::Util::DSC::LocalConfigurationManager::Parser.parse(str, true)
245
+ expect(resources[0].changes_state?).to be_falsey
246
+ end
247
+ end
164
248
  end