summaryrefslogtreecommitdiff
path: root/spec/unit/run_context
diff options
context:
space:
mode:
authordanielsdeleo <dan@opscode.com>2012-11-29 15:08:52 -0800
committerdanielsdeleo <dan@opscode.com>2012-11-30 14:51:47 -0800
commitb213ae8e8c7aac472332298f0f455d36d122a7b5 (patch)
tree69e7ff6ca2ae29c217a1b3e982b5ed74748b49f8 /spec/unit/run_context
parent8660bf4c410cc60b4028fc1f44a1fe67e71b8648 (diff)
downloadchef-b213ae8e8c7aac472332298f0f455d36d122a7b5.tar.gz
[CHEF-3376] extract CookbookCompiler specs
Diffstat (limited to 'spec/unit/run_context')
-rw-r--r--spec/unit/run_context/cookbook_compiler_spec.rb180
1 files changed, 180 insertions, 0 deletions
diff --git a/spec/unit/run_context/cookbook_compiler_spec.rb b/spec/unit/run_context/cookbook_compiler_spec.rb
new file mode 100644
index 0000000000..7796dc6189
--- /dev/null
+++ b/spec/unit/run_context/cookbook_compiler_spec.rb
@@ -0,0 +1,180 @@
+#
+# Author:: Daniel DeLeo (<dan@opscode.com>)
+# Copyright:: Copyright (c) 2012 Opscode, 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 'spec_helper'
+
+# Keeps track of what file got loaded in what order.
+module LibraryLoadOrder
+ extend self
+
+ def load_order
+ @load_order ||= []
+ end
+
+ def reset!
+ @load_order = nil
+ end
+
+ def record(file)
+ load_order << file
+ end
+end
+
+# These tests relies on fixture data in spec/data/run_context/cookbooks.
+#
+# Dependencies (circular or not) are specified by `depends` directives in the
+# metadata of these cookbooks.
+#
+# Side effects used to verify the behavior are implemented as code in the various file types.
+#
+describe Chef::RunContext::CookbookCompiler do
+
+ let(:node) { Chef::Node.new }
+
+ let(:events) { Chef::EventDispatch::Dispatcher.new }
+
+ let(:cookbook_loader) do
+ cl = Chef::CookbookLoader.new(chef_repo_path)
+ cl.load_cookbooks
+ cl
+ end
+
+ # This run_context is not accessed directly in the test, but it is used by
+ # Chef::Node to store state (which attributes files have been read).
+ # Therefore, it's eagerly created here.
+ let!(:run_context) { Chef::RunContext.new(node, cookbook_collection, events) }
+
+ let(:chef_repo_path) { File.expand_path(File.join(CHEF_SPEC_DATA, "run_context", "cookbooks")) }
+
+ let(:cookbook_collection) { Chef::CookbookCollection.new(cookbook_loader) }
+
+ # Lazy evaluation of `expansion` here is used to mutate the run list before expanding it
+ let(:run_list_expansion) { node.run_list.expand('_default') }
+
+ let(:compiler) do
+ Chef::RunContext::CookbookCompiler.new(node, cookbook_collection, run_list_expansion, events)
+ end
+
+
+ describe "loading attribute files" do
+
+ # Attribute files in the fixture data will append their
+ # "cookbook_name::attribute_file_name" to the node's `:attr_load_order`
+ # attribute when loaded.
+
+ it "loads default.rb first, then other files in sort order" do
+ node.run_list("dependency1::default")
+
+ compiler.compile_attributes
+ node[:attr_load_order].should == ["dependency1::default", "dependency1::aa_first", "dependency1::zz_last"]
+ end
+
+ it "loads dependencies before loading the depending cookbook's attributes" do
+ # Also make sure that attributes aren't loaded twice if we have two
+ # recipes from the same cookbook in the run list
+ node.run_list("test-with-deps::default", "test-with-deps::server")
+
+ compiler.compile_attributes
+
+ # dependencies are stored in a hash so therefore unordered, but they should be loaded in sort order
+ node[:attr_load_order].should == ["dependency1::default",
+ "dependency1::aa_first",
+ "dependency1::zz_last",
+ "dependency2::default",
+ "test-with-deps::default"]
+ end
+
+ it "does not follow infinite dependency loops" do
+ node.run_list("test-with-circular-deps::default")
+
+ # Circular deps should not cause infinite loops
+ compiler.compile_attributes
+
+ node[:attr_load_order].should == ["circular-dep2::default", "circular-dep1::default", "test-with-circular-deps::default"]
+ end
+
+ it "loads attributes from cookbooks that don't have a default.rb attribute file" do
+ node.run_list("no-default-attr::default.rb")
+
+ compiler.compile_attributes
+
+ node[:attr_load_order].should == ["no-default-attr::server"]
+ end
+ end
+
+ describe "loading libraries" do
+ before do
+ LibraryLoadOrder.reset!
+ end
+
+ # One big test for everything. Individual behaviors are tested by the attribute code above.
+ it "loads libraries in run list order" do
+ node.run_list("test-with-deps::default", "test-with-circular-deps::default")
+
+ compiler.compile_libraries
+ LibraryLoadOrder.load_order.should == ["dependency1", "dependency2", "test-with-deps", "circular-dep2", "circular-dep1", "test-with-circular-deps"]
+ end
+ end
+
+ describe "loading LWRPs" do
+ before do
+ LibraryLoadOrder.reset!
+ end
+
+ # One big test for everything. Individual behaviors are tested by the attribute code above.
+ it "loads LWRPs in run list order" do
+ node.run_list("test-with-deps::default", "test-with-circular-deps::default")
+
+ compiler.compile_lwrps
+ LibraryLoadOrder.load_order.should == ["dependency1-provider",
+ "dependency1-resource",
+ "dependency2-provider",
+ "dependency2-resource",
+ "test-with-deps-provider",
+ "test-with-deps-resource",
+ "circular-dep2-provider",
+ "circular-dep2-resource",
+ "circular-dep1-provider",
+ "circular-dep1-resource",
+ "test-with-circular-deps-provider",
+ "test-with-circular-deps-resource"]
+ end
+ end
+
+ describe "loading resource definitions" do
+ before do
+ LibraryLoadOrder.reset!
+ end
+
+ # One big test for all load order concerns. Individual behaviors are tested
+ # by the attribute code above.
+ it "loads resource definitions in run list order" do
+ node.run_list("test-with-deps::default", "test-with-circular-deps::default")
+
+ compiler.compile_resource_definitions
+ LibraryLoadOrder.load_order.should == ["dependency1-definition",
+ "dependency2-definition",
+ "test-with-deps-definition",
+ "circular-dep2-definition",
+ "circular-dep1-definition",
+ "test-with-circular-deps-definition"]
+ end
+
+ end
+
+end