Merge remote-tracking branch 'origin/master' into origin-2608-websocket-event-bus...
[arvados.git] / apps / workbench / test / test_helper.rb
1 ENV["RAILS_ENV"] = "test"
2 require File.expand_path('../../config/environment', __FILE__)
3 require 'rails/test_help'
4
5 $ARV_API_SERVER_DIR = File.expand_path('../../../../services/api', __FILE__)
6 SERVER_PID_PATH = 'tmp/pids/server.pid'
7
8 class ActiveSupport::TestCase
9   # Setup all fixtures in test/fixtures/*.(yml|csv) for all tests in
10   # alphabetical order.
11   #
12   # Note: You'll currently still have to declare fixtures explicitly
13   # in integration tests -- they do not yet inherit this setting
14   fixtures :all
15   def use_token token_name
16     auth = api_fixture('api_client_authorizations')[token_name.to_s]
17     Thread.current[:arvados_api_token] = auth['api_token']
18   end
19
20   def teardown
21     Thread.current[:arvados_api_token] = nil
22     super
23   end
24 end
25
26 module ApiFixtureLoader
27   def self.included(base)
28     base.extend(ClassMethods)
29   end
30
31   module ClassMethods
32     @@api_fixtures = {}
33     def api_fixture(name)
34       # Returns the data structure from the named API server test fixture.
35       @@api_fixtures[name] ||= \
36       begin
37         path = File.join($ARV_API_SERVER_DIR, 'test', 'fixtures', "#{name}.yml")
38         YAML.load(IO.read(path))
39       end
40     end
41   end
42   def api_fixture name
43     self.class.api_fixture name
44   end
45 end
46
47 class ActiveSupport::TestCase
48   include ApiFixtureLoader
49   def session_for api_client_auth_name
50     {
51       arvados_api_token: api_fixture('api_client_authorizations')[api_client_auth_name.to_s]['api_token']
52     }
53   end
54 end
55
56 class ApiServerBackedTestRunner < MiniTest::Unit
57   # Make a hash that unsets Bundle's environment variables.
58   # We'll use this environment when we launch Bundle commands in the API
59   # server.  Otherwise, those commands will try to use Workbench's gems, etc.
60   @@APIENV = Hash[ENV.map { |key, val|
61                     (key =~ /^BUNDLE_/) ? [key, nil] : nil
62                   }.compact]
63
64   def _system(*cmd)
65     if not system(@@APIENV, *cmd)
66       raise RuntimeError, "#{cmd[0]} returned exit code #{$?.exitstatus}"
67     end
68   end
69
70   def _run(args=[])
71     Capybara.javascript_driver = :poltergeist
72     server_pid = Dir.chdir($ARV_API_SERVER_DIR) do |apidir|
73       _system('bundle', 'exec', 'rake', 'db:test:load')
74       _system('bundle', 'exec', 'rake', 'db:fixtures:load')
75       _system('bundle', 'exec', 'rails', 'server', '-d')
76       timeout = Time.now.tv_sec + 10
77       begin
78         sleep 0.2
79         begin
80           server_pid = IO.read(SERVER_PID_PATH).to_i
81           good_pid = (server_pid > 0) and (Process.kill(0, pid) rescue false)
82         rescue Errno::ENOENT
83           good_pid = false
84         end
85       end while (not good_pid) and (Time.now.tv_sec < timeout)
86       if not good_pid
87         raise RuntimeError, "could not find API server Rails pid"
88       end
89       server_pid
90     end
91     begin
92       super(args)
93     ensure
94       Process.kill('TERM', server_pid)
95     end
96   end
97 end
98
99 MiniTest::Unit.runner = ApiServerBackedTestRunner.new