beaker 2.33.0 → 2.34.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (44) hide show
  1. checksums.yaml +8 -8
  2. data/HISTORY.md +173 -2
  3. data/README.md +5 -0
  4. data/acceptance/tests/base/dsl/helpers/host_helpers/check_for_package_test.rb +0 -5
  5. data/acceptance/tests/base/dsl/helpers/host_helpers/install_package_test.rb +0 -4
  6. data/acceptance/tests/base/dsl/helpers/host_helpers/upgrade_package_test.rb +0 -4
  7. data/docs/Beaker-Libraries.md +8 -0
  8. data/docs/Beaker-Recipes.md +13 -0
  9. data/docs/Docker-Support.md +19 -0
  10. data/docs/README.md +2 -0
  11. data/docs/hosts/cisco.md +60 -0
  12. data/docs/hosts/eos.md +2 -2
  13. data/lib/beaker/command.rb +4 -45
  14. data/lib/beaker/dsl/helpers/host_helpers.rb +14 -9
  15. data/lib/beaker/dsl/install_utils/foss_utils.rb +32 -32
  16. data/lib/beaker/host.rb +7 -3
  17. data/lib/beaker/host/cisco.rb +124 -0
  18. data/lib/beaker/host/pswindows/exec.rb +11 -0
  19. data/lib/beaker/host/pswindows/user.rb +1 -1
  20. data/lib/beaker/host/unix.rb +9 -2
  21. data/lib/beaker/host/unix/exec.rb +43 -0
  22. data/lib/beaker/host/unix/file.rb +19 -4
  23. data/lib/beaker/host/windows/exec.rb +13 -0
  24. data/lib/beaker/host/windows/user.rb +1 -1
  25. data/lib/beaker/hypervisor/docker.rb +9 -0
  26. data/lib/beaker/network_manager.rb +3 -1
  27. data/lib/beaker/test_case.rb +2 -0
  28. data/lib/beaker/version.rb +1 -1
  29. data/spec/beaker/command_spec.rb +17 -27
  30. data/spec/beaker/dsl/helpers/host_helpers_spec.rb +13 -1
  31. data/spec/beaker/dsl/install_utils/foss_utils_spec.rb +24 -15
  32. data/spec/beaker/dsl/install_utils/module_utils_spec.rb +2 -1
  33. data/spec/beaker/host/cisco_spec.rb +182 -0
  34. data/spec/beaker/host/pswindows/exec_spec.rb +54 -0
  35. data/spec/beaker/host/pswindows/user_spec.rb +70 -0
  36. data/spec/beaker/host/unix/exec_spec.rb +30 -0
  37. data/spec/beaker/host/unix/file_spec.rb +11 -4
  38. data/spec/beaker/host/unix/pkg_spec.rb +0 -1
  39. data/spec/beaker/host/unix_spec.rb +9 -0
  40. data/spec/beaker/host/windows/exec_spec.rb +17 -24
  41. data/spec/beaker/host/windows/user_spec.rb +70 -0
  42. data/spec/beaker/host_spec.rb +21 -0
  43. data/spec/beaker/hypervisor/docker_spec.rb +35 -0
  44. metadata +10 -2
@@ -76,4 +76,17 @@ module Windows::Exec
76
76
  ssh_service_restart()
77
77
  end
78
78
 
79
+ # Gets the specific prepend commands as needed for this host
80
+ #
81
+ # @param [String] command Command to be executed
82
+ # @param [String] user_pc List of user-specified commands to prepend
83
+ # @param [Hash] opts optional parameters
84
+ # @option opts [Boolean] :cmd_exe whether cmd.exe should be used
85
+ #
86
+ # @return [String] Command string as needed for this host
87
+ def prepend_commands(command = '', user_pc = nil, opts = {})
88
+ cygwin_prefix = (self.is_cygwin? and opts[:cmd_exe]) ? 'cmd.exe /c' : ''
89
+ spacing = (user_pc && !cygwin_prefix.empty?) ? ' ' : ''
90
+ "#{cygwin_prefix}#{spacing}#{user_pc}"
91
+ end
79
92
  end
