Commit 982e2b2b authored by Samir Noir's avatar Samir Noir 🧀
Browse files

Merge branch 'features/#10661' into 'master'

Add resources param on job controller index

See merge request !81
parents 48020484 52a10aa6
Pipeline #179915 waiting for manual action with stages
in 22 minutes and 51 seconds
......@@ -22,20 +22,35 @@ class JobsController < ApplicationController
offset = [(params[:offset] || 0).to_i, 0].max
limit = [(params[:limit] || LIMIT).to_i, LIMIT_MAX].min
jobs = OAR::Job.list(params)
total = jobs.count(:all)
params[:resources] = 'no' if params[:resources].nil?
jobs = jobs.offset(offset).limit(limit).includes(:job_types, :job_events, :gantt)
jobs_extra_hash = {}
jobs.each do |job|
job.links = links_for_item(job)
if params[:resources] != 'no'
jobs_extra_hash[job[:job_id]] = {}
jobs_extra_hash[job[:job_id]][:resources_by_type] = job.resources_by_type
jobs_extra_hash[job[:job_id]][:assigned_nodes] = job.assigned_nodes
end
end
jobs_hash = jobs.as_json
if params[:resources] != 'no'
jobs_hash.each do |job|
job.merge!(jobs_extra_hash[job[:uid]])
end
end
result = {
'total' => total,
'offset' => offset,
'items' => jobs,
'items' => jobs_hash,
'links' => links_for_collection
}
......@@ -87,8 +102,8 @@ class JobsController < ApplicationController
else
response.header['X-Oar-Info'] = begin
(
JSON.parse(http.body)['oardel_output'] || ''
).split("\n").join(' ')
JSON.parse(http.body)['oardel_output'] || ''
).split("\n").join(' ')
rescue StandardError
'-'
end
......
......@@ -144,7 +144,11 @@ module OAR
end
def assigned_nodes
(resources_by_type['cores'] || []).uniq
if resources_by_type['cores']
resources_by_type['cores'].map { |n| n.gsub(/\/([0-9]+)$/, '') }.uniq
else
[]
end
end
def resources_by_type
......@@ -153,7 +157,7 @@ module OAR
case resource.type
when 'default'
h['cores'] ||= []
h['cores'].push(resource.network_address)
h['cores'].push(resource.network_address + '/' + resource.cpuset)
when /vlan/
h['vlans'] ||= []
h['vlans'].push(resource.vlan)
......@@ -171,6 +175,21 @@ module OAR
].join('.'))
end
end
# Sort by node name and cpuset, to have nodes from a same cluster grouped
# and listed in correct order. Also sort cpuset number for a node.
if h['cores']
h['cores'].sort_by! do |n|
[n.gsub(/^([A-z]+)\-.*$/, '\1'),
n.gsub(/^([A-z]+)\-([0-9]+).*/, '\2').to_i,
n.gsub(/^.*\/([0-9]+)$/, '\1').to_i]
end
end
['vlans', 'disks', 'subnets'].each do |type|
h[type].sort if h[type]
end
h
end
......
......@@ -54,6 +54,20 @@ describe JobsController do
}
]
end
it 'should fetch the list of jobs, with their resources' do
get :index, params: { site_id: 'rennes', resources: 'yes', format: :json }
expect(response.status).to eq 200
expect(json['total']).to eq @job_uids.length
expect(json['offset']).to eq 0
expect(json['items'].length).to eq @job_uids.length
expect(json['items'].map { |i| i['uid'] }.sort).to eq @job_uids.sort
expect(json['items'].first.has_key?('assigned_nodes')).to be true
expect(json['items'].first.has_key?('resources_by_type')).to be true
expect(json['items'].first['assigned_nodes']).to eq ['parasilo-3.rennes.grid5000.fr']
expect(json['items'].first['resources_by_type']['cores']).to eq ['parasilo-3.rennes.grid5000.fr/16', 'parasilo-3.rennes.grid5000.fr/17', 'parasilo-3.rennes.grid5000.fr/18', 'parasilo-3.rennes.grid5000.fr/19', 'parasilo-3.rennes.grid5000.fr/20', 'parasilo-3.rennes.grid5000.fr/21', 'parasilo-3.rennes.grid5000.fr/22', 'parasilo-3.rennes.grid5000.fr/23']
end
it 'should correctly deal with pagination filters' do
get :index, params: { site_id: 'rennes', offset: 11, limit: 5, format: :json }
expect(response.status).to eq 200
......@@ -62,6 +76,7 @@ describe JobsController do
expect(json['items'].length).to eq 5
expect(json['items'].map { |i| i['uid'] }).to eq [374_190, 374_189, 374_188, 374_187, 374_186]
end
it 'should correctly deal with other filters' do
params = { user: 'crohr', name: 'whatever' }
expect(OAR::Job).to receive(:list).with(hash_including(params))
......@@ -86,7 +101,7 @@ describe JobsController do
expect(json['types']).to eq ['deploy']
expect(json['scheduled_at']).to eq 1_294_395_995
expect(json['assigned_nodes'].sort).to eq ['paramount-4.rennes.grid5000.fr', 'paramount-30.rennes.grid5000.fr', 'paramount-32.rennes.grid5000.fr', 'paramount-33.rennes.grid5000.fr'].sort
expect(json['resources_by_type']['cores'].sort).to eq ['paramount-4.rennes.grid5000.fr', 'paramount-4.rennes.grid5000.fr', 'paramount-4.rennes.grid5000.fr', 'paramount-4.rennes.grid5000.fr', 'paramount-30.rennes.grid5000.fr', 'paramount-30.rennes.grid5000.fr', 'paramount-30.rennes.grid5000.fr', 'paramount-30.rennes.grid5000.fr', 'paramount-32.rennes.grid5000.fr', 'paramount-32.rennes.grid5000.fr', 'paramount-32.rennes.grid5000.fr', 'paramount-32.rennes.grid5000.fr', 'paramount-33.rennes.grid5000.fr', 'paramount-33.rennes.grid5000.fr', 'paramount-33.rennes.grid5000.fr', 'paramount-33.rennes.grid5000.fr'].sort
expect(json['resources_by_type']['cores']).to eq ['paramount-4.rennes.grid5000.fr/0', 'paramount-4.rennes.grid5000.fr/1', 'paramount-4.rennes.grid5000.fr/2', 'paramount-4.rennes.grid5000.fr/3', 'paramount-30.rennes.grid5000.fr/0', 'paramount-30.rennes.grid5000.fr/1', 'paramount-30.rennes.grid5000.fr/2', 'paramount-30.rennes.grid5000.fr/3', 'paramount-32.rennes.grid5000.fr/0', 'paramount-32.rennes.grid5000.fr/1', 'paramount-32.rennes.grid5000.fr/2', 'paramount-32.rennes.grid5000.fr/3', 'paramount-33.rennes.grid5000.fr/0', 'paramount-33.rennes.grid5000.fr/1', 'paramount-33.rennes.grid5000.fr/2', 'paramount-33.rennes.grid5000.fr/3']
end
end # describe "GET /sites/{{site_id}}/jobs/{{id}}"
......
......@@ -172,9 +172,12 @@ describe OAR::Job do
# each node in the list should be repeated as many times cores are reserved
it 'should build a hash of resources indexed by their type [cores]' do
nodenb = [9,28,31,32,33,34,35,38,39,40,41,42,43,44,45,47,48,49,50,52,53,54,55,56,57,58,59,60,61,62,63,64]
ncore = *0..7
result = OAR::Job.active.first.resources_by_type
expect(result.keys).to eq(['cores'])
expect(result['cores'].sort).to eq(['paradent-9.rennes.grid5000.fr', 'paradent-9.rennes.grid5000.fr', 'paradent-9.rennes.grid5000.fr', 'paradent-9.rennes.grid5000.fr', 'paradent-9.rennes.grid5000.fr', 'paradent-9.rennes.grid5000.fr', 'paradent-9.rennes.grid5000.fr', 'paradent-9.rennes.grid5000.fr', 'paradent-28.rennes.grid5000.fr', 'paradent-28.rennes.grid5000.fr', 'paradent-28.rennes.grid5000.fr', 'paradent-28.rennes.grid5000.fr', 'paradent-28.rennes.grid5000.fr', 'paradent-28.rennes.grid5000.fr', 'paradent-28.rennes.grid5000.fr', 'paradent-28.rennes.grid5000.fr', 'paradent-31.rennes.grid5000.fr', 'paradent-31.rennes.grid5000.fr', 'paradent-31.rennes.grid5000.fr', 'paradent-31.rennes.grid5000.fr', 'paradent-31.rennes.grid5000.fr', 'paradent-31.rennes.grid5000.fr', 'paradent-31.rennes.grid5000.fr', 'paradent-31.rennes.grid5000.fr', 'paradent-32.rennes.grid5000.fr', 'paradent-32.rennes.grid5000.fr', 'paradent-32.rennes.grid5000.fr', 'paradent-32.rennes.grid5000.fr', 'paradent-32.rennes.grid5000.fr', 'paradent-32.rennes.grid5000.fr', 'paradent-32.rennes.grid5000.fr', 'paradent-32.rennes.grid5000.fr', 'paradent-33.rennes.grid5000.fr', 'paradent-33.rennes.grid5000.fr', 'paradent-33.rennes.grid5000.fr', 'paradent-33.rennes.grid5000.fr', 'paradent-33.rennes.grid5000.fr', 'paradent-33.rennes.grid5000.fr', 'paradent-33.rennes.grid5000.fr', 'paradent-33.rennes.grid5000.fr', 'paradent-34.rennes.grid5000.fr', 'paradent-34.rennes.grid5000.fr', 'paradent-34.rennes.grid5000.fr', 'paradent-34.rennes.grid5000.fr', 'paradent-34.rennes.grid5000.fr', 'paradent-34.rennes.grid5000.fr', 'paradent-34.rennes.grid5000.fr', 'paradent-34.rennes.grid5000.fr', 'paradent-35.rennes.grid5000.fr', 'paradent-35.rennes.grid5000.fr', 'paradent-35.rennes.grid5000.fr', 'paradent-35.rennes.grid5000.fr', 'paradent-35.rennes.grid5000.fr', 'paradent-35.rennes.grid5000.fr', 'paradent-35.rennes.grid5000.fr', 'paradent-35.rennes.grid5000.fr', 'paradent-38.rennes.grid5000.fr', 'paradent-38.rennes.grid5000.fr', 'paradent-38.rennes.grid5000.fr', 'paradent-38.rennes.grid5000.fr', 'paradent-38.rennes.grid5000.fr', 'paradent-38.rennes.grid5000.fr', 'paradent-38.rennes.grid5000.fr', 'paradent-38.rennes.grid5000.fr', 'paradent-39.rennes.grid5000.fr', 'paradent-39.rennes.grid5000.fr', 'paradent-39.rennes.grid5000.fr', 'paradent-39.rennes.grid5000.fr', 'paradent-39.rennes.grid5000.fr', 'paradent-39.rennes.grid5000.fr', 'paradent-39.rennes.grid5000.fr', 'paradent-39.rennes.grid5000.fr', 'paradent-40.rennes.grid5000.fr', 'paradent-40.rennes.grid5000.fr', 'paradent-40.rennes.grid5000.fr', 'paradent-40.rennes.grid5000.fr', 'paradent-40.rennes.grid5000.fr', 'paradent-40.rennes.grid5000.fr', 'paradent-40.rennes.grid5000.fr', 'paradent-40.rennes.grid5000.fr', 'paradent-41.rennes.grid5000.fr', 'paradent-41.rennes.grid5000.fr', 'paradent-41.rennes.grid5000.fr', 'paradent-41.rennes.grid5000.fr', 'paradent-41.rennes.grid5000.fr', 'paradent-41.rennes.grid5000.fr', 'paradent-41.rennes.grid5000.fr', 'paradent-41.rennes.grid5000.fr', 'paradent-42.rennes.grid5000.fr', 'paradent-42.rennes.grid5000.fr', 'paradent-42.rennes.grid5000.fr', 'paradent-42.rennes.grid5000.fr', 'paradent-42.rennes.grid5000.fr', 'paradent-42.rennes.grid5000.fr', 'paradent-42.rennes.grid5000.fr', 'paradent-42.rennes.grid5000.fr', 'paradent-43.rennes.grid5000.fr', 'paradent-43.rennes.grid5000.fr', 'paradent-43.rennes.grid5000.fr', 'paradent-43.rennes.grid5000.fr', 'paradent-43.rennes.grid5000.fr', 'paradent-43.rennes.grid5000.fr', 'paradent-43.rennes.grid5000.fr', 'paradent-43.rennes.grid5000.fr', 'paradent-44.rennes.grid5000.fr', 'paradent-44.rennes.grid5000.fr', 'paradent-44.rennes.grid5000.fr', 'paradent-44.rennes.grid5000.fr', 'paradent-44.rennes.grid5000.fr', 'paradent-44.rennes.grid5000.fr', 'paradent-44.rennes.grid5000.fr', 'paradent-44.rennes.grid5000.fr', 'paradent-45.rennes.grid5000.fr', 'paradent-45.rennes.grid5000.fr', 'paradent-45.rennes.grid5000.fr', 'paradent-45.rennes.grid5000.fr', 'paradent-45.rennes.grid5000.fr', 'paradent-45.rennes.grid5000.fr', 'paradent-45.rennes.grid5000.fr', 'paradent-45.rennes.grid5000.fr', 'paradent-47.rennes.grid5000.fr', 'paradent-47.rennes.grid5000.fr', 'paradent-47.rennes.grid5000.fr', 'paradent-47.rennes.grid5000.fr', 'paradent-47.rennes.grid5000.fr', 'paradent-47.rennes.grid5000.fr', 'paradent-47.rennes.grid5000.fr', 'paradent-47.rennes.grid5000.fr', 'paradent-48.rennes.grid5000.fr', 'paradent-48.rennes.grid5000.fr', 'paradent-48.rennes.grid5000.fr', 'paradent-48.rennes.grid5000.fr', 'paradent-48.rennes.grid5000.fr', 'paradent-48.rennes.grid5000.fr', 'paradent-48.rennes.grid5000.fr', 'paradent-48.rennes.grid5000.fr', 'paradent-49.rennes.grid5000.fr', 'paradent-49.rennes.grid5000.fr', 'paradent-49.rennes.grid5000.fr', 'paradent-49.rennes.grid5000.fr', 'paradent-49.rennes.grid5000.fr', 'paradent-49.rennes.grid5000.fr', 'paradent-49.rennes.grid5000.fr', 'paradent-49.rennes.grid5000.fr', 'paradent-50.rennes.grid5000.fr', 'paradent-50.rennes.grid5000.fr', 'paradent-50.rennes.grid5000.fr', 'paradent-50.rennes.grid5000.fr', 'paradent-50.rennes.grid5000.fr', 'paradent-50.rennes.grid5000.fr', 'paradent-50.rennes.grid5000.fr', 'paradent-50.rennes.grid5000.fr', 'paradent-52.rennes.grid5000.fr', 'paradent-52.rennes.grid5000.fr', 'paradent-52.rennes.grid5000.fr', 'paradent-52.rennes.grid5000.fr', 'paradent-52.rennes.grid5000.fr', 'paradent-52.rennes.grid5000.fr', 'paradent-52.rennes.grid5000.fr', 'paradent-52.rennes.grid5000.fr', 'paradent-53.rennes.grid5000.fr', 'paradent-53.rennes.grid5000.fr', 'paradent-53.rennes.grid5000.fr', 'paradent-53.rennes.grid5000.fr', 'paradent-53.rennes.grid5000.fr', 'paradent-53.rennes.grid5000.fr', 'paradent-53.rennes.grid5000.fr', 'paradent-53.rennes.grid5000.fr', 'paradent-54.rennes.grid5000.fr', 'paradent-54.rennes.grid5000.fr', 'paradent-54.rennes.grid5000.fr', 'paradent-54.rennes.grid5000.fr', 'paradent-54.rennes.grid5000.fr', 'paradent-54.rennes.grid5000.fr', 'paradent-54.rennes.grid5000.fr', 'paradent-54.rennes.grid5000.fr', 'paradent-55.rennes.grid5000.fr', 'paradent-55.rennes.grid5000.fr', 'paradent-55.rennes.grid5000.fr', 'paradent-55.rennes.grid5000.fr', 'paradent-55.rennes.grid5000.fr', 'paradent-55.rennes.grid5000.fr', 'paradent-55.rennes.grid5000.fr', 'paradent-55.rennes.grid5000.fr', 'paradent-56.rennes.grid5000.fr', 'paradent-56.rennes.grid5000.fr', 'paradent-56.rennes.grid5000.fr', 'paradent-56.rennes.grid5000.fr', 'paradent-56.rennes.grid5000.fr', 'paradent-56.rennes.grid5000.fr', 'paradent-56.rennes.grid5000.fr', 'paradent-56.rennes.grid5000.fr', 'paradent-57.rennes.grid5000.fr', 'paradent-57.rennes.grid5000.fr', 'paradent-57.rennes.grid5000.fr', 'paradent-57.rennes.grid5000.fr', 'paradent-57.rennes.grid5000.fr', 'paradent-57.rennes.grid5000.fr', 'paradent-57.rennes.grid5000.fr', 'paradent-57.rennes.grid5000.fr', 'paradent-58.rennes.grid5000.fr', 'paradent-58.rennes.grid5000.fr', 'paradent-58.rennes.grid5000.fr', 'paradent-58.rennes.grid5000.fr', 'paradent-58.rennes.grid5000.fr', 'paradent-58.rennes.grid5000.fr', 'paradent-58.rennes.grid5000.fr', 'paradent-58.rennes.grid5000.fr', 'paradent-59.rennes.grid5000.fr', 'paradent-59.rennes.grid5000.fr', 'paradent-59.rennes.grid5000.fr', 'paradent-59.rennes.grid5000.fr', 'paradent-59.rennes.grid5000.fr', 'paradent-59.rennes.grid5000.fr', 'paradent-59.rennes.grid5000.fr', 'paradent-59.rennes.grid5000.fr', 'paradent-60.rennes.grid5000.fr', 'paradent-60.rennes.grid5000.fr', 'paradent-60.rennes.grid5000.fr', 'paradent-60.rennes.grid5000.fr', 'paradent-60.rennes.grid5000.fr', 'paradent-60.rennes.grid5000.fr', 'paradent-60.rennes.grid5000.fr', 'paradent-60.rennes.grid5000.fr', 'paradent-61.rennes.grid5000.fr', 'paradent-61.rennes.grid5000.fr', 'paradent-61.rennes.grid5000.fr', 'paradent-61.rennes.grid5000.fr', 'paradent-61.rennes.grid5000.fr', 'paradent-61.rennes.grid5000.fr', 'paradent-61.rennes.grid5000.fr', 'paradent-61.rennes.grid5000.fr', 'paradent-62.rennes.grid5000.fr', 'paradent-62.rennes.grid5000.fr', 'paradent-62.rennes.grid5000.fr', 'paradent-62.rennes.grid5000.fr', 'paradent-62.rennes.grid5000.fr', 'paradent-62.rennes.grid5000.fr', 'paradent-62.rennes.grid5000.fr', 'paradent-62.rennes.grid5000.fr', 'paradent-63.rennes.grid5000.fr', 'paradent-63.rennes.grid5000.fr', 'paradent-63.rennes.grid5000.fr', 'paradent-63.rennes.grid5000.fr', 'paradent-63.rennes.grid5000.fr', 'paradent-63.rennes.grid5000.fr', 'paradent-63.rennes.grid5000.fr', 'paradent-63.rennes.grid5000.fr', 'paradent-64.rennes.grid5000.fr', 'paradent-64.rennes.grid5000.fr', 'paradent-64.rennes.grid5000.fr', 'paradent-64.rennes.grid5000.fr', 'paradent-64.rennes.grid5000.fr', 'paradent-64.rennes.grid5000.fr', 'paradent-64.rennes.grid5000.fr', 'paradent-64.rennes.grid5000.fr'].sort)
expect(result['cores']).to eq(nodenb.map{|n| ncore.map{|c| "paradent-#{n}.rennes.grid5000.fr/#{c}"}}.flatten)
end
it 'should build a hash of resources indexed by their type [disks]' do
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment