class ChefCLI::ComponentTest

def assert_present!

def assert_present!
  unless File.exist?( component_path )
    raise MissingComponentError.new(name, "Could not find #{component_path}")
  end
rescue Gem::LoadError => e
  raise MissingComponentError.new(name, e)
end

def bin(binary)

def bin(binary)
  File.join(omnibus_bin_dir, binary)
end

def component_path

def component_path
  if base_dir
    File.join(omnibus_root, base_dir)
  elsif gem_base_dir
    gem_base_dir
  else
    raise "`base_dir` or `gem_base_dir` must be defined for component `#{name}`"
  end
end

def default_command_options

def default_command_options
  {
    cwd: component_path,
    env: {
      # Add the embedded/bin to the PATH so that bundle executable can
      # be found while running the tests.
      path_variable_key => omnibus_path,
      "CHEF_LICENSE" => "accept-no-persist",
    },
    timeout: 3600,
  }
end

def embedded_bin(binary)

def embedded_bin(binary)
  File.join(omnibus_embedded_bin_dir, binary)
end

def fail_if_exit_zero(cmd_string, failure_string = "")

crash.
return a passing command so that the test parser doesn't
otherwise, if it returns non-zero or doesn't exist,
Run a command, if the command returns zero, raise an error,
def fail_if_exit_zero(cmd_string, failure_string = "")
  result = sh(cmd_string)
  if result.status.exitstatus == 0
    raise failure_string
  else
    sh("true")
  end
rescue Errno::ENOENT
  sh("true")
end

def gem_base_dir

def gem_base_dir
  return nil if @gem_name_for_base_dir.nil?
  # There is no way to say "give me the latest prerelease OR normal version of this gem.
  # So we first ask if there is a normal version, and if there is not, we ask if there
  # is a prerelease version.  ">= 0.a" is how we ask for a prerelease version, because a
  # prerelease version is defined as "any version with a letter in it."
  gem = Gem::Specification.find_by_name(@gem_name_for_base_dir)
  gem ||= Gem::Specification.find_by_name(@gem_name_for_base_dir, ">= 0.a")
  gem.gem_dir
end

def gem_base_dir=(gem_name)

def gem_base_dir=(gem_name)
  @gem_name_for_base_dir = gem_name
end

def initialize(name)

def initialize(name)
  @name = name
  @unit_test = DEFAULT_TEST
  @integration_test = DEFAULT_TEST
  @smoke_test = DEFAULT_TEST
  @base_dir = nil
  @gem_name_for_base_dir = nil
end

def integration_test(&test_block)

def integration_test(&test_block)
  @integration_test = test_block
end

def nix_platform_native_bin_dir

def nix_platform_native_bin_dir
  if /darwin/ =~ RUBY_PLATFORM
    "/usr/local/bin"
  else
    "/usr/bin"
  end
end

def omnibus_path

def omnibus_path
  [omnibus_bin_dir, omnibus_embedded_bin_dir, ENV["PATH"]].join(File::PATH_SEPARATOR)
end

def omnibus_root

def omnibus_root
  @omnibus_root || raise("`omnibus_root` must be set before running tests")
end

def path_variable_key

def path_variable_key
  ENV.keys.grep(/\Apath\Z/i).first
end

def run_in_tmpdir(command, options = {})

def run_in_tmpdir(command, options = {})
  tmpdir do |dir|
    options[:cwd] = dir
    sh(command, options)
  end
end

def run_integration_test

def run_integration_test
  instance_eval(&@integration_test)
end

def run_smoke_test

def run_smoke_test
  instance_eval(&@smoke_test)
end

def run_unit_test

def run_unit_test
  instance_eval(&@unit_test)
end

def sh(command, options = {})

def sh(command, options = {})
  combined_opts = default_command_options.merge(options)
  # Env is a hash, so it needs to be merged separately
  if options.key?(:env)
    combined_opts[:env] = default_command_options[:env].merge(options[:env])
  end
  system_command(command, combined_opts)
end

def sh!(*args)

this is inconvenient so you can use #sh! instead.
the return value of the test block. For tests that run a lot of commands,
ChefCLI::Command::Verify#invoke_tests handles the results by inspecting
Most verification steps just run a single command, then

unexpected exit code.
Just like #sh but raises an error if the the command returns an
def sh!(*args)
  sh(*args).tap(&:error!)
end

def smoke_test(&test_block)

def smoke_test(&test_block)
  @smoke_test = test_block
end

def tmpdir

def tmpdir
  Dir.mktmpdir do |tmpdir|
    yield tmpdir
  end
end

def unit_test(&test_block)

def unit_test(&test_block)
  @unit_test = test_block
end