chef 11.16.0.rc.0 → 11.16.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: df2b6f55c4e80aab655910adf3b81719c0f19a69
4
- data.tar.gz: c9c30bb881de7fb5dd779c75c27d1cb0db6bdbeb
3
+ metadata.gz: 35d381547e2d87fff669607dd5c7c665715ab63a
4
+ data.tar.gz: 7bcec5986b17034f0516244df9abc05f18afc44c
5
5
  SHA512:
6
- metadata.gz: 904801b965f8a0dfa042099487d8e137d120f77b82b244f85867dbfb1336828da39aab4ac5d600e041034f558f5def160c35749dcfa156c0573640ba16e1790a
7
- data.tar.gz: 7766f87df2f6ec9c7f4bcc4805759660863f1464022952c942b32aa8ae632d22df5f2d47e48811c7e5c5c82fd0e727fe2dd157ea60c7960335a9cb27856c4845
6
+ metadata.gz: 1b91d63e4a5419efe7383921f447b9b57ae07964bf498247e7269fa57b4009520be07758a9adb53f3c309e685cd8404cf6c13983d9a2c749f8f8d3747508f881
7
+ data.tar.gz: f96f17155457789f4aa2b0907ba67e624ec6e05fba6d89db5b11384b3249b6ac97c84e4dfd0c02df214fbfd7f62fe05d296687b030e2492bb5ffc0efd303538b
@@ -178,6 +178,8 @@ class Chef
178
178
 
179
179
  class ChildConvergeError < RuntimeError; end
180
180
 
181
+ class NoProviderAvailable < RuntimeError; end
182
+
181
183
  class MissingRole < RuntimeError
182
184
  NULL = Object.new
183
185
 
@@ -45,7 +45,11 @@ class Chef
45
45
 
46
46
  is_server_2003
47
47
  end
48
- end
49
48
 
49
+ def supports_dsc?(node)
50
+ node[:languages] && node[:languages][:powershell] &&
51
+ node[:languages][:powershell][:version].to_i >= 4
52
+ end
53
+ end
50
54
  end
51
55
  end
@@ -110,18 +110,18 @@ user password using shadow hash.")
110
110
  @current_resource = Chef::Resource::User.new(@new_resource.username)
111
111
  @current_resource.username(@new_resource.username)
112
112
 
113
- user_info = read_user_info
114
- if user_info
115
- @current_resource.uid(dscl_get(user_info, :uid))
116
- @current_resource.gid(dscl_get(user_info, :gid))
117
- @current_resource.home(dscl_get(user_info, :home))
118
- @current_resource.shell(dscl_get(user_info, :shell))
119
- @current_resource.comment(dscl_get(user_info, :comment))
120
- @authentication_authority = dscl_get(user_info, :auth_authority)
121
-
122
- if @new_resource.password && dscl_get(user_info, :password) == "********"
113
+ @user_info = read_user_info
114
+ if @user_info
115
+ @current_resource.uid(dscl_get(@user_info, :uid))
116
+ @current_resource.gid(dscl_get(@user_info, :gid))
117
+ @current_resource.home(dscl_get(@user_info, :home))
118
+ @current_resource.shell(dscl_get(@user_info, :shell))
119
+ @current_resource.comment(dscl_get(@user_info, :comment))
120
+ @authentication_authority = dscl_get(@user_info, :auth_authority)
121
+
122
+ if @new_resource.password && dscl_get(@user_info, :password) == "********"
123
123
  # A password is set. Let's get the password information from shadow file
124
- shadow_hash_binary = dscl_get(user_info, :shadow_hash)
124
+ shadow_hash_binary = dscl_get(@user_info, :shadow_hash)
125
125
 
126
126
  # Calling shell_out directly since we want to give an input stream
127
127
  shadow_hash_xml = convert_binary_plist_to_xml(shadow_hash_binary.string)
@@ -158,22 +158,26 @@ user password using shadow hash.")
158
158
 
159
159
  def create_user
160
160
  dscl_create_user
161
+ # set_password modifies the plist file of the user directly. So update
162
+ # the password first before making any modifications to the user.
163
+ set_password
161
164
  dscl_create_comment
