diff options
-rw-r--r-- | lib/chef/cookbook/cookbook_collection.rb | 15 | ||||
-rw-r--r-- | lib/chef/cookbook/metadata.rb | 124 | ||||
-rw-r--r-- | lib/chef/exceptions.rb | 16 | ||||
-rw-r--r-- | lib/chef/policy_builder/expand_node_object.rb | 2 | ||||
-rw-r--r-- | lib/chef/policy_builder/policyfile.rb | 1 | ||||
-rw-r--r-- | spec/integration/client/client_spec.rb | 20 | ||||
-rw-r--r-- | spec/integration/knife/upload_spec.rb | 29 | ||||
-rw-r--r-- | spec/integration/solo/solo_spec.rb | 34 | ||||
-rw-r--r-- | spec/unit/cookbook/metadata_spec.rb | 124 | ||||
-rw-r--r-- | spec/unit/policy_builder/policyfile_spec.rb | 2 |
10 files changed, 353 insertions, 14 deletions
diff --git a/lib/chef/cookbook/cookbook_collection.rb b/lib/chef/cookbook/cookbook_collection.rb index ae63abfc93..38784c22fa 100644 --- a/lib/chef/cookbook/cookbook_collection.rb +++ b/lib/chef/cookbook/cookbook_collection.rb @@ -1,7 +1,7 @@ #-- # Author:: Tim Hinderliter (<tim@opscode.com>) # Author:: Christopher Walters (<cw@opscode.com>) -# Copyright:: Copyright (c) 2010 Opscode, Inc. +# Copyright:: Copyright (c) 2010-2015 Chef Software, Inc. # License:: Apache License, Version 2.0 # # Licensed under the Apache License, Version 2.0 (the "License"); @@ -41,5 +41,18 @@ class Chef cookbook_versions.each{ |cookbook_name, cookbook_version| self[cookbook_name] = cookbook_version } end + # Validates that the cookbook metadata allows it to run on this instance. + # + # Currently checks chef_version and ohai_version in the cookbook metadata + # against the running Chef::VERSION and Ohai::VERSION. + # + # @raises [Chef::Exceptions::CookbookChefVersionMismatch] if the Chef::VERSION fails validation + # @raises [Chef::Exceptions::CookbookOhaiVersionMismatch] if the Ohai::VERSION fails validation + def validate! + each do |cookbook_name, cookbook_version| + cookbook_version.metadata.validate_chef_version! + cookbook_version.metadata.validate_ohai_version! + end + end end end diff --git a/lib/chef/cookbook/metadata.rb b/lib/chef/cookbook/metadata.rb index 9822920a7d..e9509be38c 100644 --- a/lib/chef/cookbook/metadata.rb +++ b/lib/chef/cookbook/metadata.rb @@ -2,7 +2,7 @@ # Author:: Adam Jacob (<adam@opscode.com>) # Author:: AJ Christensen (<aj@opscode.com>) # Author:: Seth Falcon (<seth@opscode.com>) -# Copyright:: Copyright 2008-2010 Opscode, Inc. +# Copyright:: Copyright 2008-2015 Chef Software, Inc. # License:: Apache License, Version 2.0 # # Licensed under the Apache License, Version 2.0 (the "License"); @@ -55,19 +55,23 @@ class Chef SOURCE_URL = 'source_url'.freeze ISSUES_URL = 'issues_url'.freeze PRIVACY = 'privacy'.freeze + CHEF_VERSIONS = 'chef_versions'.freeze + OHAI_VERSIONS = 'ohai_versions'.freeze COMPARISON_FIELDS = [ :name, :description, :long_description, :maintainer, :maintainer_email, :license, :platforms, :dependencies, :recommendations, :suggestions, :conflicting, :providing, :replacing, :attributes, :groupings, :recipes, :version, - :source_url, :issues_url, :privacy ] + :source_url, :issues_url, :privacy, :chef_versions, :ohai_versions ] - VERSION_CONSTRAINTS = {:depends => DEPENDENCIES, - :recommends => RECOMMENDATIONS, - :suggests => SUGGESTIONS, - :conflicts => CONFLICTING, - :provides => PROVIDING, - :replaces => REPLACING } + VERSION_CONSTRAINTS = {:depends => DEPENDENCIES, + :recommends => RECOMMENDATIONS, + :suggests => SUGGESTIONS, + :conflicts => CONFLICTING, + :provides => PROVIDING, + :replaces => REPLACING, + :chef_version => CHEF_VERSIONS, + :ohai_version => OHAI_VERSIONS } include Chef::Mixin::ParamsValidate include Chef::Mixin::FromFile @@ -84,6 +88,11 @@ class Chef attr_reader :recipes attr_reader :version + # @return [Array<Gem::Dependency>] Array of supported Chef versions + attr_reader :chef_versions + # @return [Array<Gem::Dependency>] Array of supported Ohai versions + attr_reader :ohai_versions + # Builds a new Chef::Cookbook::Metadata object. # # === Parameters @@ -118,6 +127,8 @@ class Chef @source_url = '' @issues_url = '' @privacy = false + @chef_versions = [] + @ohai_versions = [] @errors = [] end @@ -386,6 +397,28 @@ class Chef @replacing[cookbook] end + # Metadata DSL to set a valid chef_version. May be declared multiple times + # with the result being 'OR'd such that if any statements match, the version + # is considered supported. Uses Gem::Requirement for its implementation. + # + # @param version_args [Array<String>] Version constraint in String form + # @return [Array<Gem::Dependency>] Current chef_versions array + def chef_version(*version_args) + @chef_versions << Gem::Dependency.new('chef', *version_args) unless version_args.empty? + @chef_versions + end + + # Metadata DSL to set a valid ohai_version. May be declared multiple times + # with the result being 'OR'd such that if any statements match, the version + # is considered supported. Uses Gem::Requirement for its implementation. + # + # @param version_args [Array<String>] Version constraint in String form + # @return [Array<Gem::Dependency>] Current ohai_versions array + def ohai_version(*version_args) + @ohai_versions << Gem::Dependency.new('ohai', *version_args) unless version_args.empty? + @ohai_versions + end + # Adds a description for a recipe. # # === Parameters @@ -481,6 +514,40 @@ class Chef @groupings[name] end + # Convert an Array of Gem::Dependency objects (chef_version/ohai_version) to an Array. + # + # Gem::Dependencey#to_s is not useful, and there is no #to_json defined on it or its component + # objets, so we have to write our own rendering method. + # + # [ Gem::Dependency.new(">= 12.5"), Gem::Dependency.new(">= 11.18.0", "< 12.0") ] + # + # results in: + # + # [ [ ">= 12.5" ], [ ">= 11.18.0", "< 12.0" ] ] + # + # @param deps [Array<Gem::Dependency>] Multiple Gem-style version constraints + # @return [Array<Array<String>]] Simple object representation of version constraints (for json) + def gem_requirements_to_array(*deps) + deps.map do |dep| + dep.requirement.requirements.map do |op, version| + "#{op} #{version}" + end.sort + end + end + + # Convert an Array of Gem::Dependency objects (chef_version/ohai_version) to a hash. + # + # This is the inverse of #gem_requirements_to_array + # + # @param what [String] What version constraint we are constructing ('chef' or 'ohai' presently) + # @param array [Array<Array<String>]] Simple object representation of version constraints (from json) + # @return [Array<Gem::Dependency>] Multiple Gem-style version constraints + def gem_requirements_from_array(what, array) + array.map do |dep| + Gem::Dependency.new(what, *dep) + end + end + def to_hash { NAME => self.name, @@ -502,7 +569,9 @@ class Chef VERSION => self.version, SOURCE_URL => self.source_url, ISSUES_URL => self.issues_url, - PRIVACY => self.privacy + PRIVACY => self.privacy, + CHEF_VERSIONS => gem_requirements_to_array(*self.chef_versions), + OHAI_VERSIONS => gem_requirements_to_array(*self.ohai_versions) } end @@ -537,6 +606,8 @@ class Chef @source_url = o[SOURCE_URL] if o.has_key?(SOURCE_URL) @issues_url = o[ISSUES_URL] if o.has_key?(ISSUES_URL) @privacy = o[PRIVACY] if o.has_key?(PRIVACY) + @chef_versions = gem_requirements_from_array("chef", o[CHEF_VERSIONS]) if o.has_key?(CHEF_VERSIONS) + @ohai_versions = gem_requirements_from_array("ohai", o[OHAI_VERSIONS]) if o.has_key?(OHAI_VERSIONS) self end @@ -612,8 +683,43 @@ class Chef ) end + # Validates that the Ohai::VERSION of the running chef-client matches one of the + # configured ohai_version statements in this cookbooks metadata. + # + # @raises [Chef::Exceptions::CookbookOhaiVersionMismatch] if the cookbook fails validation + def validate_ohai_version! + unless gem_dep_matches?("ohai", Gem::Version.new(Ohai::VERSION), *ohai_versions) + raise Exceptions::CookbookOhaiVersionMismatch.new(Ohai::VERSION, name, version, *ohai_versions) + end + end + + # Validates that the Chef::VERSION of the running chef-client matches one of the + # configured chef_version statements in this cookbooks metadata. + # + # @raises [Chef::Exceptions::CookbookChefVersionMismatch] if the cookbook fails validation + def validate_chef_version! + unless gem_dep_matches?("chef", Gem::Version.new(Chef::VERSION), *chef_versions) + raise Exceptions::CookbookChefVersionMismatch.new(Chef::VERSION, name, version, *chef_versions) + end + end + private + # Helper to match a gem style version (ohai_version/chef_version) against a set of + # Gem::Dependency version constraints. If none are present, it always matches. if + # multiple are present, one must match. Returns false if none matches. + # + # @param what [String] the name of the constraint (e.g. 'chef' or 'ohai') + # @param version [String] the version to compare against the constraints + # @param deps [Array<Gem::Dependency>] Multiple Gem-style version constraints + # @return [Boolean] true if no constraints or a match, false if no match + def gem_dep_matches?(what, version, *deps) + # always match if we have no chef_version at all + return true unless deps.length > 0 + # match if we match any of the chef_version lines + deps.any? { |dep| dep.match?(what, version) } + end + def run_validation if name.nil? @errors = ["The `name' attribute is required in cookbook metadata"] diff --git a/lib/chef/exceptions.rb b/lib/chef/exceptions.rb index 855c86d9cc..8172311dd6 100644 --- a/lib/chef/exceptions.rb +++ b/lib/chef/exceptions.rb @@ -2,7 +2,7 @@ # Author:: Adam Jacob (<adam@opscode.com>) # Author:: Seth Falcon (<seth@opscode.com>) # Author:: Kyle Goodwin (<kgoodwin@primerevenue.com>) -# Copyright:: Copyright 2008-2010 Opscode, Inc. +# Copyright:: Copyright 2008-2015 Chef Software, Inc. # License:: Apache License, Version 2.0 # # Licensed under the Apache License, Version 2.0 (the "License"); @@ -482,6 +482,20 @@ class Chef end end + class CookbookChefVersionMismatch < RuntimeError + def initialize(chef_version, cookbook_name, cookbook_version, *constraints) + constraint_str = constraints.map { |c| c.requirement.as_list.to_s }.join(', ') + super "Cookbook '#{cookbook_name}' version '#{cookbook_version}' depends on chef version #{constraint_str}, but the running chef version is #{chef_version}" + end + end + + class CookbookOhaiVersionMismatch < RuntimeError + def initialize(ohai_version, cookbook_name, cookbook_version, *constraints) + constraint_str = constraints.map { |c| c.requirement.as_list.to_s }.join(', ') + super "Cookbook '#{cookbook_name}' version '#{cookbook_version}' depends on ohai version #{constraint_str}, but the running ohai version is #{ohai_version}" + end + end + class MultipleDscResourcesFound < RuntimeError attr_reader :resources_found def initialize(resources_found) diff --git a/lib/chef/policy_builder/expand_node_object.rb b/lib/chef/policy_builder/expand_node_object.rb index 2c6d644e42..848dd00684 100644 --- a/lib/chef/policy_builder/expand_node_object.rb +++ b/lib/chef/policy_builder/expand_node_object.rb @@ -74,11 +74,13 @@ class Chef cl = Chef::CookbookLoader.new(Chef::Config[:cookbook_path]) cl.load_cookbooks cookbook_collection = Chef::CookbookCollection.new(cl) + cookbook_collection.validate! run_context = Chef::RunContext.new(node, cookbook_collection, @events) else Chef::Cookbook::FileVendor.fetch_from_remote(api_service) cookbook_hash = sync_cookbooks cookbook_collection = Chef::CookbookCollection.new(cookbook_hash) + cookbook_collection.validate! run_context = Chef::RunContext.new(node, cookbook_collection, @events) end diff --git a/lib/chef/policy_builder/policyfile.rb b/lib/chef/policy_builder/policyfile.rb index d6dcdf67b2..3633110d6c 100644 --- a/lib/chef/policy_builder/policyfile.rb +++ b/lib/chef/policy_builder/policyfile.rb @@ -153,6 +153,7 @@ class Chef Chef::Cookbook::FileVendor.fetch_from_remote(http_api) sync_cookbooks cookbook_collection = Chef::CookbookCollection.new(cookbooks_to_sync) + cookbook_collection.validate! run_context = Chef::RunContext.new(node, cookbook_collection, events) setup_chef_class(run_context) diff --git a/spec/integration/client/client_spec.rb b/spec/integration/client/client_spec.rb index 314a9310be..41645adb9e 100644 --- a/spec/integration/client/client_spec.rb +++ b/spec/integration/client/client_spec.rb @@ -320,6 +320,26 @@ EOM end end + when_the_repository "has a cookbook that should fail chef_version checks" do + before do + file 'cookbooks/x/recipes/default.rb', '' + file 'cookbooks/x/metadata.rb', <<EOM +name 'x' +version '0.0.1' +chef_version '~> 999.99' +EOM + file 'config/client.rb', <<EOM +local_mode true +cookbook_path "#{path_to('cookbooks')}" +EOM + end + it "should fail the chef client run" do + command = shell_out("#{chef_client} -c \"#{path_to('config/client.rb')}\" -o 'x::default' --no-fork", :cwd => chef_dir) + expect(command.exitstatus).to eql(1) + expect(command.stdout).to match(/Chef::Exceptions::CookbookChefVersionMismatch/) + end + end + when_the_repository "has a cookbook that generates deprecation warnings" do before do file 'cookbooks/x/recipes/default.rb', <<-EOM diff --git a/spec/integration/knife/upload_spec.rb b/spec/integration/knife/upload_spec.rb index 6ca8c3d8ce..d72cbb82f5 100644 --- a/spec/integration/knife/upload_spec.rb +++ b/spec/integration/knife/upload_spec.rb @@ -1,6 +1,6 @@ # # Author:: John Keiser (<jkeiser@opscode.com>) -# Copyright:: Copyright (c) 2013 Opscode, Inc. +# Copyright:: Copyright (c) 2013-2015 Chef Software, Inc. # License:: Apache License, Version 2.0 # # Licensed under the Apache License, Version 2.0 (the "License"); @@ -699,6 +699,19 @@ EOH end end end + when_the_chef_server "is empty" do + when_the_repository 'has a cookbook with an invalid chef_version constraint in it' do + before do + file 'cookbooks/x/metadata.rb', cb_metadata('x', '1.0.0', "\nchef_version '~> 999.0'") + end + it 'knife upload succeeds' do + knife('upload /cookbooks/x').should_succeed <<EOM +Created /cookbooks/x +EOM + knife('diff --name-status /cookbooks').should_succeed '' + end + end + end end # without versioned cookbooks with_versioned_cookbooks do @@ -1219,6 +1232,20 @@ EOM end end end + + when_the_chef_server "is empty" do + when_the_repository 'has a cookbook with an invalid chef_version constraint in it' do + before do + file 'cookbooks/x-1.0.0/metadata.rb', cb_metadata('x', '1.0.0', "\nchef_version '~> 999.0'") + end + it 'knife upload succeeds' do + knife('upload /cookbooks/x-1.0.0').should_succeed <<EOM +Created /cookbooks/x-1.0.0 +EOM + knife('diff --name-status /cookbooks').should_succeed '' + end + end + end end # with versioned cookbooks when_the_chef_server 'has a user' do diff --git a/spec/integration/solo/solo_spec.rb b/spec/integration/solo/solo_spec.rb index f45933c799..6240a38144 100644 --- a/spec/integration/solo/solo_spec.rb +++ b/spec/integration/solo/solo_spec.rb @@ -70,6 +70,40 @@ EOM end end + when_the_repository "has a cookbook with an incompatible chef_version" do + before do + file 'cookbooks/x/metadata.rb', cb_metadata('x', '1.0.0', "\nchef_version '~> 999.0'") + file 'cookbooks/x/recipes/default.rb', 'puts "ITWORKS"' + file 'config/solo.rb', <<EOM +cookbook_path "#{path_to('cookbooks')}" +file_cache_path "#{path_to('config/cache')}" +EOM + end + + it "should exit with an error" do + result = shell_out("#{chef_solo} -c \"#{path_to('config/solo.rb')}\" -o 'x::default' -l debug", :cwd => chef_dir) + expect(result.exitstatus).to eq(1) + expect(result.stdout).to include("Chef::Exceptions::CookbookChefVersionMismatch") + end + end + + when_the_repository "has a cookbook with an incompatible ohai_version" do + before do + file 'cookbooks/x/metadata.rb', cb_metadata('x', '1.0.0', "\nohai_version '~> 999.0'") + file 'cookbooks/x/recipes/default.rb', 'puts "ITWORKS"' + file 'config/solo.rb', <<EOM +cookbook_path "#{path_to('cookbooks')}" +file_cache_path "#{path_to('config/cache')}" +EOM + end + + it "should exit with an error" do + result = shell_out("#{chef_solo} -c \"#{path_to('config/solo.rb')}\" -o 'x::default' -l debug", :cwd => chef_dir) + expect(result.exitstatus).to eq(1) + expect(result.stdout).to include("Chef::Exceptions::CookbookOhaiVersionMismatch") + end + end + when_the_repository "has a cookbook with a recipe with sleep" do before do diff --git a/spec/unit/cookbook/metadata_spec.rb b/spec/unit/cookbook/metadata_spec.rb index 1b30286f51..f8e96ad475 100644 --- a/spec/unit/cookbook/metadata_spec.rb +++ b/spec/unit/cookbook/metadata_spec.rb @@ -1,7 +1,7 @@ # # Author:: Adam Jacob (<adam@opscode.com>) # Author:: Seth Falcon (<seth@opscode.com>) -# Copyright:: Copyright 2008-2010 Opscode, Inc. +# Copyright:: Copyright 2008-2015 Chef Software, Inc. # License:: Apache License, Version 2.0 # # Licensed under the Apache License, Version 2.0 (the "License"); @@ -30,7 +30,7 @@ describe Chef::Cookbook::Metadata do :maintainer_email, :license, :platforms, :dependencies, :recommendations, :suggestions, :conflicting, :providing, :replacing, :attributes, :groupings, :recipes, :version, - :source_url, :issues_url, :privacy ] + :source_url, :issues_url, :privacy, :ohai_versions, :chef_versions ] end it "does not depend on object identity for equality" do @@ -326,6 +326,110 @@ describe Chef::Cookbook::Metadata do end end + describe "chef_version" do + def expect_chef_version_works(*args) + ret = [] + args.each do |arg| + metadata.send(:chef_version, *arg) + ret << Gem::Dependency.new("chef", *arg) + end + expect(metadata.send(:chef_versions)).to eql(ret) + end + + it "should work with a single simple constraint" do + expect_chef_version_works(["~> 12"]) + end + + it "should work with a single complex constraint" do + expect_chef_version_works([">= 12.0.1", "< 12.5.1"]) + end + + it "should work with multiple simple constraints" do + expect_chef_version_works(["~> 12.5.1"],["~> 11.18.10"]) + end + + it "should work with multiple complex constraints" do + expect_chef_version_works([">= 11.14.2", "< 11.18.10"],[">= 12.2.1", "< 12.5.1"]) + end + + it "should fail validation on a simple pessimistic constraint" do + expect_chef_version_works(["~> 999.0"]) + expect { metadata.validate_chef_version! }.to raise_error(Chef::Exceptions::CookbookChefVersionMismatch) + end + + it "should fail validation when that valid chef versions are too big" do + expect_chef_version_works([">= 999.0", "< 999.9"]) + expect { metadata.validate_chef_version! }.to raise_error(Chef::Exceptions::CookbookChefVersionMismatch) + end + + it "should fail validation when that valid chef versions are too small" do + expect_chef_version_works([">= 0.0.1", "< 0.0.9"]) + expect { metadata.validate_chef_version! }.to raise_error(Chef::Exceptions::CookbookChefVersionMismatch) + end + + it "should fail validation when all ranges fail" do + expect_chef_version_works([">= 999.0", "< 999.9"],[">= 0.0.1", "< 0.0.9"]) + expect { metadata.validate_chef_version! }.to raise_error(Chef::Exceptions::CookbookChefVersionMismatch) + end + + it "should pass validation when one constraint passes" do + expect_chef_version_works([">= 999.0", "< 999.9"],["= #{Chef::VERSION}"]) + expect { metadata.validate_chef_version! }.not_to raise_error + end + end + + describe "ohai_version" do + def expect_ohai_version_works(*args) + ret = [] + args.each do |arg| + metadata.send(:ohai_version, *arg) + ret << Gem::Dependency.new("ohai", *arg) + end + expect(metadata.send(:ohai_versions)).to eql(ret) + end + + it "should work with a single simple constraint" do + expect_ohai_version_works(["~> 12"]) + end + + it "should work with a single complex constraint" do + expect_ohai_version_works([">= 12.0.1", "< 12.5.1"]) + end + + it "should work with multiple simple constraints" do + expect_ohai_version_works(["~> 12.5.1"],["~> 11.18.10"]) + end + + it "should work with multiple complex constraints" do + expect_ohai_version_works([">= 11.14.2", "< 11.18.10"],[">= 12.2.1", "< 12.5.1"]) + end + + it "should fail validation on a simple pessimistic constraint" do + expect_ohai_version_works(["~> 999.0"]) + expect { metadata.validate_ohai_version! }.to raise_error(Chef::Exceptions::CookbookOhaiVersionMismatch) + end + + it "should fail validation when that valid chef versions are too big" do + expect_ohai_version_works([">= 999.0", "< 999.9"]) + expect { metadata.validate_ohai_version! }.to raise_error(Chef::Exceptions::CookbookOhaiVersionMismatch) + end + + it "should fail validation when that valid chef versions are too small" do + expect_ohai_version_works([">= 0.0.1", "< 0.0.9"]) + expect { metadata.validate_ohai_version! }.to raise_error(Chef::Exceptions::CookbookOhaiVersionMismatch) + end + + it "should fail validation when all ranges fail" do + expect_ohai_version_works([">= 999.0", "< 999.9"],[">= 0.0.1", "< 0.0.9"]) + expect { metadata.validate_ohai_version! }.to raise_error(Chef::Exceptions::CookbookOhaiVersionMismatch) + end + + it "should pass validation when one constraint passes" do + expect_ohai_version_works([">= 999.0", "< 999.9"],["= #{Ohai::VERSION}"]) + expect { metadata.validate_ohai_version! }.not_to raise_error + end + end + describe "attribute groupings" do it "should allow you set a grouping" do group = { @@ -684,9 +788,14 @@ describe Chef::Cookbook::Metadata do metadata.attribute "bizspark/has_login", :display_name => "You have nothing" metadata.version "1.2.3" + metadata.chef_version ">= 11.14.2", "< 11.18.10" + metadata.chef_version ">= 12.2.1", "< 12.5.1" + metadata.ohai_version ">= 7.1.0", "< 7.5.0" + metadata.ohai_version ">= 8.0.1", "< 8.6.0" end it "should produce the same output from to_json and Chef::JSONCompat" do + # XXX: fairly certain this is testing ruby method dispatch expect(metadata.to_json).to eq(Chef::JSONCompat.to_json(metadata)) end @@ -723,6 +832,15 @@ describe Chef::Cookbook::Metadata do expect(deserialized_metadata[t]).to eq(metadata.send(t.to_sym)) end end + + %w{ + ohai_versions + chef_versions + }.each do |t| + it "should include '#{t}'" do + expect(deserialized_metadata[t]).to eq(metadata.gem_requirements_to_array(*metadata.send(t.to_sym))) + end + end end describe "deserialize" do @@ -754,6 +872,8 @@ describe Chef::Cookbook::Metadata do source_url issues_url privacy + chef_versions + ohai_versions }.each do |t| it "should match '#{t}'" do expect(deserialized_metadata.send(t.to_sym)).to eq(metadata.send(t.to_sym)) diff --git a/spec/unit/policy_builder/policyfile_spec.rb b/spec/unit/policy_builder/policyfile_spec.rb index b656a66ec3..ed893260c2 100644 --- a/spec/unit/policy_builder/policyfile_spec.rb +++ b/spec/unit/policy_builder/policyfile_spec.rb @@ -662,6 +662,7 @@ describe Chef::PolicyBuilder::Policyfile do it "builds a run context" do expect(cookbook_synchronizer).to receive(:sync_cookbooks) expect_any_instance_of(Chef::RunContext).to receive(:load).with(policy_builder.run_list_expansion_ish) + expect_any_instance_of(Chef::CookbookCollection).to receive(:validate!) run_context = policy_builder.setup_run_context expect(run_context.node).to eq(node) expect(run_context.cookbook_collection.keys).to match_array(["example1", "example2"]) @@ -670,6 +671,7 @@ describe Chef::PolicyBuilder::Policyfile do it "makes the run context available via static method on Chef" do expect(cookbook_synchronizer).to receive(:sync_cookbooks) expect_any_instance_of(Chef::RunContext).to receive(:load).with(policy_builder.run_list_expansion_ish) + expect_any_instance_of(Chef::CookbookCollection).to receive(:validate!) run_context = policy_builder.setup_run_context expect(Chef.run_context).to eq(run_context) end |