beaker 1.13.1 → 1.14.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -16,6 +16,9 @@ module Beaker
16
16
  :project => ENV['BEAKER_PROJECT'] || ENV['BEAKER_project'],
17
17
  :department => ENV['BEAKER_DEPARTMENT'] || ENV['BEAKER_department'],
18
18
  :jenkins_build_url => ENV['BEAKER_BUILD_URL'] || ENV['BUILD_URL'],
19
+ :release_apt_repo_url=> ENV['BEAKER_RELEASE_APT_REPO'] || ENV['RELEASE_APT_REPO'] || "http://apt.puppetlabs.com",
20
+ :release_yum_repo_url=> ENV['BEAKER_RELEASE_YUM_REPO'] || ENV['RELEASE_YUM_REPO'] || "http://yum.puppetlabs.com",
21
+ :dev_builds_url => ENV['BEAKER_DEV_BUILDS_URL'] || ENV['DEV_BUILDS_URL'] || "http://builds.puppetlabs.lan",
19
22
  :consoleport => consoleport ? consoleport.to_i : nil,
20
23
  :type => (ENV['BEAKER_IS_PE'] || ENV['IS_PE']) ? 'pe' : nil,
21
24
  :pe_dir => ENV['BEAKER_PE_DIR'] || ENV['pe_dist_dir'],
@@ -80,7 +83,6 @@ module Beaker
80
83
  :repo_proxy => false,
81
84
  :package_proxy => false,
82
85
  :add_el_extras => false,
83
- :add_master_entry => false,
84
86
  :consoleport => 443,
85
87
  :pe_dir => '/opt/enterprise/dists',
86
88
  :pe_version_file => 'LATEST',
@@ -17,6 +17,16 @@ module Beaker
17
17
  },
18
18
  }
19
19
 
20
+ # A string with the name of the platform.
21
+ attr_reader :variant
22
+ # A string with the version number of the platform.
23
+ attr_reader :version
24
+ # A string with the codename of the platform+version, nil on platforms
25
+ # without codenames.
26
+ attr_reader :codename
27
+ # A string with the cpu architecture of the platform.
28
+ attr_reader :arch
29
+
20
30
  #Creates the Platform object. Checks to ensure that the platform String provided meets the platform
21
31
  #formatting rules. Platforms name must be of the format /^OSFAMILY-VERSION-ARCH.*$/ where OSFAMILY is one of:
22
32
  # * osx
@@ -36,7 +46,30 @@ module Beaker
36
46
  if name !~ PLATFORMS
37
47
  raise ArgumentError, "Unsupported platform name #{name}"
38
48
  end
49
+
39
50
  super
51
+
52
+ @variant, version, @arch = self.split('-', 3)
53
+ codename_version_hash = PLATFORM_VERSION_CODES[@variant.to_sym]
54
+
55
+ @version = version
56
+ @codename = nil
57
+
58
+ if codename_version_hash
59
+ if codename_version_hash[version]
60
+ @version = codename_version_hash[version]
61
+ else
62
+ version = version.delete('.')
63
+ version_codename_hash = codename_version_hash.invert
64
+ @codename = version_codename_hash[version]
65
+ end
66
+ end
67
+ end
68
+
69
+ # Returns array of attributes to allow single line assignment to local
70
+ # variables in DSL and test case methods.
71
+ def to_array
72
+ return @variant, @version, @arch, @codename
40
73
  end
41
74
 
42
75
  # Returns the platform string with the platform version as a codename. If no conversion is
@@ -44,20 +77,11 @@ module Beaker
44
77
  # @example Platform.new('debian-7-xxx').with_version_codename == 'debian-wheezy-xxx'
45
78
  # @return [String] the platform string with the platform version represented as a codename
46
79
  def with_version_codename
47
- name, version, extra = self.split('-', 3)
48
- PLATFORM_VERSION_CODES.each_key do |platform|
49
- if name =~ /#{platform}/
50
- PLATFORM_VERSION_CODES[platform].each do |version_codename, version_number|
51
- #remove '.' from version number
52
- if version.delete('.') =~ /#{version_number}/
53
- version = version_codename
54
- break
55
- end
56
- end
57
- break
58
- end
80
+ version_array = [@variant, @version, @arch]
81
+ if @codename
82
+ version_array = [@variant, @codename, @arch]
59
83
  end
