beaker 2.33.0 → 2.34.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.
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