cpu 0.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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
+