162
165
  dscl_set_uid
163
166
  dscl_set_gid
164
167
  dscl_set_home
165
168
  dscl_set_shell
166
- set_password
167
169
  end
168
170
 
169
171
  def manage_user
172
+ # set_password modifies the plist file of the user directly. So update
173
+ # the password first before making any modifications to the user.
174
+ set_password if diverged_password?
170
175
  dscl_create_user if diverged?(:username)
171
176
  dscl_create_comment if diverged?(:comment)
172
177
  dscl_set_uid if diverged?(:uid)
173
178
  dscl_set_gid if diverged?(:gid)
174
179
  dscl_set_home if diverged?(:home)
175
180
  dscl_set_shell if diverged?(:shell)
176
- set_password if diverged_password?
177
181
  end
178
182
 
179
183
  #
@@ -339,22 +343,18 @@ user password using shadow hash.")
339
343
  :input => shadow_info.to_plist, :live_stream => shadow_info_binary)
340
344
  command.run_command
341
345
 
346
+ if @user_info.nil?
347
+ # User is just created. read_user_info() will read the fresh information
348
+ # for the user with a cache flush. However with experimentation we've seen
349
+ # that dscl cache is not immediately updated after the creation of the user
350
+ # This is odd and needs to be investigated further.
351
+ sleep 3
352
+ @user_info = read_user_info
353
+ end
354
+
342
355
  # Replace the shadow info in user's plist
343
- user_info = read_user_info
344
- dscl_set(user_info, :shadow_hash, shadow_info_binary)
345
-
346
- #
347
- # Before saving the user's plist file we need to wait for dscl to
348
- # update its caches and flush them to disk. In order to achieve this
349
- # we need to wait first for our changes to get into the dscl cache
350
- # and then flush the cache to disk before saving password into the
351
- # plist file. 3 seconds is the minimum experimental value for dscl
352
- # cache to be updated. We can get rid of this sleep when we find a
353
- # trigger to update dscl cache.
354
- #
355
- sleep 3
356
- shell_out("dscacheutil '-flushcache'")
357
- save_user_info(user_info)
356
+ dscl_set(@user_info, :shadow_hash, shadow_info_binary)
357
+ save_user_info(@user_info)
358
358
  end
359
359
 
360
360
  #
@@ -555,6 +555,10 @@ user password using shadow hash.")
555
555
  def read_user_info
556
556
  user_info = nil
557
557
 
558
+ # We flush the cache here in order to make sure that we read fresh information
559
+ # for the user.
560
+ shell_out("dscacheutil '-flushcache'")
561
+
558
562
  begin
559
563
  user_plist_file = "#{USER_PLIST_DIRECTORY}/#{@new_resource.username}.plist"
560
564
  user_plist_info = run_plutil("convert xml1 -o - #{user_plist_file}")
@@ -16,6 +16,8 @@
16
16
  # limitations under the License.
17
17
  #
18
18
 
19
+ require 'chef/exceptions'
20
+
19
21
  class Chef
20
22
  class Resource
21
23
  class DscScript < Chef::Resource
@@ -26,7 +28,12 @@ class Chef
26
28
  super
27
29
  @allowed_actions.push(:run)
28
30
  @action = :run
29
- provider(Chef::Provider::DscScript)
31
+ if(run_context && Chef::Platform.supports_dsc?(run_context.node))
32
+ @provider = Chef::Provider::DscScript
33
+ else
34
+ raise Chef::Exceptions::NoProviderAvailable,
35
+ "#{powershell_info_str(run_context)}\nPowershell 4.0 or higher was not detected on your system and is required to use the dsc_script resource."
36
+ end
30
37
  end
31
38
 
32
39
  def code(arg=nil)
@@ -118,6 +125,16 @@ class Chef
118
125
  :kind_of => [ Integer ]
119
126
  )
120
127
  end
