chef 10.28.2 → 10.30.0.rc.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (64) hide show
  1. data/lib/chef.rb +1 -0
  2. data/lib/chef/application/knife.rb +2 -0
  3. data/lib/chef/client.rb +1 -1
  4. data/lib/chef/config.rb +5 -1
  5. data/lib/chef/cookbook_uploader.rb +7 -14
  6. data/lib/chef/data_bag.rb +2 -3
  7. data/lib/chef/exceptions.rb +9 -1
  8. data/lib/chef/formatters/error_inspectors/registration_error_inspector.rb +4 -0
  9. data/lib/chef/knife.rb +3 -0
  10. data/lib/chef/mixin/deep_merge.rb +53 -21
  11. data/lib/chef/monkey_patches/net_http.rb +34 -0
  12. data/lib/chef/monkey_patches/uri.rb +70 -0
  13. data/lib/chef/node.rb +5 -5
  14. data/lib/chef/platform.rb +1 -0
  15. data/lib/chef/provider/cookbook_file.rb +14 -6
  16. data/lib/chef/provider/directory.rb +16 -10
  17. data/lib/chef/provider/file.rb +23 -17
  18. data/lib/chef/provider/group.rb +50 -31
  19. data/lib/chef/provider/group/dscl.rb +26 -4
  20. data/lib/chef/provider/group/gpasswd.rb +14 -19
  21. data/lib/chef/provider/group/groupadd.rb +41 -1
  22. data/lib/chef/provider/group/groupmod.rb +46 -36
  23. data/lib/chef/provider/group/pw.rb +59 -16
  24. data/lib/chef/provider/group/suse.rb +16 -13
  25. data/lib/chef/provider/group/usermod.rb +40 -18
  26. data/lib/chef/provider/group/windows.rb +13 -6
  27. data/lib/chef/provider/package/yum.rb +1 -0
  28. data/lib/chef/provider/remote_file.rb +8 -2
  29. data/lib/chef/provider/ruby_block.rb +1 -1
  30. data/lib/chef/provider/template.rb +11 -5
  31. data/lib/chef/provider/user/useradd.rb +9 -1
  32. data/lib/chef/provider/whyrun_safe_ruby_block.rb +30 -0
  33. data/lib/chef/providers.rb +1 -0
  34. data/lib/chef/resource/group.rb +11 -1
  35. data/lib/chef/resource/whyrun_safe_ruby_block.rb +31 -0
  36. data/lib/chef/resources.rb +1 -0
  37. data/lib/chef/rest.rb +6 -2
  38. data/lib/chef/rest/rest_request.rb +6 -2
  39. data/lib/chef/util/windows/net_group.rb +5 -1
  40. data/lib/chef/version.rb +1 -1
  41. data/spec/functional/resource/base.rb +40 -0
  42. data/spec/functional/resource/group_spec.rb +343 -0
  43. data/spec/spec_helper.rb +4 -0
  44. data/spec/support/platform_helpers.rb +17 -0
  45. data/spec/unit/client_spec.rb +1 -1
  46. data/spec/unit/data_bag_spec.rb +4 -6
  47. data/spec/unit/mixin/deep_merge_spec.rb +416 -190
  48. data/spec/unit/monkey_patches/uri_spec.rb +34 -0
  49. data/spec/unit/node/attribute_spec.rb +49 -14
  50. data/spec/unit/node_spec.rb +31 -0
  51. data/spec/unit/provider/file_spec.rb +27 -27
  52. data/spec/unit/provider/group/dscl_spec.rb +1 -0
  53. data/spec/unit/provider/group/gpasswd_spec.rb +16 -9
  54. data/spec/unit/provider/group/groupadd_spec.rb +3 -4
  55. data/spec/unit/provider/group/groupmod_spec.rb +0 -1
  56. data/spec/unit/provider/group/pw_spec.rb +12 -15
  57. data/spec/unit/provider/group/usermod_spec.rb +21 -6
  58. data/spec/unit/provider/group/windows_spec.rb +0 -8
  59. data/spec/unit/provider/group_spec.rb +26 -4
  60. data/spec/unit/provider/user/useradd_spec.rb +21 -0
  61. data/spec/unit/provider/whyrun_safe_ruby_block_spec.rb +47 -0
  62. data/spec/unit/rest_spec.rb +55 -22
  63. metadata +119 -44
  64. checksums.yaml +0 -7
