class BaseChip::Project
Constants
- DEFINED_SUBCOMMANDS
Attributes
registered_modes[R]
workload[RW]
Public Class Methods
new()
click to toggle source
Calls superclass method
# File lib/base_chip/project.rb, line 48 def initialize() super @project = self @pwd = Dir.pwd end
Public Instance Methods
block_dereference(name,names,passive)
click to toggle source
# File lib/base_chip/project.rb, line 166 def block_dereference(name,names,passive) if block = @blocks[name.to_sym] block.configure block.dereference_workload(names,passive) else fault "Could not find block #{name} in project #{@name}" # FIXME say who wanted it, and if shortcut occurred end end
block_names()
click to toggle source
# File lib/base_chip/project.rb, line 79 def block_names return @block_names if @block_names # \@block_names = Dir.glob("#\{@directory}/*") # \@block_names.map!{|path| path.split(/\//).pop} # \@block_names.delete 'settings.yaml' # \@block_names end
configure()
click to toggle source
Calls superclass method
# File lib/base_chip/project.rb, line 385 def configure return if @configured @directory = BaseChip.root @modes += BaseChip.options.modes.split(/,/) if BaseChip.options.modes super @modes.each do |name| fault "Attempted to call mode '#{name}', which isn't registered with the project. Call register_mode(#{name}) in project.rb to allow. Valid modes are #{project.registered_modes}" unless project.registered_modes.include? name.to_s end if self.blocks @directory_prefix = figure_directory_prefix @block_names = self.blocks.keys end end
default_modes()
click to toggle source
# File lib/base_chip/project.rb, line 382 def default_modes %w{ coverage gates fast debug profiling }.each { |m| register_mode m } end
dereference_clusters()
click to toggle source
# File lib/base_chip/project.rb, line 398 def dereference_clusters return nil unless cluster_names = BaseChip.options.jobs configure fault "Cluster submission attempted, but no cluster types are configured." unless @cluster_types @dereferenced = [] cluster_names = cluster_names.split(/,/) cluster_names.each do |cn| type = nil cluster = nil jobs = nil cn_orig = cn clusters = [] if cn.sub!(/^(\d+)(?::|$)/,'') jobs = $1.to_i end if cn.sub!(/:(\d+)$/,'') fault "Multiple counts found in '#{cn_orig}'. Separate multiple cluster specifiers with commas." if jobs jobs = $1.to_i end case cn when /^([^:]+):([^:]+)$/ cluster = $2 if $1 == 'all' || $1 == '' cluster_types.each_value do |cluster_type| clusters += cluster_type.dereference(cluster,jobs,true) end elsif cluster_type = @cluster_types[$1.to_sym] clusters += cluster_type.dereference(cluster,jobs,false) else fault "Could not find cluster type '#{$1}' in cluster specifier '#{cn_orig}'." if jobs end when /^([^:]+)$/ if cluster_type = @cluster_types[$1.to_sym] clusters += cluster_type.dereference('all',jobs,true) else cluster_types.each_value do |cluster_type| clusters += cluster_type.dereference('all',jobs,true) end end when '' cluster_types.each_value do |cluster_type| clusters += cluster_type.dereference('all',jobs,true) end else fault "Could not parse the cluster specifier '#{cn_orig}'." if jobs end fault "No clusters could be determined for the cluster specifier '#{cn_orig}'." if clusters.empty? if cluster_order cluster_order.each do |name| tmp = clusters.delete_if {|c| c.full_name == "#{@name}:#{name}"} try_add_clusters tmp, jobs end end try_add_clusters clusters, jobs end @dereferenced end
dereference_workload(targets)
click to toggle source
# File lib/base_chip/project.rb, line 174 def dereference_workload(targets) configure fault "project '#{name}' has no blocks defined" unless @blocks targets ||= ['all'] out = [] workload_hash = Hash.new targets.each do |t| case t when 'gate', 'diffgate', 'all' self.block_names.each do |b| out += block_dereference(b,[t],true) end when /^all:(.*)$/ self.block_names.each do |b| out += block_dereference(b,[$1],true) end when /:/ tmp = t.split(/:/) b = tmp.shift out += block_dereference(b,[tmp.join(':')],true) else fault "Cannot determine block in order to run #{t}." end end out.uniq! out end
diffgate(targets)
click to toggle source
# File lib/base_chip/project.rb, line 118 def diffgate(targets) targets.each do |t| return false unless t =~ /\bdiffgate$/ end true end
discover_blocks()
click to toggle source
# File lib/base_chip/project.rb, line 368 def discover_blocks ; file_glob("#{@directory}/*/base_chip/block.rb" , /(\w+)\/base_chip\/block\.rb$/ , :block ) file_glob("#{@directory}/base_chip/block/*.rb" , /base_chip\/blocks\/(\w+)\.rb$/ , :block ) end
discover_cluster_types()
click to toggle source
# File lib/base_chip/project.rb, line 371 def discover_cluster_types ; file_glob("#{@directory}/base_chip/cluster_types/*.rb" , /base_chip\/cluster_types\/(\w+)\.rb$/ , :cluster_type ) end
discover_configurations()
click to toggle source
# File lib/base_chip/project.rb, line 370 def discover_configurations ; file_glob("#{@directory}/base_chip/configurations/*.rb", /base_chip\/configurations\/(\w+)\.rb$/, :configuration ) end
discover_subprojects()
click to toggle source
# File lib/base_chip/project.rb, line 366 def discover_subprojects ; file_glob("#{@directory}/*/base_chip/project.rb" , /(\w+)\/base_chip\/project\.rb$/ , :subproject ) file_glob("#{@directory}/base_chip/subprojects/*.rb" , /base_chip\/subprojects\/(\w+)\.rb$/ , :subproject ) end
figure_directory_prefix()
click to toggle source
def configure_blocks(block_names
)
block_names.each do |name| self.blocks[name.to_sym].configure end
end
# File lib/base_chip/project.rb, line 58 def figure_directory_prefix # if @directory == @pwd # return nil # elsif @pwd.length > @directory.length configure if @blocks @blocks.each do |bname,block| block.configure if @pwd =~ /^#{block.directory}\b/ block.configurations.each do |cname,configuration| configuration.configure return "#{bname}:#{cname}" if @pwd =~ /^#{configuration.directory}\b/ end return bname.to_s end end end # end nil # fault "'base_chip' should be run from a block's work directory or the top level of the project." end
find_action(t_name)
click to toggle source
# File lib/base_chip/project.rb, line 245 def find_action(t_name) address = t_name.split(/:/) block_name = address.shift.to_sym block = self.blocks[block_name] or fault("Couldn't find block '#{block_name}'") config_name = address.shift.to_sym config = block.configurations[config_name] or fault("Couldn't find configuration '#{config_name}' in block '#{block_name}") thing = address.shift.to_sym action = config.actions[thing] return action if action test_list = config.test_lists[thing] or fault("Could not find action or test list '#{thing}' in block:configuration '#{block_name}:#{config_name}'") test_name = address.shift.to_sym test = test_list.tests[test_name] or fault("Could not find test '#{test_name}' in block:configuration:list '#{block_name}:#{config_name}:#{thing}'") return test end
ready(targets=nil)
click to toggle source
# File lib/base_chip/project.rb, line 87 def ready(targets=nil) #,available_only=false) configure @orig_targets = targets if @directory_prefix # no map! here because @orig_targets needs to stay true to the original command targets = targets.map { |t| "#{@directory_prefix}:#{t}" } end @workload = dereference_workload targets @workload.delete_if {|w|w.nil?} if @workload.empty? if diffgate(targets) puts "diffgate returned no targets needing to run" exit else fault "Could not determine anything to run based on the targets #{targets}. Did you mean to run this from another directory?" end end w_names = @workload.map{|w|w.name} @workload.each do |w| w.configure if w.depends w.deep_depends.each do |d| if @workload.include? d w.wait_count += 1 d.next_tasks << w end end end end end
register_mode(name)
click to toggle source
# File lib/base_chip/project.rb, line 378 def register_mode(name) @registered_modes ||= [] @registered_modes << name.to_s end
results_line(type,block,total)
click to toggle source
# File lib/base_chip/project.rb, line 223 def results_line(type,block,total) blocks = block == 'all' ? @results[type].keys : [block] if total pass_fail_cancel = [0,0,0,0,0,0,0] blocks.each do |b| res_hash = @results[type][b] pass_fail_cancel[0] += res_hash['pass'].size pass_fail_cancel[2] += res_hash['fail'].size pass_fail_cancel[4] += res_hash[:cancel].size end pass_fail_cancel[6] = pass_fail_cancel[0] + pass_fail_cancel[2] + pass_fail_cancel[4] pass_fail_cancel[1] = (100 * pass_fail_cancel[0]/pass_fail_cancel[6]).round pass_fail_cancel[3] = (100 * pass_fail_cancel[2]/pass_fail_cancel[6]).round pass_fail_cancel[5] = (100 * pass_fail_cancel[4]/pass_fail_cancel[6]).round str = pass_fail_cancel[0] > 0 ? ' [32m%6d %3d[0m |' : ' %6d %3d |' str += pass_fail_cancel[3] > 0 ? ' [31m%6d %3d[0m |' : ' %6d %3d |' str += pass_fail_cancel[5] > 0 ? ' [33m%6d %3d[0m |' : ' %6d %3d |' return "#{str} %6d" % pass_fail_cancel else fault 'Internal error: detailed result reporting not yet supported' end end
run_all_readied()
click to toggle source
# File lib/base_chip/project.rb, line 124 def run_all_readied # @report_hash = {} FileUtils.mkdir_p "#{@directory}/reports" @report_name = "#{@directory}/reports/workload.#{BaseChip.random_string}" @report_file = File.new(@report_name,'w') if @tasker.clusters @tasker.ready else @foreground = @workload.size == 1 end begin @tasker.submit_workload_chain workload_chain @tasker.run rescue Interrupt @tasker.finish end end
shortcut(name, array)
click to toggle source
def enable_tracking(opc,opi)
# puts "enabled tracking(#{opc},#{opi})" init_results_sockets(:client) @opc = opc @opi = opi
end def track_complete(state,first_error = nil)
return unless @opc msg = Message.new msg.project = 'gandalf' msg.type = 'complete' msg.state = state msg.data = { 'opc' => @opc , 'opi' => @opi , 'first_error' => first_error } send_work_message(msg)
end def track_results(test_action,state,problem,totals)
return unless @opc msg = Message.new msg.project = 'gandalf' msg.type = 'test_action' msg.state = state msg.data = { 'name' => test_action.bundle_name, 'block' => test_action.block.name, 'opc' => @opc, 'opi' => @opi, 'first_error' => problem && problem.signature, 'file' => problem && problem.file, 'bundle' => problem && problem.bundle, 'totals' => totals } # puts "sending totals #{test_action.totals.inspect}" puts "sending message #{msg.data.inspect}" if test_action.class_string == 'Action' msg.data['action' ] = test_action.name else msg.data['test' ] = test_action.name msg.data['test_list'] = test_action.test_list.name end send_work_message(msg)
end
# File lib/base_chip/project.rb, line 361 def shortcut(name, array) @shortcuts ||= {} @shortcuts[name] = array end
tasker_finish()
click to toggle source
# File lib/base_chip/project.rb, line 295 def tasker_finish banner end
tasker_handle_results(task, result, problem_or_directory=nil, totals={})
click to toggle source
# File lib/base_chip/project.rb, line 203 def tasker_handle_results(task, result, problem_or_directory=nil, totals={}) action = @workload.select{|w|w.full_name == task.task_name}.first # track_results(action, result, problem, totals) if result == 'fail' message = (problem_or_directory || "#{action.class_string} '#{action.name}' failed without an error signature").to_s begin error message rescue end @failing ||= 0 @failing += 1 @first_error = {} @first_error[action.class_string] ||= message end @results ||= {} @results[action.class_string] ||= {} @results[action.class_string][action.block.name] ||= {'pass' => [], 'fail' => [], :cancel =>[]} @results[action.class_string][action.block.name][result] << action @report_file.puts "#{result} #{action.class_string} #{task.task_name} #{problem_or_directory}" end
tasker_run_task(t_obj)
click to toggle source
# File lib/base_chip/project.rb, line 298 def tasker_run_task(t_obj) t = find_action(t_obj.task_name) begin t.foreground = @foreground t.run rescue ReportingError => e # FIXME reuse test error states here t.state = 'fail' rescue Exception => e t.problem = Problem.new t.problem.signature = "#{t.full_name} #{e.class} --- #{e.message}" puts e.backtrace # FIXME reuse test error states here t.state = 'fail' end #track_results(t ,t.state,t.problem ,t.totals) @tasker.register_results(t_obj,t.state,t.problem || t.directory,t.totals) end
try_add_clusters(clusters, jobs)
click to toggle source
# File lib/base_chip/project.rb, line 458 def try_add_clusters(clusters, jobs) clusters.each do |c| next if @dereferenced.include? c c.configure fault "could not determine number of jobs to run in cluster '#{c.full_name}'. Consider setting a default for this cluster." unless (c.default_jobs || c.maximum_jobs || jobs) if (c.default_jobs || c.maximum_jobs) == nil; c.slots = jobs elsif jobs.nil? ; c.slots = c.default_jobs || c.maximum_jobs elsif jobs > c.maximum_jobs ; c.slots = c.maximum_jobs else c.slots = jobs end @dereferenced << c end end
use_tool(name,version)
click to toggle source
# File lib/base_chip/project.rb, line 372 def use_tool(name,version) tool :name do |t| t.select_version version end end
workload_chain()
click to toggle source
# File lib/base_chip/project.rb, line 141 def workload_chain @workload.each do |w| w.task = t = Task.new t.task_name = w.full_name t.foreground = @foreground t.worker_command = if @tasker.clusters lambda { |client_id| # The "@drb_uri ||=" is necessary because Drb.uri can change for some reason, and a command compare happens later "#{$0} #{@orig_targets.join(' ')} --client-of #{@drb_uri ||= DRb.uri} --client-id #{client_id} --work-dir #{@pwd} #{ '--modes ' + BaseChip.options.modes if BaseChip.options.modes } #{ (['--' ] + BaseChip.options. append_arguments).join(' ') if BaseChip.options. append_arguments } #{ (['---'] + BaseChip.options.replace_arguments).join(' ') if BaseChip.options.replace_arguments }" } else nil end end @workload.map do |w| t = w.task t.next_tasks = w.next_tasks.map { |nt| nt.task } t.wait_count = w.wait_count w.next_tasks.uniq! t end end