class Kitchen::Config

Base configuration class for Kitchen. This class exposes configuration such as the location of the Kitchen config file, instances, log_levels, etc. This object is a factory object, meaning that it is responsible for consuming the desired testing configuration in and returning Ruby objects which are used to perfom the work.

Most internal objects are created with the expectation of being immutable, meaning that internal state cannot be modified after creation. Any data manipulation or thread-unsafe activity is performed in this object so that the subsequently created objects (such as Instances, Platforms, Drivers, etc.) can safely run in concurrent threads of execution. To prevent the re-creation of duplicate objects, most created objects are memoized. The consequence of this is that once the Instance Array has been requested (with the `#instances` message), you will always be returned the same Instance objects.

@example fetching all instances

Kitchen::Config.new.instances

@example fetching an instance by name

Kitchen::Config.new.instances.get("default-ubuntu-16.04")

@example fetching all instances matching a regular expression

Kitchen::Config.new.instances.get_all(/ubuntu/)

@author Fletcher Nichol <fnichol@nichol.ca>

Attributes

colorize[RW]

@return [Boolean] whether to force color output or not in logger @api private

debug[RW]

@return [Boolean] whether to enable debugging in the provisioner/verifier plugin or not @api private

kitchen_root[R]

@return [String] the absolute path to the root of a Test Kitchen project @api private

loader[R]

