kingkong 0.0.3 → 0.0.7

Sign up to get free protection for your applications and to get access to all the features.
data/Gemfile CHANGED
@@ -1,17 +1,4 @@
1
1
  source "http://rubygems.org"
2
2
 
3
3
  # Specify your gem's dependencies in kingkong.gemspec
4
- gemspec
5
-
6
- gem 'em-http-request'
7
- gem 'json'
8
-
9
- group :test, :development do
10
- gem 'rspec'
11
- gem 'guard-rspec'
12
- gem 'growl'
13
- gem 'rb-fsevent'
14
- gem 'em-ventually'
15
- gem 'timecop'
16
- gem 'ruby-debug19'
17
- end
4
+ gemspec
data/README.md CHANGED
@@ -30,27 +30,46 @@
30
30
 
31
31
  KingKong makes it easy to build full-stack ping-pong health checks so you can keep an eye on crucial input/outputs and make sure things stay nice and fast. You might need this to check and graph out the response time on your website, Twitter application, SMS gateway, or whatever else you'd connect to a network.
32
32
 
33
- When its done, it will look something like this:
34
-
33
+ ## Getting Started
34
+
35
+ Install the KingKong gem.
36
+
37
+ gem install kingkong
38
+
39
+ Then implement your ping checks in Ruby.
40
+
35
41
  require 'kingkong'
36
42
  require 'em-http-request'
