chef 11.16.0.rc.0 → 11.16.0

Sign up to get free protection for your applications and to get access to all the features.
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