@@ -5,7 +5,7 @@ module Windows::User
5
5
  execute('cmd /c echo "" | wmic useraccount where localaccount="true" get name /format:value') do |result|
6
6
  users = []
7
7
  result.stdout.each_line do |line|
8
- users << (line.match(/^Name=([\w ]+)/) or next)[1]
8
+ users << (line.match(/^Name=(.+)/) or next)[1]
9
9
  end
10
10
 
11
11
  yield result if block_given?
@@ -81,6 +81,15 @@ module Beaker
81
81
  end
82
82
  end
83
83
 
84
+ unless host['mount_folders'].nil?
85
+ container_opts['HostConfig'] ||= {}
86
+ container_opts['HostConfig']['Binds'] = host['mount_folders'].values.map do |mount|
87
+ a = [ mount['host_path'], mount['container_path'] ]
88
+ a << mount['opts'] if mount.has_key?('opts')
89
+ a.join(':')
90
+ end
91
+ end
92
+
84
93
  # If the specified container exists, then use it rather creating a new one
85
94
  if container.nil?
86
95
  @logger.debug("Creating container from image #{image_name}")
@@ -57,7 +57,9 @@ module Beaker
57
57
  hypervisor = provision?(@options, host_hash) ? host_hash['hypervisor'] : 'none'
58
58
  @logger.debug "Hypervisor for #{name} is #{hypervisor}"
59
59
  @machines[hypervisor] = [] unless @machines[hypervisor]
60
- @machines[hypervisor] << Beaker::Host.create(name, host_hash, hostless_options)
60
+ host_itself = Beaker::Host.create(name, host_hash, hostless_options)
61
+ host_itself.validate_setup
62
+ @machines[hypervisor] << host_itself
61
63
  end
62
64
 
63
65
  @machines.each_key do |type|
@@ -136,6 +136,7 @@ module Beaker
136
136
  rescue StandardError, ScriptError, SignalException => e
137
137
  log_and_fail_test(e)
138
138
  ensure
139
+ @logger.info('Begin teardown')
139
140
  @teardown_procs.each do |teardown|
140
141
  begin
141
142
  teardown.call
@@ -143,6 +144,7 @@ module Beaker
143
144
  log_and_fail_test(e)
144
145
  end
145
146
  end
147
+ @logger.info('End teardown')
146
148
  end
147
149
  end
148
150
  @sublog = @logger.get_sublog
@@ -1,5 +1,5 @@
1
1
  module Beaker
2
2
  module Version
3
- STRING = '2.33.0'
3
+ STRING = '2.34.0'
4
4
  end
5
5
  end
@@ -6,7 +6,11 @@ module Beaker
6
6
  let(:args) { @args || Array.new }
7
7
  let(:options) { @options || Hash.new }
8
8
  subject(:cmd) { Command.new( command, args, options ) }
9
- let(:host) { Hash.new }
9
+ let(:host) {
10
+ h = Hash.new
11
+ allow( h ).to receive( :environment_string ).and_return( '' )
12
+ h
13
+ }
10
14
 
11
15
  it 'creates a new Command object' do
12
16
  @command = '/usr/bin/blah'
@@ -19,7 +23,6 @@ module Beaker
19
23
 
20
24
  expect( cmd.args_string ).to be == 'to the baz'
21
25
  expect( cmd.options_string ).to be == '--foo=bar'
22
- expect( cmd.environment_string_for(host, cmd.environment) ).to be == ''
23
26
 
24
27
  end
25
28
 
@@ -27,17 +30,19 @@ module Beaker
27
30
  it 'can prepend commands' do
28
31
  @command = '/usr/bin/blah'
29
32
  @args = [ 'to', 'the', 'baz' ]
30
- @options = { :foo => 'bar', :prepend_cmds => 'aloha!' }
33
+ @options = { :foo => 'bar' }
34
+ allow( host ).to receive( :prepend_commands ).and_return( 'aloha!' )
31
35
 
