Class: Beaker::CLI
- Inherits:
-
Object
- Object
- Beaker::CLI
- Defined in:
- lib/beaker/cli.rb
Constant Summary collapse
- VERSION_STRING =
<<-'ART' wWWWw |o o| | O | %s! |(")| / \X/ \ | V | | | | ART
Instance Attribute Summary collapse
-
#logger ⇒ Object
readonly
Returns the value of attribute logger.
-
#network_manager ⇒ Object
readonly
Returns the value of attribute network_manager.
-
#options ⇒ Object
readonly
Returns the value of attribute options.
Instance Method Summary collapse
-
#build_hosts_preserved_reproducing_command(command, new_hostsfile) ⇒ String
provides a new version of the command given, edited for re-use with a preserved host.
-
#combined_instance_and_options_hosts ⇒ Object
Return a host_hash that is a merging of options host hashes with instance host objects.
-
#configured_options ⇒ Object
Get the list of options that are not equal to presets.
-
#execute! ⇒ Object
Run Beaker tests.
-
#initialize ⇒ CLI
constructor
A new instance of CLI.
-
#initialize_network_manager ⇒ Object
Initialize the network manager so it can initialize hosts for testing for subcommands.
- #parse_options(args = ARGV) ⇒ Object
-
#preserve_hosts_file ⇒ Object
Sets aside the current hosts file for re-use with the –no-provision flag.
-
#print_command_line(log_level = :debug) ⇒ Object
Prints the command line that can be called to reproduce this run (assuming the environment is the same).
-
#print_env_vars_affecting_beaker(log_level) ⇒ Object
Prints Environment variables affecting the beaker run (those that beaker introspects + the ruby env that beaker runs within).
-
#print_reproduction_info(log_level = :debug) ⇒ Object
Prints all information required to reproduce the current run & results to the log.
-
#print_version_and_options ⇒ Object
only call this method after parse_options has been executed.
-
#provision ⇒ Object
Provision, validate and configure all hosts as defined in the hosts file.
-
#run_suite(suite_name, failure_strategy = nil) ⇒ Object
Run the provided test suite.
Constructor Details
#initialize ⇒ CLI
Returns a new instance of CLI.
15 16 17 18 19 20 21 22 |
# File 'lib/beaker/cli.rb', line 15 def initialize @timestamp = Time.now # Initialize a logger object prior to parsing; this should be overwritten whence # the options are parsed and replaced with a new logger based on what is passed # in to configure the logger. @logger = Beaker::Logger.new @options = {} end |
Instance Attribute Details
#logger ⇒ Object (readonly)
Returns the value of attribute logger.
13 14 15 |
# File 'lib/beaker/cli.rb', line 13 def logger @logger end |
#network_manager ⇒ Object (readonly)
Returns the value of attribute network_manager.
13 14 15 |
# File 'lib/beaker/cli.rb', line 13 def network_manager @network_manager end |
#options ⇒ Object (readonly)
Returns the value of attribute options.
13 14 15 |
# File 'lib/beaker/cli.rb', line 13 def @options end |
Instance Method Details
#build_hosts_preserved_reproducing_command(command, new_hostsfile) ⇒ String
provides a new version of the command given, edited for re-use with a preserved host. It does this by swapping the hosts file out for the new_hostsfile argument and removing any previously set provisioning flags that it finds (we add :provision => false in the new_hostsfile itself).
327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 |
# File 'lib/beaker/cli.rb', line 327 def build_hosts_preserved_reproducing_command(command, new_hostsfile) command_parts = command.split(' ') replace_hosts_file_next = false reproducing_command = [] command_parts.each do |part| if replace_hosts_file_next reproducing_command << new_hostsfile replace_hosts_file_next = false next elsif part == '--provision' || part == '--no-provision' next # skip any provisioning flag. This is handled in the new_hostsfile itself elsif part == '--hosts' replace_hosts_file_next = true end reproducing_command << part end reproducing_command.join(' ') end |
#combined_instance_and_options_hosts ⇒ Object
Return a host_hash that is a merging of options host hashes with instance host objects
229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 |
# File 'lib/beaker/cli.rb', line 229 def hosts_yaml = @options newly_keyed_hosts_entries = {} hosts_yaml['HOSTS'].each do |host_name, file_host_hash| h = Beaker::Options::OptionsHash.new file_host_hash = h.merge(file_host_hash) @hosts.each do |host| if host_name.to_s == host.name.to_s newly_keyed_hosts_entries[host.hostname] = file_host_hash.merge(host.host_hash) break end end end newly_keyed_hosts_entries end |
#configured_options ⇒ Object
Get the list of options that are not equal to presets.
189 190 191 192 193 194 195 |
# File 'lib/beaker/cli.rb', line 189 def result = Beaker::Options::OptionsHash.new @attribution.each do |attribute, setter| result[attribute] = @options[attribute] if setter != 'preset' end result end |
#execute! ⇒ Object
Run Beaker tests.
-
run pre-suite
-
run tests
-
run post-suite
-
cleanup hosts
99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 |
# File 'lib/beaker/cli.rb', line 99 def execute! begin trap(:INT) do @logger.warn "Interrupt received; exiting..." exit(1) end # Setup perf monitoring if needed @perf = Beaker::Perf.new(@hosts, @options) if /aggressive|normal/.match?(@options[:collect_perf_data].to_s) # pre acceptance phase run_suite(:pre_suite, :fast) # testing phase begin run_suite(:tests, @options[:fail_mode]) # post acceptance phase rescue => e # post acceptance on failure # run post-suite if we are in fail-slow mode if @options[:fail_mode].to_s.include?('slow') run_suite(:post_suite) @perf.print_perf_info if defined? @perf end raise e else # post acceptance on success run_suite(:post_suite) @perf.print_perf_info if defined? @perf end # cleanup phase rescue => e begin run_suite(:pre_cleanup) rescue => e # pre-cleanup failed @logger.error "Failed running the pre-cleanup suite." end # cleanup on error if /never|onpass/.match?(@options[:preserve_hosts].to_s) @logger.notify "Cleanup: cleaning up after failed run" @network_manager.cleanup if @network_manager else preserve_hosts_file end print_reproduction_info(:error) @logger.error "Failed running the test suite." puts '' exit 1 else begin run_suite(:pre_cleanup) rescue => e # pre-cleanup failed @logger.error "Failed running the pre-cleanup suite." end # cleanup on success if /never|onfail/.match?(@options[:preserve_hosts].to_s) @logger.notify "Cleanup: cleaning up after successful run" @network_manager.cleanup if @network_manager else preserve_hosts_file end print_reproduction_info(:debug) if @logger.is_debug? end end |
#initialize_network_manager ⇒ Object
Initialize the network manager so it can initialize hosts for testing for subcommands
84 85 86 87 88 89 90 91 |
# File 'lib/beaker/cli.rb', line 84 def initialize_network_manager begin @network_manager = Beaker::NetworkManager.new(@options, @logger) @hosts = @network_manager.provision rescue => e report_and_raise(@logger, e, "CLI.initialize_network_manager") end end |
#parse_options(args = ARGV) ⇒ Object
24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 |
# File 'lib/beaker/cli.rb', line 24 def (args = ARGV) @options_parser = Beaker::Options::Parser.new @options = @options_parser.parse_args(args) @attribution = @options_parser.attribution @logger = Beaker::Logger.new(@options) InParallel::InParallelExecutor.logger = @logger @options_parser.update_option(:logger, @logger, 'runtime') @options_parser.update_option(:timestamp, @timestamp, 'runtime') @options_parser.update_option(:beaker_version, Beaker::Version::STRING, 'runtime') beaker_version_string = VERSION_STRING % @options[:beaker_version] # Some flags should exit early if @options[:help] @logger.notify(@options_parser.usage) exit(0) end if @options[:beaker_version_print] @logger.notify(beaker_version_string) exit(0) end if @options[:parse_only] exit(0) end # add additional paths to the LOAD_PATH if not @options[:load_path].empty? @options[:load_path].each do |path| $LOAD_PATH << File.(path) end end @options[:helper].each do |helper| require File.(helper) end self end |
#preserve_hosts_file ⇒ Object
Sets aside the current hosts file for re-use with the –no-provision flag. This is originally intended for use on a successful tests where the hosts are preserved (the –preserve-hosts option is set accordingly). It copies the current hosts file to the log directory, and rewrites the SUT names to match their names during the finishing run.
204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 |
# File 'lib/beaker/cli.rb', line 204 def preserve_hosts_file # things that don't belong in the preserved host file dontpreserve = /HOSTS|logger|timestamp|log_prefix|_dated_dir|logger_sut/ # set the pre/post/tests to be none @options[:pre_suite] = [] @options[:post_suite] = [] @options[:tests] = [] @options[:pre_cleanup] = [] preserved_hosts_filename = File.join(@options[:log_dated_dir], 'hosts_preserved.yml') hosts_yaml = @options hosts_yaml['HOSTS'] = hosts_yaml['CONFIG'] = Beaker::Options::OptionsHash.new.merge(hosts_yaml['CONFIG'] || {}) # save the rest of the options, excepting the HOSTS that we have already processed hosts_yaml['CONFIG'] = hosts_yaml['CONFIG'].merge(@options.reject { |k, _v| dontpreserve.match?(k) }) # remove copy of HOSTS information hosts_yaml['CONFIG']['provision'] = false File.open(preserved_hosts_filename, 'w') do |file| YAML.dump(hosts_yaml, file) end @options[:hosts_preserved_yaml_file] = preserved_hosts_filename end |
#print_command_line(log_level = :debug) ⇒ Object
Re-use of already provisioned SUTs has been tested against the vmpooler & vagrant boxes. Fusion doesn’t need this, as it has no cleanup steps. Docker is untested at this time. Please contact @electrical or the Puppet QE Team for more info, or for requests to support this.
Prints the command line that can be called to reproduce this run (assuming the environment is the same)
294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 |
# File 'lib/beaker/cli.rb', line 294 def print_command_line(log_level = :debug) @logger.send(log_level, "\nYou can reproduce this run with:\n") @logger.send(log_level, @options[:command_line]) return unless @options[:hosts_preserved_yaml_file] set_docker_warning = false has_supported_hypervisor = false @hosts.each do |host| case host[:hypervisor] when /vagrant|fusion|vmpooler|vcloud/ has_supported_hypervisor = true when /docker/ set_docker_warning = true end end return unless has_supported_hypervisor reproducing_command = build_hosts_preserved_reproducing_command(@options[:command_line], @options[:hosts_preserved_yaml_file]) @logger.send(log_level, "\nYou can re-run commands against the already provisioned SUT(s) with:\n") @logger.send(log_level, '(docker support is untested for this feature. please reference the docs for more info)') if set_docker_warning @logger.send(log_level, reproducing_command) end |
#print_env_vars_affecting_beaker(log_level) ⇒ Object
Prints Environment variables affecting the beaker run (those that beaker introspects + the ruby env that beaker runs within)
262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 |
# File 'lib/beaker/cli.rb', line 262 def print_env_vars_affecting_beaker(log_level) non_beaker_env_vars = %w[BUNDLE_PATH BUNDLE_BIN GEM_HOME GEM_PATH RUBYLIB PATH] env_var_map = non_beaker_env_vars.each_with_object({}) do |possibly_set_vars, memo| set_var = Array(possibly_set_vars).detect { |possible_var| ENV.fetch(possible_var, nil) } memo[set_var] = ENV.fetch(set_var, nil) if set_var end env_var_map = env_var_map.merge(Beaker::Options::Presets.new.env_vars) @logger.send(log_level, "\nImportant ENV variables that may have affected your run:") env_var_map.each_pair do |var, value| if value.is_a?(Hash) value.each_pair do |subvar, subvalue| @logger.send(log_level, " #{subvar}\t\t#{subvalue}") end else @logger.send(log_level, " #{var}\t\t#{value}") end end end |
#print_reproduction_info(log_level = :debug) ⇒ Object
Prints all information required to reproduce the current run & results to the log
250 251 252 253 |
# File 'lib/beaker/cli.rb', line 250 def print_reproduction_info(log_level = :debug) print_command_line(log_level) print_env_vars_affecting_beaker(log_level) end |
#print_version_and_options ⇒ Object
only call this method after parse_options has been executed.
63 64 65 66 67 |
# File 'lib/beaker/cli.rb', line 63 def @logger.info("Beaker!") @logger.info(VERSION_STRING % @options[:beaker_version]) @logger.info(@options.dump) end |
#provision ⇒ Object
Provision, validate and configure all hosts as defined in the hosts file
70 71 72 73 74 75 76 77 78 79 80 81 |
# File 'lib/beaker/cli.rb', line 70 def provision begin @hosts = [] initialize_network_manager @network_manager.proxy_package_manager @network_manager.validate @network_manager.configure rescue => e report_and_raise(@logger, e, "CLI.provision") end self end |
#run_suite(suite_name, failure_strategy = nil) ⇒ Object
Run the provided test suite
177 178 179 180 181 182 183 184 185 |
# File 'lib/beaker/cli.rb', line 177 def run_suite(suite_name, failure_strategy = nil) if (@options[suite_name].empty?) @logger.notify("No tests to run for suite '#{suite_name}'") return end Beaker::TestSuite.new( suite_name, @hosts, @options, @timestamp, failure_strategy ).run_and_raise_on_failure end |