128
+
129
+ private
130
+
131
+ def powershell_info_str(run_context)
132
+ if run_context && run_context.node[:languages] && run_context.node[:languages][:powershell]
133
+ install_info = "Powershell #{run_context.node[:languages][:powershell][:version]} was found on the system."
134
+ else
135
+ install_info = 'Powershell was not found.'
136
+ end
137
+ end
121
138
  end
122
139
  end
123
140
  end
@@ -24,44 +24,6 @@ class Chef
24
24
  class DSC
25
25
  class LocalConfigurationManager
26
26
  module Parser
27
- class ParseException < RuntimeError; end
28
-
29
- class Operation
30
- attr_reader :op_type
31
- attr_reader :resources
32
- attr_reader :info
33
- attr_reader :sets
34
- attr_reader :tests
35
-
36
- def initialize(op_type, info)
37
- @op_type = op_type
38
- @info = []
39
- @sets = []
40
- @tests = []
41
- @resources = []
42
- add_info(info)
43
- end
44
-
45
- def add_info(info)
46
- @info << info
47
- end
48
-
49
- def add_set(set)
50
- raise ParseException, "add_set is not allowed in this context. Found #{@op_type}" unless [:resource, :set].include?(@op_type)
51
- @sets << set
52
- end
53
-
54
- def add_test(test)
55
- raise ParseException, "add_test is not allowed in this context. Found #{@op_type}" unless [:resource, :set].include?(@op_type)
56
- @tests << test
57
- end
58
-
59
- def add_resource(resource)
60
- raise ParseException, 'add_resource is only allowed to be added to the set op_type' unless @op_type == :set
61
- @resources << resource
62
- end
63
- end
64
-
65
27
  # Parses the output from LCM and returns a list of Chef::Util::DSC::ResourceInfo objects
66
28
  # that describe how the resources affected the system
67
29
  #
@@ -93,83 +55,76 @@ class Chef
93
55
  def self.parse(lcm_output)
94
56
  return [] unless lcm_output
95
57
 
96
- stack = Array.new
97
- popped_op = nil
58
+ current_resource = Hash.new
59
+
60
+ resources = []
98
61
  lcm_output.lines.each do |line|
99
62
  op_action, op_type, info = parse_line(line)
100
- info.strip! # Because this was formatted for humans
101
63
 
102
- # The rules:
103
- # - For each `start` action, there must be a matching `end` action
104
- # - `skip` actions do not not do anything (They don't add to the stack)
105
64
  case op_action
106
65
  when :start
107
- new_op = Operation.new(op_type, info)
108
66
  case op_type
109
67
  when :set
110
- stack[-1].add_set(new_op) if stack[-1]
111
- when :test
112
- stack[-1].add_test(new_op)
68
+ if current_resource[:name]
69
+ current_resource[:context] = :logging
70
+ current_resource[:logs] = [info]
71
+ end
113
72
  when :resource
114
- while stack[-1].op_type != :set
115
- Chef::Log.warn("Can't add resource to set...popping until it is allowed.")
116
- popped_op = stack.pop
73
+ if current_resource[:name]
74
+ resources.push(current_resource)
117
75
  end
118
- stack[-1].add_resource(new_op)
76
+ current_resource = {:name => info}
119
77
  else
120
- Chef::Log.warn("Unknown op_action #{op_action}: Read line #{line}")
78
+ Chef::Log.debug("Ignoring op_action #{op_action}: Read line #{line}")
121
79
  end
122
- stack.push(new_op)
123
80
  when :end
124
- popped_op = stack.pop
125
- popped_op.add_info(info)
126
- while popped_op.op_type != op_type
127
- Chef::Log::warn("Unmatching end for op_type. Expected op_type=#{op_type}, found op_type=#{popped_op.op_type}. From output:\n#{lcm_output}")
128
- popped_op = stack.pop
81
+ # Make sure we log the last line
82
+ if current_resource[:context] == :logging and info.include? current_resource[:name]
83
+ current_resource[:logs].push(info)
129
84
  end
85
+ current_resource[:context] = nil
130
86
  when :skip
131
- # We don't really have anything to do here
87
+ current_resource[:skipped] = true
132
88
  when :info
