diff options
-rw-r--r-- | lib/chef/provider/service/windows.rb | 12 | ||||
-rw-r--r-- | lib/chef/resource/service.rb | 21 | ||||
-rw-r--r-- | spec/unit/provider/service/windows_spec.rb | 19 |
3 files changed, 40 insertions, 12 deletions
diff --git a/lib/chef/provider/service/windows.rb b/lib/chef/provider/service/windows.rb index ae4f29b1b3..beda766b17 100644 --- a/lib/chef/provider/service/windows.rb +++ b/lib/chef/provider/service/windows.rb @@ -41,6 +41,8 @@ class Chef::Provider::Service::Windows < Chef::Provider::Service START_PENDING = 'start pending' STOP_PENDING = 'stop pending' + TIMEOUT = 60 + def whyrun_supported? false end @@ -76,11 +78,11 @@ class Chef::Provider::Service::Windows < Chef::Provider::Service end end @new_resource.updated_by_last_action(true) - else + else raise Chef::Exceptions::Service, "Service #{@new_resource} can't be started from state [#{state}]" end else - Chef::Log.debug "#{@new_resource} does not exist - nothing to do" + Chef::Log.debug "#{@new_resource} does not exist - nothing to do" end end @@ -175,12 +177,14 @@ class Chef::Provider::Service::Windows < Chef::Provider::Service sleep 1 until current_state == desired_state end - # There ain't no party like a thread party... def spawn_command_thread worker = Thread.new do yield end - Timeout.timeout(60) do + + resource_timeout = @new_resource.timeout if @new_resource.timeout + resource_timeout ||= TIMEOUT + Timeout.timeout(resource_timeout) do worker.join end end diff --git a/lib/chef/resource/service.rb b/lib/chef/resource/service.rb index 94eca259f0..4d64c3e3f4 100644 --- a/lib/chef/resource/service.rb +++ b/lib/chef/resource/service.rb @@ -42,6 +42,7 @@ class Chef @reload_command = nil @init_command = nil @priority = nil + @timeout = nil @action = "nothing" @supports = { :restart => false, :reload => false, :status => false } @allowed_actions.push(:enable, :disable, :start, :stop, :restart, :reload) @@ -154,16 +155,28 @@ class Chef # similar for other runlevels # def priority(arg=nil) - set_or_return(:priority, - arg, - :kind_of => [ Integer, String, Hash ]) + set_or_return( + :priority, + arg, + :kind_of => [ Integer, String, Hash ] + ) + end + + # timeout only applies to the windows service manager + def timeout(arg=nil) + set_or_return( + :timeout, + arg, + :kind_of => Integer + ) end def parameters(arg=nil) set_or_return( :parameters, arg, - :kind_of => [ Hash ] ) + :kind_of => [ Hash ] + ) end def supports(args={}) diff --git a/spec/unit/provider/service/windows_spec.rb b/spec/unit/provider/service/windows_spec.rb index a007e7b984..33d3cde8fd 100644 --- a/spec/unit/provider/service/windows_spec.rb +++ b/spec/unit/provider/service/windows_spec.rb @@ -92,7 +92,7 @@ describe Chef::Provider::Service::Windows, "load_current_resource" do @provider.start_service @new_resource.updated_by_last_action?.should be_false end - + it "should raise an error if the service is paused" do Win32::Service.stub(:status).with(@new_resource.service_name).and_return( double("StatusStruct", :current_state => "paused")) @@ -112,7 +112,7 @@ describe Chef::Provider::Service::Windows, "load_current_resource" do @provider.start_service @new_resource.updated_by_last_action?.should be_false end - + it "should fail if the service is in stop_pending" do Win32::Service.stub(:status).with(@new_resource.service_name).and_return( double("StatusStruct", :current_state => "stop pending")) @@ -161,7 +161,7 @@ describe Chef::Provider::Service::Windows, "load_current_resource" do @provider.stop_service @new_resource.updated_by_last_action?.should be_false end - + it "should raise an error if the service is paused" do Win32::Service.stub(:status).with(@new_resource.service_name).and_return( double("StatusStruct", :current_state => "paused")) @@ -170,7 +170,7 @@ describe Chef::Provider::Service::Windows, "load_current_resource" do expect { @provider.stop_service }.to raise_error( Chef::Exceptions::Service ) @new_resource.updated_by_last_action?.should be_false end - + it "should wait and continue if the service is in stop_pending" do Win32::Service.stub(:status).with(@new_resource.service_name).and_return( double("StatusStruct", :current_state => "stop pending"), @@ -191,6 +191,17 @@ describe Chef::Provider::Service::Windows, "load_current_resource" do @new_resource.updated_by_last_action?.should be_false end + it "should pass custom timeout to the stop command if provided" do + Win32::Service.stub!(:status).with(@new_resource.service_name).and_return( + mock("StatusStruct", :current_state => "running")) + @new_resource.timeout 1 + Win32::Service.should_receive(:stop).with(@new_resource.service_name) + Timeout.timeout(2) do + expect { @provider.stop_service }.to raise_error(Timeout::Error) + end + @new_resource.updated_by_last_action?.should be_false + end + end describe Chef::Provider::Service::Windows, "restart_service" do |