32
- expect( cmd.cmd_line({}) ).to be == "aloha! /usr/bin/blah --foo=bar to the baz"
36
+ expect( cmd.cmd_line( host ) ).to be == "aloha! /usr/bin/blah --foo=bar to the baz"
33
37
  end
34
38
 
35
39
  it 'can handle no prepend_cmds' do
36
40
  @command = '/usr/bin/blah'
37
41
  @args = [ 'to', 'the', 'baz' ]
38
- @options = { :foo => 'bar', :prepend_cmds => nil }
42
+ @options = { :foo => 'bar' }
43
+ allow( host ).to receive( :prepend_commands ).and_return( '' )
39
44
 
40
- expect( cmd.cmd_line({}) ).to be == "/usr/bin/blah --foo=bar to the baz"
45
+ expect( cmd.cmd_line( host ) ).to be == "/usr/bin/blah --foo=bar to the baz"
41
46
  end
42
47
  end
43
48
 
@@ -59,26 +64,6 @@ module Beaker
59
64
  end
60
65
  end
61
66
 
62
- describe '#environment_string_for' do
63
- let(:host) { {'pathseparator' => ':'} }
64
-
65
- it 'returns a blank string if theres no env' do
66
- expect( host ).to receive( :is_powershell? ).never
67
- expect( subject.environment_string_for(host, {}) ).to be == ''
68
- end
69
-
70
- it 'takes an env hash with var_name/value pairs' do
71
- expect( host ).to receive( :is_powershell? ).and_return(false)
72
- expect( subject.environment_string_for(host, {:HOME => '/'}) ).
73
- to be == "env HOME=\"/\""
74
- end
75
-
76
- it 'takes an env hash with var_name/value[Array] pairs' do
77
- expect( host ).to receive( :is_powershell? ).and_return(false)
78
- expect( subject.environment_string_for(host, {:LD_PATH => ['/', '/tmp']}) ).
79
- to be == "env LD_PATH=\"/:/tmp\""
80
- end
81
- end
82
67
 
83
68
  end
84
69
  describe HostCommand do
@@ -102,7 +87,12 @@ module Beaker
102
87
  end
103
88
  end
104
89
  describe SedCommand do
105
- let(:host) { Hash.new }
90
+ let(:host) {
91
+ h = Hash.new
92
+ allow( h ).to receive( :environment_string ).and_return( '' )
93
+ allow( h ).to receive( :prepend_commands ).and_return( '' )
94
+ h
95
+ }
106
96
  let(:platform) { @platform || 'unix' }
107
97
  let(:expression) { @expression || 's/b/s/' }
108
98
  let(:filename) { @filename || '/fakefile' }
@@ -50,7 +50,7 @@ describe ClassMixedWithDSLHelpers do
50
50
  subject.on( 'master', 'echo hello')
51
51
  end
52
52
 
53
- it 'if the host is a Symbol Object, finds the matching hsots with that Symbol as role' do
53
+ it 'if the host is a Symbol Object, finds the matching hosts with that Symbol as role' do
54
54
  allow( subject ).to receive( :hosts ).and_return( hosts )
55
55
 
56
56
  expect( master ).to receive( :exec ).once
@@ -157,6 +157,18 @@ describe ClassMixedWithDSLHelpers do
157
157
  end
158
158
  end
159
159
  end
160
+
161
+ it 'errors if command is not a String or Beaker::Command' do
162
+ expect {
163
+ subject.on( host, Object.new )
164
+ }.to raise_error( ArgumentError, /called\ with\ a\ String\ or\ Beaker/ )
165
+ end
166
+
167
+ it 'executes the passed Beaker::Command if given as command argument' do
168
+ command_test = Beaker::Command.new( 'echo face_testing' )
169
+ expect( master ).to receive( :exec ).with( command_test, anything )
170
+ subject.on( master, command_test )
171
+ end
160
172
  end
161
173
 
162
174
  describe "#retry_on" do
@@ -530,27 +530,31 @@ describe ClassMixedWithDSLInstallUtils do
530
530
  end
531
531
 
532
532
  describe 'configure_puppet_on' do
533
- before do
534
- allow(subject).to receive(:on).and_return(Beaker::Result.new({},''))
535
- end
536
533
  context 'on debian' do
537
534
  let(:platform) { 'debian-7-amd64' }
538
535
  let(:host) { make_host('testbox.test.local', :platform => 'debian-7-amd64') }
536
+
539
537
  it 'it sets the puppet.conf file to the provided config' do
540
538
  config = { 'main' => {'server' => 'testbox.test.local'} }
541
- expect(subject).to receive(:on).with(host, "echo \"[main]\nserver=testbox.test.local\n\n\" > #{host.puppet['config']}")
539
+ expected_config_string = "[main]\nserver=testbox.test.local\n\n"
540
+
541
+ expect( subject ).to receive( :create_remote_file ).with(
542
+ host, anything, expected_config_string
543
+ )
542
544
  subject.configure_puppet_on(host, config)
543
545
  end
544
546
  end
545
547
  context 'on windows' do
546
548
  let(:platform) { 'windows-2008R2-amd64' }
547
549
  let(:host) { make_host('testbox.test.local', :platform => 'windows-2008R2-amd64') }
550
+
548
551
  it 'it sets the puppet.conf file to the provided config' do
549
552
  config = { 'main' => {'server' => 'testbox.test.local'} }
550
- expect(subject).to receive(:on) do |host, command|
551
- expect(command.command).to eq('powershell.exe')
552
- expect(command.args).to eq(["-ExecutionPolicy Bypass", "-InputFormat None", "-NoLogo", "-NoProfile", "-NonInteractive", "-Command $text = \\\"[main]`nserver=testbox.test.local`n`n\\\"; Set-Content -path '#{host.puppet['config']}' -value $text"])
553
- end
553
+ expected_config_string = "[main]\nserver=testbox.test.local\n\n"
554
+
555
+ expect( subject ).to receive( :create_remote_file ).with(
556
+ host, anything, expected_config_string
557
+ )
554
558
  subject.configure_puppet_on(host, config)
555
559
  end
556
560
  end
@@ -565,22 +569,27 @@ describe ClassMixedWithDSLInstallUtils do
565
569
  allow( subject ).to receive(:hosts).and_return(hosts)
566
570
  allow( subject ).to receive(:on).and_return(Beaker::Result.new({},''))
567
571
  end
572
+
568
573
  context 'on debian' do
569
574
  let(:platform) { 'debian-7-amd64' }
570
- it 'it sets the puppet.conf file to the provided config' do
575
+
576
+ it 'calls configure_puppet_on correctly' do
571
577
  config = { 'main' => {'server' => 'testbox.test.local'} }
572
- expect(subject).to receive(:on).with(hosts[0], "echo \"[main]\nserver=testbox.test.local\n\n\" > #{hosts[0].puppet['config']}")
578
+ expect( subject ).to receive( :configure_puppet_on ).with(
579
+ anything, config
580
+ ).exactly( hosts.length ).times
573
581
  subject.configure_puppet(config)
574
582
  end
575
583
  end
584
+
576
585
  context 'on windows' do
577
586
  let(:platform) { 'windows-2008R2-amd64' }
578
- it 'it sets the puppet.conf file to the provided config' do
587
+
588
+ it 'calls configure_puppet_on correctly' do
579
589
  config = { 'main' => {'server' => 'testbox.test.local'} }
580
- expect(subject).to receive(:on) do |host, command|
581
- expect(command.command).to eq('powershell.exe')
582
- expect(command.args).to eq(["-ExecutionPolicy Bypass", "-InputFormat None", "-NoLogo", "-NoProfile", "-NonInteractive", "-Command $text = \\\"[main]`nserver=testbox.test.local`n`n\\\"; Set-Content -path '#{host.puppet['config']}' -value $text"])
583
- end
590
+ expect( subject ).to receive( :configure_puppet_on ).with(
591
+ anything, config
592
+ ).exactly( hosts.length ).times
584
593
  subject.configure_puppet(config)