133
- stack[-1].add_info(info) if stack[-1]
134
- else
135
- stack[-1].add_info(line) if stack[-1]
89
+ if current_resource[:context] == :logging
90
+ current_resource[:logs].push(info)
91
+ end
136
92
  end
137
93
  end
138
94
 
139
- op_to_resource_infos(popped_op)
95
+ if current_resource[:name]
96
+ resources.push(current_resource)
97
+ end
98
+
99
+ build_resource_info(resources)
140
100
  end
141
101
 
142
102
  def self.parse_line(line)
143
103
  if match = line.match(/^.*?:.*?:\s*LCM:\s*\[(.*?)\](.*)/)
144
104
  # If the line looks like
145
- # x: [y]: LCM: [op_action op_type] message
105
+ # What If: [machinename]: LCM: [op_action op_type] message
146
106
  # extract op_action, op_type, and message
147
107
  operation, info = match.captures
148
108
  op_action, op_type = operation.strip.split(' ').map {|m| m.downcase.to_sym}
149
109
  else
150
- # If the line looks like
151
- # x: [y]: message
152
- # extract message
153
- match = line.match(/^.*?:.*?: \s+(.*)/)
154
110
  op_action = op_type = :info
155
- info = match.captures[0]
111
+ if match = line.match(/^.*?:.*?: \s+(.*)/)
112
+ info = match.captures[0]
113
+ else
114
+ info = line
115
+ end
156
116
  end
157
117
  info.strip! # Because this was formatted for humans
158
118
  return [op_action, op_type, info]
159
119
  end
160
120
  private_class_method :parse_line
161
121
 
162
- def self.op_to_resource_infos(op)
163
- resources = op ? op.resources : []
164
-
122
+ def self.build_resource_info(resources)
165
123
  resources.map do |r|
166
- name = r.info[0]
167
- sets = r.sets.length > 0
168
- change_log = r.sets[-1].info if sets
169
- Chef::Util::DSC::ResourceInfo.new(name, sets, change_log)
124
+ Chef::Util::DSC::ResourceInfo.new(r[:name], !r[:skipped], r[:logs])
170
125
  end
171
126
  end
172
- private_class_method :op_to_resource_infos
127
+ private_class_method :build_resource_info
173
128
 
174
129
  end
175
130
  end
@@ -17,7 +17,7 @@
17
17
 
18
18
  class Chef
19
19
  CHEF_ROOT = File.dirname(File.expand_path(File.dirname(__FILE__)))
20
- VERSION = '11.16.0.rc.0'
20
+ VERSION = '11.16.0'
21
21
  end
22
22
 
23
23
  # NOTE: the Chef::Version class is defined in version_class.rb
@@ -65,10 +65,11 @@ describe Chef::Resource::DscScript, :windows_powershell_dsc_only do
65
65
  let(:env_value2) { 'value2' }
66
66
  let(:dsc_test_run_context) {
67
67
  node = Chef::Node.new
68
- node.default['platform'] = 'windows'
69
- node.default['platform_version'] = '6.1'
70
- node.default['kernel'][:machine] =
68
+ node.automatic['platform'] = 'windows'
69
+ node.automatic['platform_version'] = '6.1'
70
+ node.automatic['kernel'][:machine] =
71
71
  is_i386_process_on_x86_64_windows? ? :x86_64 : :i386
72
+ node.automatic[:languages][:powershell][:version] = '4.0'
72
73
  empty_events = Chef::EventDispatch::Dispatcher.new
73
74
  Chef::RunContext.new(node, {}, empty_events)
74
75
  }
@@ -30,3 +30,26 @@ describe "Chef::Platform#windows_server_2003?" do
30
30
  expect { Thread.fork { Chef::Platform.windows_server_2003? }.join }.not_to raise_error
31
31
  end
32
32
  end