60
- [name, version, extra].join('-')
84
+ return version_array.join('-')
61
85
  end
62
86
 
63
87
  # Returns the platform string with the platform version as a number. If no conversion is necessary
@@ -65,19 +89,7 @@ module Beaker
65
89
  # @example Platform.new('debian-wheezy-xxx').with_version_number == 'debian-7-xxx'
66
90
  # @return [String] the platform string with the platform version represented as a number
67
91
  def with_version_number
68
- name, version, extra = self.split('-', 3)
69
- PLATFORM_VERSION_CODES.each_key do |platform|
70
- if name =~ /#{platform}/
71
- PLATFORM_VERSION_CODES[platform].each do |version_codename, version_number|
72
- if version =~ /#{version_codename}/
73
- version = version_number
74
- break
75
- end
76
- end
77
- break
78
- end
79
- end
80
- [name, version, extra].join('-')
92
+ [@variant, @version, @arch].join('-')
81
93
  end
82
94
 
83
95
  end
data/lib/beaker/result.rb CHANGED
@@ -31,9 +31,10 @@ module Beaker
31
31
  end
32
32
 
33
33
  def convert string
34
- if string.respond_to?( :force_encoding ) and defined?( Encoding )
34
+ if string.respond_to?( :encode )
35
35
  # We're running in >= 1.9 and we'll need to convert
36
- return string.force_encoding( Encoding.default_external )
36
+ # Remove invalide and undefined UTF-8 character encodings
37
+ return string.encode('UTF-8', 'binary', :invalid => :replace, :undef => :replace, :replace => '')
37
38
  else
38
39
  # We're running in < 1.9 and Ruby doesn't care
39
40
  return string
@@ -49,14 +49,8 @@ module Beaker
49
49
 
50
50
  check_for_beaker_type_config
51
51
  command = beaker_command
52
-
53
- begin
54
- puts command if verbose
55
- success = system(command)
56
- preserve_configuration(@options_file)
57
- rescue
58
- puts failure_message if failure_message
59
- end
52
+ puts command if verbose
53
+ success = system(command)
60
54
  if fail_mode == "fast" && !success
61
55
  $stderr.puts "#{command} failed"
62
56
  exit $?.exitstatus
@@ -1,5 +1,5 @@
1
1
  module Beaker
2
2
  module Version
3
- STRING = '1.13.1'
3
+ STRING = '1.14.0'
4
4
  end
5
5
  end
@@ -9,6 +9,12 @@ module Beaker
9
9
  basic_hosts }
10
10
  let( :master_certname ) { 'master_certname' }
11
11
 
12
+ it 'generates 3.4 answers for 3.4 hosts' do
13
+ @ver = '3.4'
14
+ Beaker::Answers::Version34.should_receive( :answers ).with( hosts, master_certname, {}).once
15
+ subject.answers( @ver, hosts, master_certname, {} )
16
+ end
17
+
12
18
  it 'generates 3.2 answers for 3.3 hosts' do
13
19
  @ver = '3.3'
14
20
  Beaker::Answers::Version32.should_receive( :answers ).with( hosts, master_certname, {}).once
@@ -52,6 +58,23 @@ module Beaker
52
58
  end
53
59
 
54
60
  module Answers
61
+ describe Version34 do
62
+ let( :options ) { Beaker::Options::Presets.env_vars }
63
+ let( :basic_hosts ) { make_hosts( {'pe_ver' => @ver } ) }
64
+ let( :hosts ) { basic_hosts[0]['roles'] = ['master', 'agent']
65
+ basic_hosts[1]['roles'] = ['dashboard', 'agent']
66
+ basic_hosts[2]['roles'] = ['database', 'agent']
67
+ basic_hosts }
68
+ let( :master_certname ) { 'master_certname' }
69
+ it 'should add answers to the host objects' do
70
+ @ver = '3.4'
71
+ answers = subject.answers( hosts, master_certname, options )
72
+ hosts.each do |host|
73
+ expect( host[:answers] ).to be === answers[host.name]
74
+ end
75
+ end
76
+ end
77
+
55
78
  describe Version32 do