585
594
  end
586
595
  end
@@ -80,7 +80,7 @@ describe ClassMixedWithDSLInstallUtils do
80
80
  allow( subject ).to receive( :hosts ).and_return( hosts )
81
81
  master = hosts.first
82
82
 
83
-
83
+ allow( subject ).to receive( :on ).once
84
84
  expect( subject ).to receive( :puppet ).with('module install test ', {}).once
85
85
 
86
86
  subject.install_puppet_module_via_pmt_on( master, {:module_name => 'test'} )
@@ -92,6 +92,7 @@ describe ClassMixedWithDSLInstallUtils do
92
92
  trace_opts = { :trace => nil }
93
93
  master['default_module_install_opts'] = trace_opts
94
94
 
95
+ allow( subject ).to receive( :on ).once
95
96
  expect( subject ).to receive( :puppet ).with('module install test ', trace_opts).once
96
97
 
97
98
  subject.install_puppet_module_via_pmt_on( master, {:module_name => 'test'} )
@@ -0,0 +1,182 @@
1
+ require 'spec_helper'
2
+
3
+ module Cisco
4
+ describe Host do
5
+ let(:options) { @options ? @options : {} }
6
+ let(:platform) {
7
+ if @platform
8
+ { :platform => Beaker::Platform.new( @platform) }
9
+ else
10
+ { :platform => Beaker::Platform.new( 'cisco-vers-arch-extra' ) }
11
+ end
12
+ }
13
+ let(:host) { make_host( 'name', options.merge(platform) ) }
14
+
15
+ describe '#prepend_commands' do
16
+
17
+ context 'for cisco-5' do
18
+
19
+ before :each do
20
+ @platform = 'cisco-5-x86'
21
+ end
22
+
23
+ it 'ends with the :vrf host parameter' do
24
+ vrf_answer = 'vrf_answer_135246'
25
+ @options = { :vrf => vrf_answer }
26
+ answer_test = host.prepend_commands( 'fake_command' )
27
+ expect( answer_test ).to match( /#{vrf_answer}$/ )
28
+ end
29
+
30
+ it 'begins with sourcing the /etc/profile script' do
31
+ answer_test = host.prepend_commands( 'fake_command' )
32
+ expect( answer_test ).to match( /^#{Regexp.escape('source /etc/profile; ')}/ )
33
+ end
34
+
35
+ it 'uses sudo at the beginning of the actual command to execute' do
36
+ answer_test = host.prepend_commands( 'fake_command' )
37
+ command_start_index = answer_test.index( '; ' ) + 2
38
+ command_actual = answer_test[command_start_index, answer_test.length - command_start_index]
39
+ expect( command_actual ).to match( /^sudo / )
40
+ end
41
+
42
+ it 'guards against "vsh" usage (only scenario we dont want prefixing)' do
43
+ answer_prepend_commands = 'pc_param_unchanged_13584'
44
+ answer_test = host.prepend_commands( 'fake/vsh/command', answer_prepend_commands )
45
+ expect( answer_test ).to be === answer_prepend_commands
46
+ end
47
+ end
48
+
49
+ context 'for cisco-7' do
50
+
51
+ before :each do
52
+ @platform = 'cisco-7-x86'
53
+ end
54
+
55
+ it 'begins with sourcing the /etc/profile script' do
56
+ answer_test = host.prepend_commands( 'fake_command' )
57
+ expect( answer_test ).to match( /^#{Regexp.escape('source /etc/profile;')}/ )
58
+ end
59
+
60
+ it 'does not use sudo, as root is allowed' do
61
+ answer_test = host.prepend_commands( 'fake_command' )
62
+ expect( answer_test ).not_to match( /sudo/ )
63
+ end
64
+
65
+ it 'does not prepend with the :vrf host parameter' do
66
+ expect( host ).to receive( :[] ).with( :vrf ).never
67
+ host.prepend_commands( 'fake_command' )
68
+ end
69
+
70
+ end
71
+ end
72
+
73
+ describe '#environment_string' do
74
+
75
+ it 'starts with `env` for cisco-7' do
76
+ @platform = 'cisco-7-x86'
77
+ env_map = { 'PATH' => '/opt/pants/1' }
78
+ answer_test = host.environment_string( env_map )
79
+ expect( answer_test ).to match( /^env\ / )
80
+ end
81
+
82
+ it 'starts with `export` for cisco-5' do
83
+ @platform = 'cisco-5-x86'
84
+ env_map = { 'PATH' => '/opt/pants/2' }
85
+ answer_test = host.environment_string( env_map )
86
+ expect( answer_test ).to match( /^export\ / )
87
+ end
88
+
89
+ it 'ends with a semi-colon' do
90
+ env_map = { 'PATH' => '/opt/pants/3' }
91
+ answer_test = host.environment_string( env_map )
92
+ expect( answer_test ).to match( /\;$/ )
93
+ end
94
+
95
+ it 'turns env maps into paired strings correctly' do
96
+ @platform = 'cisco-7-x86'
97
+ env_map = { 'var1' => 'ans1', 'var2' => 'ans2' }
98
+ answer_correct = 'env VAR1="ans1" VAR2="ans2";'
99
+ answer_test = host.environment_string( env_map )
100
+ expect( answer_test ).to be === answer_correct
101
+ end
102
+ end
103
+
104
+ describe '#package_config_dir' do
105
+
106
+ it 'returns correctly for cisco platforms' do
107
+ @platform = 'cisco-5-x86_64'
108
+ expect( host.package_config_dir ).to be === '/etc/yum/repos.d/'
109
+ end
110
+ end
111
+
112
+ describe '#repo_type' do
113
+
114
+ it 'returns correctly for cisco platforms' do
115
+ @platform = 'cisco-5-x86_64'
116
+ expect( host.repo_type ).to be === 'rpm'
117
+ end
118
+ end
119
+
120
+ describe '#validate_setup' do
121
+
122
+ context 'on the cisco-5 platform' do
123
+ before :each do
124
+ @platform = 'cisco-5-x86'
125
+ end
126
+
127
+ it 'errors when no :vrf value is provided' do
128
+ expect {
129
+ host.validate_setup
130
+ }.to raise_error( ArgumentError, /provided\ with\ a\ \:vrf\ value/ )
131
+ end
132
+
133
+ it 'errors when no user is provided' do
134
+ @options = {
135
+ :vrf => 'fake_vrf',
136
+ :user => 'root',
137
+ }
138
+ expect {
139
+ host.validate_setup
140
+ }.to raise_error( ArgumentError, /provided\ with\ a\ \:user\ value/ )
141
+ end
142
+
143
+ it 'does nothing if the host is setup correctly' do
144
+ @options = {
145
+ :vrf => 'fake_vrf',
146
+ :user => 'notroot',
147
+ }
148
+ validate_test = host.validate_setup
149
+ expect( validate_test ).to be_nil
150
+ end
151
+ end
152
+
153
+ context 'on the cisco-7 platform' do
154
+ before :each do
155
+ @platform = 'cisco-7-x86'
156
+ end
157
+
158
+ it 'errors when no :vrf value is provided' do
159
+ expect {
160
+ host.validate_setup
161
+ }.to raise_error( ArgumentError, /provided\ with\ a\ \:vrf\ value/ )
162
+ end
163
+
164
+ it 'does not error when no user is provided' do
165
+ @options = {
166
+ :vrf => 'fake_vrf',
167
+ :user => 'root',
168
+ }
169
+ expect {
170
+ host.validate_setup
171
+ }.not_to raise_error()
172
+ end
173
+
174
+ it 'does nothing if the host is setup correctly' do
175
+ @options = { :vrf => 'fake_vrf' }
176
+ validate_test = host.validate_setup
177
+ expect( validate_test ).to be_nil
178
+ end
179
+ end
180
+ end
181
+ end
182
+ end