@return [#read] the data loader that responds to a `#read` message,

returning a Hash data structure

@api private

log_level[RW]

@return [Symbol] the logging verbosity level @api private

log_overwrite[RW]

@return [Boolean] whether to overwrite the log file when

Test Kitchen runs

@api private

log_root[R]

@return [String] the absolute path to the directory into which all Test

Kitchen log files will be written

@api private

test_base_path[RW]

@return [String] an absolute path to the directory containing test suites @api private

Public Class Methods

new(options = {}) click to toggle source

Creates a new configuration, representing a particular testing configuration for a project.

@param [Hash] options configuration @option options [#read] :loader an object that responds to `#read` with

a Hash structure suitable for manipulating
(default: `Kitchen::Loader::YAML.new`)

@option options [String] :kitchen_root an absolute path to the root of a

Test Kitchen project, usually containing a `.kitchen.yml` file
(default `Dir.pwd`)

@option options [String] :log_root an absolute path to the directory

into which all Test Kitchen log files will be written
(default: `"#{kitchen_root}/.kitchen/logs"`)

@option options [String] :test_base_path an absolute path to the

directory containing test suites and other testing-related files and
directories (default: `"#{kitchen_root}/test/integration"`)

@option options [Symbol] :log_level the log level verbosity that the

loggers will use when outputing information (default: `:info`)
# File lib/kitchen/config.rb, line 102
def initialize(options = {})
  @loader         = options.fetch(:loader) { Kitchen::Loader::YAML.new }
  @kitchen_root   = options.fetch(:kitchen_root) { Dir.pwd }
  @log_level      = options.fetch(:log_level) { Kitchen::DEFAULT_LOG_LEVEL }
  @log_overwrite  = options.fetch(:log_overwrite) { Kitchen::DEFAULT_LOG_OVERWRITE }
  @colorize       = options.fetch(:colorize) { Kitchen.tty? }
  @log_root       = options.fetch(:log_root) { default_log_root }
  @test_base_path = options.fetch(:test_base_path) { default_test_base_path }
  @debug          = options.fetch(:debug) { false }
end

Public Instance Methods

instances() click to toggle source

@return [Collection<Instance>] all instances, resulting from all

platform and suite combinations
# File lib/kitchen/config.rb, line 115
def instances
  @instances ||= Collection.new(build_instances)
end
platforms() click to toggle source

@return [Collection<Platform>] all defined platforms which will be used

in convergence integration
# File lib/kitchen/config.rb, line 121
def platforms
  @platforms ||= Collection.new(
    data.platform_data.map { |pdata| Platform.new(pdata) }
  )
end
suites() click to toggle source

@return [Collection<Suite>] all defined suites which will be used in

convergence integration
# File lib/kitchen/config.rb, line 129
def suites
  @suites ||= Collection.new(
    data.suite_data.map { |sdata| Suite.new(sdata) }
  )
end

Private Instance Methods

build_instances() click to toggle source

Builds the filtered list of Instance objects.

@return [Array<Instance] an array of Instances @api private

# File lib/kitchen/config.rb, line 141
def build_instances
  filter_instances.map.with_index do |(suite, platform), index|
    new_instance(suite, platform, index)
  end
end
data() click to toggle source

Returns an object which can generate configuration hashes for all the primary Test Kitchen objects such as Drivers, Provisioners, etc.

@return [DataMunger] a data manipulator @api private

# File lib/kitchen/config.rb, line 152
def data
  @data ||= DataMunger.new(loader.read, kitchen_config)
end
default_log_root() click to toggle source

Determines the default absolute path to a log directory, based on the value of `#kitchen_root`.

@return [String] an absolute path to the log directory @api private

# File lib/kitchen/config.rb, line 161
def default_log_root
  File.join(kitchen_root, Kitchen::DEFAULT_LOG_DIR)
end
default_test_base_path() click to toggle source

Determines the default absolute path to the testing files directory, based on the the value of `#kitchen_root`.

@return [String] an absolute path to the testing files directory @api private

# File lib/kitchen/config.rb, line 170
def default_test_base_path
  File.join(kitchen_root, Kitchen::DEFAULT_TEST_DIR)
end
filter_instances() click to toggle source

Generates a filtered Array of tuples (Suite/Platform pairs) which is the cartesian product of suites and platforms. A Suite has two optional arrays (`#includes` and `#excludes`) which can be used to drop or select certain Platforms with which to join.

@return [Array<Array<Suite, Platform>>] an Array of Suite/Platform

tuples

@api private

# File lib/kitchen/config.rb, line 182
def filter_instances
  suites.product(platforms).select do |suite, platform|
    if !suite.includes.empty?
      suite.includes.include?(platform.name)
    elsif !suite.excludes.empty?
      !suite.excludes.include?(platform.name)
    else
      true
    end
  end
end
instance_name(suite, platform) click to toggle source

Determines the String name for an Instance, given a Suite and a Platform.

@param suite [Suite,#name] a Suite @param platform [Platform,#name] a Platform @return [String] an Instance name @api private

# File lib/kitchen/config.rb, line 200
def instance_name(suite, platform)
  Instance.name_for(suite, platform)
end
kitchen_config() click to toggle source

Generates the immutable Test Kitchen configuration and reasonable defaults for Drivers, Provisioners and Transports.

@return [Hash] a configuration Hash @api private

# File lib/kitchen/config.rb, line 209
def kitchen_config
  @kitchen_config ||= {
    defaults: {
      driver: Driver::DEFAULT_PLUGIN,
      provisioner: Provisioner::DEFAULT_PLUGIN,
      verifier: Verifier::DEFAULT_PLUGIN,
      transport: lambda do |_suite, platform|
        /^win/i.match?(platform) ? "winrm" : Transport::DEFAULT_PLUGIN
      end,
    },
    kitchen_root: kitchen_root,
    test_base_path: test_base_path,
    log_level: log_level,
    log_overwrite: log_overwrite,
    debug: debug,
  }
end
new_driver(suite, platform) click to toggle source

Builds a newly configured Driver object, for a given Suite and Platform.

@param suite [Suite,#name] a Suite @param platform [Platform,#name] a Platform @return [Driver] a new Driver object @api private

# File lib/kitchen/config.rb, line 233
def new_driver(suite, platform)
  ddata = data.driver_data_for(suite.name, platform.name)
  Driver.for_plugin(ddata[:name], ddata)
end
new_instance(suite, platform, index) click to toggle source

Builds a newly configured Instance object, for a given Suite and Platform.

@param suite [Suite,#name] a Suite @param platform [Platform,#name] a Platform @param index [Integer] an index used for colorizing output @return [Instance] a new Instance object @api private

# File lib/kitchen/config.rb, line 246
def new_instance(suite, platform, index)
  sf = new_state_file(suite, platform)

  Instance.new(
    driver: new_driver(suite, platform),
    lifecycle_hooks: new_lifecycle_hooks(suite, platform, sf),
    logger: new_instance_logger(suite, platform, index),
    suite: suite,
    platform: platform,
    provisioner: new_provisioner(suite, platform),
    transport: new_transport(suite, platform),
    verifier: new_verifier(suite, platform),
    state_file: sf
  )
end
new_instance_logger(suite, platform, index) click to toggle source

Builds a newly configured Logger object, for a given Suite and Platform.

@param suite [Suite,#name] a Suite @param platform [Platform,#name] a Platform @param index [Integer] an index used for colorizing output @return [Logger] a new Logger object @api private

# File lib/kitchen/config.rb, line 270
def new_instance_logger(suite, platform, index)
  name = instance_name(suite, platform)
  log_location = File.join(log_root, "#{name}.log").to_s
  Logger.new(
    stdout: STDOUT,
    color: Color::COLORS[index % Color::COLORS.size].to_sym,
    logdev: log_location,
    level: Util.to_logger_level(log_level),
    log_overwrite: log_overwrite,
    progname: name,
    colorize: @colorize
  )
end
new_lifecycle_hooks(suite, platform, state_file) click to toggle source

Builds a newly configured LifecycleHooks object, for a given a Suite and Platform.

@param suite [Suite,#name] a Suite @param platform [Platform,#name] a Platform @param state_file [Kitchen::StateFile] a SateFile @return [LifecycleHooks] a new LifecycleHooks object @api private

# File lib/kitchen/config.rb, line 292
def new_lifecycle_hooks(suite, platform, state_file)
  lhdata = data.lifecycle_hooks_data_for(suite.name, platform.name)
  LifecycleHooks.new(lhdata, state_file)
end
new_provisioner(suite, platform) click to toggle source

Builds a newly configured Provisioner object, for a given Suite and Platform.

@param suite [Suite,#name] a Suite @param platform [Platform,#name] a Platform @return [Provisioner] a new Provisioner object @api private

# File lib/kitchen/config.rb, line 304
def new_provisioner(suite, platform)
  pdata = data.provisioner_data_for(suite.name, platform.name)
  Provisioner.for_plugin(pdata[:name], pdata)
end
new_state_file(suite, platform) click to toggle source

Builds a newly configured StateFile object, for a given Suite and Platform.

@param suite [Suite,#name] a Suite @param platform [Platform,#name] a Platform @return [StateFile] a new StateFile object @api private

# File lib/kitchen/config.rb, line 316
def new_state_file(suite, platform)
  StateFile.new(kitchen_root, instance_name(suite, platform))
end
new_transport(suite, platform) click to toggle source

Builds a newly configured Transport object, for a given Suite and Platform.

@param suite [Suite,#name] a Suite @param platform [Platform,#name] a Platform @return [Transport] a new Transport object @api private

# File lib/kitchen/config.rb, line 327
def new_transport(suite, platform)
  tdata = data.transport_data_for(suite.name, platform.name)
  Transport.for_plugin(tdata[:name], tdata)
end
new_verifier(suite, platform) click to toggle source

Builds a newly configured Verifier object, for a given a Suite and Platform.

@param suite [Suite,#name] a Suite @param platform [Platform,#name] a Platform @return [Verifier] a new Verifier object @api private

# File lib/kitchen/config.rb, line 339
def new_verifier(suite, platform)
  vdata = data.verifier_data_for(suite.name, platform.name)
  Verifier.for_plugin(vdata[:name], vdata)
end