33
+
34
+ describe 'Chef::Platform#supports_dsc?' do
35
+ it 'returns false if powershell is not present' do
36
+ node = Chef::Node.new
37
+ Chef::Platform.supports_dsc?(node).should be_false
38
+ end
39
+
40
+ ['1.0', '2.0', '3.0'].each do |version|
41
+ it "returns false for Powershell #{version}" do
42
+ node = Chef::Node.new
43
+ node.automatic[:languages][:powershell][:version] = version
44
+ Chef::Platform.supports_dsc?(node).should be_false
45
+ end
46
+ end
47
+
48
+ ['4.0', '5.0'].each do |version|
49
+ it "returns true for Powershell #{version}" do
50
+ node = Chef::Node.new
51
+ node.automatic[:languages][:powershell][:version] = version
52
+ Chef::Platform.supports_dsc?(node).should be_true
53
+ end
54
+ end
55
+ end
@@ -22,7 +22,11 @@ require 'chef/util/dsc/resource_info'
22
22
  require 'spec_helper'
23
23
 
24
24
  describe Chef::Provider::DscScript do
25
- let (:node) { Chef::Node.new }
25
+ let (:node) {
26
+ node = Chef::Node.new
27
+ node.automatic[:languages][:powershell][:version] = '4.0'
28
+ node
29
+ }
26
30
  let (:events) { Chef::EventDispatch::Dispatcher.new }
27
31
  let (:run_context) { Chef::RunContext.new(node, {}, events) }
28
32
  let (:resource) { Chef::Resource::DscScript.new("script", run_context) }
@@ -376,6 +376,7 @@ ea18e18b720e358e7fbe3cfbeaa561456f6ba008937a30"
376
376
  let(:user_plist_file) { nil }
377
377
 
378
378
  before do
379
+ provider.should_receive(:shell_out).with("dscacheutil '-flushcache'")
379
380
  provider.should_receive(:shell_out).with("plutil -convert xml1 -o - /var/db/dslocal/nodes/Default/users/toor.plist") do
380
381
  if user_plist_file.nil?
381
382
  ShellCmdResult.new('Can not find the file', 'Sorry!!', 1)
@@ -715,7 +716,6 @@ ea18e18b720e358e7fbe3cfbeaa561456f6ba008937a30")
715
716
  provider.should_receive(:read_user_info)
716
717
  provider.should_receive(:dscl_set)
717
718
  provider.should_receive(:sleep).with(3)
718
- provider.should_receive(:shell_out).with("dscacheutil '-flushcache'")
719
719
  provider.should_receive(:save_user_info)
720
720
  provider.set_password
721
721
  end
@@ -822,6 +822,7 @@ ea18e18b720e358e7fbe3cfbeaa561456f6ba008937a30")
822
822
 
823
823
  describe "when the user exists" do
824
824
  before do
825
+ provider.should_receive(:shell_out).with("dscacheutil '-flushcache'")
825
826
  provider.should_receive(:shell_out).with("plutil -convert xml1 -o - /var/db/dslocal/nodes/Default/users/toor.plist") do
826
827
  ShellCmdResult.new(File.read(File.join(CHEF_SPEC_DATA, "mac_users/10.9.plist.xml")), "", 0)
827
828
  end
@@ -19,76 +19,109 @@
19
19
  require 'spec_helper'
20
20
 
21
21
  describe Chef::Resource::DscScript do
22
- let(:dsc_test_run_context) {
23
- node = Chef::Node.new
24
- empty_events = Chef::EventDispatch::Dispatcher.new
25
- Chef::RunContext.new(node, {}, empty_events)
26
- }
27
22
  let(:dsc_test_resource_name) { 'DSCTest' }
28
- let(:dsc_test_resource) {
29
- Chef::Resource::DscScript.new(dsc_test_resource_name, dsc_test_run_context)
30
- }
31
- let(:configuration_code) {'echo "This is supposed to create a configuration document."'}
32
- let(:configuration_path) {'c:/myconfigs/formatc.ps1'}
33
- let(:configuration_name) { 'formatme' }
34
- let(:configuration_data) { '@{AllNodes = @( @{ NodeName = "localhost"; PSDscAllowPlainTextPassword = $true })}' }
35
- let(:configuration_data_script) { 'c:/myconfigs/data/safedata.psd1' }
36
-
37
- it "has a default action of `:run`" do
38
- expect(dsc_test_resource.action).to eq(:run)
39
- end
40
23
 
