diff options
author | Seth Chisamore <schisamo@opscode.com> | 2012-10-30 10:39:35 -0400 |
---|---|---|
committer | Seth Chisamore <schisamo@opscode.com> | 2012-10-30 10:39:35 -0400 |
commit | 24dc69a9a97e82a6e4207de68d6dcc664178249b (patch) | |
tree | 19bb289c9f88b4bbab066bc56b95d6d222fd5c35 /spec/unit/cookbook_version_spec.rb | |
parent | 9348c1c9c80ee757354d624b7dc1b78ebc7605c4 (diff) | |
download | chef-24dc69a9a97e82a6e4207de68d6dcc664178249b.tar.gz |
[OC-3564] move core Chef to the repo root \o/ \m/
The opscode/chef repository now only contains the core Chef library code
used by chef-client, knife and chef-solo!
Diffstat (limited to 'spec/unit/cookbook_version_spec.rb')
-rw-r--r-- | spec/unit/cookbook_version_spec.rb | 307 |
1 files changed, 307 insertions, 0 deletions
diff --git a/spec/unit/cookbook_version_spec.rb b/spec/unit/cookbook_version_spec.rb new file mode 100644 index 0000000000..85e1db1fae --- /dev/null +++ b/spec/unit/cookbook_version_spec.rb @@ -0,0 +1,307 @@ +# +# Author:: Daniel DeLeo (<dan@opscode.com>) +# Copyright:: Copyright (c) 2010 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' + +describe Chef::CookbookVersion do + describe "when first created" do + before do + @cookbook_version = Chef::CookbookVersion.new("tatft") + end + + it "has a name" do + @cookbook_version.name.should == 'tatft' + end + + it "has no attribute files" do + @cookbook_version.attribute_filenames.should be_empty + end + + it "has no resource definition files" do + @cookbook_version.definition_filenames.should be_empty + end + + it "has no cookbook files" do + @cookbook_version.file_filenames.should be_empty + end + + it "has no recipe files" do + @cookbook_version.recipe_filenames.should be_empty + end + + it "has no library files" do + @cookbook_version.library_filenames.should be_empty + end + + it "has no LWRP resource files" do + @cookbook_version.resource_filenames.should be_empty + end + + it "has no LWRP provider files" do + @cookbook_version.provider_filenames.should be_empty + end + + it "has no metadata files" do + @cookbook_version.metadata_filenames.should be_empty + end + + it "is not frozen" do + @cookbook_version.should_not be_frozen_version + end + + it "can be frozen" do + @cookbook_version.freeze_version + @cookbook_version.should be_frozen_version + end + + it "is \"ready\"" do + # WTF is this? what are the valid states? and why aren't they set with encapsulating methods? + # [Dan 15-Jul-2010] + @cookbook_version.status.should == :ready + end + + it "has empty metadata" do + @cookbook_version.metadata.should == Chef::Cookbook::Metadata.new + end + + it "creates a manifest hash of its contents" do + expected = {"recipes"=>[], + "definitions"=>[], + "libraries"=>[], + "attributes"=>[], + "files"=>[], + "templates"=>[], + "resources"=>[], + "providers"=>[], + "root_files"=>[], + "cookbook_name"=>"tatft", + "metadata"=>Chef::Cookbook::Metadata.new, + "version"=>"0.0.0", + "name"=>"tatft-0.0.0"} + @cookbook_version.manifest.should == expected + end + end + + describe "after the cookbook has been loaded" do + MD5 = /[0-9a-f]{32}/ + + before do + # Currently the cookbook loader finds all the files then tells CookbookVersion + # where they are. + @cookbook_version = Chef::CookbookVersion.new("tatft") + + @cookbook = Hash.new { |hash, key| hash[key] = [] } + + cookbook_root = File.join(CHEF_SPEC_DATA, 'cb_version_cookbooks', 'tatft') + + # Dunno if the paths here are representitive of what is set by CookbookLoader... + @cookbook[:attribute_filenames] = Dir[File.join(cookbook_root, 'attributes', '**', '*.rb')] + @cookbook[:definition_filenames] = Dir[File.join(cookbook_root, 'definitions', '**', '*.rb')] + @cookbook[:file_filenames] = Dir[File.join(cookbook_root, 'files', '**', '*.tgz')] + @cookbook[:recipe_filenames] = Dir[File.join(cookbook_root, 'recipes', '**', '*.rb')] + @cookbook[:template_filenames] = Dir[File.join(cookbook_root, 'templates', '**', '*.erb')] + @cookbook[:library_filenames] = Dir[File.join(cookbook_root, 'libraries', '**', '*.rb')] + @cookbook[:resource_filenames] = Dir[File.join(cookbook_root, 'resources', '**', '*.rb')] + @cookbook[:provider_filenames] = Dir[File.join(cookbook_root, 'providers', '**', '*.rb')] + @cookbook[:root_filenames] = Array(File.join(cookbook_root, 'README.rdoc')) + @cookbook[:metadata_filenames] = Array(File.join(cookbook_root, 'metadata.json')) + + @cookbook_version.attribute_filenames = @cookbook[:attribute_filenames] + @cookbook_version.definition_filenames = @cookbook[:definition_filenames] + @cookbook_version.recipe_filenames = @cookbook[:recipe_filenames] + @cookbook_version.template_filenames = @cookbook[:template_filenames] + @cookbook_version.file_filenames = @cookbook[:file_filenames] + @cookbook_version.library_filenames = @cookbook[:library_filenames] + @cookbook_version.resource_filenames = @cookbook[:resource_filenames] + @cookbook_version.provider_filenames = @cookbook[:provider_filenames] + @cookbook_version.root_filenames = @cookbook[:root_filenames] + @cookbook_version.metadata_filenames = @cookbook[:metadata_filenames] + end + + it "generates a manifest containing the cookbook's files" do + manifest = @cookbook_version.manifest + + manifest["metadata"].should == Chef::Cookbook::Metadata.new + manifest["cookbook_name"].should == "tatft" + + manifest["recipes"].should have(1).recipe_file + + recipe = manifest["recipes"].first + recipe["name"].should == "default.rb" + recipe["path"].should == "recipes/default.rb" + recipe["checksum"].should match(MD5) + recipe["specificity"].should == "default" + + manifest["definitions"].should have(1).definition_file + + definition = manifest["definitions"].first + definition["name"].should == "runit_service.rb" + definition["path"].should == "definitions/runit_service.rb" + definition["checksum"].should match(MD5) + definition["specificity"].should == "default" + + manifest["libraries"].should have(1).library_file + + library = manifest["libraries"].first + library["name"].should == "ownage.rb" + library["path"].should == "libraries/ownage.rb" + library["checksum"].should match(MD5) + library["specificity"].should == "default" + + manifest["attributes"].should have(1).attribute_file + + attribute_file = manifest["attributes"].first + attribute_file["name"].should == "default.rb" + attribute_file["path"].should == "attributes/default.rb" + attribute_file["checksum"].should match(MD5) + attribute_file["specificity"].should == "default" + + manifest["files"].should have(1).cookbook_file + + cookbook_file = manifest["files"].first + cookbook_file["name"].should == "giant_blob.tgz" + cookbook_file["path"].should == "files/default/giant_blob.tgz" + cookbook_file["checksum"].should match(MD5) + cookbook_file["specificity"].should == "default" + + manifest["templates"].should have(1).template + + template = manifest["templates"].first + template["name"].should == "configuration.erb" + template["path"].should == "templates/default/configuration.erb" + template["checksum"].should match(MD5) + template["specificity"].should == "default" + + manifest["resources"].should have(1).lwr + + lwr = manifest["resources"].first + lwr["name"].should == "lwr.rb" + lwr["path"].should == "resources/lwr.rb" + lwr["checksum"].should match(MD5) + lwr["specificity"].should == "default" + + manifest["providers"].should have(1).lwp + + lwp = manifest["providers"].first + lwp["name"].should == "lwp.rb" + lwp["path"].should == "providers/lwp.rb" + lwp["checksum"].should match(MD5) + lwp["specificity"].should == "default" + + manifest["root_files"].should have(1).file_in_the_cookbook_root + + readme = manifest["root_files"].first + readme["name"].should == "README.rdoc" + readme["path"].should == "README.rdoc" + readme["checksum"].should match(MD5) + readme["specificity"].should == "default" + end + + describe "raises an error when attempting to load a missing cookbook_file and" do + before do + node = Chef::Node.new.tap do |n| + n.name("sample.node") + n.automatic_attrs[:fqdn] = "sample.example.com" + n.automatic_attrs[:platform] = "ubuntu" + n.automatic_attrs[:platform_version] = "10.04" + end + @attempt_to_load_file = lambda { @cookbook_version.preferred_manifest_record(node, :files, "no-such-thing.txt") } + end + + it "describes the cookbook and version" do + useful_explanation = Regexp.new(Regexp.escape("Cookbook 'tatft' (0.0.0) does not contain")) + @attempt_to_load_file.should raise_error(Chef::Exceptions::FileNotFound, useful_explanation) + end + + it "lists suggested places to look" do + useful_explanation = Regexp.new(Regexp.escape("files/default/no-such-thing.txt")) + @attempt_to_load_file.should raise_error(Chef::Exceptions::FileNotFound, useful_explanation) + end + end + + end + + + describe "<=>" do + + it "should sort based on the version number" do + examples = [ + # smaller, larger + ["1.0", "2.0"], + ["1.2.3", "1.2.4"], + ["1.2.3", "1.3.0"], + ["1.2.3", "1.3"], + ["1.2.3", "2.1.1"], + ["1.2.3", "2.1"], + ["1.2", "1.2.4"], + ["1.2", "1.3.0"], + ["1.2", "1.3"], + ["1.2", "2.1.1"], + ["1.2", "2.1"] + ] + examples.each do |smaller, larger| + sm = Chef::CookbookVersion.new("foo") + lg = Chef::CookbookVersion.new("foo") + sm.version = smaller + lg.version = larger + sm.should be < lg + lg.should be > sm + sm.should_not == lg + end + end + + it "should equate versions 1.2 and 1.2.0" do + a = Chef::CookbookVersion.new("foo") + b = Chef::CookbookVersion.new("foo") + a.version = "1.2" + b.version = "1.2.0" + a.should == b + end + + + it "should not allow you to sort cookbooks with different names" do + apt = Chef::CookbookVersion.new "apt" + apt.version = "1.0" + god = Chef::CookbookVersion.new "god" + god.version = "2.0" + lambda {apt <=> god}.should raise_error(Chef::Exceptions::CookbookVersionNameMismatch) + end + end + + describe "when you set a version" do + before do + @cbv = Chef::CookbookVersion.new("version validation") + end + it "should accept valid cookbook versions" do + good_versions = %w(1.2 1.2.3 1000.80.50000 0.300.25) + good_versions.each do |v| + @cbv.version = v + end + end + + it "should raise InvalidVersion for bad cookbook versions" do + bad_versions = ["1.2.3.4", "1.2.a4", "1", "a", "1.2 3", "1.2 a", + "1 2 3", "1-2-3", "1_2_3", "1.2_3", "1.2-3"] + the_error = Chef::Exceptions::InvalidCookbookVersion + bad_versions.each do |v| + lambda {@cbv.version = v}.should raise_error(the_error) + end + end + + end + +end |