2 require 'websocket_runner'
4 require 'database_cleaner'
6 DatabaseCleaner.strategy = :deletion
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|
35 too_long = true if close_status.nil?
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
244 test "connect, subscribe, compound filter" do
248 authorize_with :admin
250 ws_helper :admin do |ws|
251 ws.on :open do |event|
252 ws.send ({method: 'subscribe', filters: [['object_uuid', 'is_a', 'arvados#trait'], ['event_type', '=', 'update']]}.to_json)
255 ws.on :message do |event|
256 d = Oj.load event.data
259 assert_equal 200, d["status"]
260 t1 = Trait.create("name" => "foo")
265 assert_equal 'update', d['event_type']
269 assert false, "Should not get any more events"
275 assert_equal 3, state
279 test "connect, subscribe, ask events starting at seq num" do
284 authorize_with :admin
286 lastid = logs(:log3).id
290 ws_helper :admin do |ws|
291 ws.on :open do |event|
292 ws.send ({method: 'subscribe', last_log_id: lastid}.to_json)
295 ws.on :message do |event|
296 d = Oj.load event.data
299 assert_equal 200, d["status"]
302 l1 = d["object_uuid"]
303 assert_not_nil l1, "Unexpected message: #{d}"
306 l2 = d["object_uuid"]
307 assert_not_nil l2, "Unexpected message: #{d}"
311 assert false, "Should not get any more events"
317 assert_equal logs(:log4).object_uuid, l1
318 assert_equal logs(:log5).object_uuid, l2
321 test "connect, subscribe, get event, unsubscribe" do
327 authorize_with :admin
329 ws_helper :admin, false do |ws|
330 ws.on :open do |event|
331 ws.send ({method: 'subscribe'}.to_json)
333 # Set a time limit on the test because after unsubscribing the server
334 # still has to process the next event (and then hopefully correctly
335 # decides not to send it because we unsubscribed.)
340 ws.on :message do |event|
341 d = Oj.load event.data
344 assert_equal 200, d["status"]
345 spec = Specimen.create
348 spec_ev_uuid = d["object_uuid"]
349 ws.send ({method: 'unsubscribe'}.to_json)
357 assert_equal 200, d["status"]
360 assert false, "Should not get any more events"
367 assert_equal spec.uuid, spec_ev_uuid
370 test "connect, subscribe, get event, unsubscribe with filter" do
375 authorize_with :admin
377 ws_helper :admin, false do |ws|
378 ws.on :open do |event|
379 ws.send ({method: 'subscribe', filters: [['object_uuid', 'is_a', 'arvados#human']]}.to_json)
381 # Set a time limit on the test because after unsubscribing the server
382 # still has to process the next event (and then hopefully correctly
383 # decides not to send it because we unsubscribed.)
388 ws.on :message do |event|
389 d = Oj.load event.data
392 assert_equal 200, d["status"]
396 spec_ev_uuid = d["object_uuid"]
397 ws.send ({method: 'unsubscribe', filters: [['object_uuid', 'is_a', 'arvados#human']]}.to_json)
405 assert_equal 200, d["status"]
408 assert false, "Should not get any more events"
415 assert_equal spec.uuid, spec_ev_uuid
419 test "connect, subscribe, get event, try to unsubscribe with bogus filter" do
426 authorize_with :admin
428 ws_helper :admin do |ws|
429 ws.on :open do |event|
430 ws.send ({method: 'subscribe'}.to_json)
433 ws.on :message do |event|
434 d = Oj.load event.data
437 assert_equal 200, d["status"]
438 spec = Specimen.create
441 spec_ev_uuid = d["object_uuid"]
442 ws.send ({method: 'unsubscribe', filters: [['foo', 'bar', 'baz']]}.to_json)
450 assert_equal 404, d["status"]
453 human_ev_uuid = d["object_uuid"]
457 assert false, "Should not get any more events"
465 assert_equal spec.uuid, spec_ev_uuid
466 assert_equal human.uuid, human_ev_uuid
471 test "connected, not subscribed, no event" do
472 authorize_with :admin
474 ws_helper :admin, false do |ws|
475 ws.on :open do |event|
485 ws.on :message do |event|
486 assert false, "Should not get any messages, message was #{event.data}"
491 test "connected, not authorized to see event" do
494 authorize_with :admin
496 ws_helper :active, false do |ws|
497 ws.on :open do |event|
498 ws.send ({method: 'subscribe'}.to_json)
505 ws.on :message do |event|
506 d = Oj.load event.data
509 assert_equal 200, d["status"]
513 assert false, "Should not get any messages, message was #{event.data}"
521 test "connect, try bogus method" do
524 ws_helper :admin do |ws|
525 ws.on :open do |event|
526 ws.send ({method: 'frobnabble'}.to_json)
529 ws.on :message do |event|
530 d = Oj.load event.data
536 assert_equal 400, status
539 test "connect, missing method" do
542 ws_helper :admin do |ws|
543 ws.on :open do |event|
544 ws.send ({fizzbuzz: 'frobnabble'}.to_json)
547 ws.on :message do |event|
548 d = Oj.load event.data
554 assert_equal 400, status
557 test "connect, send malformed request" do
560 ws_helper :admin do |ws|
561 ws.on :open do |event|
562 ws.send '<XML4EVER></XML4EVER>'
565 ws.on :message do |event|
566 d = Oj.load event.data
572 assert_equal 400, status
576 test "connect, try subscribe too many filters" do
579 authorize_with :admin
581 ws_helper :admin do |ws|
582 ws.on :open do |event|
584 ws.send ({method: 'subscribe', filters: [['object_uuid', '=', i]]}.to_json)
588 ws.on :message do |event|
589 d = Oj.load event.data
591 when (1..EventBus::MAX_FILTERS)
592 assert_equal 200, d["status"]
594 when (EventBus::MAX_FILTERS+1)
595 assert_equal 403, d["status"]
602 assert_equal 17, state
606 test "connect, subscribe, lots of events" do
609 log_start = Log.order(:id).last.id
611 authorize_with :admin
613 ws_helper :admin, false do |ws|
615 # Needs a longer timeout than the default
619 ws.on :open do |event|
620 ws.send ({method: 'subscribe'}.to_json)
623 ws.on :message do |event|
624 d = Oj.load event.data
627 assert_equal 200, d["status"]
628 ActiveRecord::Base.transaction do
630 spec = Specimen.create
636 assert_equal d['id'], event_count+log_start
637 if event_count == 202
645 assert_equal 202, event_count