2 require 'websocket_runner'
4 require 'database_cleaner'
6 DatabaseCleaner.strategy = :truncation
8 class WebsocketTest < ActionDispatch::IntegrationTest
9 self.use_transactional_fixtures = false
19 def ws_helper (token = nil, timeout = true)
26 ws = Faye::WebSocket::Client.new("ws://localhost:3002/websocket?api_token=#{api_client_authorizations(token).api_token}")
28 ws = Faye::WebSocket::Client.new("ws://localhost:3002/websocket")
31 ws.on :open do |event|
41 ws.on :close do |event|
42 close_status = [:close, event.code, event.reason]
49 assert opened, "Should have opened web socket"
50 assert (not too_long), "Test took too long"
51 assert_equal 1000, close_status[1], "Connection closed unexpectedly (check log for errors)"
54 test "connect with no token" do
58 ws.on :message do |event|
59 d = Oj.load event.data
65 assert_equal 401, status
69 test "connect, subscribe and get response" do
72 ws_helper :admin do |ws|
73 ws.on :open do |event|
74 ws.send ({method: 'subscribe'}.to_json)
77 ws.on :message do |event|
78 d = Oj.load event.data
84 assert_equal 200, status
87 test "connect, subscribe, get event" do
94 ws_helper :admin do |ws|
95 ws.on :open do |event|
96 ws.send ({method: 'subscribe'}.to_json)
99 ws.on :message do |event|
100 d = Oj.load event.data
103 assert_equal 200, d["status"]
104 spec = Specimen.create
107 ev_uuid = d["object_uuid"]
115 assert_equal spec.uuid, ev_uuid
118 test "connect, subscribe, get two events" do
125 authorize_with :admin
127 ws_helper :admin do |ws|
128 ws.on :open do |event|
129 ws.send ({method: 'subscribe'}.to_json)
132 ws.on :message do |event|
133 d = Oj.load event.data
136 assert_equal 200, d["status"]
137 spec = Specimen.create
141 spec_ev_uuid = d["object_uuid"]
144 human_ev_uuid = d["object_uuid"]
148 assert false, "Should not get any more events"
156 assert_equal spec.uuid, spec_ev_uuid
157 assert_equal human.uuid, human_ev_uuid
160 test "connect, subscribe, filter events" do
165 authorize_with :admin
167 ws_helper :admin do |ws|
168 ws.on :open do |event|
169 ws.send ({method: 'subscribe', filters: [['object_uuid', 'is_a', 'arvados#human']]}.to_json)
172 ws.on :message do |event|
173 d = Oj.load event.data
176 assert_equal 200, d["status"]
181 human_ev_uuid = d["object_uuid"]
185 assert false, "Should not get any more events"
192 assert_equal human.uuid, human_ev_uuid
196 test "connect, subscribe, multiple filters" do
203 authorize_with :admin
205 ws_helper :admin do |ws|
206 ws.on :open do |event|
207 ws.send ({method: 'subscribe', filters: [['object_uuid', 'is_a', 'arvados#human']]}.to_json)
208 ws.send ({method: 'subscribe', filters: [['object_uuid', 'is_a', 'arvados#specimen']]}.to_json)
211 ws.on :message do |event|
212 d = Oj.load event.data
215 assert_equal 200, d["status"]
218 assert_equal 200, d["status"]
219 spec = Specimen.create
220 Trait.create # not part of filters, should not be received
224 spec_ev_uuid = d["object_uuid"]
227 human_ev_uuid = d["object_uuid"]
231 assert false, "Should not get any more events"
239 assert_equal spec.uuid, spec_ev_uuid
240 assert_equal human.uuid, human_ev_uuid
243 test "connect, subscribe, ask events starting at seq num" do
248 authorize_with :admin
250 lastid = logs(:log3).id
254 ws_helper :admin do |ws|
255 ws.on :open do |event|
256 ws.send ({method: 'subscribe', last_log_id: lastid}.to_json)
259 ws.on :message do |event|
260 d = Oj.load event.data
263 assert_equal 200, d["status"]
266 l1 = d["object_uuid"]
267 assert_not_nil l1, "Unexpected message: #{d}"
270 l2 = d["object_uuid"]
271 assert_not_nil l2, "Unexpected message: #{d}"
275 assert false, "Should not get any more events"
281 assert_equal logs(:log4).object_uuid, l1
282 assert_equal logs(:log5).object_uuid, l2
285 test "connect, subscribe, get event, unsubscribe" do
291 authorize_with :admin
293 ws_helper :admin, false do |ws|
294 ws.on :open do |event|
295 ws.send ({method: 'subscribe'}.to_json)
297 # Set a time limit on the test because after unsubscribing the server
298 # still has to process the next event (and then hopefully correctly
299 # decides not to send it because we unsubscribed.)
304 ws.on :message do |event|
305 d = Oj.load event.data
308 assert_equal 200, d["status"]
309 spec = Specimen.create
312 spec_ev_uuid = d["object_uuid"]
313 ws.send ({method: 'unsubscribe'}.to_json)
321 assert_equal 200, d["status"]
324 assert false, "Should not get any more events"
331 assert_equal spec.uuid, spec_ev_uuid
334 test "connect, subscribe, get event, unsubscribe with filter" do
339 authorize_with :admin
341 ws_helper :admin, false do |ws|
342 ws.on :open do |event|
343 ws.send ({method: 'subscribe', filters: [['object_uuid', 'is_a', 'arvados#human']]}.to_json)
345 # Set a time limit on the test because after unsubscribing the server
346 # still has to process the next event (and then hopefully correctly
347 # decides not to send it because we unsubscribed.)
352 ws.on :message do |event|
353 d = Oj.load event.data
356 assert_equal 200, d["status"]
360 spec_ev_uuid = d["object_uuid"]
361 ws.send ({method: 'unsubscribe', filters: [['object_uuid', 'is_a', 'arvados#human']]}.to_json)
369 assert_equal 200, d["status"]
372 assert false, "Should not get any more events"
379 assert_equal spec.uuid, spec_ev_uuid
383 test "connect, subscribe, get event, try to unsubscribe with bogus filter" do
390 authorize_with :admin
392 ws_helper :admin do |ws|
393 ws.on :open do |event|
394 ws.send ({method: 'subscribe'}.to_json)
397 ws.on :message do |event|
398 d = Oj.load event.data
401 assert_equal 200, d["status"]
402 spec = Specimen.create
405 spec_ev_uuid = d["object_uuid"]
406 ws.send ({method: 'unsubscribe', filters: [['foo', 'bar', 'baz']]}.to_json)
414 assert_equal 404, d["status"]
417 human_ev_uuid = d["object_uuid"]
421 assert false, "Should not get any more events"
429 assert_equal spec.uuid, spec_ev_uuid
430 assert_equal human.uuid, human_ev_uuid
435 test "connected, not subscribed, no event" do
436 authorize_with :admin
438 ws_helper :admin, false do |ws|
439 ws.on :open do |event|
449 ws.on :message do |event|
450 assert false, "Should not get any messages, message was #{event.data}"
455 test "connected, not authorized to see event" do
458 authorize_with :admin
460 ws_helper :active, false do |ws|
461 ws.on :open do |event|
462 ws.send ({method: 'subscribe'}.to_json)
469 ws.on :message do |event|
470 d = Oj.load event.data
473 assert_equal 200, d["status"]
477 assert false, "Should not get any messages, message was #{event.data}"
485 test "connect, try bogus method" do
488 ws_helper :admin do |ws|
489 ws.on :open do |event|
490 ws.send ({method: 'frobnabble'}.to_json)
493 ws.on :message do |event|
494 d = Oj.load event.data
500 assert_equal 400, status
503 test "connect, missing method" do
506 ws_helper :admin do |ws|
507 ws.on :open do |event|
508 ws.send ({fizzbuzz: 'frobnabble'}.to_json)
511 ws.on :message do |event|
512 d = Oj.load event.data
518 assert_equal 400, status
521 test "connect, send malformed request" do
524 ws_helper :admin do |ws|
525 ws.on :open do |event|
526 ws.send '<XML4EVER></XML4EVER>'
529 ws.on :message do |event|
530 d = Oj.load event.data
536 assert_equal 400, status
540 test "connect, try subscribe too many filters" do
543 authorize_with :admin
545 ws_helper :admin do |ws|
546 ws.on :open do |event|
548 ws.send ({method: 'subscribe', filters: [['object_uuid', '=', i]]}.to_json)
552 ws.on :message do |event|
553 d = Oj.load event.data
555 when (1..EventBus::MAX_FILTERS)
556 assert_equal 200, d["status"]
558 when (EventBus::MAX_FILTERS+1)
559 assert_equal 403, d["status"]
566 assert_equal 17, state