37
-
38
- KingKing::Runner.start {
43
+
44
+ KingKong.start {
39
45
  socket '/tmp/king_kong.socket' # Check this socket with Munin and make a graph!
40
-
46
+
41
47
  ping(:google).every(3).seconds do |ping|
42
- google = EventMachine::HttpRequest.new('http://google.com/')
48
+ ping.start
49
+ google = EventMachine::HttpRequest.new('http://google.com/').get
43
50
  google.callback { ping.stop }
44
- google.errback { ping.fail }
45
- ping.start and google.get
51
+ google.errback { ping.fail }
46
52
  end
47
-
53
+
48
54
  ping(:twitter).every(10).seconds do |ping|
49
55
  # Wire up your own thing in here that tweets
50
56
  # .. and when you pick that up, end the pong!
51
57
  end
58
+
59
+ ping(:verizon).every(2).seconds do |ping|
60
+ # Hook your machine up to a GSM serial modem
61
+ # and perform regular SMS pings against your app.
62
+ end
52
63
  }
53
64
 
54
- and its going to aggregate stats so you can plug it into munin and get all sorts of graphing goodness.
65
+ Save the file and run it! You'll see some crazy log output right now, but eventually its going to be prettier.
66
+
67
+ You can see the stat aggregates of the pings by looking into the socket:
68
+
69
+ watch cat /tmp/king_kong.socket
70
+
71
+ If you don't understand EventMachine, you might have a little trouble getting this stuff working. Eventually I'd like to hook up Em::Syncrony and a nicer DSL for common tasks, like HTTP checks, to keep things simple.
72
+
73
+ ## Using KingKong with Munin graphs
55
74
 
56
- Stay tuned, I'm still working out the ping DSL and reporting infrastructure!
75
+ I'm working on this!
@@ -18,7 +18,14 @@ Gem::Specification.new do |s|
18
18
  s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
19
19
  s.require_paths = ["lib"]
20
20
 
21
- # specify any dependencies here; for example:
22
- # s.add_development_dependency "rspec"
21
+ s.add_development_dependency 'rspec'
22
+ s.add_development_dependency 'guard-rspec'
23
+ s.add_development_dependency 'growl'
24
+ s.add_development_dependency 'rb-fsevent'
25
+ s.add_development_dependency 'em-ventually'
26
+ s.add_development_dependency 'timecop'
27
+ s.add_development_dependency 'ruby-debug19'
28
+
23
29
  s.add_runtime_dependency "eventmachine"
24
- end
30
+ s.add_runtime_dependency "nosey"
31
+ end
@@ -4,17 +4,21 @@ module KingKong
4
4
  autoload :Ping, 'kingkong/ping'
5
5
  autoload :Pinger, 'kingkong/pinger'
6
6
  autoload :Runner, 'kingkong/runner'
7
- autoload :Server, 'kingkong/server'
8
7
  autoload :Logging, 'kingkong/logging'
9
8
  autoload :Aggregator, 'kingkong/aggregator'
10
- autoload :Reporting, 'kingkong/reporting'
11
9
 
12
10
  # Default logger for KingKong.
13
11
  def self.logger
14
12
  @logger ||= Logger.new($stdout)
15
13
  end
16
14
 
15
+ # Want to override the default logger? Its cool, change it up here.
17
16
  def self.logger=(logger)
18
17
  @logger = logger
19
18
  end
19
+
20
+ # Shortcut for starting a runner
21
+ def self.start(*args)
22
+ Runner.new(*args)
23
+ end
20
24
  end
@@ -1,8 +1,10 @@
1
1
  require 'eventmachine'
2
+ require 'nosey'
2
3
 
3
4
  module KingKong
4
5
  class Pinger
5
6
  include Logging
7
+ include Nosey::Instrumentation
6
8
 
7
9
  attr_reader :wait
8
10
 
@@ -25,11 +27,6 @@ module KingKong
25
27
  @timer.cancel if @timer
26
28
  end
27
29
 
28
- # Gather up all the numbers we need for reporting later on
29
- def aggregator
30
- @aggregatore ||= Aggregator.new
31
- end
32
-
33
30
  private
34
31
  # Add all of the instrumentation callbacks into the ping so we can aggregate it later
35
32
  def ping
@@ -38,12 +35,12 @@ module KingKong
38
35
  # Register the aggregator to process the ping
39
36
  ping.callback {
40
37
  logger.debug "Ping #{ping} successful"
41
- aggregator.process ping
38
+ process ping
42
39
  }
43
40
 
44
41
  ping.errback {
45
42
  logger.debug "Ping #{ping} error (probably a timeout)"
46
- aggregator.process ping
43
+ process ping
47
44
  }
48
45
 
49
46
  # Now pass the ping into the block so we can start/stop it
@@ -54,5 +51,19 @@ module KingKong
54
51
  def sequencer
55
52
  @sequencer ||= Ping::Sequencer.new
56
53
  end
54
+
55
+ # Process a stinkin ping and report aggregate stats to Nosey
56
+ def process(ping)
57
+ nosey.increment 'ping_count'
58
+ case ping.status
59
+ when :timed_out
60
+ nosey.increment 'ping_timed_out_count'
61
+ when :completed
62
+ nosey.increment 'ping_completed_count'
63
+ nosey.avg "ping_avg_latency", ping.latency
64
+ nosey.min "ping_min_latency", ping.latency
65
+ nosey.max "ping_max_latency", ping.latency
66
+ end
67
+ end
57
68
  end
58
69
  end
@@ -1,15 +1,20 @@
1
+ require 'nosey'
2
+
1
3
  module KingKong
2
4
  # Configure multiple pingers to run
3
5
  class Runner
4
6
  include Logging
5
7
 
6
8
  # Array of pingers that we're running
7
- def ping(name)
8
- pinger_configurations[name]
9
+ def ping(name, &block)
10
+ DSL::Pinger.new(&block).completed do |pinger|
11
+ pinger.nosey.name = name.to_s
12
+ pingers << pinger
13
+ end
9
14
  end
10
15
 
11
16
  # Setup the socket that this thing will write stats out to
12
- def socket(host=KingKong::Reporting::Server::Host, port=KingKong::Reporting::Server::Port)
17
+ def socket(host='/tmp/king_kong.socket', port=nil)
13
18
  @socket_host , @socket_port = host, port
14
19
  end
15
20
 
@@ -47,7 +52,14 @@ module KingKong
47
52
  private
48
53
  # Fire up the reporting server if a socket (and port, optionally) are given
49
54
  def start_socket
50
- Reporting::Server.start(pingers.map(&:aggregator), @socket_host, @socket_port) if @socket_host
55
+ EM::Nosey::SocketServer.start(nosey_report, @socket_host, @socket_port) if @socket_host
56
+ end
57
+
58
+ # Get us the nosey report that our nosey socket needs to get the job done son!
59
+ def nosey_report
60
+ Nosey::Report.new do |r|
61
+ r.probe_sets = pingers.map(&:nosey)
62
+ end
51
63
  end
52
64
 
53
65
  # Fire up all the pingers
@@ -55,15 +67,9 @@ module KingKong
55
67
  pingers.each(&:start)
56
68
  end
57
69
 
58
- # Hang onto pinger configuration so that we can configure pinger instances and fire them
59
- # off. We'll also be using this for writing reports.
60
- def pinger_configurations
61
- @pinger_configurations ||= Hash.new{|hash,val| hash[val] = DSL::Pinger.new }
62
- end
63
-
64
70
  # Create instances of pingers from the configurations that we setup in the runner
65
71
  def pingers
66
- @pingers ||= pinger_configurations.values.map(&:pinger)
72
+ @pingers ||= []
67
73
  end
68
74
 
69
75
  def self.ensure_running_reactor(&block)
@@ -92,18 +98,21 @@ module KingKong
92
98
  # Configure duration as seconds
93
99
  def seconds(&block)
94
100
  unitize Unit::Second, &block
101
+ complete
95
102
  end
96
103
  alias :second :seconds
97
104
 
98
105
  # Configure the duration as minutes
99
106
  def minutes(&block)
100
107
  unitize Unit::Minute, &block
108
+ complete
101
109
  end
102
110
  alias :minute :minutes
103
111
 
104
112
  # Configure the ping duration as hours
105
113
  def hours(&block)
106
114
  unitize Unit::Hour, &block
115
+ complete
107
116
  end
108
117
  alias :hour :hours
109
118
 
@@ -117,6 +126,12 @@ module KingKong
117
126
  KingKong::Pinger.new(duration, &@block)
118
127
  end
119
128
 
129
+ # Callback when we've completed the configuration of this thing.
130
+ def completed(&block)
131
+ @completed_blk = block
132
+ self
133
+ end
134
+
120
135
  private
121
136
  # Figures out the number of seconds that we multply by the units
122
137
  def unitize(units, &block)
@@ -124,6 +139,12 @@ module KingKong
124
139
  @block = block
125
140
  self
126
141
  end
142
+
143
+ # Yay! Its complete!
144
+ def complete
145
+ @completed_blk.call(pinger) if @completed_blk
146
+ self
147
+ end
127
148
  end
128
149
  end
129
150
  end
@@ -1,3 +1,3 @@
1
1
  module KingKong
2
- VERSION = "0.0.3"
2
+ VERSION = "0.0.7"
3
3
  end
@@ -1,29 +1,29 @@
1
- require 'spec_helper'
1
+ # require 'spec_helper'
2
2
 
3
- describe KingKong::Pinger do
4
- include EM::Ventually
3
+ # describe KingKong::Pinger do
4
+ # include EM::Ventually
5
5
 
6
- before(:all) do
7
- @@pinged = false
8
- @pinger = KingKong::Pinger.new(0.1) do |ping, pinger|
9
- @@ping = ping
10
- ping.start
11
- ping.stop
12
- pinger.stop
13
- end
14
- end
6
+ # before(:all) do
7
+ # @@pinged = false
8
+ # @pinger = KingKong::Pinger.new(0.1) do |ping, pinger|
9
+ # @@ping = ping
10
+ # ping.start
11
+ # ping.stop
12
+ # pinger.stop
13
+ # end
14
+ # end
15
15
 
16
- it "should ping" do
17
- @pinger.start
18
- ly(:completed) { @@ping.status }
19
- end
16
+ # it "should ping" do
17
+ # @pinger.start
18
+ # ly(:completed) { @@ping.status }
19
+ # end
20
20
 
21
- it "should stop"
22
- it "should start"
21
+ # it "should stop"
22
+ # it "should start"
23
23
 
24
- context "ping aggregation" do
25
- it "should process timed-out"
26
- it "should process successful"
27
- it "should process errors"
28
- end
29
- end
24
+ # context "ping aggregation" do
25
+ # it "should process timed-out"
26
+ # it "should process successful"
27
+ # it "should process errors"
28
+ # end
29
+ # end
@@ -8,13 +8,17 @@ describe KingKong::Runner do
8
8
  @@google_pinged = @@twitter_pinged = false
9
9
 
10
10
  @runner = KingKong::Runner.configure do |runner|
11
- runner.socket '/tmp/king_kong.socket'
11
+ runner.socket '/tmp/king_kong_test.socket'
12
12
 
13
- runner.ping(:google).every(0.1).seconds do
13
+ runner.ping(:google).every(0.1).seconds do |ping|
14
+ ping.start
15
+ ping.stop
14
16
  @@google_pinged = true
15
17
  end
16
18
 
17
- runner.ping(:twitter).every(2).seconds do
19
+ runner.ping(:twitter).every(2).seconds do |ping|
20
+ ping.start
21
+ ping.stop
18
22
  @@twitter_pinged = true
19
23
  end
20
24
  end
@@ -27,7 +31,10 @@ describe KingKong::Runner do
27
31
 
28
32
  it "should write data to socket" do
29
33
  @runner.start
30
- # puts UNIXSocket.new('/tmp/king_kong.socket').gets("\n\n")
34
+ KingKong::Test::ReadSocket.start('/tmp/king_kong_test.socket').callback{|data|
35
+ @data = data
36
+ }
37
+ ly{ @data }.test{|data| data =~ /max/ }
31
38
  end
32
39
  end
33
40
 
@@ -8,5 +8,31 @@ RSpec.configure do |config|
8
8
  config.mock_framework = :rspec
9
9
  end
10
10
 
11
+ module KingKong
12
+ module Test
13
+ # Read data from a socket and then kill it right away.
14
+ class ReadSocket < EventMachine::Connection
15
+ include EventMachine::Deferrable
16
+
17
+ def receive_data(data)
18
+ buffer << data
19
+ end
20
+
21
+ def unbind
22
+ succeed buffer
23
+ end
24
+
25
+ def self.start(host,port=nil)
26
+ EventMachine::connect host, port, self
27
+ end
28
+
29
+ private
30
+ def buffer
31
+ @buffer ||= ""
32
+ end
33
+ end
34
+ end
35
+ end
36
+
11
37
  # Squelch the logger so we can see our specs passing
12
38
  KingKong.logger = Logger.new('/dev/null')
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: kingkong
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.3
4
+ version: 0.0.7
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,12 +9,99 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2011-09-13 00:00:00.000000000 -07:00
13
- default_executable:
12
+ date: 2011-09-16 00:00:00.000000000Z
14
13
  dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: rspec
16
+ requirement: &70359584496540 !ruby/object:Gem::Requirement
17
+ none: false
18
+ requirements:
19
+ - - ! '>='
20
+ - !ruby/object:Gem::Version
21
+ version: '0'
22
+ type: :development
23
+ prerelease: false
24
+ version_requirements: *70359584496540
25
+ - !ruby/object:Gem::Dependency
26
+ name: guard-rspec
27
+ requirement: &70359584483820 !ruby/object:Gem::Requirement
28
+ none: false
29
+ requirements:
30
+ - - ! '>='
31
+ - !ruby/object:Gem::Version
32
+ version: '0'
33
+ type: :development
34
+ prerelease: false
35
+ version_requirements: *70359584483820
36
+ - !ruby/object:Gem::Dependency
37
+ name: growl
38
+ requirement: &70359584483400 !ruby/object:Gem::Requirement
39
+ none: false
40
+ requirements:
41
+ - - ! '>='
42
+ - !ruby/object:Gem::Version
43
+ version: '0'
44
+ type: :development
45
+ prerelease: false
46
+ version_requirements: *70359584483400
47
+ - !ruby/object:Gem::Dependency
48
+ name: rb-fsevent
49
+ requirement: &70359584482980 !ruby/object:Gem::Requirement
50
+ none: false
51
+ requirements:
52
+ - - ! '>='
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
55
+ type: :development
56
+ prerelease: false
57
+ version_requirements: *70359584482980
58
+ - !ruby/object:Gem::Dependency
59
+ name: em-ventually
60
+ requirement: &70359584482560 !ruby/object:Gem::Requirement
61
+ none: false
62
+ requirements:
63
+ - - ! '>='
64
+ - !ruby/object:Gem::Version
65
+ version: '0'
66
+ type: :development
67
+ prerelease: false
68
+ version_requirements: *70359584482560
69
+ - !ruby/object:Gem::Dependency
70
+ name: timecop
71
+ requirement: &70359584482140 !ruby/object:Gem::Requirement
72
+ none: false
73
+ requirements:
74
+ - - ! '>='
75
+ - !ruby/object:Gem::Version
76
+ version: '0'
77
+ type: :development
78
+ prerelease: false
79
+ version_requirements: *70359584482140
80
+ - !ruby/object:Gem::Dependency
81
+ name: ruby-debug19
82
+ requirement: &70359584481720 !ruby/object:Gem::Requirement
83
+ none: false
84
+ requirements:
85
+ - - ! '>='
86
+ - !ruby/object:Gem::Version
87
+ version: '0'
88
+ type: :development
89
+ prerelease: false
90
+ version_requirements: *70359584481720
15
91
  - !ruby/object:Gem::Dependency
16
92
  name: eventmachine
17
- requirement: &70233419803860 !ruby/object:Gem::Requirement
93
+ requirement: &70359584481300 !ruby/object:Gem::Requirement
94
+ none: false
95
+ requirements:
96
+ - - ! '>='
97
+ - !ruby/object:Gem::Version
98
+ version: '0'
99
+ type: :runtime
100
+ prerelease: false
101
+ version_requirements: *70359584481300
102
+ - !ruby/object:Gem::Dependency
103
+ name: nosey
104
+ requirement: &70359584480880 !ruby/object:Gem::Requirement
18
105
  none: false
19
106
  requirements:
20
107
  - - ! '>='
@@ -22,7 +109,7 @@ dependencies:
22
109
  version: '0'
23
110
  type: :runtime
24
111
  prerelease: false
25
- version_requirements: *70233419803860
112
+ version_requirements: *70359584480880
26
113
  description: Have you ever wanted to shoot a message throught Twitter, have your app
27
114
  pick it up, do some work on it, and report how long it takes? KingKong makes it
28
115
  slightly easier to do this with a DSL for writing custom pings and by providing
@@ -45,22 +132,17 @@ files:
45
132
  - bin/kingkong-server
46
133
  - kingkong.gemspec
47
134
  - lib/kingkong.rb
48
- - lib/kingkong/aggregator.rb
49
135
  - lib/kingkong/cli.rb
50
136
  - lib/kingkong/logging.rb
51
137
  - lib/kingkong/ping.rb
52
138
  - lib/kingkong/pinger.rb
53
- - lib/kingkong/reporting.rb
54
139
  - lib/kingkong/runner.rb
55
- - lib/kingkong/server.rb
56
140
  - lib/kingkong/version.rb
57
- - spec/lib/kingkong/aggregator_spec.rb
58
141
  - spec/lib/kingkong/ping_spec.rb
59
142
  - spec/lib/kingkong/pinger_spec.rb
60
143
  - spec/lib/kingkong/runner_spec.rb
61
144
  - spec/lib/kingkong_spec.rb
62
145
  - spec/spec_helper.rb
63
- has_rdoc: true
64
146
  homepage: ''
65
147
  licenses: []
66
148
  post_install_message:
@@ -81,12 +163,11 @@ required_rubygems_version: !ruby/object:Gem::Requirement
81
163
  version: '0'
82
164
  requirements: []
83
165
  rubyforge_project: kingkong
84
- rubygems_version: 1.6.2
166
+ rubygems_version: 1.8.10
85
167
  signing_key:
86
168
  specification_version: 3
87
169
  summary: Build complex network application health checks with Ruby and EventMachine
88
170
  test_files:
89
- - spec/lib/kingkong/aggregator_spec.rb
90
171
  - spec/lib/kingkong/ping_spec.rb
91
172
  - spec/lib/kingkong/pinger_spec.rb
92
173
  - spec/lib/kingkong/runner_spec.rb
@@ -1,71 +0,0 @@
1
- module KingKong
2
- # Processes and aggregates samples for reporting. These stats will probably
3
- # be accessed throug the KingKong::Server UNIX socket.
4
- class Aggregator
5
- attr_reader :sum, :timed_out_count, :count, :started_at, :min, :max
6
-
7
- def initialize
8
- reset
9
- end
10
-
11
- # Accept a ping message, keep a running total, and make sure we stay within the
12
- # size of the number of samples that we want to keep around.
13
- def process(*pings)
14
- pings.each do |ping|
15
- @count+=1
16
- case ping.status
17
- when :timed_out
18
- @timed_out_count+=1
19
- else
20
- # This happens on our first ping before we have a min/max
21
- @min = @max = ping.latency if @min.nil? and @max.nil?
22
- # Cool! Lets do some math
23
- @min = ping.latency if ping.latency < @min
24
- @max = ping.latency if ping.latency > @max
25
- # We need to sum latency to calculate avgs
26
- @sum += ping.latency
27
- end
28
- end
29
- end
30
-
31
- # avg latency of samples
32
- def avg
33
- count.zero? ? 0 : sum / count
34
- end
35
-
36
- # What percentage of requests are timed out?
37
- def timed_out_percentage
38
- timed_out_count > 0 ? timed_out_count / count : 0
39
- end
40
-
41
- # Basic statistical summary of ping latency
42
- def to_hash
43
- {
44
- 'started_at' => started_at,
45
- 'avg' => avg,
46
- 'sum' => sum,
47
- 'min' => min,
48
- 'max' => max,
49
- 'count' => count,
50
- 'timed_out_count' => timed_out_count,
51
- 'successful_count' => count - timed_out_count
52
- }
53
- end
54
-
55
- # Print out a string for this that is suitable for flushing out to a socket
56
- def to_s
57
- to_hash.to_yaml
58
- end
59
-
60
- # Reset all of the counts to 0 and start sampling it all again!
61
- def reset
62
- @sum = 0.0
63
- @min = nil
64
- @max = nil
65
- @count = 0
66
- @timed_out_count = 0
67
- @samples = Array.new
68
- @started_at = Time.now
69
- end
70
- end
71
- end
@@ -1,37 +0,0 @@
1
- require 'eventmachine'
2
-
3
- module KingKong
4
- # Provides access to the pinger via a Socket or TCP port so that other
5
- # services, like Munin for example, can graph the data.
6
- module Reporting
7
- class Server < EventMachine::Connection
8
- Terminator = "\n\n"
9
- Host = '/tmp/king_kong.socket'
10
- Port = nil
11
-
12
- attr_accessor :aggregators
13
-
14
- # Accept a collection of aggregators that we'll use to report our stats.
15
- def initialize(*aggregators)
16
- @aggregators = aggregators
17
- end
18
-
19
- # Dump out the stats and close down the connection
20
- def post_init
21
- begin
22
- send_data "#{aggregators.each(&:to_s).join("\n")}#{Terminator}"
23
- rescue => e
24
- send_data "Exception! #{e}\n#{e.backtrace}"
25
- ensure
26
- close_connection
27
- end
28
- end
29
-
30
- # A nice short-cut for peeps who aren't familar with EM to fire up
31
- # an Reporting server with an array of aggregators, host, and a port.
32
- def self.start(aggregators, host=Socket::Host, port=Socket::Port)
33
- EventMachine::start_server(host, port, self, aggregators)
34
- end
35
- end
36
- end
37
- end
@@ -1,24 +0,0 @@
1
- module KingKong
2
- # Opens a UNIX socket to report pinger statistics
3
- class Server < EventMachine::Connection
4
- Frame = "\r\n"
5
-
6
- def initialize(pinger)
7
- @pinger = pinger
8
- end
9
-
10
- def post_init
11
- send_data frame @pinger.aggregator.to_hash.to_yaml
12
- end
13
-
14
- # Start an instance of the aggregator server on a unix port
15
- def self.start(pinger, host='/tmp/kingkong.socket', port=nil)
16
- EM.start_server host, port, self, pinger
17
- end
18
-
19
- private
20
- def frame(message)
21
- "#{message}#{Frame}"
22
- end
23
- end
24
- end
@@ -1,32 +0,0 @@
1
- require 'spec_helper'
2
- require "rspec/mocks/standalone"
3
-
4
- describe KingKong::Aggregator do
5
- before(:all) do
6
- @agg = KingKong::Aggregator.new
7
-
8
- @pings = (1..3).map do |n|
9
- ping = KingKong::Ping.new
10
- ping.stub(:latency){ n.to_f }
11
- ping
12
- end
13
-
14
- @agg.process *@pings
15
- end
16
-
17
- it "should calculate avg" do
18
- @agg.avg.should eql(2.0)
19
- end
20
-
21
- it "should calculate sum" do
22
- @agg.sum.should eql(6.0)
23
- end
24
-
25
- it "should calculate max" do
26
- @agg.max.should eql(3.0)
27
- end
28
-
29
- it "should calculate min" do
30
- @agg.min.should eql(1.0)
31
- end
32
- end