cpu 0.0.0

Sign up to get free protection for your applications and to get access to all the features.
data/Gemfile ADDED
@@ -0,0 +1,13 @@
1
+ # vim: set filetype=ruby et sw=2 ts=2:
2
+
3
+ source :rubygems
4
+
5
+ gemspec
6
+
7
+ group :development do
8
+ gem 'rake', '~>0.9.2'
9
+ gem 'sdoc', '~>0.2.20'
10
+ gem 'rcov', '~>0.9.9'
11
+ gem 'test-unit', '~>2.3.0'
12
+ gem 'mocha', '~>0.9.12'
13
+ end
File without changes
@@ -0,0 +1,121 @@
1
+ # vim: set filetype=ruby et sw=2 ts=2:
2
+
3
+ begin
4
+ require 'rubygems/package_task'
5
+ rescue LoadError
6
+ end
7
+ begin
8
+ require 'rcov/rcovtask'
9
+ rescue LoadError
10
+ end
11
+ require 'rake/clean'
12
+ require 'rake/testtask'
13
+ require 'rbconfig'
14
+ include Config
15
+
16
+ PKG_NAME = 'cpu'
17
+ PKG_VERSION = File.read('VERSION').chomp
18
+ PKG_FILES = FileList[*`git ls-files`.split(/\n/)].exclude '.gitignore'
19
+ CLEAN.include 'coverage', 'doc'
20
+ CLOBBER.include 'pkg'
21
+
22
+ desc "Install executable/library into site_ruby directories"
23
+ task :install do
24
+ bindir = CONFIG['bindir']
25
+ libdir = CONFIG['sitelibdir']
26
+ cd 'lib' do
27
+ for file in Dir['**/*.rb']
28
+ dest = File.join(libdir, file)
29
+ mkdir_p File.dirname(dest)
30
+ install file, dest, :verbose => true
31
+ end
32
+ end
33
+ install('bin/coretemp', bindir, :verbose => true, :mode => 0755)
34
+ end
35
+
36
+ desc "Create documentation"
37
+ task :doc do
38
+ sh "sdoc -m README.rdoc -t 'CPU' README.rdoc #{Dir['lib/**/*.rb'] * ' '}"
39
+ end
40
+
41
+ namespace :gems do
42
+ desc "Install all gems from the Gemfile"
43
+ task :install do
44
+ sh 'bundle install'
45
+ end
46
+ end
47
+
48
+ if defined? Gem
49
+ spec = Gem::Specification.new do |s|
50
+ s.name = PKG_NAME
51
+ s.version = PKG_VERSION
52
+ s.summary = "CPU information in Ruby/Linux"
53
+ s.description = "Library to gather CPU information (load averages, usage,"\
54
+ " temperature) in Ruby on Linux"
55
+
56
+ s.executables = 'coretemp'
57
+ s.files = PKG_FILES
58
+
59
+ s.require_path = 'lib'
60
+
61
+ s.add_dependency 'spruz', '~>0.2.2'
62
+
63
+ s.rdoc_options << '--main' << 'README.rdoc' << '--title' << 'CPU'
64
+ s.extra_rdoc_files << 'README.rdoc'
65
+ s.test_files.concat Dir['tests/test_*.rb']
66
+
67
+ s.author = "Florian Frank"
68
+ s.email = "flori@ping.de"
69
+ s.homepage = "http://flori.github.com/#{PKG_NAME}"
70
+ s.rubyforge_project = PKG_NAME
71
+ end
72
+
73
+ desc 'Create a gemspec file'
74
+ task :gemspec => :version do
75
+ File.open('cpu.gemspec', 'w') do |gemspec|
76
+ gemspec.write spec.to_ruby
77
+ end
78
+ end
79
+
80
+ Gem::PackageTask.new(spec) do |pkg|
81
+ pkg.need_tar = true
82
+ pkg.package_files += PKG_FILES
83
+ end
84
+ end
85
+
86
+
87
+ Rake::TestTask.new do |t|
88
+ t.test_files = FileList['tests/**/*_test.rb']
89
+ t.verbose = true
90
+ end
91
+
92
+ if defined? Rcov
93
+ Rcov::RcovTask.new do |t|
94
+ t.test_files = FileList['tests/**/*_test.rb']
95
+ t.verbose = true
96
+ t.rcov_opts = %w[-x '\\btests\/' -x '\\bgems\/']
97
+ end
98
+ end
99
+
100
+ desc m = "Writing version information for #{PKG_VERSION}"
101
+ task :version do
102
+ puts m
103
+ File.open(File.join('lib', 'cpu', 'version.rb'), 'w') do |v|
104
+ v.puts <<EOT
105
+ module CPU
106
+ # CPU version
107
+ VERSION = '#{PKG_VERSION}'
108
+ VERSION_ARRAY = VERSION.split(/\\./).map { |x| x.to_i } # :nodoc:
109
+ VERSION_MAJOR = VERSION_ARRAY[0] # :nodoc:
110
+ VERSION_MINOR = VERSION_ARRAY[1] # :nodoc:
111
+ VERSION_BUILD = VERSION_ARRAY[2] # :nodoc:
112
+ end
113
+ EOT
114
+ end
115
+ end
116
+
117
+ desc "Run the tests by default"
118
+ task :default => [ :version, :test ]
119
+
120
+ desc "Prepare release of the library"
121
+ task :release => [ :clean, :gemspec, :package ]
data/VERSION ADDED
@@ -0,0 +1 @@
1
+ 0.0.0
@@ -0,0 +1,87 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'cpu'
4
+ require 'spruz/go'
5
+ include Spruz::GO
6
+ require 'bullshit'
7
+
8
+ class ParseCommands
9
+ def self.parse(argv)
10
+ new(argv).parse
11
+ end
12
+
13
+ def initialize(argv)
14
+ @argv = argv
15
+ end
16
+
17
+ def set_t_j_max(temp)
18
+ t_j_max = temp and CPU.t_j_max = t_j_max.to_i
19
+ end
20
+
21
+ def create_history_path(filename)
22
+ filename ||= '~/.coretemp-history'
23
+ File.expand_path(filename)
24
+ end
25
+
26
+ def measure_temps(opts)
27
+ set_t_j_max opts['t']
28
+ CPU.each_core.map(&:temperature)
29
+ end
30
+
31
+ def simple
32
+ opts = go 't', @argv
33
+ puts measure_temps(opts) * ' '
34
+ end
35
+
36
+ def collect
37
+ opts = go 'tf', @argv
38
+ filename = create_history_path opts['f']
39
+ temperatures = measure_temps(opts)
40
+ line = ([ Time.now.to_f ] + temperatures) * ' '
41
+ if filename
42
+ open(filename, 'a') do |o|
43
+ o.puts line
44
+ end
45
+ end
46
+ end
47
+
48
+ def clear
49
+ opts = go 'f', @argv
50
+ filename = create_history_path opts['f']
51
+ if filename and File.exist?(filename)
52
+ File.unlink(filename)
53
+ end
54
+ end
55
+
56
+ def stats
57
+ opts = go 'f', @argv
58
+ filename = create_history_path opts['f']
59
+ if filename and File.exist?(filename)
60
+ history = open(filename, 'r') { |o|
61
+ o.map do |line|
62
+ time, *temps = line.split(/\s+/)
63
+ [ Time.at(Float(time)) ] + temps.map { |t| Integer(t) }
64
+ end
65
+ }
66
+ measurements_last = history.last[1..-1]
67
+ times, *measurements = history.transpose
68
+ analyses = measurements.map { |m| Bullshit::Analysis.new(m) }
69
+ puts " min: %s" % (analyses.map { |a| a.min } * ' ')
70
+ puts "last: %s" % (measurements_last * ' ')
71
+ puts " max: %s" % (analyses.map { |a| a.max } * ' ')
72
+ puts "mean: %s" % (analyses.map { |a| a.mean.round } * ' ')
73
+ end
74
+ end
75
+
76
+ def parse
77
+ case command = @argv.shift
78
+ when 'collect' then collect
79
+ when 'clear' then clear
80
+ when 'stats' then stats
81
+ when 'collect_stats' then collect; stats
82
+ else simple
83
+ end
84
+ end
85
+ end
86
+
87
+ ParseCommands.parse(ARGV)
@@ -0,0 +1,33 @@
1
+ # -*- encoding: utf-8 -*-
2
+
3
+ Gem::Specification.new do |s|
4
+ s.name = %q{cpu}
5
+ s.version = "0.0.0"
6
+
7
+ s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
8
+ s.authors = [%q{Florian Frank}]
9
+ s.date = %q{2011-07-03}
10
+ s.description = %q{Library to gather CPU information (load averages, usage, temperature) in Ruby on Linux}
11
+ s.email = %q{flori@ping.de}
12
+ s.executables = [%q{coretemp}]
13
+ s.extra_rdoc_files = [%q{README.rdoc}]
14
+ s.files = [%q{Gemfile}, %q{README.rdoc}, %q{Rakefile}, %q{VERSION}, %q{bin/coretemp}, %q{cpu.gemspec}, %q{lib/cpu.rb}, %q{lib/cpu/load.rb}, %q{lib/cpu/msr.rb}, %q{lib/cpu/processor.rb}, %q{lib/cpu/shared.rb}, %q{lib/cpu/usage.rb}, %q{lib/cpu/usage_sampler.rb}, %q{lib/cpu/version.rb}, %q{munin/coretemp}, %q{tests/load_test.rb}, %q{tests/msr_test.rb}, %q{tests/usage_test.rb}]
15
+ s.homepage = %q{http://flori.github.com/cpu}
16
+ s.rdoc_options = [%q{--main}, %q{README.rdoc}, %q{--title}, %q{CPU}]
17
+ s.require_paths = [%q{lib}]
18
+ s.rubyforge_project = %q{cpu}
19
+ s.rubygems_version = %q{1.8.5}
20
+ s.summary = %q{CPU information in Ruby/Linux}
21
+
22
+ if s.respond_to? :specification_version then
23
+ s.specification_version = 3
24
+
25
+ if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
26
+ s.add_runtime_dependency(%q<spruz>, ["~> 0.2.2"])
27
+ else
28
+ s.add_dependency(%q<spruz>, ["~> 0.2.2"])
29
+ end
30
+ else
31
+ s.add_dependency(%q<spruz>, ["~> 0.2.2"])
32
+ end
33
+ end
@@ -0,0 +1,121 @@
1
+ require 'spruz/uniq_by'
2
+ require 'cpu/shared'
3
+ require 'cpu/processor'
4
+ require 'cpu/msr'
5
+ require 'cpu/load'
6
+ require 'cpu/usage_sampler'
7
+ require 'cpu/usage'
8
+
9
+ # This module provides (read) access to the Model Specific Registers of Intel
10
+ # CPUs on Linux.
11
+ module CPU
12
+ class << self
13
+ # The t_j_max temperature of that is used as a default for this Processor
14
+ # if it cannot be queried (e.g. Core2 architecture). It defaults to 95
15
+ # which is the correct value for Core2 Duo E8400 (Wolfsdale). Be sure to
16
+ # set the correct value for your Core2 CPU here, otherwise your
17
+ # temperature measurements will be incorrect.
18
+ attr_accessor :t_j_max
19
+ end
20
+ self.t_j_max = 95
21
+
22
+ # XXX
23
+ class CPUError < StandardError; end
24
+
25
+ # This exception is thrown if an invalid ProcessorId is queried.
26
+ class InvalidProcessorIdError < CPUError; end
27
+
28
+ # XXX
29
+ class NoSampleDataError < CPUError; end
30
+
31
+ class << self
32
+ # The path to the modprobe binary which is used to load the required module
33
+ # if necessary.
34
+ attr_accessor :modprobe_path
35
+ end
36
+ self.modprobe_path = '/sbin/modprobe'
37
+
38
+ class << self
39
+ # Return an array of all Processor instances for this machine.
40
+ def processors
41
+ cpu_cores = {}
42
+ cpuinfos = File.read('/proc/cpuinfo').chomp.split(/^$/)
43
+ processor_ids =
44
+ cpuinfos.map { |l| l[/processor\s*:\s*(\d+)/, 1].to_i rescue nil }
45
+ core_ids = cpuinfos.map { |l| l[/core id\s*:\s*(\d+)/, 1].to_i rescue nil }
46
+ processor_ids.zip(core_ids) do |processor_id, core_id|
47
+ cpu_cores[processor_id] = core_id
48
+ end
49
+ processors = Dir.open('/dev/cpu').inject([]) do |ps, processor_id|
50
+ processor_id =~ /\A\d+\Z/ or next ps
51
+ ps << processor_id.to_i
52
+ end
53
+ processors.extend Spruz::UniqBy
54
+ processors.sort!
55
+ @num_processors = processors.size
56
+ @num_cores = cpu_cores.invert.size
57
+ processors.map! do |processor_id|
58
+ Processor.new(processor_id, cpu_cores[processor_id])
59
+ end
60
+ end
61
+
62
+ def num_processors
63
+ @num_processors or processors
64
+ @num_processors
65
+ end
66
+
67
+ def num_cores
68
+ @num_cores or processors
69
+ @num_cores
70
+ end
71
+
72
+ alias to_a processors
73
+
74
+ def each_core(&block)
75
+ processors.uniq_by(&:core_id).each(&block)
76
+ end
77
+
78
+ def cores
79
+ each_core.to_a
80
+ end
81
+
82
+ # Iterate over each Processor instance for this machine and yield to the
83
+ # block for each of them.
84
+ def each_processor(&block)
85
+ processors.each(&block)
86
+ end
87
+
88
+ alias each each_processor
89
+
90
+ include Enumerable
91
+
92
+ def load
93
+ Load.new
94
+ end
95
+
96
+ def usage(interval = 1)
97
+ before_usage = UsageSampler.new
98
+ if block_given?
99
+ yield
100
+ else
101
+ sleep interval
102
+ end
103
+ after_usage = UsageSampler.new
104
+ processors.each do |processor|
105
+ processor.usage = after_usage.usages[processor.processor_id] -
106
+ before_usage.usages[processor.processor_id]
107
+ end
108
+ end
109
+
110
+ def sum_usage_processor(interval = 1)
111
+ processors = usage(interval)
112
+ processor = Processor.new -1, -1
113
+ processor.num_processors = processor.num_cores = 1
114
+ processor.temperature = processors.map(&:temperature).max
115
+ processor.usage = processors.map(&:usage).inject { |s, u| s + u }
116
+ processor.usage.num_processors = processor.usage.num_cores = 1
117
+ processor.freeze
118
+ processor
119
+ end
120
+ end
121
+ end
@@ -0,0 +1,57 @@
1
+ module CPU
2
+ class Load
3
+ include Shared
4
+
5
+ def initialize
6
+ @load_data = File.open('/proc/loadavg') do |loadavg|
7
+ loadavg.readline.split(/\s+/).first(3).map(&:to_f)
8
+ end
9
+ end
10
+
11
+ def last_minute
12
+ @load_data[0]
13
+ end
14
+
15
+ def last_minute_by_core
16
+ last_minute / num_cores
17
+ end
18
+
19
+ def last_minute_by_processor
20
+ last_minute / num_processors
21
+ end
22
+
23
+ def last_5_minutes
24
+ @load_data[1]
25
+ end
26
+
27
+ def last_5_minutes_by_core
28
+ last_5_minutes / num_cores
29
+ end
30
+
31
+ def last_5_minutes_by_processor
32
+ last_5_minutes / num_processors
33
+ end
34
+
35
+ def last_15_minutes
36
+ @load_data[2]
37
+ end
38
+
39
+ def last_15_minutes_by_core
40
+ last_15_minutes / num_cores
41
+ end
42
+
43
+ def last_15_minutes_by_processor
44
+ last_15_minutes / num_processors
45
+ end
46
+
47
+ def to_a
48
+ @load_data.dup
49
+ end
50
+
51
+ def inspect
52
+ "#<#{self.class}: #{to_a * ' '}>"
53
+ end
54
+
55
+ alias to_s inspect
56
+ end
57
+ end
@@ -0,0 +1,31 @@
1
+ module CPU
2
+ class MSR
3
+ # Returns true if the msr functionality is already available in the kernel
4
+ # (either compiled into it or via a module).
5
+ def self.available?
6
+ File.exist?('/dev/cpu/0/msr')
7
+ end
8
+
9
+ # Loads the msr module and sleeps for a second afterwards.
10
+ def self.load_module
11
+ system "#{CPU.modprobe_path} msr"
12
+ sleep 1
13
+ end
14
+
15
+ def initialize(processor_id)
16
+ self.class.available? or self.class.load_module
17
+ begin
18
+ @io = IO.new IO.sysopen('/dev/cpu/%d/msr' % processor_id, 'rb')
19
+ rescue Errno::ENOENT
20
+ raise InvalidProcessorIdError, "'#{processor_id}' is not a valid processor_id on this machine"
21
+ end
22
+ end
23
+
24
+ # Returns the byte at +offset+ as an integer number.
25
+ def [](offset)
26
+ @io.sysseek(offset)
27
+ data, = @io.sysread(8).unpack('q')
28
+ data
29
+ end
30
+ end
31
+ end
@@ -0,0 +1,72 @@
1
+ module CPU
2
+ class Processor
3
+ include Shared
4
+
5
+ # Returns a Processor instance for Processor +processor_id+. If this
6
+ # Processor doesn't exist an InvalidProcessorIdError exception is thrown.
7
+ def initialize(processor_id, core_id = nil)
8
+ @processor_id, @core_id = processor_id, core_id
9
+ end
10
+
11
+ # Returns the processor_id of this Processor, an integer in (0..(n - 1))
12
+ # for a n-core machine.
13
+ attr_reader :processor_id
14
+
15
+ # Returns the core_id of this Processor.
16
+ attr_reader :core_id
17
+
18
+ # Returns an msr object and caches it.
19
+ def msr
20
+ @msr ||= MSR.new(processor_id)
21
+ end
22
+
23
+ attr_writer :usage
24
+
25
+ def usage(interval = 1)
26
+ unless @usage
27
+ if processor = CPU.usage(interval).find { |p| p.processor_id == processor_id }
28
+ @usage = processor.usage
29
+ end
30
+ end
31
+ @usage
32
+ end
33
+
34
+ # Returns the distance between the core temperature of this Processor and
35
+ # its t_j_max temperature as an integer number.
36
+ def t_j_max_distance
37
+ (msr[0x19c] >> 16) & 0x7f
38
+ end
39
+
40
+ # This method returns the t_j_max temperature of this Processor if the
41
+ # processor supports it (e. g. Intel i7 architecture) as an integer number,
42
+ # otherwise 0 is returned.
43
+ def t_j_max
44
+ (msr[0x1a2] >> 16) & 0x7f
45
+ end
46
+
47
+ # Returns the core temperature of this Processor as an integer number. This
48
+ # should work on all Core2 architecures if you set CPU.t_j_max
49
+ # to the correct value for your Processor. On i7 architectures (and newer?)
50
+ # it should work without any further configuration.
51
+ def temperature
52
+ if @temperature
53
+ @temperature
54
+ else
55
+ my_t_j_max = t_j_max.nonzero? || CPU.t_j_max
56
+ my_t_j_max - t_j_max_distance
57
+ end
58
+ end
59
+
60
+ attr_writer :temperature
61
+
62
+ def inspect
63
+ if processor_id >= 0
64
+ result = "#<#{self.class}: #@processor_id"
65
+ result << " (core#@core_id)" if @core_id
66
+ result << '>'
67
+ else
68
+ "#<#{self.class}: total>"
69
+ end
70
+ end
71
+ end
72
+ end
@@ -0,0 +1,25 @@
1
+ module CPU
2
+ module Shared
3
+ # Returns the number of processors in this computer
4
+ def num_processors
5
+ if @num_processors
6
+ @num_processors
7
+ else
8
+ CPU.num_processors
9
+ end
10
+ end
11
+
12
+ attr_writer :num_processors
13
+
14
+ # Returns the number of cores in this computer
15
+ def num_cores
16
+ if @num_cores
17
+ @num_cores
18
+ else
19
+ CPU.num_cores
20
+ end
21
+ end
22
+
23
+ attr_writer :num_cores
24
+ end
25
+ end
@@ -0,0 +1,65 @@
1
+ module CPU
2
+ class Usage < Struct.new('Usage', :usage, :processor_id, :user, :nice,
3
+ :system, :idle, :start_at, :stop_at)
4
+ include Shared
5
+
6
+ def +(other)
7
+ self.class.new(*(
8
+ [
9
+ usage,
10
+ processor_id == other.processor_id ? processor_id : 0,
11
+ ] +
12
+ values_at(2..-3).zip(other.values_at(2..-3)).map { |x, y| x + y } +
13
+ [
14
+ [ start_at, other.start_at ].min,
15
+ [ stop_at, other.stop_at ].max
16
+ ])
17
+ )
18
+ end
19
+
20
+ def -(other)
21
+ self + other * -1
22
+ end
23
+
24
+ def *(scalar)
25
+ scalar = scalar.to_f
26
+ self.class.new(*(
27
+ [
28
+ usage,
29
+ processor_id,
30
+ ] +
31
+ values_at(2..-3).map { |x| x * scalar } +
32
+ [
33
+ start_at,
34
+ stop_at,
35
+ ])
36
+ )
37
+ end
38
+
39
+ def /(scalar)
40
+ self * (1.0 / scalar)
41
+ end
42
+
43
+ def process_time
44
+ user + nice + system
45
+ end
46
+
47
+ def real_time
48
+ stop_at - start_at
49
+ end
50
+
51
+ def total_time
52
+ values_at(2..-3).inject(0.0) { |s, x| s + x }
53
+ end
54
+
55
+ def percentage(time = total_time)
56
+ 100.0 * process_time / time
57
+ end
58
+
59
+ def inspect
60
+ "#<#{self.class}: #{percentage}>"
61
+ end
62
+
63
+ alias to_s inspect
64
+ end
65
+ end
@@ -0,0 +1,40 @@
1
+ module CPU
2
+ class UsageSampler
3
+ def initialize
4
+ sample
5
+ end
6
+
7
+ attr_reader :usages
8
+
9
+ def sum_usages
10
+ @usages and @usages.values.inject(&:+)
11
+ end
12
+
13
+ CPU = /^cpu(\d+)#{'\s+(\d+)' * 4}/
14
+
15
+ USER_HZ = 100
16
+
17
+ def sample
18
+ total, @usages = nil, {}
19
+ timestamp = Time.now
20
+ File.foreach('/proc/stat') do |line|
21
+ case line
22
+ when /^cpu[^\d]/
23
+ next
24
+ when CPU
25
+ times = $~.captures
26
+ processor_id = times[0] = times[0].to_i
27
+ (1...times.size).each { |i| times[i] = times[i].to_f / USER_HZ }
28
+ times << timestamp << timestamp
29
+ @usages[processor_id] = Usage.new(self, *times)
30
+ else
31
+ break
32
+ end
33
+ end
34
+ if @usages.empty?
35
+ raise NoSampleDataError, "could not sample measurement data"
36
+ end
37
+ self
38
+ end
39
+ end
40
+ end
@@ -0,0 +1,8 @@
1
+ module CPU
2
+ # CPU version
3
+ VERSION = '0.0.0'
4
+ VERSION_ARRAY = VERSION.split(/\./).map { |x| x.to_i } # :nodoc:
5
+ VERSION_MAJOR = VERSION_ARRAY[0] # :nodoc:
6
+ VERSION_MINOR = VERSION_ARRAY[1] # :nodoc:
7
+ VERSION_BUILD = VERSION_ARRAY[2] # :nodoc:
8
+ end
@@ -0,0 +1,24 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'cpu'
4
+
5
+ if t_j_max = ENV['t_j_max']
6
+ CPU.t_j_max = t_j_max.to_i
7
+ end
8
+
9
+ case ARGV.shift
10
+ when 'config'
11
+ puts <<EOT
12
+ graph_title CPU Core temperatures
13
+ graph_args --base 1000 -l 0
14
+ graph_vtitle Celsius
15
+ graph_category sensors
16
+ EOT
17
+ for c in CPU.cores
18
+ puts "core#{c.core_id}.label Core #{c.core_id}"
19
+ end
20
+ else
21
+ for c in CPU.cores
22
+ puts "core#{c.core_id}.value #{c.temperature}"
23
+ end
24
+ end
@@ -0,0 +1,35 @@
1
+ require 'test/unit'
2
+ require 'mocha'
3
+ require 'cpu'
4
+
5
+ module CPU
6
+ class LoadTest < Test::Unit::TestCase
7
+ def test_load_minutes
8
+ @load = CPU.load
9
+ @load.stubs(:num_processors).returns(4)
10
+ @load.stubs(:num_cores).returns(2)
11
+ for v in %w[last_minute last_5_minutes last_15_minutes]
12
+ assert_kind_of Float, @load.__send__(v)
13
+ assert_operator @load.__send__(v), :>=, 0
14
+ assert_in_delta\
15
+ 4 * @load.__send__("#{v}_by_processor"),
16
+ @load.__send__(v),
17
+ 1E-3
18
+ assert_in_delta\
19
+ 2 * @load.__send__("#{v}_by_core"),
20
+ @load.__send__(v),
21
+ 1E-3
22
+ end
23
+ end
24
+
25
+ def test_load_array
26
+ load_array = CPU.load.to_a
27
+ assert_equal 3, load_array.size
28
+ for v in load_array
29
+ assert_kind_of Float, v
30
+ assert_operator v, :>=, 0
31
+ end
32
+ end
33
+ end
34
+ end
35
+
@@ -0,0 +1,32 @@
1
+ require 'test/unit'
2
+ require 'cpu'
3
+
4
+ module CPU
5
+ class MSRTest < Test::Unit::TestCase
6
+ def setup
7
+ @cpu0, @cpu1 = CPU.to_a
8
+ end
9
+
10
+ def test_loaded
11
+ assert CPU::MSR.available?
12
+ end
13
+
14
+ def test_instance
15
+ assert_kind_of CPU::Processor, @cpu0
16
+ assert_equal 0, @cpu0.processor_id
17
+ assert_kind_of CPU::Processor, @cpu1
18
+ assert_equal 1, @cpu1.processor_id
19
+ end
20
+
21
+ def test_temperature
22
+ assert_operator @cpu0.temperature, '>', 0
23
+ assert_operator @cpu1.temperature, '>', 0
24
+ end
25
+
26
+ def test_wrong_processor_id
27
+ assert_raise(InvalidProcessorIdError) do
28
+ CPU::MSR.new(CPU.num_processors)
29
+ end
30
+ end
31
+ end
32
+ end
@@ -0,0 +1,14 @@
1
+ require 'test/unit'
2
+ require 'mocha'
3
+ require 'cpu'
4
+
5
+ module CPU
6
+ class UsageTest < Test::Unit::TestCase
7
+ def test_sum_usage
8
+ @processor = CPU.sum_usage 0.1
9
+ assert_kind_of Processor, @processor
10
+ assert_operator @processor.usage.percentage, :>, 0
11
+ end
12
+ end
13
+ end
14
+
metadata ADDED
@@ -0,0 +1,84 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: cpu
3
+ version: !ruby/object:Gem::Version
4
+ prerelease:
5
+ version: 0.0.0
6
+ platform: ruby
7
+ authors:
8
+ - Florian Frank
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+
13
+ date: 2011-07-03 00:00:00 Z
14
+ dependencies:
15
+ - !ruby/object:Gem::Dependency
16
+ name: spruz
17
+ prerelease: false
18
+ requirement: &id001 !ruby/object:Gem::Requirement
19
+ none: false
20
+ requirements:
21
+ - - ~>
22
+ - !ruby/object:Gem::Version
23
+ version: 0.2.2
24
+ type: :runtime
25
+ version_requirements: *id001
26
+ description: Library to gather CPU information (load averages, usage, temperature) in Ruby on Linux
27
+ email: flori@ping.de
28
+ executables:
29
+ - coretemp
30
+ extensions: []
31
+
32
+ extra_rdoc_files:
33
+ - README.rdoc
34
+ files:
35
+ - Gemfile
36
+ - README.rdoc
37
+ - Rakefile
38
+ - VERSION
39
+ - bin/coretemp
40
+ - cpu.gemspec
41
+ - lib/cpu.rb
42
+ - lib/cpu/load.rb
43
+ - lib/cpu/msr.rb
44
+ - lib/cpu/processor.rb
45
+ - lib/cpu/shared.rb
46
+ - lib/cpu/usage.rb
47
+ - lib/cpu/usage_sampler.rb
48
+ - lib/cpu/version.rb
49
+ - munin/coretemp
50
+ - tests/load_test.rb
51
+ - tests/msr_test.rb
52
+ - tests/usage_test.rb
53
+ homepage: http://flori.github.com/cpu
54
+ licenses: []
55
+
56
+ post_install_message:
57
+ rdoc_options:
58
+ - --main
59
+ - README.rdoc
60
+ - --title
61
+ - CPU
62
+ require_paths:
63
+ - lib
64
+ required_ruby_version: !ruby/object:Gem::Requirement
65
+ none: false
66
+ requirements:
67
+ - - ">="
68
+ - !ruby/object:Gem::Version
69
+ version: "0"
70
+ required_rubygems_version: !ruby/object:Gem::Requirement
71
+ none: false
72
+ requirements:
73
+ - - ">="
74
+ - !ruby/object:Gem::Version
75
+ version: "0"
76
+ requirements: []
77
+
78
+ rubyforge_project: cpu
79
+ rubygems_version: 1.8.5
80
+ signing_key:
81
+ specification_version: 3
82
+ summary: CPU information in Ruby/Linux
83
+ test_files: []
84
+