berkshelf 0.1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/.gitignore +20 -0
- data/.rbenv-version +1 -0
- data/Gemfile +3 -0
- data/Guardfile +23 -0
- data/LICENSE +22 -0
- data/README.rdoc +102 -0
- data/Thorfile +47 -0
- data/berkshelf.gemspec +39 -0
- data/features/config.sample.yml +3 -0
- data/features/init_command.feature +40 -0
- data/features/install.feature +55 -0
- data/features/lockfile.feature +22 -0
- data/features/step_definitions/chef_server_steps.rb +13 -0
- data/features/step_definitions/cli_steps.rb +56 -0
- data/features/step_definitions/filesystem_steps.rb +79 -0
- data/features/support/env.rb +55 -0
- data/features/update.feature +23 -0
- data/features/upload_command.feature +43 -0
- data/features/without.feature +25 -0
- data/lib/berkshelf.rb +90 -0
- data/lib/berkshelf/berksfile.rb +170 -0
- data/lib/berkshelf/cached_cookbook.rb +253 -0
- data/lib/berkshelf/cookbook_source.rb +139 -0
- data/lib/berkshelf/cookbook_source/git_location.rb +54 -0
- data/lib/berkshelf/cookbook_source/path_location.rb +27 -0
- data/lib/berkshelf/cookbook_source/site_location.rb +206 -0
- data/lib/berkshelf/cookbook_store.rb +77 -0
- data/lib/berkshelf/core_ext.rb +3 -0
- data/lib/berkshelf/core_ext/file.rb +14 -0
- data/lib/berkshelf/core_ext/kernel.rb +33 -0
- data/lib/berkshelf/core_ext/pathname.rb +24 -0
- data/lib/berkshelf/downloader.rb +92 -0
- data/lib/berkshelf/dsl.rb +39 -0
- data/lib/berkshelf/errors.rb +20 -0
- data/lib/berkshelf/generator_files/Berksfile.erb +3 -0
- data/lib/berkshelf/generator_files/chefignore +44 -0
- data/lib/berkshelf/git.rb +70 -0
- data/lib/berkshelf/init_generator.rb +38 -0
- data/lib/berkshelf/lockfile.rb +42 -0
- data/lib/berkshelf/resolver.rb +176 -0
- data/lib/berkshelf/tx_result.rb +12 -0
- data/lib/berkshelf/tx_result_set.rb +37 -0
- data/lib/berkshelf/uploader.rb +153 -0
- data/lib/berkshelf/version.rb +3 -0
- data/lib/chef/knife/berks_init.rb +29 -0
- data/lib/chef/knife/berks_install.rb +27 -0
- data/lib/chef/knife/berks_update.rb +23 -0
- data/lib/chef/knife/berks_upload.rb +39 -0
- data/spec/fixtures/Berksfile +3 -0
- data/spec/fixtures/cookbooks/example_cookbook-0.5.0/README.md +12 -0
- data/spec/fixtures/cookbooks/example_cookbook-0.5.0/metadata.rb +6 -0
- data/spec/fixtures/cookbooks/example_cookbook-0.5.0/recipes/default.rb +8 -0
- data/spec/fixtures/cookbooks/example_cookbook/README.md +12 -0
- data/spec/fixtures/cookbooks/example_cookbook/metadata.rb +6 -0
- data/spec/fixtures/cookbooks/example_cookbook/recipes/default.rb +8 -0
- data/spec/fixtures/cookbooks/invalid_ruby_files-1.0.0/recipes/default.rb +1 -0
- data/spec/fixtures/cookbooks/invalid_template_files-1.0.0/templates/default/broken.erb +1 -0
- data/spec/fixtures/cookbooks/nginx-0.100.5/README.md +77 -0
- data/spec/fixtures/cookbooks/nginx-0.100.5/attributes/default.rb +65 -0
- data/spec/fixtures/cookbooks/nginx-0.100.5/definitions/nginx_site.rb +35 -0
- data/spec/fixtures/cookbooks/nginx-0.100.5/files/default/mime.types +73 -0
- data/spec/fixtures/cookbooks/nginx-0.100.5/files/ubuntu/mime.types +73 -0
- data/spec/fixtures/cookbooks/nginx-0.100.5/libraries/nginxlib.rb +1 -0
- data/spec/fixtures/cookbooks/nginx-0.100.5/metadata.rb +91 -0
- data/spec/fixtures/cookbooks/nginx-0.100.5/providers/defprovider.rb +1 -0
- data/spec/fixtures/cookbooks/nginx-0.100.5/recipes/default.rb +59 -0
- data/spec/fixtures/cookbooks/nginx-0.100.5/resources/defresource.rb +1 -0
- data/spec/fixtures/cookbooks/nginx-0.100.5/templates/default/nginx.pill.erb +15 -0
- data/spec/fixtures/cookbooks/nginx-0.100.5/templates/default/plugins/nginx.rb.erb +66 -0
- data/spec/fixtures/lockfile_spec/with_lock/Berksfile +1 -0
- data/spec/fixtures/lockfile_spec/without_lock/Berksfile.lock +5 -0
- data/spec/spec_helper.rb +92 -0
- data/spec/support/chef_api.rb +27 -0
- data/spec/support/matchers/file_system_matchers.rb +115 -0
- data/spec/support/matchers/filepath_matchers.rb +19 -0
- data/spec/unit/berkshelf/cached_cookbook_spec.rb +420 -0
- data/spec/unit/berkshelf/cookbook_source/git_location_spec.rb +59 -0
- data/spec/unit/berkshelf/cookbook_source/path_location_spec.rb +34 -0
- data/spec/unit/berkshelf/cookbook_source/site_location_spec.rb +166 -0
- data/spec/unit/berkshelf/cookbook_source_spec.rb +194 -0
- data/spec/unit/berkshelf/cookbook_store_spec.rb +71 -0
- data/spec/unit/berkshelf/cookbookfile_spec.rb +160 -0
- data/spec/unit/berkshelf/downloader_spec.rb +82 -0
- data/spec/unit/berkshelf/dsl_spec.rb +42 -0
- data/spec/unit/berkshelf/git_spec.rb +63 -0
- data/spec/unit/berkshelf/init_generator_spec.rb +52 -0
- data/spec/unit/berkshelf/lockfile_spec.rb +25 -0
- data/spec/unit/berkshelf/resolver_spec.rb +126 -0
- data/spec/unit/berkshelf/tx_result_set_spec.rb +77 -0
- data/spec/unit/berkshelf/tx_result_spec.rb +21 -0
- data/spec/unit/berkshelf/uploader_spec.rb +71 -0
- data/spec/unit/berkshelf_spec.rb +29 -0
- metadata +411 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
cookbook 'nginx', '= 0.101.0'
|
data/spec/spec_helper.rb
ADDED
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
require 'rubygems'
|
|
2
|
+
require 'bundler'
|
|
3
|
+
require 'spork'
|
|
4
|
+
require 'vcr'
|
|
5
|
+
|
|
6
|
+
Spork.prefork do
|
|
7
|
+
require 'rspec'
|
|
8
|
+
require 'simplecov'
|
|
9
|
+
require 'pp'
|
|
10
|
+
require 'json_spec'
|
|
11
|
+
require 'webmock/rspec'
|
|
12
|
+
|
|
13
|
+
APP_ROOT = File.expand_path('../../', __FILE__)
|
|
14
|
+
|
|
15
|
+
Dir[File.join(APP_ROOT, "spec/support/**/*.rb")].each {|f| require f}
|
|
16
|
+
|
|
17
|
+
VCR.configure do |c|
|
|
18
|
+
c.cassette_library_dir = File.join(File.dirname(__FILE__), 'fixtures', 'vcr_cassettes')
|
|
19
|
+
c.hook_into :webmock
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
RSpec.configure do |config|
|
|
23
|
+
config.include Berkshelf::RSpec::FileSystemMatchers
|
|
24
|
+
config.include JsonSpec::Helpers
|
|
25
|
+
|
|
26
|
+
config.mock_with :rspec
|
|
27
|
+
config.treat_symbols_as_metadata_keys_with_true_values = true
|
|
28
|
+
config.filter_run :focus => true
|
|
29
|
+
config.run_all_when_everything_filtered = true
|
|
30
|
+
|
|
31
|
+
config.around do |example|
|
|
32
|
+
# Dynamically create cassettes based on the name of the example
|
|
33
|
+
# being run. This creates a new cassette for every test.
|
|
34
|
+
cur = example.metadata
|
|
35
|
+
identifiers = [example.metadata[:description_args]]
|
|
36
|
+
while cur = cur[:example_group] do
|
|
37
|
+
identifiers << cur[:description_args]
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
VCR.use_cassette(identifiers.reverse.join(' ')) do
|
|
41
|
+
example.run
|
|
42
|
+
end
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
config.before(:each) do
|
|
46
|
+
clean_tmp_path
|
|
47
|
+
Berkshelf.cookbook_store = Berkshelf::CookbookStore.new(tmp_path.join("downloader_tmp"))
|
|
48
|
+
end
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
SimpleCov.start do
|
|
52
|
+
add_filter 'spec/'
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
def capture(stream)
|
|
56
|
+
begin
|
|
57
|
+
stream = stream.to_s
|
|
58
|
+
eval "$#{stream} = StringIO.new"
|
|
59
|
+
yield
|
|
60
|
+
result = eval("$#{stream}").string
|
|
61
|
+
ensure
|
|
62
|
+
eval("$#{stream} = #{stream.upcase}")
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
result
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
def example_cookbook_from_path
|
|
69
|
+
@example_cookbook_from_path ||= Berkshelf::Cookbook.new('example_cookbook', path: File.join(File.dirname(__FILE__), 'fixtures', 'cookbooks'))
|
|
70
|
+
end
|
|
71
|
+
|
|
72
|
+
def app_root_path
|
|
73
|
+
Pathname.new(APP_ROOT)
|
|
74
|
+
end
|
|
75
|
+
|
|
76
|
+
def tmp_path
|
|
77
|
+
app_root_path.join('spec/tmp')
|
|
78
|
+
end
|
|
79
|
+
|
|
80
|
+
def fixtures_path
|
|
81
|
+
app_root_path.join('spec/fixtures')
|
|
82
|
+
end
|
|
83
|
+
|
|
84
|
+
def clean_tmp_path
|
|
85
|
+
FileUtils.rm_rf(tmp_path)
|
|
86
|
+
FileUtils.mkdir_p(tmp_path)
|
|
87
|
+
end
|
|
88
|
+
end
|
|
89
|
+
|
|
90
|
+
Spork.each_run do
|
|
91
|
+
require 'berkshelf'
|
|
92
|
+
end
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
require 'chef/rest'
|
|
2
|
+
require 'chef/cookbook_version'
|
|
3
|
+
|
|
4
|
+
module Berkshelf
|
|
5
|
+
module RSpec
|
|
6
|
+
module ChefAPI
|
|
7
|
+
def purge_cookbook(name, version)
|
|
8
|
+
rest.delete_rest("cookbooks/#{name}/#{version}?purge=true")
|
|
9
|
+
rescue Net::HTTPServerException => e
|
|
10
|
+
raise unless e.to_s =~ /^404/
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
def server_has_cookbook?(name, version)
|
|
14
|
+
rest.get_rest("cookbooks/#{name}/#{version}")
|
|
15
|
+
true
|
|
16
|
+
rescue Net::HTTPServerException => e
|
|
17
|
+
false
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
private
|
|
21
|
+
|
|
22
|
+
def rest
|
|
23
|
+
quietly { Chef::REST.new(Chef::Config[:chef_server_url]) }
|
|
24
|
+
end
|
|
25
|
+
end
|
|
26
|
+
end
|
|
27
|
+
end
|
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
# Taken from (https://github.com/carlhuda/beard)
|
|
2
|
+
# Permission granted by Yehuda Katz (Jan 4th, 2012)
|
|
3
|
+
module Berkshelf
|
|
4
|
+
module RSpec
|
|
5
|
+
module FileSystemMatchers
|
|
6
|
+
class File
|
|
7
|
+
def initialize(name, &block)
|
|
8
|
+
@contents = []
|
|
9
|
+
@name = name
|
|
10
|
+
|
|
11
|
+
if block_given?
|
|
12
|
+
instance_eval(&block)
|
|
13
|
+
end
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
def contains(text)
|
|
17
|
+
@contents << text
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
def matches?(root)
|
|
21
|
+
unless root.join(@name).exist?
|
|
22
|
+
throw :failure, root.join(@name)
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
contents = ::File.read(root.join(@name))
|
|
26
|
+
|
|
27
|
+
@contents.each do |string|
|
|
28
|
+
unless contents.include?(string)
|
|
29
|
+
throw :failure, [root.join(@name), string, contents]
|
|
30
|
+
end
|
|
31
|
+
end
|
|
32
|
+
end
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
class Directory
|
|
36
|
+
attr_reader :tree
|
|
37
|
+
|
|
38
|
+
def initialize(root = nil, &block)
|
|
39
|
+
@tree = {}
|
|
40
|
+
@negative_tree = []
|
|
41
|
+
@root = root
|
|
42
|
+
instance_eval(&block) if block_given?
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
def directory(name, &block)
|
|
46
|
+
@tree[name] = block_given? && Directory.new(location(name), &block)
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
def file(name, &block)
|
|
50
|
+
@tree[name] = File.new(location(name), &block)
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
def no_file(name)
|
|
54
|
+
@negative_tree << name
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
def location(name)
|
|
58
|
+
[@root, name].compact.join("/")
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
def matches?(root)
|
|
62
|
+
@tree.each do |file, value|
|
|
63
|
+
unless value
|
|
64
|
+
unless root.join(location(file)).exist?
|
|
65
|
+
throw :failure, "#{root}/#{location(file)}"
|
|
66
|
+
end
|
|
67
|
+
else
|
|
68
|
+
value.matches?(root)
|
|
69
|
+
end
|
|
70
|
+
end
|
|
71
|
+
|
|
72
|
+
@negative_tree.each do |file|
|
|
73
|
+
if root.join(location(file)).exist?
|
|
74
|
+
throw :failure, [:not, "unexpected #{root}/#{location(file)}"]
|
|
75
|
+
end
|
|
76
|
+
end
|
|
77
|
+
|
|
78
|
+
nil
|
|
79
|
+
end
|
|
80
|
+
end
|
|
81
|
+
|
|
82
|
+
class Root < Directory
|
|
83
|
+
def failure_message
|
|
84
|
+
if @failure.is_a?(Array) && @failure[0] == :not
|
|
85
|
+
"Structure should not have had #{@failure[1]}, but it did"
|
|
86
|
+
elsif @failure.is_a?(Array)
|
|
87
|
+
"Structure should have #{@failure[0]} with #{@failure[1]}. It had:\n#{@failure[2]}"
|
|
88
|
+
else
|
|
89
|
+
"Structure should have #{@failure}, but it didn't"
|
|
90
|
+
end
|
|
91
|
+
end
|
|
92
|
+
|
|
93
|
+
def negative_failure_message
|
|
94
|
+
if @failure.is_a?(Array) && @failure[0] == :not
|
|
95
|
+
"Structure had #{@failure}, but it shouldn't have"
|
|
96
|
+
else
|
|
97
|
+
"Structure had #{@failure}, but it shouldn't have"
|
|
98
|
+
end
|
|
99
|
+
end
|
|
100
|
+
|
|
101
|
+
def matches?(root)
|
|
102
|
+
@failure = catch :failure do
|
|
103
|
+
super
|
|
104
|
+
end
|
|
105
|
+
|
|
106
|
+
!@failure
|
|
107
|
+
end
|
|
108
|
+
end
|
|
109
|
+
|
|
110
|
+
def have_structure(&block)
|
|
111
|
+
Root.new(&block)
|
|
112
|
+
end
|
|
113
|
+
end
|
|
114
|
+
end
|
|
115
|
+
end
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
require 'pathname'
|
|
2
|
+
|
|
3
|
+
RSpec::Matchers.define :be_relative_path do
|
|
4
|
+
match do |given|
|
|
5
|
+
if given.nil?
|
|
6
|
+
false
|
|
7
|
+
else
|
|
8
|
+
Pathname.new(given).relative?
|
|
9
|
+
end
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
failure_message_for_should do |given|
|
|
13
|
+
"Expected '#{given}' to be a relative path but got an absolute path."
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
failure_message_for_should_not do |given|
|
|
17
|
+
"Expected '#{given}' to not be a relative path but got an absolute path."
|
|
18
|
+
end
|
|
19
|
+
end
|
|
@@ -0,0 +1,420 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
|
|
3
|
+
module Berkshelf
|
|
4
|
+
describe CachedCookbook do
|
|
5
|
+
describe "ClassMethods" do
|
|
6
|
+
subject { CachedCookbook }
|
|
7
|
+
|
|
8
|
+
describe "#from_path" do
|
|
9
|
+
before(:each) do
|
|
10
|
+
@cached_cb = subject.from_path(fixtures_path.join("cookbooks", "example_cookbook-0.5.0"))
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
it "returns an instance of CachedCookbook" do
|
|
14
|
+
@cached_cb.should be_a(CachedCookbook)
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
it "sets a version number" do
|
|
18
|
+
@cached_cb.version.should eql("0.5.0")
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
context "given a path that does not contain a cookbook" do
|
|
22
|
+
it "returns nil" do
|
|
23
|
+
subject.from_path(tmp_path).should be_nil
|
|
24
|
+
end
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
context "given a path that does not match the CachedCookbook dirname format" do
|
|
28
|
+
it "returns nil" do
|
|
29
|
+
subject.from_path(fixtures_path.join("cookbooks", "example_cookbook")).should be_nil
|
|
30
|
+
end
|
|
31
|
+
end
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
describe "#checksum" do
|
|
35
|
+
it "returns a checksum of the given filepath" do
|
|
36
|
+
subject.checksum(fixtures_path.join("cookbooks", "example_cookbook-0.5.0", "README.md")).should eql("6e21094b7a920e374e7261f50e9c4eef")
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
context "given path does not exist" do
|
|
40
|
+
it "raises an Errno::ENOENT error" do
|
|
41
|
+
lambda {
|
|
42
|
+
subject.checksum(fixtures_path.join("notexisting.file"))
|
|
43
|
+
}.should raise_error(Errno::ENOENT)
|
|
44
|
+
end
|
|
45
|
+
end
|
|
46
|
+
end
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
let(:cb_path) { fixtures_path.join("cookbooks", "nginx-0.100.5") }
|
|
50
|
+
subject { CachedCookbook.from_path(cb_path) }
|
|
51
|
+
|
|
52
|
+
describe "#checksums" do
|
|
53
|
+
it "returns a Hash containing an entry for all matching cookbook files on disk" do
|
|
54
|
+
subject.checksums.should have(11).items
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
it "has a checksum for each key" do
|
|
58
|
+
subject.checksums.should have_key("fb1f925dcd5fc4ebf682c4442a21c619")
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
it "has a filepath for each value" do
|
|
62
|
+
subject.checksums.should have_value(cb_path.join("recipes/default.rb").to_s)
|
|
63
|
+
end
|
|
64
|
+
end
|
|
65
|
+
|
|
66
|
+
describe "#manifest" do
|
|
67
|
+
it "returns a Mash with a key for each cookbook file category" do
|
|
68
|
+
[
|
|
69
|
+
:recipes,
|
|
70
|
+
:definitions,
|
|
71
|
+
:libraries,
|
|
72
|
+
:attributes,
|
|
73
|
+
:files,
|
|
74
|
+
:templates,
|
|
75
|
+
:resources,
|
|
76
|
+
:providers,
|
|
77
|
+
:root_files
|
|
78
|
+
].each do |category|
|
|
79
|
+
subject.manifest.should have_key(category)
|
|
80
|
+
end
|
|
81
|
+
end
|
|
82
|
+
end
|
|
83
|
+
|
|
84
|
+
describe "#validate!" do
|
|
85
|
+
it "returns true if the cookbook of the given name and version is valid" do
|
|
86
|
+
@cb = CachedCookbook.from_path(fixtures_path.join("cookbooks", "example_cookbook-0.5.0"))
|
|
87
|
+
|
|
88
|
+
@cb.validate!.should be_true
|
|
89
|
+
end
|
|
90
|
+
|
|
91
|
+
it "raises CookbookSyntaxError if the cookbook contains invalid ruby files" do
|
|
92
|
+
@cb = CachedCookbook.from_path(fixtures_path.join("cookbooks", "invalid_ruby_files-1.0.0"))
|
|
93
|
+
|
|
94
|
+
lambda {
|
|
95
|
+
@cb.validate!
|
|
96
|
+
}.should raise_error(CookbookSyntaxError)
|
|
97
|
+
end
|
|
98
|
+
|
|
99
|
+
it "raises CookbookSyntaxError if the cookbook contains invalid template files" do
|
|
100
|
+
@cb = CachedCookbook.from_path(fixtures_path.join("cookbooks", "invalid_template_files-1.0.0"))
|
|
101
|
+
|
|
102
|
+
lambda {
|
|
103
|
+
@cb.validate!
|
|
104
|
+
}.should raise_error(CookbookSyntaxError)
|
|
105
|
+
end
|
|
106
|
+
end
|
|
107
|
+
|
|
108
|
+
describe "#file_metadata" do
|
|
109
|
+
let(:file) { subject.path.join("files", "default", "mime.types") }
|
|
110
|
+
|
|
111
|
+
before(:each) { @metadata = subject.file_metadata(:file, file) }
|
|
112
|
+
|
|
113
|
+
it "has a 'path' key whose value is a relative path from the CachedCookbook's path" do
|
|
114
|
+
@metadata.should have_key(:path)
|
|
115
|
+
@metadata[:path].should be_relative_path
|
|
116
|
+
@metadata[:path].should eql("files/default/mime.types")
|
|
117
|
+
end
|
|
118
|
+
|
|
119
|
+
it "has a 'name' key whose value is the basename of the target file" do
|
|
120
|
+
@metadata.should have_key(:name)
|
|
121
|
+
@metadata[:name].should eql("mime.types")
|
|
122
|
+
end
|
|
123
|
+
|
|
124
|
+
it "has a 'checksum' key whose value is the checksum of the target file" do
|
|
125
|
+
@metadata.should have_key(:checksum)
|
|
126
|
+
@metadata[:checksum].should eql("06e7eca1d6cb608e2e74fd1f8e059f34")
|
|
127
|
+
end
|
|
128
|
+
|
|
129
|
+
it "has a 'specificity' key" do
|
|
130
|
+
@metadata.should have_key(:specificity)
|
|
131
|
+
end
|
|
132
|
+
|
|
133
|
+
context "given a 'template' or 'file' berksfile type" do
|
|
134
|
+
let(:file) { subject.path.join("files", "ubuntu", "mime.types") }
|
|
135
|
+
before(:each) { @metadata = subject.file_metadata(:files, file) }
|
|
136
|
+
|
|
137
|
+
it "has a 'specificity' key whose value represents the specificity found in filepath" do
|
|
138
|
+
@metadata[:specificity].should eql("ubuntu")
|
|
139
|
+
end
|
|
140
|
+
end
|
|
141
|
+
|
|
142
|
+
context "given any berksfile type that is not a 'template' or 'file'" do
|
|
143
|
+
let(:file) { subject.path.join("README.md") }
|
|
144
|
+
before(:each) { @metadata = subject.file_metadata(:root, file) }
|
|
145
|
+
|
|
146
|
+
it "has a 'specificity' key whose value is 'default'" do
|
|
147
|
+
@metadata[:specificity].should eql("default")
|
|
148
|
+
end
|
|
149
|
+
end
|
|
150
|
+
end
|
|
151
|
+
|
|
152
|
+
describe "#to_hash" do
|
|
153
|
+
before(:each) do
|
|
154
|
+
@hash = subject.to_hash
|
|
155
|
+
end
|
|
156
|
+
|
|
157
|
+
let(:cookbook_name) { subject.cookbook_name }
|
|
158
|
+
let(:cookbook_version) { subject.version }
|
|
159
|
+
|
|
160
|
+
it "has a 'recipes' key with a value of an Array Hashes" do
|
|
161
|
+
@hash.should have_key('recipes')
|
|
162
|
+
@hash['recipes'].should be_a(Array)
|
|
163
|
+
@hash['recipes'].each do |item|
|
|
164
|
+
item.should be_a(Hash)
|
|
165
|
+
end
|
|
166
|
+
end
|
|
167
|
+
|
|
168
|
+
it "has a 'name' key value pair in a Hash of the 'recipes' Array of Hashes" do
|
|
169
|
+
@hash['recipes'].first.should have_key('name')
|
|
170
|
+
end
|
|
171
|
+
|
|
172
|
+
it "has a 'path' key value pair in a Hash of the 'recipes' Array of Hashes" do
|
|
173
|
+
@hash['recipes'].first.should have_key('path')
|
|
174
|
+
end
|
|
175
|
+
|
|
176
|
+
it "has a 'checksum' key value pair in a Hash of the 'recipes' Array of Hashes" do
|
|
177
|
+
@hash['recipes'].first.should have_key('checksum')
|
|
178
|
+
end
|
|
179
|
+
|
|
180
|
+
it "has a 'specificity' key value pair in a Hash of the 'recipes' Array of Hashes" do
|
|
181
|
+
@hash['recipes'].first.should have_key('specificity')
|
|
182
|
+
end
|
|
183
|
+
|
|
184
|
+
it "has a 'definitions' key with a value of an Array Hashes" do
|
|
185
|
+
@hash.should have_key('definitions')
|
|
186
|
+
@hash['definitions'].should be_a(Array)
|
|
187
|
+
@hash['definitions'].each do |item|
|
|
188
|
+
item.should be_a(Hash)
|
|
189
|
+
end
|
|
190
|
+
end
|
|
191
|
+
|
|
192
|
+
it "has a 'name' key value pair in a Hash of the 'definitions' Array of Hashes" do
|
|
193
|
+
@hash['definitions'].first.should have_key('name')
|
|
194
|
+
end
|
|
195
|
+
|
|
196
|
+
it "has a 'path' key value pair in a Hash of the 'definitions' Array of Hashes" do
|
|
197
|
+
@hash['definitions'].first.should have_key('path')
|
|
198
|
+
end
|
|
199
|
+
|
|
200
|
+
it "has a 'checksum' key value pair in a Hash of the 'definitions' Array of Hashes" do
|
|
201
|
+
@hash['definitions'].first.should have_key('checksum')
|
|
202
|
+
end
|
|
203
|
+
|
|
204
|
+
it "has a 'specificity' key value pair in a Hash of the 'definitions' Array of Hashes" do
|
|
205
|
+
@hash['definitions'].first.should have_key('specificity')
|
|
206
|
+
end
|
|
207
|
+
|
|
208
|
+
it "has a 'libraries' key with a value of an Array Hashes" do
|
|
209
|
+
@hash.should have_key('libraries')
|
|
210
|
+
@hash['libraries'].should be_a(Array)
|
|
211
|
+
@hash['libraries'].each do |item|
|
|
212
|
+
item.should be_a(Hash)
|
|
213
|
+
end
|
|
214
|
+
end
|
|
215
|
+
|
|
216
|
+
it "has a 'name' key value pair in a Hash of the 'libraries' Array of Hashes" do
|
|
217
|
+
@hash['libraries'].first.should have_key('name')
|
|
218
|
+
end
|
|
219
|
+
|
|
220
|
+
it "has a 'path' key value pair in a Hash of the 'libraries' Array of Hashes" do
|
|
221
|
+
@hash['libraries'].first.should have_key('path')
|
|
222
|
+
end
|
|
223
|
+
|
|
224
|
+
it "has a 'checksum' key value pair in a Hash of the 'libraries' Array of Hashes" do
|
|
225
|
+
@hash['libraries'].first.should have_key('checksum')
|
|
226
|
+
end
|
|
227
|
+
|
|
228
|
+
it "has a 'specificity' key value pair in a Hash of the 'libraries' Array of Hashes" do
|
|
229
|
+
@hash['libraries'].first.should have_key('specificity')
|
|
230
|
+
end
|
|
231
|
+
|
|
232
|
+
it "has a 'attributes' key with a value of an Array Hashes" do
|
|
233
|
+
@hash.should have_key('attributes')
|
|
234
|
+
@hash['attributes'].should be_a(Array)
|
|
235
|
+
@hash['attributes'].each do |item|
|
|
236
|
+
item.should be_a(Hash)
|
|
237
|
+
end
|
|
238
|
+
end
|
|
239
|
+
|
|
240
|
+
it "has a 'name' key value pair in a Hash of the 'attributes' Array of Hashes" do
|
|
241
|
+
@hash['attributes'].first.should have_key('name')
|
|
242
|
+
end
|
|
243
|
+
|
|
244
|
+
it "has a 'path' key value pair in a Hash of the 'attributes' Array of Hashes" do
|
|
245
|
+
@hash['attributes'].first.should have_key('path')
|
|
246
|
+
end
|
|
247
|
+
|
|
248
|
+
it "has a 'checksum' key value pair in a Hash of the 'attributes' Array of Hashes" do
|
|
249
|
+
@hash['attributes'].first.should have_key('checksum')
|
|
250
|
+
end
|
|
251
|
+
|
|
252
|
+
it "has a 'specificity' key value pair in a Hash of the 'attributes' Array of Hashes" do
|
|
253
|
+
@hash['attributes'].first.should have_key('specificity')
|
|
254
|
+
end
|
|
255
|
+
|
|
256
|
+
it "has a 'files' key with a value of an Array Hashes" do
|
|
257
|
+
@hash.should have_key('files')
|
|
258
|
+
@hash['files'].should be_a(Array)
|
|
259
|
+
@hash['files'].each do |item|
|
|
260
|
+
item.should be_a(Hash)
|
|
261
|
+
end
|
|
262
|
+
end
|
|
263
|
+
|
|
264
|
+
it "has a 'name' key value pair in a Hash of the 'files' Array of Hashes" do
|
|
265
|
+
@hash['files'].first.should have_key('name')
|
|
266
|
+
end
|
|
267
|
+
|
|
268
|
+
it "has a 'path' key value pair in a Hash of the 'files' Array of Hashes" do
|
|
269
|
+
@hash['files'].first.should have_key('path')
|
|
270
|
+
end
|
|
271
|
+
|
|
272
|
+
it "has a 'checksum' key value pair in a Hash of the 'files' Array of Hashes" do
|
|
273
|
+
@hash['files'].first.should have_key('checksum')
|
|
274
|
+
end
|
|
275
|
+
|
|
276
|
+
it "has a 'specificity' key value pair in a Hash of the 'files' Array of Hashes" do
|
|
277
|
+
@hash['files'].first.should have_key('specificity')
|
|
278
|
+
end
|
|
279
|
+
|
|
280
|
+
it "has a 'templates' key with a value of an Array Hashes" do
|
|
281
|
+
@hash.should have_key('templates')
|
|
282
|
+
@hash['templates'].should be_a(Array)
|
|
283
|
+
@hash['templates'].each do |item|
|
|
284
|
+
item.should be_a(Hash)
|
|
285
|
+
end
|
|
286
|
+
end
|
|
287
|
+
|
|
288
|
+
it "has a 'name' key value pair in a Hash of the 'templates' Array of Hashes" do
|
|
289
|
+
@hash['templates'].first.should have_key('name')
|
|
290
|
+
end
|
|
291
|
+
|
|
292
|
+
it "has a 'path' key value pair in a Hash of the 'templates' Array of Hashes" do
|
|
293
|
+
@hash['templates'].first.should have_key('path')
|
|
294
|
+
end
|
|
295
|
+
|
|
296
|
+
it "has a 'checksum' key value pair in a Hash of the 'templates' Array of Hashes" do
|
|
297
|
+
@hash['templates'].first.should have_key('checksum')
|
|
298
|
+
end
|
|
299
|
+
|
|
300
|
+
it "has a 'specificity' key value pair in a Hash of the 'templates' Array of Hashes" do
|
|
301
|
+
@hash['templates'].first.should have_key('specificity')
|
|
302
|
+
end
|
|
303
|
+
|
|
304
|
+
it "has a 'resources' key with a value of an Array Hashes" do
|
|
305
|
+
@hash.should have_key('resources')
|
|
306
|
+
@hash['resources'].should be_a(Array)
|
|
307
|
+
@hash['resources'].each do |item|
|
|
308
|
+
item.should be_a(Hash)
|
|
309
|
+
end
|
|
310
|
+
end
|
|
311
|
+
|
|
312
|
+
it "has a 'name' key value pair in a Hash of the 'resources' Array of Hashes" do
|
|
313
|
+
@hash['resources'].first.should have_key('name')
|
|
314
|
+
end
|
|
315
|
+
|
|
316
|
+
it "has a 'path' key value pair in a Hash of the 'resources' Array of Hashes" do
|
|
317
|
+
@hash['resources'].first.should have_key('path')
|
|
318
|
+
end
|
|
319
|
+
|
|
320
|
+
it "has a 'checksum' key value pair in a Hash of the 'resources' Array of Hashes" do
|
|
321
|
+
@hash['resources'].first.should have_key('checksum')
|
|
322
|
+
end
|
|
323
|
+
|
|
324
|
+
it "has a 'specificity' key value pair in a Hash of the 'resources' Array of Hashes" do
|
|
325
|
+
@hash['resources'].first.should have_key('specificity')
|
|
326
|
+
end
|
|
327
|
+
|
|
328
|
+
it "has a 'providers' key with a value of an Array Hashes" do
|
|
329
|
+
@hash.should have_key('providers')
|
|
330
|
+
@hash['providers'].should be_a(Array)
|
|
331
|
+
@hash['providers'].each do |item|
|
|
332
|
+
item.should be_a(Hash)
|
|
333
|
+
end
|
|
334
|
+
end
|
|
335
|
+
|
|
336
|
+
it "has a 'name' key value pair in a Hash of the 'providers' Array of Hashes" do
|
|
337
|
+
@hash['providers'].first.should have_key('name')
|
|
338
|
+
end
|
|
339
|
+
|
|
340
|
+
it "has a 'path' key value pair in a Hash of the 'providers' Array of Hashes" do
|
|
341
|
+
@hash['providers'].first.should have_key('path')
|
|
342
|
+
end
|
|
343
|
+
|
|
344
|
+
it "has a 'checksum' key value pair in a Hash of the 'providers' Array of Hashes" do
|
|
345
|
+
@hash['providers'].first.should have_key('checksum')
|
|
346
|
+
end
|
|
347
|
+
|
|
348
|
+
it "has a 'specificity' key value pair in a Hash of the 'providers' Array of Hashes" do
|
|
349
|
+
@hash['providers'].first.should have_key('specificity')
|
|
350
|
+
end
|
|
351
|
+
|
|
352
|
+
it "has a 'root_files' key with a value of an Array Hashes" do
|
|
353
|
+
@hash.should have_key('root_files')
|
|
354
|
+
@hash['root_files'].should be_a(Array)
|
|
355
|
+
@hash['root_files'].each do |item|
|
|
356
|
+
item.should be_a(Hash)
|
|
357
|
+
end
|
|
358
|
+
end
|
|
359
|
+
|
|
360
|
+
it "has a 'name' key value pair in a Hash of the 'root_files' Array of Hashes" do
|
|
361
|
+
@hash['root_files'].first.should have_key('name')
|
|
362
|
+
end
|
|
363
|
+
|
|
364
|
+
it "has a 'path' key value pair in a Hash of the 'root_files' Array of Hashes" do
|
|
365
|
+
@hash['root_files'].first.should have_key('path')
|
|
366
|
+
end
|
|
367
|
+
|
|
368
|
+
it "has a 'checksum' key value pair in a Hash of the 'root_files' Array of Hashes" do
|
|
369
|
+
@hash['root_files'].first.should have_key('checksum')
|
|
370
|
+
end
|
|
371
|
+
|
|
372
|
+
it "has a 'specificity' key value pair in a Hash of the 'root_files' Array of Hashes" do
|
|
373
|
+
@hash['root_files'].first.should have_key('specificity')
|
|
374
|
+
end
|
|
375
|
+
|
|
376
|
+
it "has a 'cookbook_name' key with a String value" do
|
|
377
|
+
@hash.should have_key('cookbook_name')
|
|
378
|
+
@hash['cookbook_name'].should be_a(String)
|
|
379
|
+
end
|
|
380
|
+
|
|
381
|
+
it "has a 'metadata' key with a Cookbook::Metadata value" do
|
|
382
|
+
@hash.should have_key('metadata')
|
|
383
|
+
@hash['metadata'].should be_a(Chef::Cookbook::Metadata)
|
|
384
|
+
end
|
|
385
|
+
|
|
386
|
+
it "has a 'version' key with a String value" do
|
|
387
|
+
@hash.should have_key('version')
|
|
388
|
+
@hash['version'].should be_a(String)
|
|
389
|
+
end
|
|
390
|
+
|
|
391
|
+
it "has a 'name' key with a String value" do
|
|
392
|
+
@hash.should have_key('name')
|
|
393
|
+
@hash['name'].should be_a(String)
|
|
394
|
+
end
|
|
395
|
+
|
|
396
|
+
it "has a value containing the cookbook name and version separated by a dash for 'name'" do
|
|
397
|
+
name, version = @hash['name'].split('-')
|
|
398
|
+
|
|
399
|
+
name.should eql(cookbook_name)
|
|
400
|
+
version.should eql(cookbook_version)
|
|
401
|
+
end
|
|
402
|
+
|
|
403
|
+
it "has a 'chef_type' key with 'cookbook_version' as the value" do
|
|
404
|
+
@hash.should have_key('chef_type')
|
|
405
|
+
@hash['chef_type'].should eql("cookbook_version")
|
|
406
|
+
end
|
|
407
|
+
end
|
|
408
|
+
|
|
409
|
+
describe "#to_json" do
|
|
410
|
+
before(:each) do
|
|
411
|
+
@json = subject.to_json
|
|
412
|
+
end
|
|
413
|
+
|
|
414
|
+
it "has a 'json_class' key with 'Chef::CookbookVersion' as the value" do
|
|
415
|
+
@json.should have_json_path('json_class')
|
|
416
|
+
parse_json(@json)['json_class'].should eql("Chef::CookbookVersion")
|
|
417
|
+
end
|
|
418
|
+
end
|
|
419
|
+
end
|
|
420
|
+
end
|