@@ -34,12 +34,12 @@ class Chef
34
34
  @current_resource = Chef::Resource::Template.new(@new_resource.name)
35
35
  super
36
36
  end
37
-
37
+
38
38
  def define_resource_requirements
39
39
  super
40
40
 
41
- requirements.assert(:create, :create_if_missing) do |a|
42
- a.assertion { ::File::exist?(template_location) }
41
+ requirements.assert(:create, :create_if_missing) do |a|
42
+ a.assertion { ::File::exist?(template_location) }
43
43
  a.failure_message "Template source #{template_location} could not be found."
44
44
  a.whyrun "Template source #{template_location} does not exist. Assuming it would have been created."
45
45
  a.block_action!
@@ -54,7 +54,7 @@ class Chef
54
54
  Chef::Log.debug("#{@new_resource} content has not changed.")
55
55
  set_all_access_controls
56
56
  else
57
- description = []
57
+ description = []
58
58
  action_message = update ? "update #{@current_resource} from #{short_cksum(@current_resource.checksum)} to #{short_cksum(@new_resource.checksum)}" :
59
59
  "create #{@new_resource}"
60
60
  description << action_message
@@ -74,7 +74,7 @@ class Chef
74
74
  @new_resource.group(stat.gid)
75
75
  end
76
76
  end
77
- end
77
+ end
78
78
  end
79
79
 
80
80
 
@@ -112,6 +112,12 @@ class Chef
112
112
  render_template(IO.read(template_location), context, &block)
113
113
  end
114
114
 
115
+ def managing_content?
116
+ return true if @new_resource.checksum
117
+ return true if !@new_resource.source.nil? && @action != :create_if_missing
118
+ false
119
+ end
120
+
115
121
  end
116
122
  end
117
123
  end
@@ -51,7 +51,15 @@ class Chef
51
51
 
52
52
  def check_lock
53
53
  status = popen4("passwd -S #{@new_resource.username}") do |pid, stdin, stdout, stderr|
54
- status_line = stdout.gets.split(' ')
54
+ output = stdout.gets
55
+ if whyrun_mode? && output.nil? && stderr.gets.match(/does not exist/)
56
+ # if we're in whyrun mode and the user is not yet created we assume it would be
57
+ return false
58
+ end
59
+
60
+ raise Chef::Exceptions::User, "Cannot determine if #{@new_resource} is locked!" if output.nil?
61
+
62
+ status_line = output.split(' ')
55
63
  case status_line[1]
56
64
  when /^P/
57
65
  @locked = false
@@ -0,0 +1,30 @@
1
+ #
2
+ # Author:: Phil Dibowitz (<phild@fb.com>)
3
+ # Copyright:: Copyright (c) 2013 Facebook
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
+ class Chef
20
+ class Provider
21
+ class WhyrunSafeRubyBlock < Chef::Provider::RubyBlock
22
+ def action_create
23
+ @new_resource.block.call
24
+ @new_resource.updated_by_last_action(true)
25
+ @run_context.events.resource_update_applied(@new_resource, :create, "execute the whyrun_safe_ruby_block #{@new_resource.name}")
26
+ Chef::Log.info("#{@new_resource} called")
27
+ end
28
+ end
29
+ end
30
+ end
@@ -45,6 +45,7 @@ require 'chef/provider/service'
45
45
  require 'chef/provider/subversion'
46
46
  require 'chef/provider/template'
47
47
  require 'chef/provider/user'
