ardtweeno 0.3.1 → 0.4.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.
@@ -10,7 +10,7 @@ require 'rubygems'
10
10
  require 'sinatra/base'
11
11
  require 'ardtweeno'
12
12
  require 'logger'
13
- require 'rufus/scheduler'
13
+
14
14
 
15
15
  class RESTAPI < Sinatra::Base
16
16
 
@@ -58,9 +58,6 @@ class RESTAPI < Sinatra::Base
58
58
  set :options, {:test=>true, :log=>Logger.new(STDOUT), :level=>Logger::DEBUG, :confdata=>@confdata}
59
59
  end
60
60
 
61
- # Rufus-scheduler object
62
- set :scheduler, Rufus::Scheduler.start_new
63
-
64
61
  # Setup the system for use
65
62
  Ardtweeno.setup(settings.options)
66
63
  @@theDispatcher = Ardtweeno::Dispatcher.instance
@@ -70,21 +67,6 @@ class RESTAPI < Sinatra::Base
70
67
 
71
68
  # Posts URI
72
69
  set :newsURI, @@theDispatcher.getPostsURI
73
-
74
- #########################################################################################################
75
-
76
-
77
- settings.scheduler.every '60m' do
78
-
79
- begin
80
- settings.log.debug "Running scheduled data flush"
81
- @@theDispatcher.flush()
82
-
83
- rescue Ardtweeno::DBError => e
84
- settings.log.warn "ERROR: #{e.message}"
85
- end
86
-
87
- end
88
70
 
89
71
 
90
72
  #########################################################################################################
@@ -109,7 +91,40 @@ class RESTAPI < Sinatra::Base
109
91
 
110
92
 
111
93
  get '/status' do
112
- erb :status
94
+ begin
95
+ diskusage = @@theDispatcher.diskUsage
96
+
97
+ rescue Exception => e
98
+ throw :halt, [ 500, "500 Internal Server Error" ]
99
+ end
100
+
101
+ erb :status, :locals => {:diskusage=>diskusage}
102
+ end
103
+
104
+
105
+ get '/topology' do
106
+ settings.log.debug params.inspect
107
+
108
+ begin
109
+ theResponse = @@theDispatcher.constructTopology(params)
110
+
111
+ rescue Exception => e
112
+ throw :halt, [ 500, "500 Internal Server Error" ]
113
+ end
114
+
115
+ erb :topology, :locals => {:theTopology=>theResponse}
116
+ end
117
+
118
+
119
+ get '/graph/v1/punchcard/:node' do |node|
120
+ begin
121
+ theData, theDays, theRange= @@theDispatcher.constructPunchcard(params)
122
+
123
+ rescue Exception => e
124
+ throw :halt, [ 500, "500 Internal Server Error" ]
125
+ end
126
+
127
+ erb :punchcard, :locals => {:node=>params[:node], :ourGraphData=>theData, :ourGraphDays=>theDays, :ourGraphRange=>theRange}
113
128
  end
114
129
 
115
130
 
@@ -229,10 +244,35 @@ class RESTAPI < Sinatra::Base
229
244
  rescue Exception => e
230
245
  throw :halt, [ 400, "400 Bad Request" ]
231
246
  end
247
+ end
248
+
249
+
250
+ get '/api/v1/watch/:node' do |node|
251
+ settings.log.debug params.inspect
252
+ throw :halt, [ 404, "404 Page Not Found" ] unless @@theDispatcher.authenticate?(params[:key])
253
+ settings.log.debug "Check if a node is being watched"
232
254
 
255
+ begin
256
+ @@theDispatcher.watched?(params).to_json
257
+ rescue Exception => e
258
+ throw :halt, [ 400, "400 Bad Request" ]
259
+ end
233
260
  end
234
261
 
235
262
 
263
+ get '/api/v1/watch' do
264
+ settings.log.debug params.inspect
265
+ throw :halt, [ 404, "404 Page Not Found" ] unless @@theDispatcher.authenticate?(params[:key])
266
+ settings.log.debug "Check if a node is being watched"
267
+
268
+ begin
269
+ @@theDispatcher.watchList.to_json
270
+ rescue Exception => e
271
+ raise e
272
+ #throw :halt, [ 400, "400 Bad Request" ]
273
+ end
274
+ end
275
+
236
276
  #########################################################################################################
237
277
 
