From 093f0737205d00c478516001b3dd5577d94bb124 Mon Sep 17 00:00:00 2001 From: Tom Preston-Werner Date: Sat, 16 Jun 2007 18:34:07 -0700 Subject: [PATCH] started implementation of System::Process --- lib/god.rb | 6 ++++- lib/god/system/process.rb | 55 +++++++++++++++++++++++++++++++++++++++++++++ test/test_helper.rb | 29 ++++++++++++++++++++++++ test/test_system_process.rb | 51 +++++++++++++++++++++++++++++++++++++++++ 4 files changed, 140 insertions(+), 1 deletion(-) create mode 100644 lib/god/system/process.rb create mode 100644 test/test_system_process.rb diff --git a/lib/god.rb b/lib/god.rb index 76c2526..a55a6be 100644 --- a/lib/god.rb +++ b/lib/god.rb @@ -3,10 +3,14 @@ $:.unshift File.dirname(__FILE__) # For use/testing when no gem is installed # internal requires require 'god/base' require 'god/errors' + +require 'god/system/process' + require 'god/condition' +require 'god/conditions/process_not_running' + require 'god/watch' require 'god/meddle' -require 'god/conditions/process_not_running' module God VERSION = '0.1.0' diff --git a/lib/god/system/process.rb b/lib/god/system/process.rb new file mode 100644 index 0000000..e2c0e72 --- /dev/null +++ b/lib/god/system/process.rb @@ -0,0 +1,55 @@ +module God + module System + + class Process + def initialize(pid) + @pid = pid.to_i + end + + # Return true if this process is running, false otherwise + def exists? + !ps_string('command').empty? + end + + # Memory usage in kilobytes (resident set size) + def memory + ps_int('rss') + end + + # Percentage memory usage + def percent_memory + ps_float('%mem') + end + + # Percentage CPU usage + def percent_cpu + ps_float('%cpu') + end + + # Seconds of CPU time (accumulated cpu time, user + system) + def cpu_time + time_string_to_seconds(ps_string('time')) + end + + private + + def ps_int(keyword) + `ps -o #{keyword}= -p #{@pid}`.to_i + end + + def ps_float(keyword) + `ps -o #{keyword}= -p #{@pid}`.to_f + end + + def ps_string(keyword) + `ps -o #{keyword}= -p #{@pid}`.strip + end + + def time_string_to_seconds(text) + _, minutes, seconds, useconds = *text.match(/(\d+):(\d{2}).(\d{2})/) + (minutes.to_i * 60) + seconds.to_i + end + end + + end +end \ No newline at end of file diff --git a/test/test_helper.rb b/test/test_helper.rb index 36f19a4..db0ab66 100644 --- a/test/test_helper.rb +++ b/test/test_helper.rb @@ -23,3 +23,32 @@ module God end end + +# This allows you to be a good OOP citizen and honor encapsulation, but +# still make calls to private methods (for testing) by doing +# +# obj.bypass.private_thingie(arg1, arg2) +# +# Which is easier on the eye than +# +# obj.send(:private_thingie, arg1, arg2) +# +class Object + class Bypass + instance_methods.each do |m| + undef_method m unless m =~ /^__/ + end + + def initialize(ref) + @ref = ref + end + + def method_missing(sym, *args) + @ref.__send__(sym, *args) + end + end + + def bypass + Bypass.new(self) + end +end \ No newline at end of file diff --git a/test/test_system_process.rb b/test/test_system_process.rb new file mode 100644 index 0000000..e8569da --- /dev/null +++ b/test/test_system_process.rb @@ -0,0 +1,51 @@ +require 'test_helper' + +class TestSystemProcessCreation < Test::Unit::TestCase + def test_new_should_succeed_for_existing_pid + pid = Process.pid + assert_nothing_raised do + @process = System::Process.new(pid) + end + end +end + +class TestSystemProcess < Test::Unit::TestCase + def setup + pid = Process.pid + @process = System::Process.new(pid) + end + + def test_exists_should_return_true_for_running_process + assert_equal true, @process.exists? + end + + def test_exists_should_return_false_for_non_existant_process + assert_equal false, System::Process.new(0).exists? + end + + def test_memory + assert_kind_of Integer, @process.memory + assert @process.memory > 0 + end + + def test_percent_cpu + assert_kind_of Float, @process.percent_mem + end + + def test_percent_cpu + assert_kind_of Float, @process.percent_cpu + end + + def test_cpu_time + assert_kind_of Integer, @process.cpu_time + end + + def test_time_string_to_seconds + assert_equal 0, @process.bypass.time_string_to_seconds('0:00:00') + assert_equal 0, @process.bypass.time_string_to_seconds('0:00:55') + assert_equal 27, @process.bypass.time_string_to_seconds('0:27:32') + assert_equal 75, @process.bypass.time_string_to_seconds('1:15:13') + assert_equal 735, @process.bypass.time_string_to_seconds('12:15:13') + end +end + -- 2.11.4.GIT