ridley 0.11.0.rc1 → 0.11.1
Sign up to get free protection for your applications and to get access to all the features.
- data/.travis.yml +3 -2
- data/Gemfile +1 -0
- data/Guardfile +2 -2
- data/Thorfile +2 -2
- data/lib/ridley/chef.rb +1 -0
- data/lib/ridley/chef/chefignore.rb +76 -0
- data/lib/ridley/chef/cookbook.rb +17 -7
- data/lib/ridley/chef/cookbook/metadata.rb +8 -0
- data/lib/ridley/chef_objects/cookbook_object.rb +21 -37
- data/lib/ridley/chef_objects/data_bag_item_obect.rb +9 -0
- data/lib/ridley/client.rb +2 -2
- data/lib/ridley/connection.rb +12 -6
- data/lib/ridley/errors.rb +14 -0
- data/lib/ridley/host_connector.rb +10 -3
- data/lib/ridley/resource.rb +25 -5
- data/lib/ridley/resources/cookbook_resource.rb +19 -9
- data/lib/ridley/resources/data_bag_item_resource.rb +8 -4
- data/lib/ridley/resources/search_resource.rb +5 -5
- data/lib/ridley/sandbox_uploader.rb +6 -0
- data/lib/ridley/version.rb +1 -1
- data/ridley.gemspec +1 -1
- data/spec/acceptance/client_resource_spec.rb +44 -62
- data/spec/acceptance/cookbook_resource_spec.rb +27 -0
- data/spec/acceptance/data_bag_item_resource_spec.rb +36 -54
- data/spec/acceptance/data_bag_resource_spec.rb +9 -21
- data/spec/acceptance/environment_resource_spec.rb +34 -63
- data/spec/acceptance/node_resource_spec.rb +27 -47
- data/spec/acceptance/role_resource_spec.rb +27 -67
- data/spec/acceptance/sandbox_resource_spec.rb +3 -13
- data/spec/acceptance/search_resource_spec.rb +5 -15
- data/spec/fixtures/chefignore +8 -0
- data/spec/spec_helper.rb +15 -1
- data/spec/support/chef_server.rb +77 -0
- data/spec/unit/ridley/chef/chefignore_spec.rb +40 -0
- data/spec/unit/ridley/chef/cookbook_spec.rb +30 -2
- data/spec/unit/ridley/chef_objects/cookbook_object_spec.rb +3 -3
- data/spec/unit/ridley/connection_spec.rb +1 -2
- data/spec/unit/ridley/resources/cookbook_resource_spec.rb +85 -48
- data/spec/unit/ridley/resources/data_bag_resource_spec.rb +1 -1
- data/spec/unit/ridley/resources/search_resource_spec.rb +39 -2
- data/spec/unit/ridley/sandbox_uploader_spec.rb +25 -0
- metadata +19 -7
@@ -1,20 +1,10 @@
|
|
1
1
|
require 'spec_helper'
|
2
2
|
|
3
3
|
describe "Sandbox API operations", type: "acceptance" do
|
4
|
-
let(:server_url)
|
4
|
+
let(:server_url) { Ridley::RSpec::ChefServer.server_url }
|
5
5
|
let(:client_name) { "reset" }
|
6
|
-
let(:client_key)
|
7
|
-
|
8
|
-
let(:connection) do
|
9
|
-
Ridley.new(
|
10
|
-
server_url: server_url,
|
11
|
-
client_name: client_name,
|
12
|
-
client_key: client_key
|
13
|
-
)
|
14
|
-
end
|
15
|
-
|
16
|
-
before(:all) { WebMock.allow_net_connect! }
|
17
|
-
after(:all) { WebMock.disable_net_connect! }
|
6
|
+
let(:client_key) { fixtures_path.join('reset.pem').to_s }
|
7
|
+
let(:connection) { Ridley.new(server_url: server_url, client_name: client_name, client_key: client_key) }
|
18
8
|
|
19
9
|
let(:checksums) do
|
20
10
|
[
|
@@ -1,24 +1,14 @@
|
|
1
1
|
require 'spec_helper'
|
2
2
|
|
3
3
|
describe "Search API operations", type: "acceptance" do
|
4
|
-
let(:server_url)
|
4
|
+
let(:server_url) { Ridley::RSpec::ChefServer.server_url }
|
5
5
|
let(:client_name) { "reset" }
|
6
|
-
let(:client_key)
|
7
|
-
|
8
|
-
let(:client) do
|
9
|
-
Ridley.new(
|
10
|
-
server_url: server_url,
|
11
|
-
client_name: client_name,
|
12
|
-
client_key: client_key
|
13
|
-
)
|
14
|
-
end
|
15
|
-
|
16
|
-
before(:all) { WebMock.allow_net_connect! }
|
17
|
-
after(:all) { WebMock.disable_net_connect! }
|
6
|
+
let(:client_key) { fixtures_path.join('reset.pem').to_s }
|
7
|
+
let(:connection) { Ridley.new(server_url: server_url, client_name: client_name, client_key: client_key) }
|
18
8
|
|
19
9
|
describe "listing indexes" do
|
20
10
|
it "returns an array of indexes" do
|
21
|
-
indexes =
|
11
|
+
indexes = connection.search_indexes
|
22
12
|
|
23
13
|
indexes.should include("role")
|
24
14
|
indexes.should include("node")
|
@@ -30,7 +20,7 @@ describe "Search API operations", type: "acceptance" do
|
|
30
20
|
describe "searching an index that doesn't exist" do
|
31
21
|
it "it raises a Ridley::Errors::HTTPNotFound error" do
|
32
22
|
lambda {
|
33
|
-
|
23
|
+
connection.search(:notthere)
|
34
24
|
}.should raise_error(Ridley::Errors::HTTPNotFound)
|
35
25
|
end
|
36
26
|
end
|
data/spec/spec_helper.rb
CHANGED
@@ -11,6 +11,7 @@ def setup_rspec
|
|
11
11
|
|
12
12
|
RSpec.configure do |config|
|
13
13
|
config.include Ridley::SpecHelpers
|
14
|
+
config.include Ridley::RSpec::ChefServer
|
14
15
|
config.include JsonSpec::Helpers
|
15
16
|
|
16
17
|
config.mock_with :rspec
|
@@ -19,12 +20,25 @@ def setup_rspec
|
|
19
20
|
config.run_all_when_everything_filtered = true
|
20
21
|
|
21
22
|
config.before(:all) do
|
22
|
-
Ridley.logger = nil
|
23
23
|
Celluloid.logger = nil
|
24
|
+
Ridley.logger = nil
|
25
|
+
WebMock.disable_net_connect!(allow_localhost: true, net_http_connect_on_start: true)
|
26
|
+
Ridley::RSpec::ChefServer.start
|
27
|
+
end
|
28
|
+
|
29
|
+
config.after(:all) do
|
30
|
+
Ridley::RSpec::ChefServer.stop
|
24
31
|
end
|
25
32
|
|
26
33
|
config.before(:each) do
|
34
|
+
Celluloid.shutdown
|
35
|
+
Celluloid.boot
|
27
36
|
clean_tmp_path
|
37
|
+
Ridley::RSpec::ChefServer.server.clear_data
|
38
|
+
end
|
39
|
+
|
40
|
+
config.after(:each) do
|
41
|
+
Ridley::RSpec::ChefServer.server.clear_data
|
28
42
|
end
|
29
43
|
end
|
30
44
|
end
|
@@ -0,0 +1,77 @@
|
|
1
|
+
require 'chef_zero/server'
|
2
|
+
require_relative 'spec_helpers'
|
3
|
+
|
4
|
+
module Ridley::RSpec
|
5
|
+
module ChefServer
|
6
|
+
PORT = 8889
|
7
|
+
|
8
|
+
class << self
|
9
|
+
include Ridley::SpecHelpers
|
10
|
+
|
11
|
+
def clear_request_log
|
12
|
+
@request_log = Array.new
|
13
|
+
end
|
14
|
+
|
15
|
+
def request_log
|
16
|
+
@request_log ||= Array.new
|
17
|
+
end
|
18
|
+
|
19
|
+
def server
|
20
|
+
@server ||= ChefZero::Server.new(port: PORT, signals: false, log_requests: true)
|
21
|
+
end
|
22
|
+
|
23
|
+
def server_url
|
24
|
+
"http://localhost:#{PORT}"
|
25
|
+
end
|
26
|
+
|
27
|
+
def start
|
28
|
+
Thin::Logging.silent = true
|
29
|
+
server.start_background
|
30
|
+
server.on_response do |request, response|
|
31
|
+
request_log << [ request, response ]
|
32
|
+
end
|
33
|
+
clear_request_log
|
34
|
+
|
35
|
+
server
|
36
|
+
end
|
37
|
+
|
38
|
+
def stop
|
39
|
+
@server.stop if @server
|
40
|
+
end
|
41
|
+
|
42
|
+
def running?
|
43
|
+
@server && @server.running?
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
def chef_client(name, hash = Hash.new)
|
48
|
+
load_data(:clients, name, hash)
|
49
|
+
end
|
50
|
+
|
51
|
+
def chef_cookbook(name, version, cookbook = Hash.new)
|
52
|
+
ChefServer.server.load_data("cookbooks" => { "#{name}-#{version}" => cookbook })
|
53
|
+
end
|
54
|
+
|
55
|
+
def chef_data_bag(name, hash = Hash.new)
|
56
|
+
ChefServer.server.load_data({ 'data' => { name => hash }})
|
57
|
+
end
|
58
|
+
|
59
|
+
def chef_environment(name, hash = Hash.new)
|
60
|
+
load_data(:environments, name, hash)
|
61
|
+
end
|
62
|
+
|
63
|
+
def chef_node(name, hash = Hash.new)
|
64
|
+
load_data(:nodes, name, hash)
|
65
|
+
end
|
66
|
+
|
67
|
+
def chef_role(name, hash = Hash.new)
|
68
|
+
load_data(:roles, name, hash)
|
69
|
+
end
|
70
|
+
|
71
|
+
private
|
72
|
+
|
73
|
+
def load_data(key, name, hash)
|
74
|
+
ChefServer.server.load_data(key.to_s => { name => MultiJson.encode(hash) })
|
75
|
+
end
|
76
|
+
end
|
77
|
+
end
|
@@ -0,0 +1,40 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Ridley::Chef::Chefignore do
|
4
|
+
describe "ClassMethods" do
|
5
|
+
subject { described_class }
|
6
|
+
|
7
|
+
describe "::find_relative_to" do
|
8
|
+
let(:path) { tmp_path.join('chefignore-test') }
|
9
|
+
before(:each) { FileUtils.mkdir_p(path) }
|
10
|
+
|
11
|
+
it "finds a chefignore file in a 'cookbooks' directory relative to the given path" do
|
12
|
+
FileUtils.touch(path.join('chefignore'))
|
13
|
+
subject.find_relative_to(path)
|
14
|
+
end
|
15
|
+
|
16
|
+
it "finds a chefignore file relative to the given path" do
|
17
|
+
FileUtils.mkdir_p(path.join('cookbooks'))
|
18
|
+
FileUtils.touch(path.join('cookbooks', 'chefignore'))
|
19
|
+
subject.find_relative_to(path)
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
subject { described_class.new(File.join(fixtures_path)) }
|
25
|
+
|
26
|
+
it "loads the globs in the chefignore file" do
|
27
|
+
subject.ignores.should =~ %w[recipes/ignoreme.rb ignored]
|
28
|
+
end
|
29
|
+
|
30
|
+
it "removes items from an array that match the ignores" do
|
31
|
+
file_list = %w[ recipes/ignoreme.rb recipes/dontignoreme.rb ]
|
32
|
+
subject.remove_ignores_from(file_list).should == %w[recipes/dontignoreme.rb]
|
33
|
+
end
|
34
|
+
|
35
|
+
it "determines if a file is ignored" do
|
36
|
+
subject.ignored?('ignored').should be_true
|
37
|
+
subject.ignored?('recipes/ignoreme.rb').should be_true
|
38
|
+
subject.ignored?('recipes/dontignoreme.rb').should be_false
|
39
|
+
end
|
40
|
+
end
|
@@ -4,7 +4,7 @@ describe Ridley::Chef::Cookbook do
|
|
4
4
|
describe "ClassMethods" do
|
5
5
|
subject { described_class }
|
6
6
|
|
7
|
-
describe "
|
7
|
+
describe "::from_path" do
|
8
8
|
let(:cookbook_path) { fixtures_path.join("example_cookbook") }
|
9
9
|
|
10
10
|
it "returns an instance of Ridley::Chef::Cookbook" do
|
@@ -26,9 +26,37 @@ describe Ridley::Chef::Cookbook do
|
|
26
26
|
}.should raise_error(IOError)
|
27
27
|
end
|
28
28
|
end
|
29
|
+
|
30
|
+
context "when the metadata does not contain a value for name and no value for :name option was given" do
|
31
|
+
let(:cookbook_path) { tmp_path.join("directory_name").to_s }
|
32
|
+
|
33
|
+
before do
|
34
|
+
FileUtils.mkdir_p(cookbook_path)
|
35
|
+
FileUtils.touch(File.join(cookbook_path, 'metadata.rb'))
|
36
|
+
end
|
37
|
+
|
38
|
+
it "sets the name of the cookbook to the name of the directory containing it" do
|
39
|
+
subject.from_path(cookbook_path).cookbook_name.should eql("directory_name")
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
context "when a metadata.rb is missing but metadata.json is present", focus: true do
|
44
|
+
let(:cookbook_path) { tmp_path.join("temp_cookbook").to_s }
|
45
|
+
|
46
|
+
before do
|
47
|
+
FileUtils.mkdir_p(cookbook_path)
|
48
|
+
File.open(File.join(cookbook_path, 'metadata.json'), 'w+') do |f|
|
49
|
+
f.write MultiJson.encode(name: "rspec_test")
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
it "sets the name of the cookbook from the metadata.json" do
|
54
|
+
subject.from_path(cookbook_path).cookbook_name.should eql("rspec_test")
|
55
|
+
end
|
56
|
+
end
|
29
57
|
end
|
30
58
|
|
31
|
-
describe "
|
59
|
+
describe "::checksum" do
|
32
60
|
it "delegates to Ridley::Chef::Digester.md5_checksum_for_file" do
|
33
61
|
path = fixtures_path.join("example_cookbook", "metadata.rb")
|
34
62
|
Ridley::Chef::Digester.should_receive(:md5_checksum_for_file).with(path)
|
@@ -1,9 +1,9 @@
|
|
1
1
|
require 'spec_helper'
|
2
2
|
|
3
3
|
describe Ridley::CookbookObject do
|
4
|
-
let(:connection) { double('
|
5
|
-
|
6
|
-
|
4
|
+
let(:connection) { double('connection') }
|
5
|
+
let(:resource) { double('resource', connection: connection) }
|
6
|
+
subject { described_class.new(resource) }
|
7
7
|
|
8
8
|
describe "#download" do
|
9
9
|
it "downloads each file" do
|
@@ -56,8 +56,7 @@ describe Ridley::Connection do
|
|
56
56
|
let(:contents) { "SOME STRING STUFF\nHERE.\n" }
|
57
57
|
|
58
58
|
before(:each) do
|
59
|
-
stub_request(:get, "http://test.it/file").
|
60
|
-
to_return(status: 200, body: contents)
|
59
|
+
stub_request(:get, "http://test.it/file").to_return(status: 200, body: contents)
|
61
60
|
end
|
62
61
|
|
63
62
|
it "creates a destination file on disk" do
|
@@ -3,85 +3,122 @@ require 'spec_helper'
|
|
3
3
|
describe Ridley::CookbookResource do
|
4
4
|
let(:client_name) { "reset" }
|
5
5
|
let(:client_key) { fixtures_path.join('reset.pem') }
|
6
|
-
let(:connection) {
|
6
|
+
let(:connection) { Ridley::Connection.new("http://localhost:8889", "reset", fixtures_path.join("reset.pem").to_s) }
|
7
7
|
subject { described_class.new(double('registry'), client_name, client_key) }
|
8
8
|
before { subject.stub(connection: connection) }
|
9
9
|
|
10
10
|
describe "#download" do
|
11
|
-
|
11
|
+
let(:name) { "example_cookbook" }
|
12
|
+
let(:version) { "0.1.0" }
|
13
|
+
let(:destination) { tmp_path.join("example_cookbook-0.1.0").to_s }
|
14
|
+
|
15
|
+
context "when the cookbook of the name/version is found" do
|
16
|
+
it "downloads the cookbook to the destination" do
|
17
|
+
pending "can't test downloading until https://github.com/jkeiser/chef-zero/issues/5 is fixed"
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
context "when the cookbook of the name/version is not found" do
|
22
|
+
before { subject.should_receive(:find).with(name, version).and_return(nil) }
|
23
|
+
|
24
|
+
it "raises a ResourceNotFound error" do
|
25
|
+
expect {
|
26
|
+
subject.download(name, version, destination)
|
27
|
+
}.to raise_error(Ridley::Errors::ResourceNotFound)
|
28
|
+
end
|
29
|
+
end
|
12
30
|
end
|
13
31
|
|
14
32
|
describe "#latest_version" do
|
15
33
|
let(:name) { "ant" }
|
16
34
|
|
17
|
-
before(:each) do
|
18
|
-
subject.should_receive(:versions).with(name).and_return(versions)
|
19
|
-
end
|
20
|
-
|
21
35
|
context "when the cookbook has no versions" do
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
36
|
+
it "returns a ResourceNotFound error" do
|
37
|
+
expect {
|
38
|
+
subject.latest_version(name)
|
39
|
+
}.to raise_error(Ridley::Errors::ResourceNotFound)
|
26
40
|
end
|
27
41
|
end
|
28
42
|
|
29
43
|
context "when the cookbook has versions" do
|
30
|
-
|
31
|
-
|
44
|
+
before do
|
45
|
+
chef_cookbook(name, "1.0.0")
|
46
|
+
chef_cookbook(name, "1.2.0")
|
47
|
+
chef_cookbook(name, "3.0.0")
|
32
48
|
end
|
33
49
|
|
34
|
-
it "returns
|
50
|
+
it "returns the latest version" do
|
35
51
|
subject.latest_version(name).should eql("3.0.0")
|
36
52
|
end
|
37
53
|
end
|
38
54
|
end
|
39
55
|
|
40
56
|
describe "#versions" do
|
41
|
-
let(:
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
})
|
57
|
+
let(:name) { "artifact" }
|
58
|
+
|
59
|
+
context "when the cookbook has versions" do
|
60
|
+
before do
|
61
|
+
chef_cookbook(name, "1.0.0")
|
62
|
+
chef_cookbook(name, "1.1.0")
|
63
|
+
chef_cookbook(name, "1.2.0")
|
64
|
+
end
|
65
|
+
|
66
|
+
it "returns an array" do
|
67
|
+
subject.versions(name).should be_a(Array)
|
68
|
+
end
|
69
|
+
|
70
|
+
it "contains a version string for each cookbook version available" do
|
71
|
+
result = subject.versions(name)
|
72
|
+
|
73
|
+
result.should have(3).versions
|
74
|
+
result.should include("1.0.0")
|
75
|
+
result.should include("1.1.0")
|
76
|
+
result.should include("1.2.0")
|
77
|
+
end
|
63
78
|
end
|
64
79
|
|
65
|
-
|
66
|
-
|
80
|
+
context "when the cookbook has no versions" do
|
81
|
+
it "raises a ResourceNotFound error" do
|
82
|
+
expect {
|
83
|
+
subject.versions(name)
|
84
|
+
}.to raise_error(Ridley::Errors::ResourceNotFound)
|
85
|
+
end
|
67
86
|
end
|
87
|
+
end
|
68
88
|
|
69
|
-
|
70
|
-
|
89
|
+
describe "#satisfy" do
|
90
|
+
let(:name) { "ridley_test" }
|
91
|
+
|
92
|
+
context "when there is a solution" do
|
93
|
+
before do
|
94
|
+
chef_cookbook(name, "2.0.0")
|
95
|
+
chef_cookbook(name, "3.0.0")
|
96
|
+
end
|
97
|
+
|
98
|
+
it "returns a CookbookObject" do
|
99
|
+
subject.satisfy(name, ">= 2.0.0").should be_a(Ridley::CookbookObject)
|
100
|
+
end
|
101
|
+
|
102
|
+
it "is the best solution" do
|
103
|
+
subject.satisfy(name, ">= 2.0.0").version.should eql("3.0.0")
|
104
|
+
end
|
71
105
|
end
|
72
106
|
|
73
|
-
|
74
|
-
|
107
|
+
context "when there is no solution" do
|
108
|
+
before { chef_cookbook(name, "1.0.0") }
|
75
109
|
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
result.should include("1.2.0")
|
110
|
+
it "returns nil" do
|
111
|
+
subject.satisfy(name, ">= 2.0.0").should be_nil
|
112
|
+
end
|
80
113
|
end
|
81
|
-
end
|
82
114
|
|
83
|
-
|
84
|
-
|
115
|
+
context "when the cookbook does not exist" do
|
116
|
+
it "raises a ResourceNotFound error" do
|
117
|
+
expect {
|
118
|
+
subject.satisfy(name, ">= 1.2.3")
|
119
|
+
}.to raise_error(Ridley::Errors::ResourceNotFound)
|
120
|
+
end
|
121
|
+
end
|
85
122
|
end
|
86
123
|
|
87
124
|
describe "#upload" do
|