class Origen::RegressionManager
Supports executing code regression testing.
Reference workspace used for comparison will automatically be populated based on tag selected (default: latest).
An instance of this class is hooked up to:
Origen.regression_manager
Basic Usage¶ ↑
options[:target] = %w{target1.rb target2.rb target3.rb} Origen.regression_manager.run(options) do |options| Origen.target.loop(options) do |options| Origen.lsf.submit_origen_job "generate regression.list -t #{options[:target]}" end end
Public Instance Methods
We want the reference workspace to run the same regression as the local workspace, so copy the current version of the regression command file across.
# File lib/origen/regression_manager.rb, line 254 def copy_regression_file path_to_command_file = regression_command_file.relative_path_from(Origen.root) system "rm -f #{reference_origen_root}/#{path_to_command_file}" system "cp #{Origen.root}/#{path_to_command_file} #{reference_origen_root}/#{path_to_command_file}" end
# File lib/origen/regression_manager.rb, line 120 def disable_origen_version_check if Origen.respond_to?(:with_disable_origen_version_check) Origen.with_disable_origen_version_check(all_processes: true) do yield end else yield end end
# File lib/origen/regression_manager.rb, line 268 def get_reference_workspace(_options = {}) puts '' puts 'It looks like this is the first time that you have run a regression from this workspace.' puts '' puts 'In order to run a regression test Origen must have access to a secondary workspace in which' puts 'it can build the reference files.' puts '' puts 'Generally all of your developments workspaces should use the same reference workspace.' puts '' puts 'Origen will make a suggestion for the reference workspace below, however if you know that' puts 'you already have an existing one at a different location then please enter the path.' puts '' puts 'WHERE SHOULD THE REFERENCE WORKSPACE RESIDE?' puts '' get_text(default: ws.reference_workspace_proposal, single: true) end
# File lib/origen/regression_manager.rb, line 285 def get_version(_options = {}) puts '' puts 'WHAT VERSION DO YOU WANT TO COMPARE AGAINST?' puts '' if Origen.app.rc.git? puts "Valid values are 'latest', 'last' (production release), a tag, a commit or a branch." else puts "Valid values are 'latest', 'last' (production release), or a tag." end puts '' v = VersionString.new(get_text(default: Origen.app.version, single: true)) if v.semantic? v.prefixed else v end end
# File lib/origen/regression_manager.rb, line 182 def load_options options = {} if File.exist?(store_file) File.open(store_file.to_s) do |f| options = Marshal.load(f) end FileUtils.rm_f store_file end options end
Cycle through all targets in the upcoming run to ensure that all output directories exist
# File lib/origen/regression_manager.rb, line 167 def prepare_targets(options) targets = [options[:target], options[:targets]].flatten.compact if targets.empty? puts 'You must supply the targets you are going to run in the options' puts 'passed to regression_manager.run.' fail end Origen.target.loop(options) { |_options| } targets end
# File lib/origen/regression_manager.rb, line 208 def reference_origen_root if running_in_reference_workspace? Origen.root else ws.origen_root(@reference_workspace) end end
Returns a full path to the regression command file within the local application
# File lib/origen/regression_manager.rb, line 261 def regression_command_file first_call = caller.find { |line| line =~ /regression_manager.rb.*run/ } app_caller_line = caller[caller.index(first_call) + 1] app_caller_line =~ /(.*\.rb)/ path = Pathname.new(Regexp.last_match[1]) end
Serves to execute a regression. Any block of code passed to this method will receive regression check @param [Hash] options Options to customize the run instance @option options [Array] :target String
Array
of target names on which to run regression @option options [Boolean] :build_reference (true) Build reference workspace automatically @option options [Symbol] :build_method (:init) whether to use a git init or git clone method to build the workspace @option options [Boolean] :send_email (false) Send results email when regression complete @option options [Boolean] :email_all_developers (false) If sending email, whether to email all developers or just user @option options [Boolean] :report_results (false) Whether to report results inline to console
# File lib/origen/regression_manager.rb, line 36 def run(options = {}) options = { build_reference: true, build_method: :init, send_email: false, email_all_developers: false, report_results: false, uses_lsf: true }.merge(options) options = load_options if running_in_reference_workspace? targets = prepare_targets(options) if running_in_reference_workspace? Origen.lsf.clear_all yield options wait_for_completion(options) if options[:uses_lsf] save_and_delete_output(options) else if options[:build_reference] @reference_tag = version_to_tag(options[:version] || get_version(options)) # passing the options for regression to the setup reference workspace method. setup_reference_workspace(options) # Generate the reference files save_options(options) Origen.with_origen_root(reference_origen_root) do disable_origen_version_check do Dir.chdir reference_origen_root do Bundler.with_clean_env do # Origen 0.40.0 started using origen-owned binstubs system 'rm -rf lbin' if Gem::Version.new(Origen.version) < Gem::Version.new('0.40.0') # If regression is run using a service account, we need to setup the path/bundler manually # The regression manager needs to be passed a --service_account option when initiated. if options[:service_account] puts "Running with a service account, setting up the workspace manually now, assuming it runs BASH!! <-- can't assume bash always" puts 'This is not an ideal way, need to discuss. Though, a normal user will never set service_account to true' # Future enhancement, probably add the sourcing of files in a service_origen_setup file. # Check if service_origen_setup exists, if it does, load/execute the file. If not, ask user to provide it. # If running as a service account, service_origen_setup file is NOT optional. # More enhancements to come on this bit of code, but if someone finds a better cleaner way, I am happy to discuss the issues I have seen and come up with a solution. system 'source ~/.bash_profile' system 'source ~/.bashrc.user' system 'bundle install --gemfile Gemfile --binstubs lbin --path ~/.origen/gems/' # this needs to be executed as 'origen -v' does not seem to handle it on its own. system 'origen -v' # Let origen handle the gems installation and bundler setup. else if Origen.site_config.gem_manage_bundler system 'origen -v' system 'bundle install' # Make sure bundle updates the necessary config/gems required for Origen. system 'origen m debug' else system 'bundle install' # Make sure bundle updates the necessary config/gems required for Origen. system 'bundle exec origen -v' system 'origen m debug' end end Origen.log.info '######################################################' Origen.log.info 'running regression command in reference workspace...' Origen.log.info '######################################################' Origen.log.info if Origen.site_config.gem_manage_bundler system 'origen regression' else system 'bundle exec origen regression' end end end end end end # Generate the latest files for comparison Origen.lsf.clear_all Origen.log.info '######################################################' Origen.log.info 'running regression command in local workspace...' Origen.log.info '######################################################' Origen.log.info yield options wait_for_completion(options) if options[:uses_lsf] summarize_results(options) # call exit code false to force process fail unless Origen.app.stats.clean_run? exit 1 end end end
# File lib/origen/regression_manager.rb, line 199 def running_in_reference_workspace? File.exist?("#{Origen.root}/.this_is_a_reference_workspace") end
Saves all generated output (to the reference dir) and then deletes the output directory to save space
# File lib/origen/regression_manager.rb, line 150 def save_and_delete_output(options = {}) Origen.lsf.build_log(options) Origen.log.flush Dir.chdir reference_origen_root do Bundler.with_clean_env do if options[:log_file] system "bundle exec origen save all -f log/#{options[:log_file]}.txt" else system 'bundle exec origen save all' end end end FileUtils.rm_rf "#{reference_origen_root}/output" end
# File lib/origen/regression_manager.rb, line 193 def save_options(options) File.open(store_file.to_s, 'w') do |f| Marshal.dump(options, f) end end
# File lib/origen/regression_manager.rb, line 216 def setup_reference_workspace(options) if ws.reference_workspace_set? # If the reference workspace option is true, overwrite the @reference_workspace accessor if options[:reference_workspace] @reference_workspace = options[:reference_workspace] # Build the new reference workspace now. unless File.exist?(@reference_workspace) highlight { Origen.log.info 'Building reference workspace...' } ws.build(@reference_workspace, options) end ws.set_reference_workspace(@reference_workspace) else @reference_workspace = ws.reference_workspace end else if options[:reference_workspace] # If the reference workspace option is true, overwrite the @reference_workspace accessor @reference_workspace = options[:reference_workspace] else @reference_workspace = get_reference_workspace end unless File.exist?(@reference_workspace) highlight { Origen.log.info 'Building reference workspace...' } ws.build(@reference_workspace, options) end ws.set_reference_workspace(@reference_workspace) end highlight { Origen.log.info "Switching reference workspace to version #{@reference_tag}..." } ws.switch_version(@reference_workspace, @reference_tag, origen_root_only: true) unless File.exist?("#{reference_origen_root}/.this_is_a_reference_workspace") system "touch #{reference_origen_root}/.this_is_a_reference_workspace" end copy_regression_file end
# File lib/origen/regression_manager.rb, line 178 def store_file @store_file ||= Pathname.new "#{reference_origen_root}/.regression_options" end
# File lib/origen/regression_manager.rb, line 130 def summarize_results(options = {}) Origen.lsf.build_log(options) stats = Origen.app.stats if options[:report_results] puts "Regression results: \n" puts "#{stats.summary_text}\n" end if stats.clean_run? stats.report_pass else stats.report_fail end if options[:send_email] to = options[:email_all_developers] ? developers : current_user Origen.mailer.send_regression_complete_notice(to: to) end end
# File lib/origen/regression_manager.rb, line 303 def version_to_tag(version) version = version.strip if version.downcase == 'last' Origen.app.version_tracker.versions.last elsif version.downcase == 'latest' if Origen.app.rc.git? if Origen.app.config.rc_workflow == :gitflow 'develop' else 'master' end else version end else version end end
# File lib/origen/regression_manager.rb, line 203 def wait_for_completion(_options = {}) highlight { Origen.log.info 'Waiting for all to complete...' } Origen.lsf.wait_for_completion end
# File lib/origen/regression_manager.rb, line 21 def ws Origen.app.workspace_manager end
Private Instance Methods
# File lib/origen/regression_manager.rb, line 324 def highlight Origen.log.info '' Origen.log.info '######################################################################' yield Origen.log.info '######################################################################' Origen.log.info '' end