48
+ require 'chef/provider/whyrun_safe_ruby_block'
48
49
 
49
50
  require 'chef/provider/env/windows'
50
51
 
@@ -31,6 +31,7 @@ class Chef
31
31
  @group_name = name
32
32
  @gid = nil
33
33
  @members = []
34
+ @excluded_members = []
34
35
  @action = :create
35
36
  @append = false
36
37
  @allowed_actions.push(:create, :remove, :modify, :manage)
@@ -62,7 +63,16 @@ class Chef
62
63
  end
63
64
 
64
65
  alias_method :users, :members
65
-
66
+
67
+ def excluded_members(arg=nil)
68
+ converted_members = arg.is_a?(String) ? [].push(arg) : arg
69
+ set_or_return(
70
+ :excluded_members,
71
+ converted_members,
72
+ :kind_of => [ Array ]
73
+ )
74
+ end
75
+
66
76
  def append(arg=nil)
67
77
  set_or_return(
68
78
  :append,
@@ -0,0 +1,31 @@
1
+ #
2
+ # Author:: Phil Dibowitz (<phild@fb.com>)
3
+ # Copyright:: Copyright (c) 2013 Facebook
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
+ class Chef
20
+ class Resource
21
+ class WhyrunSafeRubyBlock < Chef::Resource::RubyBlock
22
+
23
+ def initialize(name, run_context=nil)
24
+ super
25
+ @resource_name = :whyrun_safe_ruby_block
26
+ @provider = Chef::Provider::WhyrunSafeRubyBlock
27
+ end
28
+
29
+ end
30
+ end
31
+ end
@@ -64,4 +64,5 @@ require 'chef/resource/smartos_package'
64
64
  require 'chef/resource/template'
65
65
  require 'chef/resource/timestamped_deploy'
66
66
  require 'chef/resource/user'
67
+ require 'chef/resource/whyrun_safe_ruby_block'
67
68
  require 'chef/resource/yum_package'
data/lib/chef/rest.rb CHANGED
@@ -275,7 +275,11 @@ class Chef
275
275
  response_body
276
276
  end
277
277
  elsif redirect_location = redirected_to(response)
278
- follow_redirect {api_request(:GET, create_url(redirect_location))}
278
+ if [:GET, :HEAD].include?(method)
279
+ follow_redirect {api_request(method, create_url(redirect_location), headers)}
280
+ else
281
+ raise Exceptions::InvalidRedirect, "#{method} request was redirected from #{url} to #{redirect_location}. Only GET and HEAD support redirects."
282
+ end
279
283
  else
280
284
  # have to decompress the body before making an exception for it. But the body could be nil.
281
285
  response.body.replace(decompress_body(response)) if response.body.respond_to?(:replace)
@@ -332,7 +336,7 @@ class Chef
332
336
  tempfile = stream_to_tempfile(url, r, &block)
333
337
  yield tempfile
334
338
  ensure
335
- tempfile.close!
339
+ tempfile && tempfile.close!
336
340
  end
337
341
  else
338
342
  tempfile = stream_to_tempfile(url, r)
@@ -82,6 +82,10 @@ class Chef
82
82
  @url.host
83
83
  end
84
84
 
85
+ def hostname
86
+ @url.hostname
87
+ end
88
+
85
89
  def port
86
90
  @url.port
87
91
  end
@@ -155,12 +159,12 @@ class Chef
155
159
  def configure_http_client
156
160
  http_proxy = proxy_uri
157
161
  if http_proxy.nil?
158
- @http_client = Net::HTTP.new(host, port)
162
+ @http_client = Net::HTTP.new(hostname, port)
159
163
  else
160
164
  Chef::Log.debug("Using #{http_proxy.host}:#{http_proxy.port} for proxy")
161
165
  user = Chef::Config["#{url.scheme}_proxy_user"]
162
166
  pass = Chef::Config["#{url.scheme}_proxy_pass"]
163
- @http_client = Net::HTTP.Proxy(http_proxy.host, http_proxy.port, user, pass).new(host, port)
167
+ @http_client = Net::HTTP.Proxy(http_proxy.host, http_proxy.port, user, pass).new(hostname, port)
164
168
  end
165
169
  if url.scheme == HTTPS
166
170
  @http_client.use_ssl = true
@@ -63,7 +63,7 @@ class Chef::Util::Windows::NetGroup < Chef::Util::Windows
63
63
  members = 0.chr * (nread * (PTR_SIZE * 3)) #nread * sizeof(LOCALGROUP_MEMBERS_INFO_1)
64
64
  memcpy(members, ptr, members.size)
65
65
 
66
- #3 pointer fields in LOCALGROUP_MEMBERS_INFO_1, offset 2*PTR_SIZE is lgrmi1_name
66
+ # 3 pointer fields in LOCALGROUP_MEMBERS_INFO_1, offset 2*PTR_SIZE is lgrmi1_name
67
67
  nread.times do |i|
68
68
  offset = (i * 3) + 2
69
69
  member = lpwstr_to_s(members, offset)
@@ -92,6 +92,10 @@ class Chef::Util::Windows::NetGroup < Chef::Util::Windows
92
92
  modify_members(members, NetLocalGroupAddMembers)
93
93
  end
94
94
 
95
+ def local_delete_members(members)
96
+ modify_members(members, NetLocalGroupDelMembers)
97
+ end
98
+
95
99
  def local_delete
96
100
  rc = NetLocalGroupDel.call(nil, @name)
97
101
  if rc != NERR_Success
data/lib/chef/version.rb CHANGED
@@ -17,7 +17,7 @@
17
17
 
18
18
  class Chef
19
19
  CHEF_ROOT = File.dirname(File.expand_path(File.dirname(__FILE__)))
20
- VERSION = '10.28.2'
20
+ VERSION = '10.30.0.rc.0'
21
21
  end
22
22
 
23
23
  # NOTE: the Chef::Version class is defined in version_class.rb
@@ -0,0 +1,40 @@
1
+ #
2
+ # Author:: Kaustubh Deorukhkar (<kaustubh@clogeny.com>)
3
+ # Copyright:: Copyright (c) 2013 Opscode, 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
+ def ohai
22
+ # provider is platform-dependent, we need platform ohai data:
23
+ @OHAI_SYSTEM ||= begin
24
+ ohai = Ohai::System.new
25
+ ohai.require_plugin("os")
26
+ ohai.require_plugin("platform")
27
+ ohai.require_plugin("passwd")
28
+ ohai
29
+ end
30
+ end
31
+
32
+ def run_context
33
+ @run_context ||= begin
34
+ node = Chef::Node.new
35
+ node.default[:platform] = ohai[:platform]
36
+ node.default[:platform_version] = ohai[:platform_version]
37
+ events = Chef::EventDispatch::Dispatcher.new
38
+ Chef::RunContext.new(node, {}, events)
39
+ end
40
+ end
@@ -0,0 +1,343 @@
1
+ #
2
+ # Author:: Chirag Jog (<chirag@clogeny.com>)
3
+ # Author:: Siddheshwar More (<siddheshwar.more@clogeny.com>)
4
+ # Copyright:: Copyright (c) 2013 Opscode, Inc.
5
+ # License:: Apache License, Version 2.0
6
+ #
7
+ # Licensed under the Apache License, Version 2.0 (the "License");
8
+ # you may not use this file except in compliance with the License.
9
+ # You may obtain a copy of the License at
10
+ #
11
+ # http://www.apache.org/licenses/LICENSE-2.0
12
+ #
13
+ # Unless required by applicable law or agreed to in writing, software
14
+ # distributed under the License is distributed on an "AS IS" BASIS,
15
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16
+ # See the License for the specific language governing permissions and
17
+ # limitations under the License.
18
+ #
19
+
20
+ require 'spec_helper'
21
+ require 'functional/resource/base'
22
+
23
+ # Chef::Resource::Group are turned off on Mac OS X 10.6 due to caching
24
+ # issues around Etc.getgrnam() not picking up the group membership
25
+ # changes that are done on the system. Etc.endgrent is not functioning
26
+ # correctly on certain 10.6 boxes.
27
+ describe Chef::Resource::Group, :requires_root_or_running_windows, :not_supported_on_mac_osx_106 do
28
+ def group_should_exist(group)
29
+ case ohai[:platform_family]
30
+ when "debian", "fedora", "rhel", "suse", "gentoo", "slackware", "arch"
31
+ expect { Etc::getgrnam(group) }.to_not raise_error(ArgumentError, "can't find group for #{group}")
32
+ expect(group).to eq(Etc::getgrnam(group).name)
33
+ when "windows"
34
+ expect { Chef::Util::Windows::NetGroup.new(group).local_get_members }.to_not raise_error(ArgumentError, "The group name could not be found.")
35
+ end
36
+ end
37
+
38
+ def user_exist_in_group?(user)
39
+ case ohai[:platform_family]
40
+ when "windows"
41
+ Chef::Util::Windows::NetGroup.new(group_name).local_get_members.include?(user)
42
+ else
43
+ Etc::getgrnam(group_name).mem.include?(user)
44
+ end
45
+ end
46
+
47
+ def group_should_not_exist(group)
48
+ case ohai[:platform_family]
49
+ when "debian", "fedora", "rhel", "suse", "gentoo", "slackware", "arch"
50
+ expect { Etc::getgrnam(group) }.to raise_error(ArgumentError, "can't find group for #{group}")
51
+ when "windows"
52
+ expect { Chef::Util::Windows::NetGroup.new(group).local_get_members }.to raise_error(ArgumentError, "The group name could not be found.")
53
+ end
54
+ end
55
+
56
+ def compare_gid(resource, gid)
57
+ return resource.gid == Etc::getgrnam(resource.name).gid if unix?
58
+ end
59
+
60
+ def user(username)
61
+ usr = Chef::Resource::User.new("#{username}", run_context)
62
+ if ohai[:platform_family] == "windows"
63
+ usr.password("ComplexPass11!")
64
+ end
65
+ usr
66
+ end
67
+
68
+ def create_user(username)
69
+ user(username).run_action(:create)
70
+ # TODO: User shouldn't exist
71
+ end
72
+
73
+ def remove_user(username)
74
+ user(username).run_action(:remove)
75
+ # TODO: User shouldn't exist
76
+ end
77
+
78
+ shared_examples_for "correct group management" do
79
+ def add_members_to_group(members)
80
+ temp_resource = group_resource.dup
81
+ temp_resource.members(members)
82
+ temp_resource.excluded_members([ ])
83
+ temp_resource.append(true)
84
+ temp_resource.run_action(:modify)
85
+ members.each do |member|
86
+ user_exist_in_group?(member).should == true
87
+ end
88
+ end
89
+
90
+ def create_group
91
+ temp_resource = group_resource.dup
92
+ temp_resource.members([ ])
93
+ temp_resource.excluded_members([ ])
94
+ temp_resource.run_action(:create)
95
+ group_should_exist(group_name)
96
+ included_members.each do |member|
97
+ user_exist_in_group?(member).should == false
98
+ end
99
+ end
100
+
101
+ before(:each) do
102
+ create_group
103
+ end
104
+
105
+ after(:each) do
106
+ group_resource.run_action(:remove)
107
+ group_should_not_exist(group_name)
108
+ end
109
+
110
+ describe "when append is not set" do
111
+ let(:included_members) { ["spec-Eric"] }
112
+
113
+ before do
114
+ create_user("spec-Eric")
115
+ create_user("spec-Gordon")
116
+ add_members_to_group(["spec-Gordon"])
117
+ end
118
+
119
+ after do
120
+ remove_user("spec-Eric")
121
+ remove_user("spec-Gordon")
122
+ end
123
+
124
+ it "should remove the existing users and add the new users to the group" do
125
+ group_resource.run_action(tested_action)
126
+
127
+ user_exist_in_group?("spec-Eric").should == true
128
+ user_exist_in_group?("spec-Gordon").should == false
129
+ end
130
+ end
131
+
132
+ describe "when append is set" do
133
+ before(:each) do
134
+ group_resource.append(true)
135
+ end
136
+
137
+ describe "when the users exist" do
138
+ before do
139
+ (included_members + excluded_members).each do |member|
140
+ create_user(member)
141
+ end
142
+ end
143
+
144
+ after do
145
+ (included_members + excluded_members).each do |member|
146
+ remove_user(member)
147
+ end
148
+ end
149
+
150
+ it "should add included members to the group" do
151
+ group_resource.run_action(tested_action)
152
+
153
+ included_members.each do |member|
154
+ user_exist_in_group?(member).should == true
155
+ end
156
+ excluded_members.each do |member|
157
+ user_exist_in_group?(member).should == false
158
+ end
159
+ end
160
+
161
+ describe "when group contains some users" do
162
+ before(:each) do
163
+ add_members_to_group([ "spec-Gordon", "spec-Anthony" ])
164
+ end
165
+
166
+ it "should add the included users and remove excluded users" do
167
+ group_resource.run_action(tested_action)
168
+
169
+ included_members.each do |member|
170
+ user_exist_in_group?(member).should == true
171
+ end
172
+ excluded_members.each do |member|
173
+ user_exist_in_group?(member).should == false
174
+ end
175
+ end
176
+ end
177
+ end
178
+
179
+ describe "when the users doesn't exist" do
180
+ describe "when append is not set" do
181
+ it "should raise an error" do
182
+ lambda { @grp_resource.run_action(tested_action) }.should raise_error
183
+ end
184
+ end
185
+
186
+ describe "when append is set" do
187
+ it "should raise an error" do
188
+ lambda { @grp_resource.run_action(tested_action) }.should raise_error
189
+ end
190
+ end
191
+ end
192
+ end
193
+ end
194
+
195
+ let(:group_name) { "cheftest-#{SecureRandom.random_number(9999)}" }
196
+ let(:included_members) { nil }
197
+ let(:excluded_members) { nil }
198
+ let(:group_resource) {
199
+ group = Chef::Resource::Group.new(group_name, run_context)
200
+ group.members(included_members)
201
+ group.excluded_members(excluded_members)
202
+ group
203
+ }
204
+
205
+ it "append should be false by default" do
206
+ group_resource.append.should == false
207
+ end
208
+
209
+ describe "group create action" do
210
+ after(:each) do
211
+ group_resource.run_action(:remove)
212
+ group_should_not_exist(group_name)
213
+ end
214
+
215
+ it "should create a group" do
216
+ group_resource.run_action(:create)
217
+ group_should_exist(group_name)
218
+ end
219
+
220
+ describe "when group name is length 256", :windows_only do
221
+ let!(:group_name) { "theoldmanwalkingdownthestreetalwayshadagood\
222
+ smileonhisfacetheoldmanwalkingdownthestreetalwayshadagoodsmileonhisface\
223
+ theoldmanwalkingdownthestreetalwayshadagoodsmileonhisfacetheoldmanwalking\
224
+ downthestreetalwayshadagoodsmileonhisfacetheoldmanwalkingdownthestree" }
225
+
226
+ it "should create a group" do
227
+ group_resource.run_action(:create)
228
+ group_should_exist(group_name)
229
+ end
230
+ end
231
+
232
+ describe "when group name length is more than 256", :windows_only do
233
+ let!(:group_name) { "theoldmanwalkingdownthestreetalwayshadagood\
234
+ smileonhisfacetheoldmanwalkingdownthestreetalwayshadagoodsmileonhisface\
235
+ theoldmanwalkingdownthestreetalwayshadagoodsmileonhisfacetheoldmanwalking\
236
+ downthestreetalwayshadagoodsmileonhisfacetheoldmanwalkingdownthestreeQQQQQQ" }
237
+
238
+ it "should not create a group" do
239
+ lambda { group_resource.run_action(:create) }.should raise_error
240
+ group_should_not_exist(group_name)
241
+ end
242
+ end
243
+
244
+ # not_supported_on_solaris because of the use of excluded_members
245
+ describe "should raise an error when same member is included in the members and excluded_members", :not_supported_on_solaris do
246
+ it "should raise an error" do
247
+ invalid_resource = group_resource.dup
248
+ invalid_resource.members(["Jack"])
249
+ invalid_resource.excluded_members(["Jack"])
250
+ lambda { invalid_resource.run_action(:create)}.should raise_error(Chef::Exceptions::ConflictingMembersInGroup)
251
+ end
252
+ end
253
+ end
254
+
255
+ describe "group remove action" do
256
+ describe "when there is a group" do
257
+ before do
258
+ group_resource.run_action(:create)
259
+ group_should_exist(group_name)
260
+ end
261
+
262
+ it "should remove a group" do
263
+ group_resource.run_action(:remove)
264
+ group_should_not_exist(group_name)
265
+ end
266
+ end
267
+
268
+ describe "when there is no group" do
269
+ it "should be no-op" do
270
+ group_resource.run_action(:remove)
271
+ group_should_not_exist(group_name)
272
+ end
273
+ end
274
+ end
275
+
276
+ describe "group modify action", :not_supported_on_solaris do
277
+ let(:included_members) { ["spec-Gordon", "spec-Eric"] }
278
+ let(:excluded_members) { ["spec-Anthony"] }
279
+ let(:tested_action) { :modify }
280
+
281
+ describe "when there is no group" do
282
+ it "should raise an error" do
283
+ lambda { group_resource.run_action(:modify) }.should raise_error
284
+ end
285
+ end
286
+
287
+ describe "when there is a group" do
288
+ it_behaves_like "correct group management"
289
+ end
290
+ end
291
+
292
+ describe "group manage action", :not_supported_on_solaris do
293
+ let(:included_members) { ["spec-Gordon", "spec-Eric"] }
294
+ let(:excluded_members) { ["spec-Anthony"] }
295
+ let(:tested_action) { :manage }
296
+
297
+ describe "when there is no group" do
298
+ it "should raise an error" do
299
+ lambda { group_resource.run_action(:manage) }.should_not raise_error
300
+ group_should_not_exist(group_name)
301
+ end
302
+ end
303
+
304
+ describe "when there is a group" do
305
+ it_behaves_like "correct group management"
306
+ end
307
+ end
308
+
309
+ describe "group resource with Usermod provider", :solaris_only do
310
+ describe "when excluded_members is set" do
311
+ let(:excluded_members) { ["spec-Anthony"] }
312
+
313
+ it ":manage should raise an error" do
314
+ lambda {group_resource.run_action(:manage) }.should raise_error
315
+ end
316
+
317
+ it ":modify should raise an error" do
318
+ lambda {group_resource.run_action(:modify) }.should raise_error
319
+ end
320
+
321
+ it ":create should raise an error" do
322
+ lambda {group_resource.run_action(:create) }.should raise_error
323
+ end
324
+ end
325
+
326
+ describe "when append is not set" do
327
+ let(:included_members) { ["spec-Gordon", "spec-Eric"] }
328
+
329
+ before(:each) do
330
+ group_resource.append(false)
331
+ end
332
+
333
+ it ":manage should raise an error" do
334
+ lambda {group_resource.run_action(:manage) }.should raise_error
335
+ end
336
+
337
+ it ":modify should raise an error" do
338
+ lambda {group_resource.run_action(:modify) }.should raise_error
339
+ end
340
+ end
341
+ end
342
+ end
343
+