chef 10.14.0.beta.2 → 10.14.0.beta.3

Sign up to get free protection for your applications and to get access to all the features.
Files changed (100) hide show
  1. data/distro/common/html/chef-client.8.html +3 -3
  2. data/distro/common/html/chef-expander.8.html +3 -3
  3. data/distro/common/html/chef-expanderctl.8.html +3 -3
  4. data/distro/common/html/chef-server-webui.8.html +3 -3
  5. data/distro/common/html/chef-server.8.html +3 -3
  6. data/distro/common/html/chef-solo.8.html +3 -3
  7. data/distro/common/html/chef-solr.8.html +3 -3
  8. data/distro/common/html/knife-bootstrap.1.html +3 -3
  9. data/distro/common/html/knife-client.1.html +3 -3
  10. data/distro/common/html/knife-configure.1.html +4 -4
  11. data/distro/common/html/knife-cookbook-site.1.html +6 -6
  12. data/distro/common/html/knife-cookbook.1.html +3 -3
  13. data/distro/common/html/knife-data-bag.1.html +3 -3
  14. data/distro/common/html/knife-environment.1.html +6 -6
  15. data/distro/common/html/knife-exec.1.html +4 -4
  16. data/distro/common/html/knife-index.1.html +3 -3
  17. data/distro/common/html/knife-node.1.html +3 -3
  18. data/distro/common/html/knife-role.1.html +3 -3
  19. data/distro/common/html/knife-search.1.html +3 -3
  20. data/distro/common/html/knife-ssh.1.html +4 -4
  21. data/distro/common/html/knife-status.1.html +4 -4
  22. data/distro/common/html/knife-tag.1.html +4 -4
  23. data/distro/common/html/knife.1.html +3 -3
  24. data/distro/common/html/shef.1.html +7 -7
  25. data/distro/common/man/man1/knife-bootstrap.1 +1 -1
  26. data/distro/common/man/man1/knife-client.1 +1 -1
  27. data/distro/common/man/man1/knife-configure.1 +1 -1
  28. data/distro/common/man/man1/knife-cookbook-site.1 +1 -1
  29. data/distro/common/man/man1/knife-cookbook.1 +1 -1
  30. data/distro/common/man/man1/knife-data-bag.1 +1 -1
  31. data/distro/common/man/man1/knife-environment.1 +1 -1
  32. data/distro/common/man/man1/knife-exec.1 +1 -1
  33. data/distro/common/man/man1/knife-index.1 +1 -1
  34. data/distro/common/man/man1/knife-node.1 +1 -1
  35. data/distro/common/man/man1/knife-role.1 +1 -1
  36. data/distro/common/man/man1/knife-search.1 +1 -1
  37. data/distro/common/man/man1/knife-ssh.1 +1 -1
  38. data/distro/common/man/man1/knife-status.1 +1 -1
  39. data/distro/common/man/man1/knife-tag.1 +1 -1
  40. data/distro/common/man/man1/knife.1 +1 -1
  41. data/distro/common/man/man1/shef.1 +1 -1
  42. data/distro/common/man/man8/chef-client.8 +1 -1
  43. data/distro/common/man/man8/chef-expander.8 +1 -1
  44. data/distro/common/man/man8/chef-expanderctl.8 +1 -1
  45. data/distro/common/man/man8/chef-server-webui.8 +1 -1
  46. data/distro/common/man/man8/chef-server.8 +1 -1
  47. data/distro/common/man/man8/chef-solo.8 +1 -1
  48. data/distro/common/man/man8/chef-solr.8 +1 -1
  49. data/lib/chef/application/client.rb +6 -2
  50. data/lib/chef/application/solo.rb +7 -3
  51. data/lib/chef/application/windows_service.rb +1 -2
  52. data/lib/chef/client.rb +72 -47
  53. data/lib/chef/config.rb +3 -1
  54. data/lib/chef/cookbook_uploader.rb +28 -18
  55. data/lib/chef/cookbook_version.rb +2 -2
  56. data/lib/chef/event_dispatch/base.rb +4 -0
  57. data/lib/chef/exceptions.rb +1 -0
  58. data/lib/chef/formatters/base.rb +13 -9
  59. data/lib/chef/formatters/error_inspectors/compile_error_inspector.rb +12 -6
  60. data/lib/chef/formatters/error_inspectors/resource_failure_inspector.rb +1 -2
  61. data/lib/chef/formatters/error_mapper.rb +13 -6
  62. data/lib/chef/knife/bootstrap.rb +4 -4
  63. data/lib/chef/knife/bootstrap/ubuntu12.04-gems.erb +2 -2
  64. data/lib/chef/knife/client_create.rb +1 -0
  65. data/lib/chef/knife/cookbook_upload.rb +60 -33
  66. data/lib/chef/knife/core/node_presenter.rb +1 -0
  67. data/lib/chef/knife/tag_delete.rb +1 -1
  68. data/lib/chef/mixin/file_class.rb +46 -0
  69. data/lib/chef/provider/cron.rb +1 -1
  70. data/lib/chef/provider/deploy.rb +1 -1
  71. data/lib/chef/provider/link.rb +2 -18
  72. data/lib/chef/provider/package/apt.rb +7 -4
  73. data/lib/chef/provider/remote_directory.rb +17 -5
  74. data/lib/chef/provider/user/useradd.rb +1 -0
  75. data/lib/chef/resource_reporter.rb +4 -4
  76. data/lib/chef/rest.rb +8 -0
  77. data/lib/chef/run_context.rb +4 -1
  78. data/lib/chef/solr_query/lucene.treetop +2 -2
  79. data/lib/chef/version.rb +1 -1
  80. data/spec/support/shared/functional/file_resource.rb +2 -1
  81. data/spec/support/shared/functional/securable_resource.rb +28 -12
  82. data/spec/unit/client_spec.rb +49 -13
  83. data/spec/unit/formatters/error_inspectors/resource_failure_inspector_spec.rb +21 -1
  84. data/spec/unit/knife/config_file_selection_spec.rb +5 -4
  85. data/spec/unit/knife/cookbook_upload_spec.rb +4 -3
  86. data/spec/unit/mixin/enforce_ownership_and_permissions_spec.rb +21 -0
  87. data/spec/unit/provider/cookbook_file_spec.rb +2 -0
  88. data/spec/unit/provider/cron_spec.rb +46 -0
  89. data/spec/unit/provider/deploy_spec.rb +12 -0
  90. data/spec/unit/provider/execute_spec.rb +3 -0
  91. data/spec/unit/provider/file_spec.rb +9 -6
  92. data/spec/unit/provider/package/apt_spec.rb +13 -0
  93. data/spec/unit/provider/remote_directory_spec.rb +16 -5
  94. data/spec/unit/provider/template_spec.rb +10 -0
  95. data/spec/unit/provider/user/useradd_spec.rb +2 -2
  96. data/spec/unit/provider/user_spec.rb +28 -17
  97. data/spec/unit/resource/file_spec.rb +14 -7
  98. data/spec/unit/resource/template_spec.rb +13 -6
  99. data/spec/unit/solr_query/query_transform_spec.rb +4 -0
  100. metadata +5 -4