238
278
  get '/api/v1/system/config' do
@@ -292,22 +332,33 @@ class RESTAPI < Sinatra::Base
292
332
 
293
333
 
294
334
  get '/api/v1/system/status' do
295
- # Considering making this api target public to avoid having to store API keys in the highcarts.js
296
- # graphs..
297
- #throw :halt, [ 404, "404 Page Not Found" ] unless @@theDispatcher.authenticate?(params[:key])
298
335
  settings.log.debug "The system status hook has been called, reading the host configuration"
299
336
 
300
337
  begin
301
- return @@theDispatcher.status?().to_json
338
+ return @@theDispatcher.status?.to_json
302
339
 
303
340
  rescue Exception => e
304
- raise e
305
- #throw :halt, [ 500, "500 Internal Server Error" ]
341
+ throw :halt, [ 500, "500 Internal Server Error" ]
306
342
  end
307
343
 
308
344
  end
309
345
 
346
+
347
+ get '/api/v1/system/status/list' do
348
+ settings.log.debug "The system status list hook has been called, returning the last 15 mins of status data"
349
+
350
+ begin
351
+ return {:buffer=>@@theDispatcher.statuslist}.to_json
352
+
353
+ rescue Exception => e
354
+ throw :halt, [ 500, "500 Internal Server Error"]
355
+ end
356
+ end
357
+
310
358
  #########################################################################################################
311
359
 
360
+
361
+
362
+
312
363
  # End of RESTAPI Class
313
364
  end
@@ -0,0 +1,115 @@
1
+ ####################################################################################################
2
+ # @author David Kirwan https://github.com/davidkirwan/ardtweeno
3
+ # @description Ardtweeno::RingBuffer storage class
4
+ #
5
+ # @date 2013-08-18
6
+ ####################################################################################################
7
+
8
+ require 'ardtweeno'
9
+
10
+
11
+ module Ardtweeno
12
+ class RingBuffer
13
+
14
+
15
+ ##
16
+ # Ardtweeno::RingBuffer#new Constructor
17
+ #
18
+ # * *Args* :
19
+ # - ++ -> Fixnum size
20
+ # * *Returns* :
21
+ # - An instanciated copy of the RingBuffer class
22
+ # * *Raises* :
23
+ # TypeError if size is of type other than a Fixnum,
24
+ # ArgumentError if size is < 1
25
+ #
26
+ def initialize(size)
27
+ unless size.class == Fixnum then raise TypeError, "Size must be a Fixnum"; end
28
+ unless size >= 1 then raise ArgumentError, "Size must be a Fixnum of size >= 1"; end
29
+ @max = size
30
+ @buffer = []
31
+ end
32
+
33
+
34
+
35
+ ##
36
+ # Ardtweeno::RingBuffer#push This method adds an element at the end of the buffer, if size is exceeded,
37
+ # the first element is dropped
38
+ #
39
+ # * *Args* :
40
+ # - ++ ->
41
+ # * *Returns* :
42
+ # -
43
+ # * *Raises* :
44
+ #
45
+ def push(line)
46
+ if @buffer.size == @max
47
+ @buffer.shift
48
+ end
49
+ @buffer.push(line)
50
+ end
51
+
52
+
53
+
54
+ ##
55
+ # Ardtweeno::RingBuffer#clear empties the internal buffer
56
+ #
57
+ # * *Args* :
58
+ # - ++ ->
59
+ # * *Returns* :
60
+ # -
61
+ # * *Raises* :
62
+ #
63
+ def clear
64
+ @buffer = []
65
+ end
66
+
67
+
68
+
69
+ ##
70
+ # Ardtweeno::RingBuffer#to_a
71
+ #
72
+ # * *Args* :
73
+ # - ++ ->
74
+ # * *Returns* :
75
+ # - Copy of the internal buffer in Array form
76
+ # * *Raises* :
77
+ #
78
+ def to_a
79
+ return @buffer.dup
80
+ end
81
+
82
+
83
+
84
+ ##
85
+ # Ardtweeno::RingBuffer#to_s converts the internal buffer to a String
86
+ #
87
+ # * *Args* :
88
+ # - ++ ->
89
+ # * *Returns* :
90
+ # - String representation of the internal buffer
91
+ # * *Raises* :
92
+ #
93
+ def to_s
94
+ return @buffer.to_s
95
+ end
96
+
97
+
98
+
99
+ ##
100
+ # Ardtweeno::RingBuffer#each call the closure block on each element in the buffer
101
+ #
102
+ # * *Args* :
103
+ # - ++ ->
104
+ # * *Returns* :
105
+ # -
106
+ # * *Raises* :
107
+ #
108
+ def each(&block)
109
+ @buffer.each(&block)
110
+ end
111
+
112
+
113
+
114
+ end # End of RingBuffer class
115
+ end # End of Ardtweeno module
data/lib/ardtweeno.rb CHANGED
@@ -5,7 +5,6 @@
5
5
  # @date 14-06-2013
