Browse files

Added overflow detection to Device#diff

  • Loading branch information...
1 parent 920e258 commit 4536d735e235e80ec6d32e1eac4f0f3952dee6bd @drbrain drbrain committed Apr 2, 2012
Showing with 60 additions and 4 deletions.
  1. +1 −0 CHANGELOG.rdoc
  2. +1 −0 Manifest.txt
  3. +14 −4 lib/spectacular/device.rb
  4. +44 −0 test/test_spectacular_device.rb
View
1 CHANGELOG.rdoc
@@ -5,6 +5,7 @@
* The physical interface address is shown along with the interface name
* Now uses command a line argument instead of an environment variable for
the router IP
+ * Overflow of SNMP counters is now supported
=== 1.0.0 / 2012-03-25
View
1 Manifest.txt
@@ -13,3 +13,4 @@ lib/spectacular/sized_list.rb
test/helper.rb
test/test_history.rb
test/test_sized_list.rb
+test/test_spectacular_device.rb
View
18 lib/spectacular/device.rb
@@ -24,7 +24,6 @@ def initialize host, history = 10, interface_args
@interface_args = interface_args
end
-
def interfaces
manager = snmp_manager host
if @interface_args.empty?
@@ -43,6 +42,7 @@ def interfaces
def monitor interval = 1
manager = snmp_manager host
+ Thread.abort_on_exception = true
loop do
manager.walk(COLUMNS) do |row|
next if row[1].value == 2 # down
@@ -81,9 +81,19 @@ def snmp_manager host
def diff from, to
return [] unless from && to
- to.first(2) + from.zip(to).last(2).map { |left, right|
- diff = right.value.to_i - left.value.to_i
- Klass.new left.name, diff
+ to.first(2) + from.zip(to).last(2).map { |old, new|
+ name = new.name
+ new = new.value.to_i
+ old = old.value.to_i
+
+ # handle overflow of 32 bit counters
+ diff = if new >= old then
+ new - old
+ else
+ (2**32 - old - 1) + new
+ end
+
+ Klass.new name, diff
}
end
View
44 test/test_spectacular_device.rb
@@ -0,0 +1,44 @@
+require 'helper'
+
+class TestSpectacularDevice < Spectacular::TestCase
+
+ def setup
+ super
+
+ @device = Spectacular::Device.new '192.0.2.1', []
+ @klass = Spectacular::Device::Klass
+ end
+
+ def test_diff
+ from = [1, 1, 'en0', '',
+ @klass.new('ifInOctets', '2'), @klass.new('ifOutOctets', '3')]
+ to = [1, 1, 'en0', '',
+ @klass.new('ifInOctets', '5'), @klass.new('ifOutOctets', '7')]
+
+ result = @device.send :diff, from, to
+
+ expected = [
+ 1, 1, @klass.new('ifInOctets', 3), @klass.new('ifOutOctets', 4)
+ ]
+
+ assert_equal expected, result
+ end
+
+ def test_diff_overflow
+ from = [1, 1, 'en0', '',
+ @klass.new('ifInOctets', '0'),
+ @klass.new('ifOutOctets', 2**32 - 100)]
+ to = [1, 1, 'en0', '',
+ @klass.new('ifInOctets', '0'),
+ @klass.new('ifOutOctets', 7)]
+
+ result = @device.send :diff, from, to
+
+ expected = [
+ 1, 1, @klass.new('ifInOctets', 0), @klass.new('ifOutOctets', 106)
+ ]
+
+ assert_equal expected, result
+ end
+
+end

0 comments on commit 4536d73

Please sign in to comment.