2 require 'crunch_dispatch'
4 class CrunchDispatchTest < ActiveSupport::TestCase
5 test 'choose cheaper nodes first' do
8 [['compute1', 3.20, 32],
9 ['compute2', 1.60, 16],
10 ['compute3', 0.80, 8]].each do |hostname, price, cores|
11 Node.create!(hostname: hostname,
13 'slurm_state' => 'idle',
19 'total_cpu_cores' => cores,
20 'total_ram_mb' => cores*1024,
21 'total_scratch_mb' => cores*10000,
24 # Node with no price information
25 Node.create!(hostname: 'compute4',
27 'slurm_state' => 'idle',
30 'total_cpu_cores' => 8,
31 'total_ram_mb' => 8192,
32 'total_scratch_mb' => 80000,
35 Node.create!(hostname: 'compute5',
37 'slurm_state' => 'alloc',
43 'total_cpu_cores' => 32,
44 'total_ram_mb' => 32768,
45 'total_scratch_mb' => 320000,
49 dispatch = CrunchDispatch.new
50 [[1, 16384, ['compute2']],
51 [2, 16384, ['compute2', 'compute1']],
52 [2, 8000, ['compute4', 'compute3']],
53 ].each do |min_nodes, min_ram, expect_nodes|
54 job = Job.new(runtime_constraints: {
55 'min_nodes' => min_nodes,
56 'min_ram_mb_per_node' => min_ram,
58 nodes = dispatch.nodes_available_for_job_now job
59 assert_equal expect_nodes, nodes
63 test 'respond to TERM' do
64 lockfile = Rails.root.join 'tmp', 'dispatch.lock'
65 ENV['CRUNCH_DISPATCH_LOCKFILE'] = lockfile.to_s
69 # Abandon database connections inherited from parent
71 # https://github.com/kstephens/rails_is_forked
72 ActiveRecord::Base.connection_handler.connection_pools.each_value do |pool|
74 @reserved_connections = {}
78 ActiveRecord::Base.establish_connection
79 CrunchDispatch.new.run []
84 assert_with_timeout 5, "Dispatch did not lock #{lockfile}" do
88 Process.kill("TERM", pid)
90 assert_with_timeout 5, "Dispatch did not unlock #{lockfile}" do
95 def assert_with_timeout timeout, message
97 while (t += 0.1) < timeout
103 assert false, message + " (waited #{timeout} seconds)"
106 def can_lock lockfile
107 lockfile.open(File::RDWR|File::CREAT, 0644) do |f|
108 return f.flock(File::LOCK_EX|File::LOCK_NB)