6
6
  ####################################################################################################
7
7
 
8
- require 'rubygems'
9
8
  require 'logger'
10
9
  require 'fileutils'
11
10
  require 'ardtweeno/serialparser'
@@ -17,6 +16,7 @@ require 'ardtweeno/node'
17
16
  require 'ardtweeno/configreader'
18
17
  require 'ardtweeno/api'
19
18
  require 'ardtweeno/db'
19
+ require 'ardtweeno/ringbuffer'
20
20
 
21
21
 
22
22
  ##
@@ -37,7 +37,7 @@ module Ardtweeno
37
37
  Ardtweeno::NODEPATH = Ardtweeno::CONFIGPATH + "/nodelist.yaml" unless defined? Ardtweeno::NODEPATH
38
38
  Ardtweeno::POSTPATH = Ardtweeno::CONFIGPATH + "/posts.yaml" unless defined? Ardtweeno::POSTPATH
39
39
 
40
- # Global Variables
40
+ # Class Variables
41
41
  @@seqCount = 0 unless defined? @@seqCount
42
42
  @@options = {} unless defined? @@options
43
43
 
Binary file
data/public/main.css CHANGED
@@ -1,34 +1,63 @@
1
1
  html, body {
2
- margin: 0;
3
- padding: 0;
2
+ margin: 0;
3
+ padding: 0;
4
4
  }
5
5
 
6
6
  body {
7
- background: #1E1C17;
8
- color: #ccc;
9
- font-family: 'Trebuchet MS', 'Lucida Grande', Arial, Helvetica, sans-serif;
10
- line-height: 1.2em;
7
+ background: #1E1C17;
8
+ color: #ccc;
9
+ font-family: 'Trebuchet MS', 'Lucida Grande', Arial, Helvetica, sans-serif;
10
+ line-height: 1.2em;
11
11
  }
12
12
 
13
13
  img {
14
- border: 0;
14
+ border: 0;
15
15
  }
16
16
 
17
17
  .preloader{
18
- display:block;
19
- margin:120px auto;
18
+ display:block;
19
+ margin:120px auto;
20
+ }
21
+
22
+ #punchcard-home {
23
+ position:relative;
24
+ right: 15px;
25
+ }
26
+
27
+ #punchcard-title {
28
+ position: relative;
29
+ top: -90px;
30
+ left: 125px;
31
+ }
32
+
33
+ #punchcard-range {
34
+ position: relative;
35
+ top: -90px;
36
+ left: 125px;
37
+ }
38
+
39
+ #punchcard-holder {
40
+ position: relative;
41
+ top: -90px;
42
+ background-color: #F0F0F0;
43
+ margin: 1em;
44
+ border-radius: 10px;
45
+ }
46
+
47
+ #topology-canvas {
48
+ background-color: #F0F0F0;
20
49
  }
21
50
 
22
51
  #status {
23
- position: relative;
24
- top: 6px;
52
+ position: relative;
53
+ top: 6px;
25
54
  }
26
55
 
27
56
 
28
57
  a {
29
- text-decoration: underline;
30
- color: #FCC240;
31
- text-decoration: none;
58
+ text-decoration: underline;
59
+ color: #FCC240;
60
+ text-decoration: none;
32
61
  }
33
62
  a:hover {
34
63
  color: #BF4B31;
@@ -462,3 +491,40 @@ table th[class*="span"],
462
491
  background-color: #c4e3f3;
463
492
  }
464
493
 
