lib/chef-dk/component_test.rb in chef-dk-0.11.2 vs lib/chef-dk/component_test.rb in chef-dk-0.12.0

- old
+ new

@@ -1,173 +1,194 @@ -# -# Copyright:: Copyright (c) 2014 Chef Software Inc. -# License:: Apache License, Version 2.0 -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# - -require 'chef-dk/exceptions' -require 'chef-dk/helpers' - -module ChefDK - class ComponentTest - - class NullTestResult - def exitstatus - 0 - end - - def stdout - "" - end - - def stderr - "" - end - end - - DEFAULT_TEST = lambda { |context| NullTestResult.new } - - include Helpers - - attr_accessor :base_dir - - attr_writer :omnibus_root - - attr_reader :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 unit_test(&test_block) - @unit_test = test_block - end - - def run_unit_test - instance_eval(&@unit_test) - end - - def integration_test(&test_block) - @integration_test = test_block - end - - def run_integration_test - instance_eval(&@integration_test) - end - - def smoke_test(&test_block) - @smoke_test = test_block - end - - def run_smoke_test - instance_eval(&@smoke_test) - end - - 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 - - # Just like #sh but raises an error if the the command returns an - # unexpected exit code. - # - # Most verification steps just run a single command, then - # ChefDK::Command::Verify#invoke_tests handles the results by inspecting - # the return value of the test block. For tests that run a lot of commands, - # this is inconvenient so you can use #sh! instead. - def sh!(*args) - sh(*args).tap { |result| result.error! } - end - - def run_in_tmpdir(command, options={}) - tmpdir do |dir| - options[:cwd] = dir - sh(command, options) - end - end - - def tmpdir - Dir.mktmpdir do |tmpdir| - yield tmpdir - end - end - - def assert_present! - unless File.exists?( component_path ) - raise MissingComponentError.new(name, "Could not find #{component_path}") - end - rescue Gem::LoadError => e - raise MissingComponentError.new(name, e) - end - - 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 - }, - :timeout => 3600 - } - end - - def component_path - if base_dir - File.join(omnibus_apps_dir, 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 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) - @gem_name_for_base_dir = gem_name - end - - def omnibus_root - @omnibus_root or raise "`omnibus_root` must be set before running tests" - end - - def omnibus_path - [omnibus_bin_dir, omnibus_embedded_bin_dir, ENV['PATH']].join(File::PATH_SEPARATOR) - end - - def path_variable_key - ENV.keys.grep(/\Apath\Z/i).first - end - - end -end +# +# Copyright:: Copyright (c) 2014 Chef Software Inc. +# License:: Apache License, Version 2.0 +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +require 'chef-dk/exceptions' +require 'chef-dk/helpers' + +# https://github.com/bundler/bundler/issues/4368 +# As of rubygems 2.6.2, Rubygems will call Bundler::SpecSet#size, which does +# not exist as of Bundler 1.11.2. +# +# `#size` and `#length` should be synonyms in idiomatic ruby so we alias to +# make bundler and rubygems play nicely. +if Object.const_defined?(:Bundler) && + Bundler.const_defined?(:SpecSet) && + Bundler::SpecSet.instance_methods.include?(:length) && + !Bundler::SpecSet.instance_methods.include?(:size) + + module Bundler + class SpecSet + + alias_method :size, :length + + end + end + +end + +module ChefDK + class ComponentTest + + class NullTestResult + def exitstatus + 0 + end + + def stdout + "" + end + + def stderr + "" + end + end + + DEFAULT_TEST = lambda { |context| NullTestResult.new } + + include Helpers + + attr_accessor :base_dir + + attr_writer :omnibus_root + + attr_reader :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 unit_test(&test_block) + @unit_test = test_block + end + + def run_unit_test + instance_eval(&@unit_test) + end + + def integration_test(&test_block) + @integration_test = test_block + end + + def run_integration_test + instance_eval(&@integration_test) + end + + def smoke_test(&test_block) + @smoke_test = test_block + end + + def run_smoke_test + instance_eval(&@smoke_test) + end + + 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 + + # Just like #sh but raises an error if the the command returns an + # unexpected exit code. + # + # Most verification steps just run a single command, then + # ChefDK::Command::Verify#invoke_tests handles the results by inspecting + # the return value of the test block. For tests that run a lot of commands, + # this is inconvenient so you can use #sh! instead. + def sh!(*args) + sh(*args).tap { |result| result.error! } + end + + def run_in_tmpdir(command, options={}) + tmpdir do |dir| + options[:cwd] = dir + sh(command, options) + end + end + + def tmpdir + Dir.mktmpdir do |tmpdir| + yield tmpdir + end + end + + def assert_present! + unless File.exists?( component_path ) + raise MissingComponentError.new(name, "Could not find #{component_path}") + end + rescue Gem::LoadError => e + raise MissingComponentError.new(name, e) + end + + 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 + }, + :timeout => 3600 + } + end + + def component_path + if base_dir + File.join(omnibus_apps_dir, 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 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) + @gem_name_for_base_dir = gem_name + end + + def omnibus_root + @omnibus_root or raise "`omnibus_root` must be set before running tests" + end + + def omnibus_path + [omnibus_bin_dir, omnibus_embedded_bin_dir, ENV['PATH']].join(File::PATH_SEPARATOR) + end + + def path_variable_key + ENV.keys.grep(/\Apath\Z/i).first + end + + end +end