@@ -66,6 +66,26 @@ describe Chef::Formatters::ErrorInspectors::ResourceFailureInspector do
66
66
  @description.display(@outputter)
67
67
  end
68
68
 
69
- end
69
+ describe "recipe_snippet" do
70
+ before do
71
+ # fake code to run through #recipe_snippet
72
+ source_file = [ "if true", "var = non_existant", "end" ]
73
+ IO.stub!(:readlines).and_return(source_file)
74
+ end
75
+
76
+ it "parses a Windows path" do
77
+ source_line = "C:/Users/btm/chef/chef/spec/unit/fake_file.rb:2: undefined local variable or method `non_existant' for main:Object (NameError)"
78
+ @resource.source_line = source_line
79
+ @inspector = Chef::Formatters::ErrorInspectors::ResourceFailureInspector.new(@resource, :create, @exception)
80
+ @inspector.recipe_snippet.should match(/^# In C:\/Users\/btm/)
81
+ end
70
82
 
83
+ it "parses a unix path" do
84
+ source_line = "/home/btm/src/chef/chef/spec/unit/fake_file.rb:2: undefined local variable or method `non_existant' for main:Object (NameError)"
85
+ @resource.source_line = source_line
86
+ @inspector = Chef::Formatters::ErrorInspectors::ResourceFailureInspector.new(@resource, :create, @exception)
87
+ @inspector.recipe_snippet.should match(/^# In \/home\/btm/)
88
+ end
89
+ end
90
+ end
71
91
  end
@@ -17,6 +17,7 @@
17
17
  #
18
18
 
19
19
  require File.expand_path(File.dirname(__FILE__) + '/../../spec_helper')
20
+ require 'tmpdir'
20
21
 
21
22
  describe Chef::Knife do
22
23
  before :each do
@@ -24,11 +25,11 @@ describe Chef::Knife do
24
25
  end
25
26
 
26
27
  it "configure knife from KNIFE_HOME env variable" do
27
- env_config = File.expand_path('/tmp/knife.rb')
28
+ env_config = File.expand_path(File.join(Dir.tmpdir, 'knife.rb'))
28
29
  File.stub!(:exist?).and_return(false)
29
30
  File.stub!(:exist?).with(env_config).and_return(true)
30
31
 
31
- ENV['KNIFE_HOME'] = '/tmp'
32
+ ENV['KNIFE_HOME'] = Dir.tmpdir
32
33
  @knife = Chef::Knife.new
33
34
  @knife.configure_chef
34
35
  @knife.config[:config_file].should == env_config
@@ -78,7 +79,7 @@ describe Chef::Knife do
78
79
  end
79
80
 
80
81
  it "configure knife precedence" do
81
- env_config = '/tmp/knife.rb'
82
+ env_config = File.join(Dir.tmpdir, 'knife.rb')
82
83
  pwd_config = "#{Dir.pwd}/knife.rb"
83
84
  upward_dir = File.expand_path "#{Dir.pwd}/.chef"
84
85
  upward_config = File.expand_path "#{upward_dir}/knife.rb"
@@ -88,7 +89,7 @@ describe Chef::Knife do
88
89
  configs.include? arg
89
90
  end
90
91
  Chef::Knife.stub!(:chef_config_dir).and_return(upward_dir)
91
- ENV['KNIFE_HOME'] = '/tmp'
92
+ ENV['KNIFE_HOME'] = Dir.tmpdir
92
93
 
93
94
  @knife = Chef::Knife.new
94
95
  @knife.configure_chef
@@ -81,6 +81,7 @@ describe Chef::Knife::CookbookUpload do
81
81
  "test_cookbook2" => @test_cookbook2,
82
82
  "test_cookbook3" => @test_cookbook3 }[ckbk]
83
83
  end
84
+ @knife.stub!(:cookbook_names).and_return(["test_cookbook1", "test_cookbook2", "test_cookbook3"])
84
85
  @knife.should_receive(:upload).exactly(3).times
85
86
  Timeout::timeout(5) do
86
87
  @knife.run
@@ -104,13 +105,13 @@ describe Chef::Knife::CookbookUpload do
104
105
  end
105
106
 
106
107
  it 'should upload all cookbooks' do
107
- @knife.should_receive(:upload).twice
108
+ @knife.should_receive(:upload).once
108
109
  @knife.run
109
110
  end
110
111
 
111
112
  it 'should report on success' do
112
- @knife.should_receive(:upload).twice
113
- @knife.ui.should_receive(:info).with(/Uploaded 2 cookbooks/)
113
+ @knife.should_receive(:upload).once
114
+ @knife.ui.should_receive(:info).with(/Uploaded all cookbooks/)
114
115
  @knife.run
115
116
  end
116
117
 
@@ -17,6 +17,8 @@
17
17
  #
18
18
 
19
19
  require 'spec_helper'
20
+ require 'etc'
21
+ require 'ostruct'
20
22
 
21
23
  describe Chef::Mixin::EnforceOwnershipAndPermissions do
22
24
 
@@ -40,7 +42,17 @@ describe Chef::Mixin::EnforceOwnershipAndPermissions do
40
42
  before do
41
43
  Chef::FileAccessControl.any_instance.stub(:uid_from_resource).and_return(0)
42
44
  Chef::FileAccessControl.any_instance.stub(:requires_changes?).and_return(false)
45
+
46
+ passwd_struct = if windows?
47
+ Struct::Passwd.new("root", "x", 0, 0, "/root", "/bin/bash")
48
+ else
49
+ Struct::Passwd.new("root", "x", 0, 0, "root", "/root", "/bin/bash")
50
+ end
51
+ group_struct = OpenStruct.new(:name => "root", :passwd => "x", :gid => 0)
52
+ Etc.stub!(:getpwuid).and_return(passwd_struct)
53
+ Etc.stub!(:getgrgid).and_return(group_struct)
43
54
  end
55
+
44
56
  it "does not set updated_by_last_action on the new resource" do
45
57
  @provider.new_resource.should_not_receive(:updated_by_last_action)
46
58
 
@@ -54,6 +66,15 @@ describe Chef::Mixin::EnforceOwnershipAndPermissions do
54
66
  before do
55
67
  Chef::FileAccessControl.any_instance.stub(:requires_changes?).and_return(true)
56
68
  Chef::FileAccessControl.any_instance.stub(:uid_from_resource).and_return(0)
69
+
70
+ passwd_struct = if windows?
71
+ Struct::Passwd.new("root", "x", 0, 0, "/root", "/bin/bash")
72
+ else
73
+ Struct::Passwd.new("root", "x", 0, 0, "root", "/root", "/bin/bash")
74
+ end
75
+ group_struct = OpenStruct.new(:name => "root", :passwd => "x", :gid => 0)
76
+ Etc.stub!(:getpwuid).and_return(passwd_struct)
77
+ Etc.stub!(:getgrgid).and_return(group_struct)
57
78
  end
58
79
 
59
80
  it "sets updated_by_last_action on the new resource" do
@@ -139,6 +139,8 @@ EXPECTED
139
139
  end
140
140
 
141
141
  it "stages the cookbook to a temporary file" do
142
+ # prevents file backups where we might not have write access
143
+ @provider.should_receive(:backup_new_resource)
142
144
  @new_resource.path(@install_to)
143
145
  @provider.should_receive(:deploy_tempfile)
144
146
  @provider.run_action(:create)
@@ -177,6 +177,42 @@ CRONTAB
177
177
  end
178
178
  end
179
179
 
180
+ context "with a matching entry in the user's crontab using month names and weekday names (#CHEF-3178)" do
181
+ before :each do
182
+ @provider.stub!(:read_crontab).and_return(<<-CRONTAB)
183
+ 0 2 * * * /some/other/command
184
+
185
+ # Chef Name: cronhole some stuff
186
+ * 5 * Jan Mon /bin/true param1 param2
187
+ # Chef Name: something else
188
+ 2 * 1 * * /bin/false
189
+
190
+ # Another comment
191
+ CRONTAB
192
+ end
193
+
194
+ it "should set cron_exists" do
195
+ @provider.load_current_resource
196
+ @provider.cron_exists.should == true
197
+ @provider.cron_empty.should == false
198
+ end
199
+
200
+ it "should pull the details out of the cron line" do
201
+ cron = @provider.load_current_resource
202
+ cron.minute.should == '*'
203
+ cron.hour.should == '5'
204
+ cron.day.should == '*'
205
+ cron.month.should == 'Jan'
206
+ cron.weekday.should == 'Mon'
207
+ cron.command.should == '/bin/true param1 param2'
208
+ end
209
+
210
+ it "should report the match" do
211
+ Chef::Log.should_receive(:debug).with("Found cron '#{@new_resource.name}'")
212
+ @provider.load_current_resource
213
+ end
214
+ end
215
+
180
216
  context "with a matching entry without a crontab line" do
181
217
  it "should set cron_exists and leave current_resource values at defaults" do
182
218
  @provider.stub!(:read_crontab).and_return(<<-CRONTAB)
@@ -263,6 +299,7 @@ CRONTAB
263
299
  describe "action_create" do
264
300
  before :each do
265
301
  @provider.stub!(:write_crontab)
302
+ @provider.stub!(:read_crontab).and_return(nil)
266
303
  end
267
304
 
268
305
  context "when there is no existing crontab" do
@@ -523,6 +560,14 @@ HOME=/home/foo
523
560
  before :each do
524
561
  @provider.cron_exists = true
525
562
  @provider.stub!(:cron_different?).and_return(false)
563
+ @provider.stub!(:read_crontab).and_return(<<-CRONTAB)
564
+ 0 2 * * * /some/other/command
565
+
566
+ # Chef Name: something else
567
+ * 5 * * * /bin/true
568
+
569
+ # Another comment
570
+ CRONTAB
526
571
  end
527
572
 
528
573
  it "should not update the crontab" do
@@ -545,6 +590,7 @@ HOME=/home/foo
545
590
  describe "action_delete" do
546
591
  before :each do
547
592
  @provider.stub!(:write_crontab)
593
+ @provider.stub!(:read_crontab).and_return(nil)
548
594
  end
549
595
 
550
596
  context "when the user's crontab has no matching section" do
@@ -67,6 +67,18 @@ describe Chef::Provider::Deploy do
67
67
  @provider.converge
68
68
  end
69
69
 
70
+ it "ensures the deploy_to dir ownership after the verfication that it exists" do
71
+ @provider.should_receive(:verify_directories_exist).ordered
72
+ @provider.should_receive(:enforce_ownership).ordered
73
+ @provider.stub(:copy_cached_repo)
74
+ @provider.stub(:update_cached_repo)
75
+ @provider.stub(:install_gems)
76
+ @provider.stub(:enforce_ownership)
77
+ @provider.stub(:symlink)
78
+ @provider.stub(:migrate)
79
+ @provider.deploy
80
+ end
81
+
70
82
  it "updates and copies the repo, then does a migrate, symlink, restart, restart, cleanup on deploy" do
71
83
  FileUtils.stub(:mkdir_p).with("/my/deploy/dir")
72
84
  FileUtils.stub(:mkdir_p).with("/my/deploy/dir/shared")
@@ -31,6 +31,9 @@ describe Chef::Provider::Execute do
31
31
  @provider = Chef::Provider::Execute.new(@new_resource, @run_context)
32
32
  @current_resource = Chef::Resource::Ifconfig.new("foo_resource", @run_context)
33
33
  @provider.current_resource = @current_resource
34
+ Chef::Log.level = :info
35
+ # FIXME: There should be a test for how STDOUT.tty? changes the live_stream option being passed
36
+ STDOUT.stub!(:tty?).and_return(true)
34
37
  end
35
38
 
36
39
 
@@ -18,6 +18,7 @@
18
18
 
19
19
 
20
20
  require 'spec_helper'
21
+ require 'tmpdir'
21
22
 
22
23
  describe Chef::Provider::File do
23
24
  before(:each) do
@@ -113,7 +114,7 @@ describe Chef::Provider::File do
113
114
 
114
115
  it "should create the file if it is missing, then set the attributes on action_create" do
115
116
  @provider.load_current_resource
116
- @provider.new_resource.stub!(:path).and_return("/tmp/monkeyfoo")
117
+ @provider.new_resource.stub!(:path).and_return(File.join(Dir.tmpdir, "monkeyfoo"))
117
118
  @provider.access_controls.should_receive(:set_all)
118
119
  @provider.should_receive(:diff_current_from_content).and_return("")
119
120
  File.stub!(:open).and_return(1)
@@ -127,7 +128,7 @@ describe Chef::Provider::File do
127
128
  io = StringIO.new
128
129
  @provider.load_current_resource
129
130
  @provider.new_resource.content "foobar"
130
- @provider.new_resource.stub!(:path).and_return("/tmp/monkeyfoo")
131
+ @provider.new_resource.stub!(:path).and_return(File.join(Dir.tmpdir, "monkeyfoo"))
131
132
  @provider.should_receive(:diff_current_from_content).and_return("")
132
133
  File.should_receive(:open).with(@provider.new_resource.path, "w+").and_yield(io)
133
134
  @provider.access_controls.should_receive(:set_all)
@@ -137,7 +138,7 @@ describe Chef::Provider::File do
137
138
  end
138
139
 
139
140
  it "should delete the file if it exists and is writable on action_delete" do
140
- @provider.new_resource.stub!(:path).and_return("/tmp/monkeyfoo")
141
+ @provider.new_resource.stub!(:path).and_return(File.join(Dir.tmpdir, "monkeyfoo"))
141
142
  @provider.stub!(:backup).and_return(true)
142
143
  File.should_receive("exists?").exactly(2).times.with(@provider.new_resource.path).and_return(true)
143
144
  File.should_receive("writable?").with(@provider.new_resource.path).and_return(true)
@@ -147,7 +148,7 @@ describe Chef::Provider::File do
147
148
  end
148
149
 
149
150
  it "should not raise an error if it cannot delete the file because it does not exist" do
150
- @provider.new_resource.stub!(:path).and_return("/tmp/monkeyfoo")
151
+ @provider.new_resource.stub!(:path).and_return(File.join(Dir.tmpdir, "monkeyfoo"))
151
152
  @provider.stub!(:backup).and_return(true)
152
153
  File.should_receive("exists?").exactly(2).times.with(@provider.new_resource.path).and_return(false)
153
154
  lambda { @provider.run_action(:delete) }.should_not raise_error()
@@ -156,7 +157,7 @@ describe Chef::Provider::File do
156
157
 
157
158
  it "should update the atime/mtime on action_touch" do
158
159
  @provider.load_current_resource
159
- @provider.new_resource.stub!(:path).and_return("/tmp/monkeyfoo")
160
+ @provider.new_resource.stub!(:path).and_return(File.join(Dir.tmpdir, "monkeyfoo"))
160
161
  @provider.should_receive(:diff_current_from_content).and_return("")
161
162
  File.should_receive(:utime).once.and_return(1)
162
163
  File.stub!(:open).and_return(1)
@@ -281,8 +282,10 @@ describe Chef::Provider::File do
281
282
  @resource.path file.path
282
283
  @provider = Chef::Provider::File.new(@resource, @run_context)
283
284
  @provider.load_current_resource
284
- result = @provider.diff_current_from_content "foo baz\n"
285
+ result = @provider.diff_current_from_content "foo baz"
285
286
  # remove the file name info which varies.
287
+ require 'pp'
288
+ pp result
286
289
  result.shift(2)
287
290
  result.should == ["@@ -0,0 +1 @@", "+foo baz"]
288
291
  end
@@ -215,6 +215,19 @@ SHOWPKG_STDOUT
215
215
 
216
216
  @provider.install_package("irssi", "0.8.12-7")
217
217
  end
218
+
219
+ it "should run apt-get install with the package name and version and default_release if there is one and provider is explicitly defined" do
220
+ @provider.should_receive(:run_command_with_systems_locale).with({
221
+ :command => "apt-get -q -y -o APT::Default-Release=lenny-backports install irssi=0.8.12-7",
222
+ :environment => {
223
+ "DEBIAN_FRONTEND" => "noninteractive"
224
+ }
225
+ })
226
+ @new_resource.stub!(:default_release).and_return("lenny-backports")
227
+ @new_resource.stub!(:provider).and_return("Chef::Provider::Package::Apt")
228
+
229
+ @provider.install_package("irssi", "0.8.12-7")
230
+ end
218
231
  end
219
232
 
220
233
  describe Chef::Provider::Package::Apt, "upgrade_package" do
@@ -19,6 +19,11 @@
19
19
  require 'spec_helper'
20
20
  require 'digest/md5'
21
21
  require 'tmpdir'
22
+ require 'chef/mixin/file_class'
23
+
24
+ class Chef::CFCCheck
25
+ include Chef::Mixin::FileClass
26
+ end
22
27
 
23
28
  describe Chef::Provider::RemoteDirectory do
24
29
  before do
@@ -153,14 +158,20 @@ describe Chef::Provider::RemoteDirectory do
153
158
  @provider.action = :create
154
159
  @provider.run_action
155
160
 
161
+ @fclass = Chef::CFCCheck.new
162
+
156
163
  Dir.mktmpdir do |tmp_dir|
157
- FileUtils.ln_s(tmp_dir, symlinked_dir_path)
158
- ::File.exist?(symlinked_dir_path).should be_true
164
+ begin
165
+ @fclass.file_class.symlink(tmp_dir.dup, symlinked_dir_path)
166
+ ::File.exist?(symlinked_dir_path).should be_true
159
167
 
160
- @provider.run_action
168
+ @provider.run_action
161
169
 
162
- ::File.exist?(symlinked_dir_path).should be_false
163
- ::File.exist?(tmp_dir).should be_true
170
+ ::File.exist?(symlinked_dir_path).should be_false
171
+ ::File.exist?(tmp_dir).should be_true
172
+ rescue Chef::Exceptions::Win32APIError => e
173
+ pending "This must be run as an Administrator to create symlinks"
174
+ end
164
175
  end
165
176
  end
166
177
  end
@@ -17,6 +17,8 @@
17
17
  #
18
18
  require 'stringio'
19
19
  require 'spec_helper'
20
+ require 'etc'
21
+ require 'ostruct'
20
22
 
21
23
  describe Chef::Provider::Template do
22
24
  before(:each) do
@@ -38,6 +40,14 @@ describe Chef::Provider::Template do
38
40
  @provider.current_resource = @current_resource
39
41
  @access_controls = mock("access controls")
40
42
  @provider.stub!(:access_controls).and_return(@access_controls)
43
+ passwd_struct = if windows?
44
+ Struct::Passwd.new("root", "x", 0, 0, "/root", "/bin/bash")
45
+ else
46
+ Struct::Passwd.new("root", "x", 0, 0, "root", "/root", "/bin/bash")
47
+ end
48
+ group_struct = OpenStruct.new(:name => "root", :passwd => "x", :gid => 0)
49
+ Etc.stub!(:getpwuid).and_return(passwd_struct)
50
+ Etc.stub!(:getgrgid).and_return(group_struct)
41
51
  end
42
52
 
43
53
  describe "when creating the template" do
@@ -199,13 +199,13 @@ describe Chef::Provider::User::Useradd do
199
199
  end
200
200
 
201
201
  it "runs usermod with the computed command options" do
202
- @provider.should_receive(:run_command).with({ :command => "usermod -g '23' -d '/Users/mud' adam" }).and_return(true)
202
+ @provider.should_receive(:run_command).with({ :command => "usermod -g '23' -d '/Users/mud' adam -m" }).and_return(true)
203
203
  @provider.manage_user
204
204
  end
205
205
 
206
206
  it "does not set the -r option to usermod" do
207
207
  @new_resource.system(true)
208
- @provider.should_receive(:run_command).with({ :command => "usermod -g '23' -d '/Users/mud' adam" }).and_return(true)
208
+ @provider.should_receive(:run_command).with({ :command => "usermod -g '23' -d '/Users/mud' adam -m" }).and_return(true)
209
209
  @provider.manage_user
210
210
  end
211
211
 
@@ -71,7 +71,7 @@ describe Chef::Provider::User do
71
71
  #)
72
72
  Chef::Resource::User.stub!(:new).and_return(@current_resource)
73
73
  @pw_user = EtcPwnamIsh.new
74
- @pw_user.uid = "adam"
74
+ @pw_user.name = "adam"
75
75
  @pw_user.gid = 1000
76
76
  @pw_user.uid = 1000
77
77
  @pw_user.gecos = "Adam Jacob"
@@ -133,33 +133,44 @@ describe Chef::Provider::User do
133
133
  end
134
134
 
135
135
  describe "and running assertions" do
136
- before do
137
- # We can only perform one of these tests if the
138
- # ruby-shadow library is installed.
139
- @shadow_lib_unavail = false
136
+ def self.shadow_lib_unavail?
140
137
  begin
138
+ require 'rubygems'
141
139
  require 'shadow'
142
- rescue LoadError
143
- @shadow_lib_unavail = true
140
+ rescue LoadError => e
141
+ pending "ruby-shadow gem not installed for dynamic load test"
142
+ true
143
+ else
144
+ false
144
145
  end
145
146
  end
146
147
 
147
148
  before (:each) do
148
- # force ruby-shadow library to be required
149
149
  user = @pw_user.dup
150
+ user.name = "root"
150
151
  user.passwd = "x"
151
152
  @new_resource.password "some new password"
152
153
  Etc.stub!(:getpwnam).and_return(user)
153
154
  end
154
-
155
- it "should pass assertions when ruby-shadow can be loaded" do
156
- pending "ruby-shadow gem not installed for dynamic load test" if @shadow_lib_unavail
157
- puts "SHADOW LIB UNAVAIL: #{@shadow_lib_unavail}"
158
- original_method = @provider.method(:require)
159
- @provider.should_receive(:require) { |*args| original_method.call(*args) }
160
- @provider.load_current_resource
161
- @provider.define_resource_requirements
162
- @provider.process_resource_requirements
155
+
156
+ unless shadow_lib_unavail?
157
+ context "and we have the ruby-shadow gem" do
158
+ pending "and we are not root (rerun this again as root)", :requires_unprivileged_user => true
159
+
160
+ context "and we are root", :requires_root => true do
161
+ it "should pass assertions when ruby-shadow can be loaded" do
162
+ @provider.action = 'create'
163
+ original_method = @provider.method(:require)
164
+ @provider.should_receive(:require) { |*args| original_method.call(*args) }
165
+ passwd_info = Struct::PasswdEntry.new(:sp_namp => "adm ", :sp_pwdp => "$1$T0N0Q.lc$nyG6pFI3Dpqa5cxUz/57j0", :sp_lstchg => 14861, :sp_min => 0, :sp_max => 99999,
166
+ :sp_warn => 7, :sp_inact => -1, :sp_expire => -1, :sp_flag => -1)
167
+ Shadow::Passwd.should_receive(:getspnam).with("adam").and_return(passwd_info)
168
+ @provider.load_current_resource
169
+ @provider.define_resource_requirements
170
+ @provider.process_resource_requirements
171
+ end
172
+ end
173
+ end
163
174
  end
164
175
 
165
176
  it "should fail assertions when ruby-shadow cannot be loaded" do