41
- it "has an allowed_actions attribute with only the `:run` and `:nothing` attributes" do
42
- expect(dsc_test_resource.allowed_actions.to_set).to eq([:run,:nothing].to_set)
43
- end
24
+ context 'when Powershell supports Dsc' do
25
+ let(:dsc_test_run_context) {
26
+ node = Chef::Node.new
27
+ node.automatic[:languages][:powershell][:version] = '4.0'
28
+ empty_events = Chef::EventDispatch::Dispatcher.new
29
+ Chef::RunContext.new(node, {}, empty_events)
30
+ }
31
+ let(:dsc_test_resource) {
32
+ Chef::Resource::DscScript.new(dsc_test_resource_name, dsc_test_run_context)
33
+ }
34
+ let(:configuration_code) {'echo "This is supposed to create a configuration document."'}
35
+ let(:configuration_path) {'c:/myconfigs/formatc.ps1'}
36
+ let(:configuration_name) { 'formatme' }
37
+ let(:configuration_data) { '@{AllNodes = @( @{ NodeName = "localhost"; PSDscAllowPlainTextPassword = $true })}' }
38
+ let(:configuration_data_script) { 'c:/myconfigs/data/safedata.psd1' }
44
39
 
45
- it "allows the code attribute to be set" do
46
- dsc_test_resource.code(configuration_code)
47
- expect(dsc_test_resource.code).to eq(configuration_code)
48
- end
40
+ it "has a default action of `:run`" do
41
+ expect(dsc_test_resource.action).to eq(:run)
42
+ end
49
43
 
50
- it "allows the command attribute to be set" do
51
- dsc_test_resource.command(configuration_path)
52
- expect(dsc_test_resource.command).to eq(configuration_path)
53
- end
44
+ it "has an allowed_actions attribute with only the `:run` and `:nothing` attributes" do
45
+ expect(dsc_test_resource.allowed_actions.to_set).to eq([:run,:nothing].to_set)
46
+ end
54
47
 
55
- it "allows the configuration_name attribute to be set" do
56
- dsc_test_resource.configuration_name(configuration_name)
57
- expect(dsc_test_resource.configuration_name).to eq(configuration_name)
58
- end
48
+ it "allows the code attribute to be set" do
49
+ dsc_test_resource.code(configuration_code)
50
+ expect(dsc_test_resource.code).to eq(configuration_code)
51
+ end
59
52
 
60
- it "allows the configuration_data attribute to be set" do
61
- dsc_test_resource.configuration_data(configuration_data)
62
- expect(dsc_test_resource.configuration_data).to eq(configuration_data)
63
- end
53
+ it "allows the command attribute to be set" do
54
+ dsc_test_resource.command(configuration_path)
55
+ expect(dsc_test_resource.command).to eq(configuration_path)
56
+ end
64
57
 
65
- it "allows the configuration_data_script attribute to be set" do
66
- dsc_test_resource.configuration_data_script(configuration_data_script)
67
- expect(dsc_test_resource.configuration_data_script).to eq(configuration_data_script)
68
- end
58
+ it "allows the configuration_name attribute to be set" do
59
+ dsc_test_resource.configuration_name(configuration_name)
60
+ expect(dsc_test_resource.configuration_name).to eq(configuration_name)
61
+ end
69
62
 
70
- it "raises an ArgumentError exception if an attempt is made to set the code attribute when the command attribute is already set" do
71
- dsc_test_resource.command(configuration_path)
72
- expect { dsc_test_resource.code(configuration_code) }.to raise_error(ArgumentError)
73
- end
63
+ it "allows the configuration_data attribute to be set" do
64
+ dsc_test_resource.configuration_data(configuration_data)
65
+ expect(dsc_test_resource.configuration_data).to eq(configuration_data)
66
+ end
74
67
 
