Class: Onceover::TestConfig

Inherits:
Object
  • Object
show all
Defined in:
lib/onceover/testconfig.rb

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(file, opts = {}) ⇒ TestConfig

Returns a new instance of TestConfig.



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
61
62
63
64
65
66
67
68
69
70
71
# File 'lib/onceover/testconfig.rb', line 27

def initialize(file,opts = {})
  begin
    config = YAML.load(File.read(file))
  rescue Errno::ENOENT
    raise "Could not find #{file}"
  rescue Psych::SyntaxError
    raise "Could not #{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']

  # 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)

  config['classes'].each { |clarse| @classes << Onceover::Class.new(clarse) } unless config['classes'] == nil
  config['nodes'].each { |node| @nodes << Onceover::Node.new(node) } unless config['nodes'] == nil
  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

  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

Instance Attribute Details

#acceptance_testsObject

Returns the value of attribute acceptance_tests.



19
20
21
# File 'lib/onceover/testconfig.rb', line 19

def acceptance_tests
  @acceptance_tests
end

#class_groupsObject

Returns the value of attribute class_groups.



17
18
19
# File 'lib/onceover/testconfig.rb', line 17

def class_groups
  @class_groups
end

#classesObject

Returns the value of attribute classes.



14
15
16
# File 'lib/onceover/testconfig.rb', line 14

def classes
  @classes
end

#environmentObject

Returns the value of attribute environment.



20
21
22
# File 'lib/onceover/testconfig.rb', line 20

def environment
  @environment
end

#filter_classesObject

Returns the value of attribute filter_classes.



23
24
25
# File 'lib/onceover/testconfig.rb', line 23

def filter_classes
  @filter_classes
end

#filter_nodesObject

Returns the value of attribute filter_nodes.



24
25
26
# File 'lib/onceover/testconfig.rb', line 24

def filter_nodes
  @filter_nodes
end

#filter_tagsObject

Returns the value of attribute filter_tags.



22
23
24
# File 'lib/onceover/testconfig.rb', line 22

def filter_tags
  @filter_tags
end

#mock_functionsObject

Returns the value of attribute mock_functions.



25
26
27
# File 'lib/onceover/testconfig.rb', line 25

def mock_functions
  @mock_functions
end

#node_groupsObject

Returns the value of attribute node_groups.



16
17
18
# File 'lib/onceover/testconfig.rb', line 16

def node_groups
  @node_groups
end

#nodesObject

Returns the value of attribute nodes.



15
16
17
# File 'lib/onceover/testconfig.rb', line 15

def nodes
  @nodes
end

#optsObject

Returns the value of attribute opts.



21
22
23
# File 'lib/onceover/testconfig.rb', line 21

def opts
  @opts
end

#spec_testsObject

Returns the value of attribute spec_tests.



18
19
20
# File 'lib/onceover/testconfig.rb', line 18

def spec_tests
  @spec_tests
end

Class Method Details

.find_list(thing) ⇒ Object



73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
# File 'lib/onceover/testconfig.rb', line 73

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

Instance Method Details



225
226
227
228
229
230
231
232
233
234
235
236
# File 'lib/onceover/testconfig.rb', line 225

def create_fixtures_symlinks(repo)
  logger.debug "Creating fixtures symlinks"
  FileUtils.rm_rf("#{repo.tempdir}/spec/fixtures/modules")
  FileUtils.mkdir_p("#{repo.tempdir}/spec/fixtures/modules")
  repo.temp_modulepath.split(':').each do |path|
    Dir["#{path}/*"].each do |mod|
      modulename = File.basename(mod)
      logger.debug "Symlinking #{mod} to #{repo.tempdir}/spec/fixtures/modules/#{modulename}"
      FileUtils.ln_s(mod, "#{repo.tempdir}/spec/fixtures/modules/#{modulename}")
    end
  end
end

#pre_conditionObject



113
114
115
116
117
118
119
120
121
122
123
# File 'lib/onceover/testconfig.rb', line 113

def pre_condition
  # Read all the pre_conditions and return the string
  spec_dir = Onceover::Controlrepo.new.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 == 0
  puppetcode.join("\n")
end

#r10k_deploy_local(repo = Onceover::Controlrepo.new) ⇒ Object



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
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
# File 'lib/onceover/testconfig.rb', line 125

