class Onceover::TestConfig

Attributes

acceptance_tests[RW]
after_conditions[RW]
before_conditions[RW]
class_groups[RW]
classes[RW]
environment[RW]
fail_fast[RW]
filter_classes[RW]
filter_nodes[RW]
filter_tags[RW]
force[RW]
formatters[RW]
mock_functions[RW]
node_groups[RW]
nodes[RW]
opts[RW]
skip_r10k[RW]
spec_tests[RW]
strict_variables[RW]

Public Class Methods

find_list(thing) click to toggle source
# File lib/onceover/testconfig.rb, line 118
def self.find_list(thing)
  # Takes a string and finds an object or list of objects to match, will
  # take nodes, classes or groups

  # We want to supress warnings for this bit
  old_level = logger.level
  logger.level = :error
  if Onceover::Group.find(thing)
    logger.level = old_level
    return Onceover::Group.find(thing).members
  elsif Onceover::Class.find(thing)
    logger.level = old_level
    return [Onceover::Class.find(thing)]
  elsif Onceover::Node.find(thing)
    logger.level = old_level
    return [Onceover::Node.find(thing)]
  else
    logger.level = old_level
    raise "Could not find #{thing} in list of classes, nodes or groups"
  end
end
new(file, opts = {}) click to toggle source
# File lib/onceover/testconfig.rb, line 34
def initialize(file, opts = {})
  begin
    config = YAML.safe_load(File.read(file), permitted_classes: [Symbol])
  rescue Errno::ENOENT
    raise "Could not find #{file}"
  rescue Psych::SyntaxError
    raise "Could not parse #{file}, check that it is valid YAML and that the encoding is correct"
  end

  @classes           = []
  @nodes             = []
  @node_groups       = []
  @class_groups      = []
  @spec_tests        = []
  @acceptance_tests  = []
  @opts              = opts
  @mock_functions    = config['functions']
  @before_conditions = config['before'] || []
  @after_conditions  = config['after']
  @strict_variables  = opts[:strict_variables] ? 'yes' : 'no'
  @included_specs    = [config['include_spec_files'] || ['**/*']].flatten
  
  # Set dynamic defaults for format
  if Array(opts[:format]) == [:defaults]
    @formatters = opts[:parallel] ? ['OnceoverFormatterParallel'] : ['OnceoverFormatter']
  else
    @formatters = Array(opts[:format])
  end

  # Initialise all of the classes and nodes
  config['classes'].each { |clarse| Onceover::Class.new(clarse) } unless config['classes'] == nil
  @classes = Onceover::Class.all

  config['nodes'].each { |node| Onceover::Node.new(node) } unless config['nodes'] == nil
  @nodes = Onceover::Node.all

  # Add the 'all_classes' and 'all_nodes' default groups
  @node_groups  << Onceover::Group.new('all_nodes', @nodes)
  @class_groups << Onceover::Group.new('all_classes', @classes)

  # Initialise all of the groups
  config['node_groups'].each { |name, members| @node_groups << Onceover::Group.new(name, members) } unless config['node_groups'] == nil
  config['class_groups'].each { |name, members| @class_groups << Onceover::Group.new(name, members) } unless config['class_groups'] == nil

  @filter_tags    = opts[:tags]      ? [opts[:tags].split(',')].flatten : nil
  @filter_classes = opts[:classes]   ? [opts[:classes].split(',')].flatten.map {|x| Onceover::Class.find(x)} : nil
  @filter_nodes   = opts[:nodes]     ? [opts[:nodes].split(',')].flatten.map {|x| Onceover::Node.find(x)} : nil
  @skip_r10k      = opts[:skip_r10k] ? true : false
  @force          = opts[:force] || false
  @fail_fast      = opts[:fail_fast] || false

  # Validate the mock_functions
  if @mock_functions && @mock_functions.any? { |name, details| details.has_key? 'type' }
    logger.warn "The 'type' key for mocked functions is deprecated and will be ignored, please remove it."
  end

  # Loop over all of the items in the test matrix and add those as test
  # objects to the list of tests
  config['test_matrix'].each do |test_hash|
    test_hash.each do |machines, settings|
      if settings['tests'] == 'spec'
        @spec_tests << Onceover::Test.new(machines, settings['classes'], settings)
      elsif settings['tests'] == 'acceptance'
        @acceptance_tests << Onceover::Test.new(machines, settings['classes'], settings)
      elsif settings['tests'] == 'all_tests'
        tst = Onceover::Test.new(machines,settings['classes'],settings)
        @spec_tests << tst
        @acceptance_tests << tst
      end
    end
  end
end
subtractive_to_list(subtractive_hash) click to toggle source
# File lib/onceover/testconfig.rb, line 140
def self.subtractive_to_list(subtractive_hash)
  # Take a hash that looks like this:
  # { 'include' => 'somegroup'
  #   'exclude' => 'other'}
  # and return a list of classes/nodes
  if subtractive_hash.has_key?('include') && subtractive_hash.has_key?('exclude')
    include_list = Onceover::TestConfig.find_list(subtractive_hash['include']).flatten
    exclude_list = Onceover::TestConfig.find_list(subtractive_hash['exclude']).flatten
    include_list - exclude_list
  else
    raise "The classes/nodes hash must have an `exclude` if using an `include`"
  end
end

Public Instance Methods