75
- it "raises an ArgumentError exception if an attempt is made to set the command attribute when the code attribute is already set" do
76
- dsc_test_resource.code(configuration_code)
77
- expect { dsc_test_resource.command(configuration_path) }.to raise_error(ArgumentError)
78
- end
68
+ it "allows the configuration_data_script attribute to be set" do
69
+ dsc_test_resource.configuration_data_script(configuration_data_script)
70
+ expect(dsc_test_resource.configuration_data_script).to eq(configuration_data_script)
71
+ end
72
+
73
+ it "raises an ArgumentError exception if an attempt is made to set the code attribute when the command attribute is already set" do
74
+ dsc_test_resource.command(configuration_path)
75
+ expect { dsc_test_resource.code(configuration_code) }.to raise_error(ArgumentError)
76
+ end
77
+
78
+ it "raises an ArgumentError exception if an attempt is made to set the command attribute when the code attribute is already set" do
79
+ dsc_test_resource.code(configuration_code)
80
+ expect { dsc_test_resource.command(configuration_path) }.to raise_error(ArgumentError)
81
+ end
82
+
83
+ it "raises an ArgumentError exception if an attempt is made to set the configuration_name attribute when the code attribute is already set" do
84
+ dsc_test_resource.code(configuration_code)
85
+ expect { dsc_test_resource.configuration_name(configuration_name) }.to raise_error(ArgumentError)
86
+ end
79
87
 
80
- it "raises an ArgumentError exception if an attempt is made to set the configuration_name attribute when the code attribute is already set" do
81
- dsc_test_resource.code(configuration_code)
82
- expect { dsc_test_resource.configuration_name(configuration_name) }.to raise_error(ArgumentError)
88
+ it "raises an ArgumentError exception if an attempt is made to set the configuration_data attribute when the configuration_data_script attribute is already set" do
89
+ dsc_test_resource.configuration_data_script(configuration_data_script)
90
+ expect { dsc_test_resource.configuration_data(configuration_data) }.to raise_error(ArgumentError)
91
+ end
92
+
93
+ it "raises an ArgumentError exception if an attempt is made to set the configuration_data_script attribute when the configuration_data attribute is already set" do
94
+ dsc_test_resource.configuration_data(configuration_data)
95
+ expect { dsc_test_resource.configuration_data_script(configuration_data_script) }.to raise_error(ArgumentError)
96
+ end
83
97
  end
84
98
 
85
- it "raises an ArgumentError exception if an attempt is made to set the configuration_data attribute when the configuration_data_script attribute is already set" do
86
- dsc_test_resource.configuration_data_script(configuration_data_script)
87
- expect { dsc_test_resource.configuration_data(configuration_data) }.to raise_error(ArgumentError)
99
+ context 'when Powershell does not supported Dsc' do
100
+ ['1.0', '2.0', '3.0'].each do |version|
101
+ it "raises an exception for powershell version '#{version}'" do
102
+ node = Chef::Node.new
103
+ node.automatic[:languages][:powershell][:version] = version
104
+ empty_events = Chef::EventDispatch::Dispatcher.new
105
+ dsc_test_run_context = Chef::RunContext.new(node, {}, empty_events)
106
+
107
+ expect {
108
+ Chef::Resource::DscScript.new(dsc_test_resource_name, dsc_test_run_context)
109
+ }.to raise_error(Chef::Exceptions::NoProviderAvailable)
110
+ end
111
+ end
88
112
  end
89
113
 
90
- it "raises an ArgumentError exception if an attempt is made to set the configuration_data_script attribute when the configuration_data attribute is already set" do
91
- dsc_test_resource.configuration_data(configuration_data)
92
- expect { dsc_test_resource.configuration_data_script(configuration_data_script) }.to raise_error(ArgumentError)
114
+ context 'when Powershell is not present' do
115
+ let (:dsc_test_run_context) {
116
+ node = Chef::Node.new
117
+ empty_events = Chef::EventDispatch::Dispatcher.new
118
+ dsc_test_run_context = Chef::RunContext.new(node, {}, empty_events)
119
+ }
120
+
121
+ it 'raises an exception if powershell is not present' do
122
+ expect {
123
+ Chef::Resource::DscScript.new(dsc_test_resource_name, dsc_test_run_context)
124
+ }.to raise_error(Chef::Exceptions::NoProviderAvailable)
125
+ end
93
126
  end
94
127
  end