clc-promote 0.9.8 → 0.10.0
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.
- checksums.yaml +4 -4
- data/clc-promote.gemspec +1 -0
- data/lib/promote.rb +2 -0
- data/lib/promote/environment_file.rb +6 -6
- data/lib/promote/node_shell.rb +17 -0
- data/lib/promote/node_shell/base_shell.rb +20 -0
- data/lib/promote/node_shell/ssh_shell.rb +40 -0
- data/lib/promote/node_shell/winrm_shell.rb +27 -0
- data/lib/promote/password_vault.rb +38 -0
- data/lib/promote/promoter.rb +53 -31
- data/lib/promote/rake_tasks.rb +9 -2
- data/lib/promote/version.rb +1 -1
- data/spec/unit/promote/cookbook_spec.rb +205 -79
- data/spec/unit/promote/environment_file_spec.rb +28 -0
- data/spec/unit/promote/node_shell/ssh_shell_spec.rb +39 -0
- data/spec/unit/promote/node_shell/winrm_shell_spec.rb +30 -0
- data/spec/unit/promote/node_shell_spec.rb +40 -0
- data/spec/unit/promote/password_vault_spec.rb +39 -0
- data/spec/unit/promote/promoter_spec.rb +152 -45
- data/spec/unit/promote/uploader_spec.rb +49 -33
- data/spec/unit/stubs/environments/env1.json +29 -0
- data/spec/unit/stubs/environments/env2.json +16 -0
- metadata +35 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 375087f3ef3e0a22501b5fec3bb66fe4790269ea
|
4
|
+
data.tar.gz: 8df292375cfc83442f7b52c430a4e80c297fa8ef
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: a770c6d74a6a9b9df514990eb0b455182c6f9b32469ac947e2d207e78a7a8da93856b92dee3192bb1c0f888b7a88fd74cdb38016958b001d53f5b396c2075f90
|
7
|
+
data.tar.gz: 750dabb13120d715c5db7c12a8528e903097f3002987468d2f1daacfbc1d16e857b0379197d67041cb611e6528ea5f20109a1514e5931de63379107ed1adb5dd
|
data/clc-promote.gemspec
CHANGED
@@ -19,6 +19,7 @@ Gem::Specification.new do |s|
|
|
19
19
|
s.add_runtime_dependency 'clc-git', '~> 1.2', '>= 1.2.8'
|
20
20
|
s.add_runtime_dependency 'berkshelf', '~> 3.2', '>= 3.2.3'
|
21
21
|
s.add_runtime_dependency 'highline', '~> 1.6', '>= 1.6.21'
|
22
|
+
s.add_runtime_dependency 'chef-vault'
|
22
23
|
|
23
24
|
s.add_development_dependency 'rspec', '~> 3.0', '>= 3.0.0'
|
24
25
|
s.add_development_dependency 'rake', '~> 10.3', '>= 10.3.2'
|
data/lib/promote.rb
CHANGED
@@ -4,6 +4,8 @@ require 'promote/cookbook'
|
|
4
4
|
require 'promote/environment_file'
|
5
5
|
require 'promote/git_repo'
|
6
6
|
require 'promote/node_finder'
|
7
|
+
require 'promote/node_shell'
|
8
|
+
require 'promote/password_vault'
|
7
9
|
require 'promote/promoter'
|
8
10
|
require 'promote/uploader'
|
9
11
|
require 'promote/utils'
|
@@ -13,8 +13,12 @@ module Promote
|
|
13
13
|
File.join(@config.environment_directory, "#{name}.json")
|
14
14
|
end
|
15
15
|
|
16
|
+
def overrides
|
17
|
+
content['override_attributes'] || {}
|
18
|
+
end
|
19
|
+
|
16
20
|
def cookbook_versions
|
17
|
-
content
|
21
|
+
content['cookbook_versions'] || {}
|
18
22
|
end
|
19
23
|
|
20
24
|
def write_cookbook_versions(versions)
|
@@ -28,11 +32,7 @@ module Promote
|
|
28
32
|
private
|
29
33
|
|
30
34
|
def content
|
31
|
-
@content ||=
|
32
|
-
end
|
33
|
-
|
34
|
-
def get_environment_content
|
35
|
-
JSON.parse(File.read(file_path))
|
35
|
+
@content ||= JSON.parse(File.read(file_path))
|
36
36
|
end
|
37
37
|
end
|
38
38
|
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
require 'promote/node_shell/base_shell'
|
2
|
+
require 'promote/node_shell/ssh_shell'
|
3
|
+
require 'promote/node_shell/winrm_shell'
|
4
|
+
|
5
|
+
module Promote
|
6
|
+
module NodeShell
|
7
|
+
def self.for_node(node, config)
|
8
|
+
vault = PasswordVault.new(node, config)
|
9
|
+
case node.platform_family
|
10
|
+
when 'windows'
|
11
|
+
WinrmShell.new(node, vault)
|
12
|
+
else
|
13
|
+
SshShell.new(node, vault)
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
module Promote
|
2
|
+
module NodeShell
|
3
|
+
class BaseShell
|
4
|
+
def initialize(node, vault)
|
5
|
+
@node = node
|
6
|
+
@vault = vault
|
7
|
+
end
|
8
|
+
|
9
|
+
attr_accessor :vault
|
10
|
+
attr_accessor :node
|
11
|
+
|
12
|
+
def converge?(ui = nil)
|
13
|
+
execute('chef-client', ui) == 0
|
14
|
+
end
|
15
|
+
|
16
|
+
def execute(command, ui = nil)
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
@@ -0,0 +1,40 @@
|
|
1
|
+
module Promote
|
2
|
+
module NodeShell
|
3
|
+
class SshShell < BaseShell
|
4
|
+
def session
|
5
|
+
@session ||= Net::SSH.start(
|
6
|
+
node.ipaddress,
|
7
|
+
'root',
|
8
|
+
password: vault.root_password
|
9
|
+
)
|
10
|
+
end
|
11
|
+
|
12
|
+
def execute(command, ui = nil)
|
13
|
+
exit_code = nil
|
14
|
+
out = []
|
15
|
+
session.open_channel do |channel|
|
16
|
+
|
17
|
+
channel.request_pty
|
18
|
+
channel.exec(command) do |_ch, _success|
|
19
|
+
|
20
|
+
channel.on_data do |_ch, data|
|
21
|
+
ui.info(data) if ui
|
22
|
+
out << data
|
23
|
+
end
|
24
|
+
|
25
|
+
channel.on_extended_data do |_ch, _type, data|
|
26
|
+
ui.info(data) if ui
|
27
|
+
out << data
|
28
|
+
end
|
29
|
+
|
30
|
+
channel.on_request("exit-status") do |_ch, data|
|
31
|
+
exit_code = data.read_long
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
session.loop
|
36
|
+
exit_code
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
require 'winrm'
|
2
|
+
|
3
|
+
module Promote
|
4
|
+
module NodeShell
|
5
|
+
class WinrmShell < BaseShell
|
6
|
+
def session
|
7
|
+
@session ||= begin
|
8
|
+
::WinRM::WinRMWebService.new(
|
9
|
+
"http://#{node.ipaddress}:5985/wsman",
|
10
|
+
:plaintext,
|
11
|
+
user: 'administrator',
|
12
|
+
pass: vault.admin_password,
|
13
|
+
basic_auth_only: true
|
14
|
+
)
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
def execute(command, ui = nil)
|
19
|
+
response = session.run_cmd(command) do |stdout, stderr|
|
20
|
+
ui.info(stdout) if stdout && ui
|
21
|
+
ui.error(stderr) if stderr && ui
|
22
|
+
end
|
23
|
+
response[:exitcode]
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
@@ -0,0 +1,38 @@
|
|
1
|
+
require 'chef-vault'
|
2
|
+
|
3
|
+
module Promote
|
4
|
+
class PasswordVault
|
5
|
+
|
6
|
+
include ChefServer
|
7
|
+
|
8
|
+
def initialize(node, config)
|
9
|
+
@node = node
|
10
|
+
@config = config
|
11
|
+
end
|
12
|
+
|
13
|
+
attr_accessor :config
|
14
|
+
attr_accessor :node
|
15
|
+
|
16
|
+
def root_password
|
17
|
+
raw['local_root_password']
|
18
|
+
end
|
19
|
+
|
20
|
+
def admin_password
|
21
|
+
raw['local_admin_password']
|
22
|
+
end
|
23
|
+
|
24
|
+
def raw
|
25
|
+
@raw ||= load_secrets
|
26
|
+
end
|
27
|
+
|
28
|
+
private
|
29
|
+
|
30
|
+
def load_secrets
|
31
|
+
bag = node['provisioner']['vault_bag']
|
32
|
+
item = "#{node['clc_library']['win_fqdn']}_domain"
|
33
|
+
with_chef_server(config) do
|
34
|
+
return ChefVault::Item.load(bag, item)
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
data/lib/promote/promoter.rb
CHANGED
@@ -23,19 +23,30 @@ module Promote
|
|
23
23
|
dest.write_cookbook_versions(source.cookbook_versions)
|
24
24
|
end
|
25
25
|
|
26
|
-
def monitor_promotion(source_environment, destination_environments,
|
26
|
+
def monitor_promotion(source_environment, destination_environments, number_to_test, converge_interval, force = false, ui = nil)
|
27
27
|
ui.info "Waiting for #{source_environment} to finish" if ui
|
28
|
-
check_promotion(source_environment,
|
28
|
+
check_promotion(source_environment, converge_interval, ui)
|
29
29
|
|
30
|
-
|
30
|
+
test_environments = destination_environments[0, number_to_test]
|
31
|
+
final_environments = []
|
32
|
+
if destination_environments.count > number_to_test
|
33
|
+
final_environments = destination_environments[number_to_test..-1]
|
34
|
+
end
|
31
35
|
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
+
test_environments.each do |env|
|
37
|
+
promote_and_upload(source_environment, env, force, ui)
|
38
|
+
check_promotion(env, converge_interval, ui)
|
39
|
+
end
|
36
40
|
|
37
|
-
|
41
|
+
final_environments.each do |env|
|
42
|
+
promote_and_upload(source_environment, env, force, ui)
|
38
43
|
end
|
44
|
+
start = Time.now.to_i
|
45
|
+
final_environments.each do |env|
|
46
|
+
check_promotion(env, converge_interval, ui, start)
|
47
|
+
end
|
48
|
+
|
49
|
+
ui.info 'This promotion is complete' if ui
|
39
50
|
end
|
40
51
|
|
41
52
|
def stage_promotion(promote_environment, destination_config, ui)
|
@@ -86,6 +97,21 @@ module Promote
|
|
86
97
|
|
87
98
|
private
|
88
99
|
|
100
|
+
def promote_and_upload(source, target, force, ui)
|
101
|
+
msg = "Promoting #{source} to #{target}..."
|
102
|
+
if ui
|
103
|
+
if force
|
104
|
+
ui.info msg
|
105
|
+
else
|
106
|
+
ui.confirm msg
|
107
|
+
end
|
108
|
+
end
|
109
|
+
|
110
|
+
uploader = Uploader.new(config)
|
111
|
+
promote_to(source, target, ui)
|
112
|
+
uploader.upload_environment(target, ui)
|
113
|
+
end
|
114
|
+
|
89
115
|
def download_files(local_root, path, cookbook_version = nil)
|
90
116
|
with_chef_server(config) do
|
91
117
|
fs_config = Chef::ChefFS::Config.new(Chef::Config, cwd = Dir.pwd, {:cookbook_version => cookbook_version})
|
@@ -102,32 +128,28 @@ module Promote
|
|
102
128
|
end
|
103
129
|
end
|
104
130
|
|
105
|
-
def check_promotion(environment_to_check,
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
result.each do |node|
|
131
|
+
def check_promotion(environment_to_check, converge_interval, ui, start = Time.now.to_i)
|
132
|
+
vault = PasswordVault.new(environment_to_check, config)
|
133
|
+
query = "chef_environment:#{environment_to_check}"
|
134
|
+
|
135
|
+
%w(windows ubuntu).each do |platform|
|
136
|
+
nodes = NodeFinder.new("#{query} AND platform:#{platform}", config).search
|
137
|
+
|
138
|
+
nodes.each do |node|
|
114
139
|
next if node.name == config.node_name
|
115
|
-
if node
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
ui.info "#{node.name}
|
140
|
+
next if node.name.include?('PROVISIONER')
|
141
|
+
|
142
|
+
fresh_node = NodeFinder.new("name:#{node.name}", config).search.first
|
143
|
+
if fresh_node['ohai_time'].to_i > start
|
144
|
+
ui.info "#{node.name} already converged" if ui
|
145
|
+
else
|
146
|
+
ui.info "converging #{node.name}" if ui
|
147
|
+
unless NodeShell.for_node(node, config).converge?(ui)
|
148
|
+
raise "Stopping promotion in #{environment_to_check}! Node (#{node.name}) failed to converge."
|
149
|
+
end
|
150
|
+
sleep converge_interval
|
120
151
|
end
|
121
152
|
end
|
122
|
-
break if unconverged.count == 0
|
123
|
-
|
124
|
-
ui.stdout.print "." if ui
|
125
|
-
|
126
|
-
sleep probe_interval
|
127
|
-
end
|
128
|
-
|
129
|
-
if unconverged.count > 0
|
130
|
-
raise "Stopping promotion! Nodes (#{unconverged}) are not converging in #{environment_to_check}"
|
131
153
|
end
|
132
154
|
end
|
133
155
|
end
|
data/lib/promote/rake_tasks.rb
CHANGED
@@ -109,10 +109,17 @@ module Promote
|
|
109
109
|
def define_promote_environments
|
110
110
|
namespace "Promote" do
|
111
111
|
desc "Promote a list of environments from another"
|
112
|
-
task "promote_environments", :source_environment, :destination_environments, :force do |task, args|
|
112
|
+
task "promote_environments", :source_environment, :destination_environments, :number_to_test, :force do |task, args|
|
113
113
|
puts "Promoting constraints in #{args.source_environment} to #{args.destination_environments}"
|
114
114
|
ui = Chef::Knife::UI.new(STDOUT, STDERR, STDIN, {})
|
115
|
-
@promoter.monitor_promotion(
|
115
|
+
@promoter.monitor_promotion(
|
116
|
+
args.source_environment,
|
117
|
+
args.destination_environments.split(' '),
|
118
|
+
args.number_to_test,
|
119
|
+
5,
|
120
|
+
args.force,
|
121
|
+
ui
|
122
|
+
)
|
116
123
|
end
|
117
124
|
end
|
118
125
|
end
|
data/lib/promote/version.rb
CHANGED
@@ -1,30 +1,43 @@
|
|
1
1
|
require 'promote'
|
2
2
|
|
3
|
-
describe Promote::Cookbook do
|
4
|
-
let(:cookbook_dir) {'/tmp/promote_test_cookbooks/stubs'}
|
5
|
-
let(:config) { Promote::Config.new(
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
before(:all) {
|
3
|
+
describe Promote::Cookbook do
|
4
|
+
let(:cookbook_dir) { '/tmp/promote_test_cookbooks/stubs' }
|
5
|
+
let(:config) { Promote::Config.new(cookbook_directory: cookbook_dir) }
|
6
|
+
let(:fake_berks) { double('berksfile', list: nil, install: nil, update: nil) }
|
7
|
+
|
8
|
+
before(:all) do
|
11
9
|
cb_dir = '/tmp/promote_test_cookbooks'
|
12
10
|
FileUtils.rm_rf(cb_dir) if Dir.exist?(cb_dir)
|
13
11
|
Dir.mkdir(cb_dir)
|
14
|
-
FileUtils.cp_r(
|
15
|
-
|
12
|
+
FileUtils.cp_r(
|
13
|
+
File.join(File.dirname(File.dirname(__FILE__)), 'stubs'), cb_dir)
|
14
|
+
end
|
16
15
|
|
17
16
|
subject { Promote::Cookbook.new('cookbook_1', config) }
|
18
17
|
|
19
18
|
describe 'dependencies' do
|
20
|
-
before
|
19
|
+
before do
|
21
20
|
allow(Berkshelf::Berksfile).to receive(:from_file).and_return(fake_berks)
|
22
|
-
allow(fake_berks).to receive(:list).and_return(
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
21
|
+
allow(fake_berks).to receive(:list).and_return(
|
22
|
+
[
|
23
|
+
double(
|
24
|
+
'Dependency',
|
25
|
+
name: 'cookbook_2',
|
26
|
+
locked_version: Semverse::Version.new('1.1.1')
|
27
|
+
),
|
28
|
+
double(
|
29
|
+
'Dependency',
|
30
|
+
name: 'cookbook_3',
|
31
|
+
locked_version: Semverse::Version.new('2.2.2')
|
32
|
+
),
|
33
|
+
double(
|
34
|
+
'Dependency',
|
35
|
+
name: 'cookbook_4',
|
36
|
+
locked_version: Semverse::Version.new('3.3.3')
|
37
|
+
)
|
38
|
+
]
|
39
|
+
)
|
40
|
+
end
|
28
41
|
|
29
42
|
it 'returns dependencies from lockfile' do
|
30
43
|
expect(subject.dependencies.keys.count).to be 3
|
@@ -35,7 +48,6 @@ describe Promote::Cookbook do
|
|
35
48
|
end
|
36
49
|
|
37
50
|
describe 'metadata_dependencies' do
|
38
|
-
|
39
51
|
it 'returns dependencies from metadata.rb' do
|
40
52
|
expect(subject.metadata_dependencies.keys.count).to be 1
|
41
53
|
expect(subject.metadata_dependencies['cookbook_2'].to_s).to eq '= 1.1.1'
|
@@ -43,21 +55,20 @@ describe Promote::Cookbook do
|
|
43
55
|
end
|
44
56
|
|
45
57
|
describe 'path' do
|
46
|
-
|
47
58
|
it 'returns the correct path of the cookbook' do
|
48
59
|
expect(subject.path).to eq(File.join(cookbook_dir, 'cookbook_1'))
|
49
60
|
end
|
50
61
|
end
|
51
62
|
|
52
63
|
describe 'version' do
|
53
|
-
|
54
64
|
it 'reads the current version' do
|
55
65
|
expect(subject.version.to_s).to eq('1.0.0')
|
56
66
|
end
|
57
67
|
|
58
68
|
it 'writes changed version to metadata.rb' do
|
59
69
|
subject.version = Semverse::Version.new('2.2.2')
|
60
|
-
expect(
|
70
|
+
expect(
|
71
|
+
Promote::Cookbook.new('cookbook_1', config).version.to_s).to eq '2.2.2'
|
61
72
|
end
|
62
73
|
|
63
74
|
it 'returns the new version after a version has changed' do
|
@@ -80,10 +91,10 @@ describe Promote::Cookbook do
|
|
80
91
|
end
|
81
92
|
|
82
93
|
describe 'sync_berksfile' do
|
83
|
-
before
|
94
|
+
before do
|
84
95
|
allow(File).to receive(:exist?).with(/Berksfile$/).and_return(true)
|
85
96
|
allow(File).to receive(:exist?).with(/Berksfile.lock/).and_return(true)
|
86
|
-
|
97
|
+
end
|
87
98
|
|
88
99
|
it 'Installs berks dependencies' do
|
89
100
|
dummy = double('berksfile')
|
@@ -104,9 +115,9 @@ describe Promote::Cookbook do
|
|
104
115
|
end
|
105
116
|
|
106
117
|
context 'update berksfile with no lock file' do
|
107
|
-
before
|
118
|
+
before do
|
108
119
|
allow(File).to receive(:exist?).with(/Berksfile.lock/).and_return(false)
|
109
|
-
|
120
|
+
end
|
110
121
|
|
111
122
|
it 'Installs berks dependencies instead of update' do
|
112
123
|
dummy = double('berksfile')
|
@@ -120,15 +131,27 @@ describe Promote::Cookbook do
|
|
120
131
|
end
|
121
132
|
|
122
133
|
describe 'dependencies_changed_after_update?' do
|
123
|
-
before
|
134
|
+
before do
|
124
135
|
allow(File).to receive(:exist?).and_return(true)
|
125
136
|
allow(Berkshelf::Berksfile).to receive(:from_file).and_return(fake_berks)
|
126
137
|
allow(fake_berks).to receive(:list).and_return([
|
127
|
-
double(
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
138
|
+
double(
|
139
|
+
'Dependency',
|
140
|
+
name: 'cookbook_2',
|
141
|
+
locked_version: Semverse::Version.new('1.1.1')
|
142
|
+
),
|
143
|
+
double(
|
144
|
+
'Dependency',
|
145
|
+
name: 'cookbook_3',
|
146
|
+
locked_version: Semverse::Version.new('2.2.2')
|
147
|
+
),
|
148
|
+
double(
|
149
|
+
'Dependency',
|
150
|
+
name: 'cookbook_4',
|
151
|
+
locked_version: Semverse::Version.new('3.3.3')
|
152
|
+
)
|
153
|
+
])
|
154
|
+
end
|
132
155
|
|
133
156
|
it 'performs a berks update' do
|
134
157
|
expect(fake_berks).to receive(:update)
|
@@ -136,21 +159,44 @@ describe Promote::Cookbook do
|
|
136
159
|
end
|
137
160
|
|
138
161
|
context 'there is no change' do
|
139
|
-
|
140
|
-
before {
|
162
|
+
before do
|
141
163
|
allow(fake_berks).to receive(:list).and_return(
|
142
164
|
[
|
143
|
-
double(
|
144
|
-
|
145
|
-
|
165
|
+
double(
|
166
|
+
'Dependency',
|
167
|
+
name: 'cookbook_2',
|
168
|
+
locked_version: Semverse::Version.new('1.1.1')
|
169
|
+
),
|
170
|
+
double(
|
171
|
+
'Dependency',
|
172
|
+
name: 'cookbook_3',
|
173
|
+
locked_version: Semverse::Version.new('2.2.2')
|
174
|
+
),
|
175
|
+
double(
|
176
|
+
'Dependency',
|
177
|
+
name: 'cookbook_4',
|
178
|
+
locked_version: Semverse::Version.new('3.3.3')
|
179
|
+
)
|
146
180
|
],
|
147
181
|
[
|
148
|
-
double(
|
149
|
-
|
150
|
-
|
182
|
+
double(
|
183
|
+
'Dependency',
|
184
|
+
name: 'cookbook_2',
|
185
|
+
locked_version: Semverse::Version.new('1.1.1')
|
186
|
+
),
|
187
|
+
double(
|
188
|
+
'Dependency',
|
189
|
+
name: 'cookbook_3',
|
190
|
+
locked_version: Semverse::Version.new('2.2.2')
|
191
|
+
),
|
192
|
+
double(
|
193
|
+
'Dependency',
|
194
|
+
name: 'cookbook_4',
|
195
|
+
locked_version: Semverse::Version.new('3.3.3')
|
196
|
+
)
|
151
197
|
]
|
152
198
|
)
|
153
|
-
|
199
|
+
end
|
154
200
|
|
155
201
|
it 'returns false' do
|
156
202
|
expect(subject.dependencies_changed_after_update?).to be false
|
@@ -158,22 +204,44 @@ describe Promote::Cookbook do
|
|
158
204
|
end
|
159
205
|
|
160
206
|
context 'there is a version change' do
|
161
|
-
|
162
|
-
before {
|
163
|
-
allow(Berkshelf::Berksfile).to receive(:from_file).and_return(fake_berks)
|
207
|
+
before do
|
164
208
|
allow(fake_berks).to receive(:list).and_return(
|
165
209
|
[
|
166
|
-
double(
|
167
|
-
|
168
|
-
|
210
|
+
double(
|
211
|
+
'Dependency',
|
212
|
+
name: 'cookbook_2',
|
213
|
+
locked_version: Semverse::Version.new('1.1.1')
|
214
|
+
),
|
215
|
+
double(
|
216
|
+
'Dependency',
|
217
|
+
name: 'cookbook_3',
|
218
|
+
locked_version: Semverse::Version.new('2.2.2')
|
219
|
+
),
|
220
|
+
double(
|
221
|
+
'Dependency',
|
222
|
+
name: 'cookbook_4',
|
223
|
+
locked_version: Semverse::Version.new('3.3.3')
|
224
|
+
)
|
169
225
|
],
|
170
226
|
[
|
171
|
-
double(
|
172
|
-
|
173
|
-
|
227
|
+
double(
|
228
|
+
'Dependency',
|
229
|
+
name: 'cookbook_2',
|
230
|
+
locked_version: Semverse::Version.new('1.1.1')
|
231
|
+
),
|
232
|
+
double(
|
233
|
+
'Dependency',
|
234
|
+
name: 'cookbook_3',
|
235
|
+
locked_version: Semverse::Version.new('2.2.3')
|
236
|
+
),
|
237
|
+
double(
|
238
|
+
'Dependency',
|
239
|
+
name: 'cookbook_4',
|
240
|
+
locked_version: Semverse::Version.new('3.3.3')
|
241
|
+
)
|
174
242
|
]
|
175
243
|
)
|
176
|
-
|
244
|
+
end
|
177
245
|
|
178
246
|
it 'returns true' do
|
179
247
|
expect(subject.dependencies_changed_after_update?).to be true
|
@@ -181,21 +249,39 @@ describe Promote::Cookbook do
|
|
181
249
|
end
|
182
250
|
|
183
251
|
context 'a dependency is removed' do
|
184
|
-
|
185
|
-
before {
|
186
|
-
allow(Berkshelf::Berksfile).to receive(:from_file).and_return(fake_berks)
|
252
|
+
before do
|
187
253
|
allow(fake_berks).to receive(:list).and_return(
|
188
254
|
[
|
189
|
-
double(
|
190
|
-
|
191
|
-
|
255
|
+
double(
|
256
|
+
'Dependency',
|
257
|
+
name: 'cookbook_2',
|
258
|
+
locked_version: Semverse::Version.new('1.1.1')
|
259
|
+
),
|
260
|
+
double(
|
261
|
+
'Dependency',
|
262
|
+
name: 'cookbook_3',
|
263
|
+
locked_version: Semverse::Version.new('2.2.2')
|
264
|
+
),
|
265
|
+
double(
|
266
|
+
'Dependency',
|
267
|
+
name: 'cookbook_4',
|
268
|
+
locked_version: Semverse::Version.new('3.3.3')
|
269
|
+
)
|
192
270
|
],
|
193
271
|
[
|
194
|
-
double(
|
195
|
-
|
272
|
+
double(
|
273
|
+
'Dependency',
|
274
|
+
name: 'cookbook_2',
|
275
|
+
locked_version: Semverse::Version.new('1.1.1')
|
276
|
+
),
|
277
|
+
double(
|
278
|
+
'Dependency',
|
279
|
+
name: 'cookbook_4',
|
280
|
+
locked_version: Semverse::Version.new('3.3.3')
|
281
|
+
)
|
196
282
|
]
|
197
283
|
)
|
198
|
-
|
284
|
+
end
|
199
285
|
|
200
286
|
it 'returns true' do
|
201
287
|
expect(subject.dependencies_changed_after_update?).to be true
|
@@ -203,23 +289,49 @@ describe Promote::Cookbook do
|
|
203
289
|
end
|
204
290
|
|
205
291
|
context 'a dependency is added' do
|
206
|
-
|
207
|
-
before {
|
208
|
-
allow(Berkshelf::Berksfile).to receive(:from_file).and_return(fake_berks)
|
292
|
+
before do
|
209
293
|
allow(fake_berks).to receive(:list).and_return(
|
210
294
|
[
|
211
|
-
double(
|
212
|
-
|
213
|
-
|
295
|
+
double(
|
296
|
+
'Dependency',
|
297
|
+
name: 'cookbook_2',
|
298
|
+
locked_version: Semverse::Version.new('1.1.1')
|
299
|
+
),
|
300
|
+
double(
|
301
|
+
'Dependency',
|
302
|
+
name: 'cookbook_3',
|
303
|
+
locked_version: Semverse::Version.new('2.2.2')
|
304
|
+
),
|
305
|
+
double(
|
306
|
+
'Dependency',
|
307
|
+
name: 'cookbook_4',
|
308
|
+
locked_version: Semverse::Version.new('3.3.3')
|
309
|
+
)
|
214
310
|
],
|
215
311
|
[
|
216
|
-
double(
|
217
|
-
|
218
|
-
|
219
|
-
|
312
|
+
double(
|
313
|
+
'Dependency',
|
314
|
+
name: 'cookbook_2',
|
315
|
+
locked_version: Semverse::Version.new('1.1.1')
|
316
|
+
),
|
317
|
+
double(
|
318
|
+
'Dependency',
|
319
|
+
name: 'cookbook_3',
|
320
|
+
locked_version: Semverse::Version.new('2.2.2')
|
321
|
+
),
|
322
|
+
double(
|
323
|
+
'Dependency',
|
324
|
+
name: 'cookbook_4',
|
325
|
+
locked_version: Semverse::Version.new('3.3.3')
|
326
|
+
),
|
327
|
+
double(
|
328
|
+
'Dependency',
|
329
|
+
name: 'cookbook_5',
|
330
|
+
locked_version: Semverse::Version.new('3.3.3')
|
331
|
+
)
|
220
332
|
]
|
221
333
|
)
|
222
|
-
|
334
|
+
end
|
223
335
|
|
224
336
|
it 'returns true' do
|
225
337
|
expect(subject.dependencies_changed_after_update?).to be true
|
@@ -227,24 +339,38 @@ describe Promote::Cookbook do
|
|
227
339
|
end
|
228
340
|
|
229
341
|
context 'the cookbook under test has changed' do
|
230
|
-
|
231
|
-
before {
|
232
|
-
allow(Berkshelf::Berksfile).to receive(:from_file).and_return(fake_berks)
|
342
|
+
before do
|
233
343
|
allow(fake_berks).to receive(:list).and_return(
|
234
344
|
[
|
235
|
-
double(
|
236
|
-
|
345
|
+
double(
|
346
|
+
'Dependency',
|
347
|
+
name: 'cookbook_1',
|
348
|
+
locked_version: Semverse::Version.new('1.1.1')
|
349
|
+
),
|
350
|
+
double(
|
351
|
+
'Dependency',
|
352
|
+
name: 'cookbook_3',
|
353
|
+
locked_version: Semverse::Version.new('2.2.2')
|
354
|
+
)
|
237
355
|
],
|
238
356
|
[
|
239
|
-
double(
|
240
|
-
|
357
|
+
double(
|
358
|
+
'Dependency',
|
359
|
+
name: 'cookbook_1',
|
360
|
+
locked_version: Semverse::Version.new('1.1.2')
|
361
|
+
),
|
362
|
+
double(
|
363
|
+
'Dependency',
|
364
|
+
name: 'cookbook_3',
|
365
|
+
locked_version: Semverse::Version.new('2.2.2')
|
366
|
+
)
|
241
367
|
]
|
242
368
|
)
|
243
|
-
|
369
|
+
end
|
244
370
|
|
245
371
|
it 'returns false' do
|
246
372
|
expect(subject.dependencies_changed_after_update?).to be false
|
247
373
|
end
|
248
374
|
end
|
249
375
|
end
|
250
|
-
end
|
376
|
+
end
|