closes #10518
[arvados.git] / services / api / test / websocket_runner.rb
1 require 'bundler'
2 require 'socket'
3
4 $ARV_API_SERVER_DIR = File.expand_path('../..', __FILE__)
5
6 s = TCPServer.new('0.0.0.0', 0)
7 WEBSOCKET_PORT = s.addr[1]
8 s.close
9 SERVER_PID_PATH = "tmp/pids/passenger.#{WEBSOCKET_PORT}.pid"
10
11 class WebsocketTestRunner < MiniTest::Unit
12   def _system(*cmd)
13     Bundler.with_clean_env do
14       if not system({'ARVADOS_WEBSOCKETS' => 'ws-only', 'RAILS_ENV' => 'test'}, *cmd)
15         raise RuntimeError, "Command failed with exit status #{$?}: #{cmd.inspect}"
16       end
17     end
18   end
19
20   def _run(args=[])
21     server_pid = Dir.chdir($ARV_API_SERVER_DIR) do |apidir|
22       # Only passenger seems to be able to run the websockets server successfully.
23       _system('passenger', 'start', '-d', "-p#{WEBSOCKET_PORT}")
24       timeout = Time.now.tv_sec + 10
25       begin
26         sleep 0.2
27         begin
28           server_pid = IO.read(SERVER_PID_PATH).to_i
29           good_pid = (server_pid > 0) and (Process.kill(0, pid) rescue false)
30         rescue Errno::ENOENT
31           good_pid = false
32         end
33       end while (not good_pid) and (Time.now.tv_sec < timeout)
34       if not good_pid
35         raise RuntimeError, "could not find API server Rails pid"
36       end
37       server_pid
38     end
39     begin
40       super(args)
41     ensure
42       Dir.chdir($ARV_API_SERVER_DIR) do
43         _system('passenger', 'stop', "-p#{WEBSOCKET_PORT}")
44       end
45       # DatabaseCleaner leaves the database empty. Prefer to leave it full.
46       dc = DatabaseController.new
47       dc.define_singleton_method :render do |*args| end
48       dc.reset
49     end
50   end
51 end
52
53 MiniTest::Unit.runner = WebsocketTestRunner.new