def r10k_deploy_local(repo = Onceover::Controlrepo.new)
  require 'onceover/controlrepo'
  require 'pathname'
  if repo.tempdir == nil
    repo.tempdir = Dir.mktmpdir('r10k')
  else
    logger.debug "Creating #{repo.tempdir}"
    FileUtils.mkdir_p(repo.tempdir)
  end

  # We need to do the copy to a tempdir then move the tempdir to the
  # destination, just in case we get a recursive copy
  # TODO: Improve this to save I/O

  # We might need to exclude some files
  #
  # if we are using bundler to install gems below the controlrepo
  # we don't wan two copies so exclude those
  #
  # If there are more situations like this we can add them to this array as
  # full paths
  excluded_files = []
  if ENV['GEM_HOME']
    logger.debug "Excluding #{ENV['GEM_HOME']} from controlrepo copy"
    excluded_files << Dir.glob("#{ENV['GEM_HOME']}/**/*")
    excluded_files.flatten!
  end

  # Exclude the files we need to
  controlrepo_files = Dir.glob("#{repo.root}/**/*")
  files_to_copy = (controlrepo_files - excluded_files).delete_if { |path| Pathname(path).directory? }
  folders_to_copy = (controlrepo_files - excluded_files).keep_if { |path| Pathname(path).directory? }

  logger.debug "Creating temp dir as a staging directory for copying the controlrepo to #{repo.tempdir}"
  temp_controlrepo = Dir.mktmpdir('controlrepo')

  logger.debug "Creating directories under #{temp_controlrepo}"
  FileUtils.mkdir_p(folders_to_copy.map { |folder| "#{temp_controlrepo}/#{(Pathname(folder).relative_path_from(Pathname(repo.root))).to_s}"})

  logger.debug "Copying files to #{temp_controlrepo}"
  files_to_copy.each do |file|
    FileUtils.cp(file,"#{temp_controlrepo}/#{(Pathname(file).relative_path_from(Pathname(repo.root))).to_s}")
  end
  FileUtils.mkdir_p("#{repo.tempdir}/#{repo.environmentpath}/production")

  logger.debug "Copying #{temp_controlrepo} to #{repo.tempdir}/#{repo.environmentpath}/production"
  FileUtils.cp_r(Dir["#{temp_controlrepo}/*"], "#{repo.tempdir}/#{repo.environmentpath}/production")
  FileUtils.rm_rf(temp_controlrepo)

  # Pull the trigger! If it's not already been pulled
  if repo.tempdir
    if File.directory?(repo.tempdir)
      # TODO: Change this to call out to r10k directly to do this
      # Probably something like:
      # R10K::Settings.global_settings.evaluate(with_overrides)
      # R10K::Action::Deploy::Environment
      Dir.chdir("#{repo.tempdir}/#{repo.environmentpath}/production") do
        logger.debug "Runing r10k puppetfile install --verbose --color --puppetfile #{repo.puppetfile} from #{repo.tempdir}/#{repo.environmentpath}/production"
        system("r10k puppetfile install --verbose --color --puppetfile #{repo.puppetfile}")
      end
    else
      raise "#{repo.tempdir} is not a directory"
    end
  end

  # Return repo.tempdir for use
  repo.tempdir
end

#run_filters(tests) ⇒ Object



238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
# File 'lib/onceover/testconfig.rb', line 238

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|
          if test.send(method)
            test.send(method).include?(filter)
          else
            false
          end
        end
      end
    end
  end
  tests
end

#verify_acceptance_test(controlrepo, test) ⇒ Object



103
104
105
106
107
108
109
110
111
# File 'lib/onceover/testconfig.rb', line 103

def verify_acceptance_test(controlrepo,test)
  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) ⇒ Object



95
96
97
98
99
100
101
# File 'lib/onceover/testconfig.rb', line 95

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) ⇒ Object



199
200
201
# File 'lib/onceover/testconfig.rb', line 199

def write_acceptance_tests(location, tests)
  File.write("#{location}/acceptance_spec.rb",Onceover::Controlrepo.evaluate_template('acceptance_test_spec.rb.erb',binding))
end

#write_rakefile(location, pattern) ⇒ Object



207
208
209
# File 'lib/onceover/testconfig.rb', line 207

def write_rakefile(location, pattern)
  File.write("#{location}/Rakefile",Onceover::Controlrepo.evaluate_template('Rakefile.erb',binding))
end

#write_spec_helper(location, repo) ⇒ Object



211
212
213
214
215
216
217
218
219
220
221
222
223
# File 'lib/onceover/testconfig.rb', line 211

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
  modulepath = modulepath.join(":")
  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) ⇒ Object



203
204
205
# 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) ⇒ Object



194
195
196
197
# File 'lib/onceover/testconfig.rb', line 194

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