copy_spec_files(repo) click to toggle source
# File lib/onceover/testconfig.rb, line 242
def copy_spec_files(repo)
  source_files = @included_specs.map { |glob| Dir.glob "#{repo.spec_dir}/#{glob}" }.flatten.uniq
  source_files.each do |source_file|
    target_file = File.join(repo.tempdir, 'spec', source_file.sub(/^#{repo.spec_dir}/, ''))
    if File.directory?(source_file)
      FileUtils.cp_r source_file, target_file unless File.exist? target_file
    else
      FileUtils.mkdir_p File.dirname target_file
      FileUtils.cp source_file, target_file
    end
  end
end
filter_test(test, method, filter) click to toggle source
# File lib/onceover/testconfig.rb, line 302
def filter_test(test, method, filter)
  if test.send(method)
    if method == 'tags' && filter.start_with?('~')
      filter = filter.sub(/^~/, '')
      ! test.send(method).include?(filter)
    else
      test.send(method).include?(filter)
    end
  else
    false
  end
end
pre_condition() click to toggle source
# File lib/onceover/testconfig.rb, line 174
def pre_condition
  # Read all the pre_conditions and return the string
  spec_dir = Onceover::Controlrepo.new(@opts).spec_dir
  puppetcode = []
  Dir["#{spec_dir}/pre_conditions/*.pp"].each do |condition_file|
    logger.debug "Reading pre_conditions from #{condition_file}"
    puppetcode << File.read(condition_file)
  end
  return nil if puppetcode.count.zero?

  puppetcode.join("\n")
end
run_filters(tests) click to toggle source
# File lib/onceover/testconfig.rb, line 282
def run_filters(tests)
  # All of this needs to be applied AFTER deduplication but BEFORE writing
  filters = {
    'tags'    => @filter_tags,
    'classes' => @filter_classes,
    'nodes'   => @filter_nodes
  }
  filters.each do |method, filter_list|
    if filter_list
      # Remove tests that do not have matching tags
      tests.keep_if do |test|
        filter_list.any? do |filter|
          filter_test test, method, filter
        end
      end
    end
  end
  tests
end
to_s() click to toggle source
# File lib/onceover/testconfig.rb, line 107
    def to_s
      require 'colored'

      <<-TESTCONF.gsub(/^\s{4}/,'')
      #{'classes'.green}      #{@classes.map{|c|c.name}}
      #{'nodes'.green}        #{@nodes.map{|n|n.name}}
      #{'class_groups'.green} #{@class_groups}
      #{'node_groups'.green}  #{@node_groups.map{|g|g.name}}
      TESTCONF
    end
verify_acceptance_test(controlrepo, test) click to toggle source
# File lib/onceover/testconfig.rb, line 162
def verify_acceptance_test(controlrepo, test)
  warn "[DEPRECATION] #{__method__} is deprecated due to the removal of Beaker"

  require 'yaml'
  nodeset = YAML.load_file(controlrepo.nodeset_file)
  test.nodes.each do |node|
    unless nodeset['HOSTS'].has_key?(node.name)
      raise "Could not find nodeset for node: #{node.name}"
    end
  end
end
verify_spec_test(controlrepo, test) click to toggle source
# File lib/onceover/testconfig.rb, line 154
def verify_spec_test(controlrepo, test)
  test.nodes.each do |node|
    unless controlrepo.facts_files.any? { |file| file =~ /\/#{node.name}\.json/ }
      raise "Could not find factset for node: #{node.name}"
    end
  end
end
write_acceptance_tests(location, tests) click to toggle source
# File lib/onceover/testconfig.rb, line 195
def write_acceptance_tests(location, tests)
  warn "[DEPRECATION] #{__method__} is deprecated due to the removal of Beaker"

  File.write(
    "#{location}/acceptance_spec.rb",
    Onceover::Controlrepo.evaluate_template('acceptance_test_spec.rb.erb', binding))
end
write_rakefile(location, pattern) click to toggle source
# File lib/onceover/testconfig.rb, line 210
def write_rakefile(location, pattern)
  File.write(
    "#{location}/Rakefile",
    Onceover::Controlrepo.evaluate_template('testconfig_Rakefile.erb', binding)
  )
end
write_spec_helper(location, repo) click to toggle source
# File lib/onceover/testconfig.rb, line 217
def write_spec_helper(location, repo)
  environmentpath = "#{repo.tempdir}/#{repo.environmentpath}"
  modulepath = repo.config['modulepath']
  modulepath.delete("$basemodulepath")
  modulepath.map! do |path|
    "#{environmentpath}/production/#{path}"
  end

  # We need to select the right delimiter based on OS
  require 'facter'
  if Facter[:kernel].value == 'windows'
    modulepath = modulepath.join(";")
  else
    modulepath = modulepath.join(':')
  end

  repo.temp_modulepath = modulepath

  # Use an ERB template to write a spec test
  File.write(
    "#{location}/spec_helper.rb",
    Onceover::Controlrepo.evaluate_template('spec_helper.rb.erb', binding)
  )
end
write_spec_helper_acceptance(location, repo) click to toggle source
# File lib/onceover/testconfig.rb, line 203
def write_spec_helper_acceptance(location, repo)
  File.write(
    "#{location}/spec_helper_acceptance.rb",
    Onceover::Controlrepo.evaluate_template('spec_helper_acceptance.rb.erb', binding)
  )
end
write_spec_test(location, test) click to toggle source
# File lib/onceover/testconfig.rb, line 187
def write_spec_test(location, test)
  # Use an ERB template to write a spec test
  File.write(
    "#{location}/#{test.to_s}_spec.rb",
    Onceover::Controlrepo.evaluate_template('test_spec.rb.erb', binding)
  )
end