494
+
495
+ .graph-container {
496
+ box-sizing: border-box;
497
+ width: 850px;
498
+ height: 450px;
499
+ padding: 20px 15px 15px 15px;
500
+ margin: 15px auto 30px auto;
501
+ border: 1px solid #ddd;
502
+ background: #fff;
503
+ background: linear-gradient(#f6f6f6 0, #fff 50px);
504
+ background: -o-linear-gradient(#f6f6f6 0, #fff 50px);
505
+ background: -ms-linear-gradient(#f6f6f6 0, #fff 50px);
506
+ background: -moz-linear-gradient(#f6f6f6 0, #fff 50px);
507
+ background: -webkit-linear-gradient(#f6f6f6 0, #fff 50px);
508
+ box-shadow: 0 3px 10px rgba(0,0,0,0.15);
509
+ -o-box-shadow: 0 3px 10px rgba(0,0,0,0.1);
510
+ -ms-box-shadow: 0 3px 10px rgba(0,0,0,0.1);
511
+ -moz-box-shadow: 0 3px 10px rgba(0,0,0,0.1);
512
+ -webkit-box-shadow: 0 3px 10px rgba(0,0,0,0.1);
513
+ }
514
+
515
+
516
+ .graph-container {
517
+ width: 85%;
518
+ height: 300px;
519
+ }
520
+
521
+ .graph-placeholder {
522
+ width: 100%;
523
+ height: 100%;
524
+ font-size: 14px;
525
+ line-height: 1.2em;
526
+ }
527
+
528
+ .legend table {
529
+ border-spacing: 5px;
530
+ }
data/public/main.js CHANGED
@@ -1,5 +1,11 @@
1
1
  var containerId = '#tabs-container';
2
2
  var tabsId = '#tabs';
3
+ var keepUpdating = false;
4
+
5
+
6
+ function hashchanged(){
7
+ keepUpdating = false;
8
+ }
3
9
 
4
10
  $(document).ready(function(){
5
11
  // Preload tab on page load
@@ -18,6 +24,7 @@ $(document).ready(function(){
18
24
  });
19
25
  });
20
26
 
27
+
21
28
  function loadTab(tabObj){
22
29
  if(!tabObj || !tabObj.length){ return; }
23
30
  $(containerId).addClass('loading');
@@ -27,4 +34,4 @@ function loadTab(tabObj){
27
34
  $(containerId).removeClass('loading');
28
35
  $(containerId).fadeIn('fast');
29
36
  });
30
- }
37
+ }
data/test/api_test.rb CHANGED
@@ -13,8 +13,6 @@ class APITest < Test::Unit::TestCase
13
13
 
14
14
  include Rack::Test::Methods
15
15
 
16
- attr_accessor :dispatch, :nodelist, :params, :date, :hour, :minute, :confdata
17
-
18
16
 
19
17
  # Test suite fixtures
20
18
  def setup
@@ -51,7 +49,7 @@ class APITest < Test::Unit::TestCase
51
49
 
52
50
  # Create a DateTime instance
53
51
  today = DateTime.now
54
- theDate = today.year.to_s() + "-" + "%02d" % today.month.to_s() + "-" + "%02d" % today.day.to_s()
52
+ theDate = today.year.to_s() + "-" + "%02d" % today.month.to_s() + "-" + "%02d" % today.day.to_s()
55
53
 
56
54
  # Default values
57
55
  @date = theDate
@@ -85,7 +83,6 @@ class APITest < Test::Unit::TestCase
85
83
  :withhourwrong=> {:hour=>"022"},
86
84
  :withminute=> {:minute=>@minute},
87
85
  :withminutewrong=> {:minute=>"022"},
88
- :withseqno=> {:seqno=>35},
89
86
  :withseqnowrong=> {:seqno=>50000},
90
87
  :withversion=> {:version=> "0.5.0"},
91
88
  :withversionwrong=> {:version=> "0.0.0"},
@@ -101,6 +98,45 @@ class APITest < Test::Unit::TestCase
101
98
  @dispatch.store('{"data":[23.5,997.5,65],"key":"abcdef1"}')
102
99
  end
103
100
 
101
+ @punchData = Array.new
102
+
103
+ 144.times do
104
+ @punchData << 0
105
+ end
106
+
107
+ (1..today.hour).each do
108
+ @punchData << 0
109
+ end
110
+
111
+ @punchData << 5
112
+
113
+ ((today.hour + 1)..23).each do
114
+ @punchData << 0
115
+ end
116
+
117
+ @punchDays = Array.new
118
+
119
+ theStart = today - 6
120
+
121
+ (theStart..today).each do |i|
122
+ @punchDays << i.strftime('%a')
123
+ end
124
+
125
+ @punchDays.reverse!
126
+
127
+ theStartDay = "%02d" % theStart.day
128
+ theStartMonth = "%02d" % theStart.month
129
+ theStartYear = theStart.year.to_s
130
+
131
+ theEndDay = "%02d" % today.day
132
+ theEndMonth = "%02d" % today.month
133
+ theEndYear = today.year.to_s
134
+
135
+ startRange = theStartYear + "-" + theStartMonth + "-" + theStartDay
136
+ endRange = theEndYear + "-" + theEndMonth + "-" + theEndDay
137
+
138
+ @punchRange = "#{startRange} to #{endRange}"
139
+
104
140
  rescue Exception => e
105
141
  puts e.message
106
142
  puts e.backtrace
@@ -129,8 +165,7 @@ class APITest < Test::Unit::TestCase
129
165
 
130
166
  end
131
167
 
132
-
133
-
168
+
134
169
  # Test the retrievenodes method
135
170
  def test_retrievenodes
136
171
  results = @dispatch.retrieve_nodes(@params[:empty])
@@ -184,13 +219,19 @@ class APITest < Test::Unit::TestCase
184
219
 
185
220
  # Test the handleSeqNo method
186
221
  def test_handleSeqNo
187
- results = @dispatch.retrieve_packets(@params[:withseqno])
222
+ initial = @dispatch.retrieve_packets(@params[:empty])
223
+ value = initial[:packets].first
224
+
225
+ sequenceNo = {:seqno=>value.seqNo}
226
+
227
+ results = @dispatch.retrieve_packets(sequenceNo)
188
228
  assert_equal(1, results[:packets].size)
189
229
 
190
230
  results = @dispatch.retrieve_packets(@params[:withseqnowrong])
191
231
  assert_equal(0, results[:packets].size)
192
232
  end
193
233
 
234
+
194
235
  # Test the handleMinute method
195
236
  def test_handleMinute
196
237
  results = @dispatch.retrieve_packets(@params[:withminute])
@@ -273,5 +314,17 @@ class APITest < Test::Unit::TestCase
273
314
  end
274
315
 
275
316
  end
317
+
318
+
319
+ # Test the buildPunchcard method
320
+ def test_buildPunchcard
321
+ data, days, range = Ardtweeno::API.buildPunchcard(@nodeList, {:node=>"node1"})
322
+
323
+ assert_equal(data, @punchData)
324
+ assert_equal(days, @punchDays)
325
+ assert_equal(range, @punchRange)
326
+ end
327
+
328
+
276
329
 
277
330
  end
data/test/debug/run_mock CHANGED
@@ -1,7 +1,7 @@
1
1
  require 'rubygems'
2
2
  require 'serialport'
3
3
  require 'json'
4
- require "./serialport_mock.rb"
4
+ require "../serialport_mock.rb"
5
5
 
6
6
  mock = SerialDeviceMock.new('/dev/pts/3', 9600, 100)
7
7
 
@@ -7,8 +7,8 @@ while true
7
7
  testData = {"data" => [rand(0..100)], "key" => "2dbf44a68b77b15bfa5bc3d66c97892a57402bbe"}.to_json
8
8
  testData2 = {"data" => [rand(0..100), rand(0..1000)], "key" => "a46fe0c4dab0453f5d86bed6206040880f59393e"}.to_json
9
9
 
10
- puts Typhoeus::Request.post("http://192.168.1.8:4567/api/v1/packets", :body=> {:key => key, :payload=>testData})
11
- sleep(rand(0..90))
12
- #puts Typhoeus::Request.post("http://localhost:4567/api/v1/packets", :body=> {:key => key, :payload=>testData2})
13
- #sleep(rand(0.90))
10
+ puts Typhoeus::Request.post("http://localhost:4567/api/v1/packets", :body=> {:key => key, :payload=>testData})
11
+ sleep(rand(0..9))
12
+ puts Typhoeus::Request.post("http://localhost:4567/api/v1/packets", :body=> {:key => key, :payload=>testData2})
13
+ sleep(rand(0.9))
14
14
  end
@@ -4,9 +4,9 @@ require 'json'
4
4
 
5
5
 
6
6
  body = {:key=> "1230aea77d7bd38898fec74a75a87738dea9f657",
7
- :node=>"node1",
8
- :notifyURL=>"http://192.168.1.2:5000/push/node1",
7
+ # :node=>"node1",
8
+ :notifyURL=>"http://localhost:5000/push/node1",
9
9
  :method=>"GET",
10
- :timeout=>"60"}
10
+ :timeout=>60}
11
11
 
12
- puts Typhoeus::Request.post("http://192.168.1.8:4567/api/v1/watch/node1", :body=>body)
12
+ puts Typhoeus::Request.post("http://localhost:4567/api/v1/watch/node1", :body=>body)
Binary file
@@ -2,10 +2,9 @@
2
2
  # @author David Kirwan https://github.com/davidkirwan/ardtweeno
3
3
  # @description Ardtweeno dispatcher test fixtures
4
4
  #
5
- # @date 14-06-2013
5
+ # @date 2013-06-14
6
6
  ####################################################################################################
7
7
 
8
- require 'rubygems'
9
8
  require 'test/unit'
10
9
  require 'rack/test'
11
10
  require 'ardtweeno'
@@ -19,8 +18,6 @@ class DispatcherTest < Test::Unit::TestCase
19
18
 
20
19
  include Rack::Test::Methods
21
20
 
22
- attr_accessor :dispatch, :confdata
23
-
24
21
 
25
22
  # Test suite fixtures
26
23
  def setup
@@ -76,20 +73,20 @@ class DispatcherTest < Test::Unit::TestCase
76
73
  :method=>"GET",
77
74
  :timeout=>60}
78
75
 
79
- @nomethod = {:node=>"node1",
76
+ @nomethod = {:node=>"node2",
80
77
  :notifyURL=>"http://192.168.1.2:5000/push/node1",
81
78
  :timeout=>60}
82
79
 
83
- @notimeout = {:node=>"node1",
80
+ @notimeout = {:node=>"node3",
84
81
  :notifyURL=>"http://192.168.1.2:5000/push/node1",
85
82
  :method=>"GET"}
86
83
 
87
- @invalidtimeout = {:node=>"node1",
84
+ @invalidtimeout = {:node=>"node4",
88
85
  :notifyURL=>"http://192.168.1.2:5000/push/node1",
89
86
  :method=>"GET",
90
87
  :timeout=>-60}
91
88
 
92
- @invalidmethod = {:node=>"node1",
89
+ @invalidmethod = {:node=>"node5",
93
90
  :notifyURL=>"http://192.168.1.2:5000/push/node1",
94
91
  :method=>"POSTSS",
95
92
  :timeout=>60}
@@ -192,6 +189,7 @@ class DispatcherTest < Test::Unit::TestCase
192
189
  assert_nothing_raised do
193
190
  @dispatch.addWatch(@validwatch)
194
191
  end
192
+ assert_equal({:watched=>true}, @dispatch.watched?({:node=>"node1"}))
195
193
 
196
194
  assert_raise Ardtweeno::AlreadyWatched do
197
195
  @dispatch.addWatch(@validwatch)
@@ -200,22 +198,27 @@ class DispatcherTest < Test::Unit::TestCase
200
198
  assert_raise Ardtweeno::InvalidWatch do
201
199
  @dispatch.addWatch(@nonode)
202
200
  end
201
+ assert_equal({:watched=>false}, @dispatch.watched?({}))
203
202
 
204
203
  assert_raise Ardtweeno::InvalidWatch do
205
204
  @dispatch.addWatch(@nomethod)
206
205
  end
206
+ assert_equal({:watched=>false}, @dispatch.watched?({:node=>"node2"}))
207
207
 
208
208
  assert_raise Ardtweeno::InvalidWatch do
209
209
  @dispatch.addWatch(@notimeout)
210
210
  end
211
+ assert_equal({:watched=>false}, @dispatch.watched?({:node=>"node3"}))
211
212
 
212
213
  assert_raise Ardtweeno::InvalidWatch do
213
214
  @dispatch.addWatch(@invalidtimeout)
214
215
  end
216
+ assert_equal({:watched=>false}, @dispatch.watched?({:node=>"node4"}))
215
217
 
216
218
  assert_raise Ardtweeno::InvalidWatch do
217
219
  @dispatch.addWatch(@invalidmethod)
218
220
  end
221
+ assert_equal({:watched=>false}, @dispatch.watched?({:node=>"node5"}))
219
222
 
220
223
  end
221
224