56
79
  let( :options ) { Beaker::Options::Presets.env_vars }
57
80
  let( :basic_hosts ) { make_hosts( {'pe_ver' => @ver } ) }
@@ -0,0 +1,239 @@
1
+ require 'spec_helper'
2
+
3
+ EZBAKE_CONFIG_EXAMPLE= {
4
+ :project => 'jvm-puppet',
5
+ :real_name => 'jvm-puppet',
6
+ :user => 'puppet',
7
+ :group => 'puppet',
8
+ :uberjar_name => 'jvm-puppet-release.jar',
9
+ :config_files => [],
10
+ :terminus_info => {},
11
+ :debian => { :additional_dependencies => ["puppet (= 3.6.1-puppetlabs1)"], },
12
+ :redhat => { :additional_dependencies => ["puppet = 3.6.1"], },
13
+ :java_args => '-Xmx192m',
14
+ }
15
+
16
+ class ClassMixedWithEZBakeUtils
17
+ include Beaker::DSL::EZBakeUtils
18
+
19
+ def initialize_ezbake_config
20
+ Beaker::DSL::EZBakeUtils.config = EZBAKE_CONFIG_EXAMPLE
21
+ end
22
+
23
+ def wipe_out_ezbake_config
24
+ Beaker::DSL::EZBakeUtils.config = nil
25
+ end
26
+
27
+ def logger
28
+ @logger ||= RSpec::Mocks::Mock.new('logger').as_null_object
29
+ end
30
+ end
31
+
32
+ module Beaker::DSL::EZBakeUtils::EZBake
33
+ Config = EZBAKE_CONFIG_EXAMPLE
34
+ end
35
+
36
+ describe ClassMixedWithEZBakeUtils do
37
+ let( :opts ) { Beaker::Options::Presets.env_vars }
38
+ let( :host ) { double.as_null_object }
39
+ let( :local_commands ) { Beaker::DSL::EZBakeUtils::LOCAL_COMMANDS_REQUIRED }
40
+ let( :remote_packages ) { Beaker::DSL::EZBakeUtils::REMOTE_PACKAGES_REQUIRED }
41
+
42
+ describe '#ezbake_config' do
43
+ it "returns a map with ezbake configuration parameters" do
44
+ subject.initialize_ezbake_config
45
+ config = subject.ezbake_config
46
+ expect(config).to include(EZBAKE_CONFIG_EXAMPLE)
47
+ end
48
+ end
49
+
50
+ describe '#ezbake_tools_available?' do
51
+
52
+ before do
53
+ allow(subject).to receive(:check_for_package) { true }
54
+ allow(subject).to receive(:system) { true }
55
+ end
56
+
57
+ describe "checks for remote packages when given a host" do
58
+
59
+ it "and succeeds if all packages are found" do
60
+ remote_packages.each do |package|
61
+ expect(subject).to receive(:check_for_package).with(host, package)
62
+ end
63
+ subject.ezbake_tools_available? host
64
+ end
65
+
66
+ it "and raises an exception if a package is missing" do
67
+ allow(subject).to receive(:check_for_package) { false }
68
+ remote_packages.each do |package|
69
+ expect(subject).to receive(:check_for_package).with(host, package)
70
+ break # just need first element
71
+ end
72
+ expect{
73
+ subject.ezbake_tools_available? host
74
+ }.to raise_error(RuntimeError, /Required package, .*, not installed on/)
75
+ end
76
+
77
+ end
78
+
79
+ describe "checks for local successful local commands when no host given" do
80
+
81
+ it "and succeeds if all commands return successfully" do
82
+ local_commands.each do |software_name, command, additional_error_messages|
83
+ expect(subject).to receive(:system).with(/#{command}/)
84
+ end
85
+ subject.ezbake_tools_available?
86
+ end
87
+
88
+ it "and raises an exception if a command returns failure" do
89
+ allow(subject).to receive(:system) { false }
90
+ local_commands.each do |software_name, command, additional_error_messages|
91
+ expect(subject).to receive(:system).with(/#{command}/)
92
+ break # just need first element
93
+ end
94
+ expect{
95
+ subject.ezbake_tools_available?
96
+ }.to raise_error(RuntimeError, /Must have .* installed on development system./)
97
+ end
98
+
99
+ end
100
+
101
+ end
102
+
103
+ describe '#ezbake_stage' do
104
+ before do
105
+ allow(subject).to receive(:ezbake_tools_available?) { true }
106
+ subject.wipe_out_ezbake_config
107
+ end
108
+
109
+ it "initializes EZBakeUtils.config" do
110
+ Dir.stub( :chdir ).and_yield()
111
+ allow(subject).to receive(:conditionally_clone) { true }
112
+
113
+ expect(subject).to receive(:`).with(/^lein.*/).ordered
114
+ expect(subject).to receive(:`).with("rake package:bootstrap").ordered
115
+ expect(subject).to receive(:load) { }.ordered
116
+ expect(subject).to receive(:`).with(anything()).ordered
117
+
118
+ config = subject.ezbake_config
119
+ expect(config).to eq(nil)
120
+
121
+ subject.ezbake_stage "ruby", "is", "junky"
122
+
123
+ config = subject.ezbake_config
124
+ expect(config).to include(EZBAKE_CONFIG_EXAMPLE)
125
+ end
126
+ end
127
+
128
+ RSpec.shared_examples "installs-ezbake-dependencies" do
129
+ it "installs ezbake dependencies" do
130
+ expect(subject).to receive(:install_package).
131
+ with( kind_of(FakeHost), anything(), anything())
132
+ subject.install_ezbake_deps host
133
+ end
134
+ end
135
+
136
+ describe '#install_ezbake_deps' do
137
+ let( :platform ) { Beaker::Platform.new('redhat-7-i386') }
138
+ let(:host) do
139
+ FakeHost.new( :options => { 'platform' => platform })
140
+ end
141
+
142
+ before do
143
+ allow(subject).to receive(:ezbake_tools_available?) { true }
144
+ subject.initialize_ezbake_config
145
+ end
146
+
147
+ it "Raises an exception for unsupported platforms." do
148
+ expect{
149
+ subject.install_ezbake_deps host
150
+ }.to raise_error(RuntimeError, /No repository installation step for/)
151
+ end
152
+
153
+ context "When host is a debian-like platform" do
154
+ let( :platform ) { Beaker::Platform.new('debian-7-i386') }
155
+ include_examples "installs-ezbake-dependencies"
156
+ end
157
+
158
+ context "When host is a redhat-like platform" do
159
+ let( :platform ) { Beaker::Platform.new('centos-7-i386') }
160
+ include_examples "installs-ezbake-dependencies"
161
+ end
162
+ end
163
+
164
+ def install_from_ezbake_common_expects
165
+ expect(subject).to receive(:`).with(/rake package:tar/).ordered
166
+ expect(subject).to receive(:scp_to).
167
+ with( kind_of(FakeHost), anything(), anything()).ordered
168
+ expect(subject).to receive(:on).
169
+ with( kind_of(FakeHost), /tar -xzf/).ordered
170
+ expect(subject).to receive(:on).
171
+ with( kind_of(FakeHost), /make -e install-#{EZBAKE_CONFIG_EXAMPLE[:real_name]}/).ordered
172
+ end
173
+
174
+ describe '#install_from_ezbake' do
175
+ let( :platform ) { Beaker::Platform.new('redhat-7-i386') }
176
+ let(:host) do
177
+ FakeHost.new( :options => { 'platform' => platform })
178
+ end
179
+
180
+ before do
181
+ allow(subject).to receive(:ezbake_tools_available?) { true }
182
+ end
183
+
184
+
185
+ context "for non *nix-like platforms" do
186
+ let( :platform ) { Beaker::Platform.new('windows-7-i386') }
187
+ it "raises an exception" do
188
+ expect{
189
+ subject.install_from_ezbake host, "blah", "blah"
190
+ }.to raise_error(RuntimeError, /Beaker::DSL::EZBakeUtils unsupported platform:/)
191
+ end
192
+ end
193
+
194
+ it "raises an exception for unsupported *nix-like platforms" do
195
+ Dir.stub( :chdir ).and_yield()
196
+ install_from_ezbake_common_expects
197
+ expect{
198
+ subject.install_from_ezbake host, "blah", "blah"
199
+ }.to raise_error(RuntimeError, /No ezbake installation step for/)
200
+ end
201
+
202
+ context "When Beaker::DSL::EZBakeUtils.config is nil" do
203
+ let( :platform ) { Beaker::Platform.new('el-7-i386') }
204
+ before do
205
+ Dir.stub( :chdir ).and_yield()
206
+ subject.wipe_out_ezbake_config
207
+ end
208
+
209
+ it "runs ezbake_stage" do
210
+ expect(subject).to receive(:ezbake_stage) {
211
+ Beaker::DSL::EZBakeUtils.config = EZBAKE_CONFIG_EXAMPLE
212
+ }.ordered
213
+ install_from_ezbake_common_expects
214
+ expect(subject).to receive(:on).
215
+ with( kind_of(FakeHost), /install-rpm-sysv-init/).ordered
216
+ subject.install_from_ezbake host, "blah", "blah"
217
+ end
218
+
219
+ end
220
+
221
+ context "When Beaker::DSL::EZBakeUtils.config is a hash" do
222
+ let( :platform ) { Beaker::Platform.new('el-7-i386') }
223
+ before do
224
+ Dir.stub( :chdir ).and_yield()
225
+ subject.initialize_ezbake_config
226
+ end
227
+
228
+ it "skips ezbake_stage" do
229
+ install_from_ezbake_common_expects
230
+ expect(subject).to receive(:on).
231
+ with( kind_of(FakeHost), /install-rpm-sysv-init/).ordered
232
+ subject.install_from_ezbake host, "blah", "blah"
233
+ end
234
+
235
+ end
236
+
237
+ end
238
+
239
+ end
@@ -300,7 +300,7 @@ describe ClassMixedWithDSLHelpers do
300
300
  it 'scps the module to the module dir' do
301
301
  subject.stub( :hosts ).and_return( hosts )
302
302
 
303
- subject.should_receive( :scp_to ).with( master, '/module', '/etc/puppet/modules/test' ).once
303
+ subject.should_receive( :puppet ).with('module install test' ).once
304
304
  subject.puppet_module_install_on( master, {:source => '/module', :module_name => 'test'} )
305
305
  end
306
306
  end
@@ -776,6 +776,7 @@ describe ClassMixedWithDSLHelpers do
776
776
  subject.instance_variable_set(:@path, test_case_path)
777
777
  host.stub(:tmpdir).and_return(tmpdir_path)
778
778
  host.stub(:file_exist?).and_return(true)
779
+ subject.stub( :options ).and_return( {} )
779
780
  end
780
781
 
781
782
  before do
@@ -802,12 +803,14 @@ describe ClassMixedWithDSLHelpers do
802
803
  let(:puppetservice) { 'whatever' }
803
804
 
804
805
  it 'bounces puppet twice' do
806
+ subject.stub(:curl_with_retries)
805
807
  subject.with_puppet_running_on(host, {})
806
808
  expect(host).to execute_commands_matching(/#{@ps} restart/).exactly(2).times
807
809
  end
808
810
 
809
811
  it 'yield to a block after bouncing service' do
810
812
  execution = 0
813
+ subject.stub(:curl_with_retries)
811
814
  expect do
812
815
  subject.with_puppet_running_on(host, {}) do
813
816
  expect(host).to execute_commands_matching(/#{@ps} restart/).once
@@ -966,43 +969,50 @@ describe ClassMixedWithDSLHelpers do
966
969
  end
967
970
 
968
971
 
969
- describe 'copy_root_module_to' do
970
- def source_to_scp (source, target, items)
971
- subject.stub(:parse_for_moduleroot).and_return('/totalfake/testmodule')
972
- Dir.stub(:getpwd).and_return('/totalfake/testmodule')
973
-
974
- items = [items] unless items.kind_of?(Array)
975
- File.stub(:exists?).with(any_args()).and_return(false)
976
- File.stub(:directory?).with(any_args()).and_return(false)
977
- items.each do |item|
978
- source_item = File.join(source,item)
979
- File.stub(:exists?).with(source_item).and_return(true)
980
- options = {}
981
- if ['manifests','lib','templates','files'].include? item
982
- File.stub(:directory?).with(source_item).and_return(true)
983
- options = {:mkdir => true}
972
+ describe 'copy_module_to' do
973
+ let(:ignore_list){%w(.git .idea .vagrant .vendor acceptance spec tests log . ..)}
974
+ let(:source){'./'}
975
+ let(:target){'/etc/puppetlabs/puppet/modules/testmodule'}
976
+ let(:module_parse_name){'testmodule'}
977
+
978
+ shared_examples 'copy_module_to' do |opts|
979
+ it{
980
+ host = double("host")
981
+ host.stub(:[]).with('distmoduledir').and_return('/etc/puppetlabs/puppet/modules')
982
+ Dir.stub(:getpwd).and_return(source)
983
+
984
+ subject.stub(:parse_for_moduleroot).and_return(source)
985
+ if module_parse_name
986
+ subject.stub(:parse_for_modulename).with(any_args()).and_return(module_parse_name)
987
+ else
988
+ subject.should_not_receive(:parse_for_modulename)
984
989
  end
985
- master.should_receive(:do_scp_to).with(source_item,target,options).ordered
986
- end
990
+
991
+ File.stub(:exists?).with(any_args()).and_return(false)
992
+ File.stub(:directory?).with(any_args()).and_return(false)
993
+
994
+ subject.should_receive(:scp_to).with(host,source, target, {:ignore => ignore_list})
995
+ if opts.nil?
996
+ subject.copy_module_to(host)
997
+ else
998
+ subject.copy_module_to(host,opts)
999
+ end
1000
+ }
1001
+ end
1002
+ describe 'should call scp with the correct info, with only providing host' do
1003
+ let(:target){'/etc/puppetlabs/puppet/modules/testmodule'}
1004
+
1005
+ it_should_behave_like 'copy_module_to'
1006
+ end
1007
+ describe 'should call scp with the correct info, when specifying the modulename' do
1008
+ let(:target){'/etc/puppetlabs/puppet/modules/bogusmodule'}
1009
+ let(:module_parse_name){false}
1010
+ it_should_behave_like 'copy_module_to', {:module_name =>'bogusmodule'}
987
1011
  end
988
- it 'should call scp with the correct info, with only providing host' do
989
- files = ['manifests','lib','templates','metadata.json','Modulefile','files']
990
- source_to_scp '/totalfake/testmodule',"#{master['puppetpath']}/modules/testmodule",files
991
- subject.stub(:parse_for_modulename).with(any_args()).and_return("testmodule")
992
- subject.copy_root_module_to(master)
993
- end
994
- it 'should call scp with the correct info, when specifying the modulename' do
995
- files = ['manifests','lib','metadata.json','Modulefile']
996
- source_to_scp '/totalfake/testmodule',"#{master['puppetpath']}/modules/bogusmodule",files
997
- subject.stub(:parse_for_modulename).and_return('testmodule')
998
- subject.copy_root_module_to(master,{:module_name =>"bogusmodule"})
999
- end
1000
- it 'should call scp with the correct info, when specifying the target to a different path' do
1001
- files = ['manifests','lib','templates','metadata.json','Modulefile','files']
1002
- target = "/opt/shared/puppet/modules"
1003
- source_to_scp '/totalfake/testmodule',"#{target}/testmodule",files
1004
- subject.stub(:parse_for_modulename).and_return('testmodule')
1005
- subject.copy_root_module_to(master,{:target_module_path => target})
1012
+ describe 'should call scp with the correct info, when specifying the target to a different path' do
1013
+ target = '/opt/shared/puppet/modules'
1014
+ let(:target){"#{target}/testmodule"}
1015
+ it_should_behave_like 'copy_module_to', {:target_module_path => target}
1006
1016
  end
1007
1017
  end
1008
1018