beaker 4.38.1 → 5.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.github/dependabot.yml +9 -0
- data/.github/workflows/release.yml +2 -2
- data/.github/workflows/test.yml +36 -11
- data/.rubocop.yml +75 -0
- data/.rubocop_todo.yml +239 -0
- data/CHANGELOG.md +88 -33
- data/Gemfile +16 -4
- data/HISTORY.md +103 -0
- data/Rakefile +101 -112
- data/acceptance/config/acceptance-options.rb +1 -1
- data/acceptance/config/base/acceptance-options.rb +2 -2
- data/acceptance/config/hypervisor/acceptance-options.rb +2 -2
- data/acceptance/config/subcommands/acceptance-options.rb +2 -2
- data/acceptance/fixtures/module/Gemfile +1 -1
- data/acceptance/fixtures/module/Rakefile +3 -3
- data/acceptance/fixtures/module/spec/acceptance/demo_spec.rb +16 -23
- data/acceptance/fixtures/module/spec/classes/init_spec.rb +1 -2
- data/acceptance/fixtures/module/spec/spec_helper_acceptance.rb +3 -5
- data/acceptance/lib/helpers/test_helper.rb +7 -6
- data/acceptance/pre_suite/subcommands/05_install_ruby.rb +2 -3
- data/acceptance/pre_suite/subcommands/08_install_beaker.rb +1 -2
- data/acceptance/tests/base/dsl/helpers/configuration_test.rb +4 -4
- data/acceptance/tests/base/dsl/helpers/hocon_helpers_test.rb +7 -8
- data/acceptance/tests/base/dsl/helpers/host_helpers/add_system32_hosts_entry_test.rb +0 -3
- data/acceptance/tests/base/dsl/helpers/host_helpers/archive_file_from_test.rb +9 -7
- data/acceptance/tests/base/dsl/helpers/host_helpers/backup_the_file_test.rb +15 -21
- data/acceptance/tests/base/dsl/helpers/host_helpers/check_for_package_test.rb +0 -4
- data/acceptance/tests/base/dsl/helpers/host_helpers/create_remote_file_test.rb +23 -30
- data/acceptance/tests/base/dsl/helpers/host_helpers/curl_on_test.rb +3 -3
- data/acceptance/tests/base/dsl/helpers/host_helpers/curl_with_retries_test.rb +0 -1
- data/acceptance/tests/base/dsl/helpers/host_helpers/on_test.rb +21 -16
- data/acceptance/tests/base/dsl/helpers/host_helpers/retry_on_test.rb +7 -7
- data/acceptance/tests/base/dsl/helpers/host_helpers/rsync_to_test.rb +30 -38
- data/acceptance/tests/base/dsl/helpers/host_helpers/run_cron_on_test.rb +14 -18
- data/acceptance/tests/base/dsl/helpers/host_helpers/run_script_on_test.rb +8 -14
- data/acceptance/tests/base/dsl/helpers/host_helpers/run_script_test.rb +7 -11
- data/acceptance/tests/base/dsl/helpers/host_helpers/scp_from_test.rb +5 -5
- data/acceptance/tests/base/dsl/helpers/host_helpers/scp_to_test.rb +4 -5
- data/acceptance/tests/base/dsl/helpers/host_helpers/shell_test.rb +8 -8
- data/acceptance/tests/base/dsl/helpers/host_helpers/upgrade_package_test.rb +4 -6
- data/acceptance/tests/base/dsl/platform_tag_confiner_test.rb +14 -17
- data/acceptance/tests/base/dsl/structure_test.rb +9 -21
- data/acceptance/tests/base/host/file_test.rb +8 -8
- data/acceptance/tests/base/host/group_test.rb +2 -3
- data/acceptance/tests/base/host/host_test.rb +69 -66
- data/acceptance/tests/base/host/packages.rb +27 -30
- data/acceptance/tests/base/host/packages_unix.rb +0 -55
- data/acceptance/tests/base/host/user_test.rb +2 -3
- data/acceptance/tests/base/host_prebuilt_steps/ssh_environment_test.rb +1 -2
- data/acceptance/tests/base/test_suite/export.rb +6 -9
- data/acceptance/tests/install/from_file.rb +3 -5
- data/acceptance/tests/load_path_bootstrap.rb +1 -1
- data/acceptance/tests/subcommands/destroy.rb +19 -21
- data/acceptance/tests/subcommands/exec.rb +0 -1
- data/acceptance/tests/subcommands/init.rb +2 -3
- data/acceptance/tests/subcommands/provision.rb +0 -1
- data/beaker.gemspec +10 -14
- data/docs/concepts/argument_processing_and_precedence.md +1 -10
- data/docs/concepts/style_guide.md +1 -1
- data/docs/how_to/debug_beaker_tests.md +13 -13
- data/docs/how_to/hosts/eos.md +2 -12
- data/docs/how_to/install_puppet.md +0 -18
- data/docs/how_to/test_arbitrary_beaker_versions.md +2 -2
- data/docs/how_to/the_beaker_dsl.md +0 -2
- data/lib/beaker/cli.rb +63 -74
- data/lib/beaker/command.rb +22 -30
- data/lib/beaker/command_factory.rb +4 -3
- data/lib/beaker/dsl/assertions.rb +7 -19
- data/lib/beaker/dsl/helpers/hocon_helpers.rb +5 -9
- data/lib/beaker/dsl/helpers/host_helpers.rb +72 -133
- data/lib/beaker/dsl/helpers/test_helpers.rb +3 -5
- data/lib/beaker/dsl/helpers/web_helpers.rb +20 -28
- data/lib/beaker/dsl/helpers.rb +2 -4
- data/lib/beaker/dsl/outcomes.rb +17 -19
- data/lib/beaker/dsl/patterns.rb +1 -3
- data/lib/beaker/dsl/roles.rb +18 -21
- data/lib/beaker/dsl/structure.rb +55 -67
- data/lib/beaker/dsl/test_tagging.rb +7 -10
- data/lib/beaker/dsl/wrappers.rb +15 -16
- data/lib/beaker/dsl.rb +2 -3
- data/lib/beaker/host/aix/exec.rb +1 -1
- data/lib/beaker/host/aix/file.rb +0 -1
- data/lib/beaker/host/aix/group.rb +3 -3
- data/lib/beaker/host/aix/user.rb +3 -3
- data/lib/beaker/host/aix.rb +3 -4
- data/lib/beaker/host/cisco.rb +36 -48
- data/lib/beaker/host/eos.rb +4 -30
- data/lib/beaker/host/freebsd/exec.rb +1 -1
- data/lib/beaker/host/freebsd/pkg.rb +3 -3
- data/lib/beaker/host/freebsd.rb +9 -12
- data/lib/beaker/host/mac/exec.rb +5 -5
- data/lib/beaker/host/mac/group.rb +13 -13
- data/lib/beaker/host/mac/pkg.rb +6 -109
- data/lib/beaker/host/mac/user.rb +7 -7
- data/lib/beaker/host/mac.rb +8 -9
- data/lib/beaker/host/pswindows/exec.rb +70 -74
- data/lib/beaker/host/pswindows/file.rb +4 -6
- data/lib/beaker/host/pswindows/group.rb +5 -5
- data/lib/beaker/host/pswindows/pkg.rb +17 -17
- data/lib/beaker/host/pswindows/user.rb +4 -4
- data/lib/beaker/host/pswindows.rb +4 -3
- data/lib/beaker/host/unix/exec.rb +86 -88
- data/lib/beaker/host/unix/file.rb +41 -47
- data/lib/beaker/host/unix/group.rb +3 -3
- data/lib/beaker/host/unix/pkg.rb +158 -421
- data/lib/beaker/host/unix/user.rb +4 -4
- data/lib/beaker/host/unix.rb +18 -20
- data/lib/beaker/host/windows/exec.rb +20 -20
- data/lib/beaker/host/windows/file.rb +5 -5
- data/lib/beaker/host/windows/group.rb +5 -5
- data/lib/beaker/host/windows/pkg.rb +6 -57
- data/lib/beaker/host/windows/user.rb +4 -4
- data/lib/beaker/host/windows.rb +13 -13
- data/lib/beaker/host.rb +82 -139
- data/lib/beaker/host_prebuilt_steps.rb +121 -233
- data/lib/beaker/hypervisor/noop.rb +2 -4
- data/lib/beaker/hypervisor.rb +46 -63
- data/lib/beaker/local_connection.rb +4 -6
- data/lib/beaker/logger.rb +71 -85
- data/lib/beaker/logger_junit.rb +22 -26
- data/lib/beaker/network_manager.rb +40 -43
- data/lib/beaker/options/command_line_parser.rb +12 -23
- data/lib/beaker/options/hosts_file_parser.rb +34 -25
- data/lib/beaker/options/options_file_parser.rb +3 -6
- data/lib/beaker/options/options_hash.rb +3 -10
- data/lib/beaker/options/parser.rb +89 -105
- data/lib/beaker/options/presets.rb +114 -123
- data/lib/beaker/options/subcommand_options_file_parser.rb +3 -6
- data/lib/beaker/options/validator.rb +26 -31
- data/lib/beaker/perf.rb +29 -34
- data/lib/beaker/platform.rb +38 -46
- data/lib/beaker/result.rb +7 -6
- data/lib/beaker/shared/error_handler.rb +8 -10
- data/lib/beaker/shared/fog_credentials.rb +5 -9
- data/lib/beaker/shared/host_manager.rb +40 -46
- data/lib/beaker/shared/options_resolver.rb +3 -7
- data/lib/beaker/shared/repetition.rb +6 -8
- data/lib/beaker/shared/semvar.rb +39 -43
- data/lib/beaker/shared/timed.rb +2 -5
- data/lib/beaker/shared.rb +1 -1
- data/lib/beaker/ssh_connection.rb +46 -55
- data/lib/beaker/subcommand.rb +23 -30
- data/lib/beaker/subcommands/subcommand_util.rb +4 -4
- data/lib/beaker/tasks/quick_start.rb +5 -10
- data/lib/beaker/tasks/rake_task.rb +26 -28
- data/lib/beaker/tasks/test.rb +4 -4
- data/lib/beaker/test_case.rb +15 -27
- data/lib/beaker/test_suite.rb +35 -39
- data/lib/beaker/test_suite_result.rb +52 -57
- data/lib/beaker/version.rb +1 -1
- data/lib/beaker.rb +5 -6
- data/spec/beaker/cli_spec.rb +135 -153
- data/spec/beaker/command_spec.rb +64 -58
- data/spec/beaker/dsl/assertions_spec.rb +38 -47
- data/spec/beaker/dsl/helpers/host_helpers_spec.rb +114 -135
- data/spec/beaker/dsl/helpers/test_helpers_spec.rb +9 -10
- data/spec/beaker/dsl/helpers/web_helpers_spec.rb +30 -36
- data/spec/beaker/dsl/outcomes_spec.rb +15 -14
- data/spec/beaker/dsl/roles_spec.rb +170 -132
- data/spec/beaker/dsl/structure_spec.rb +181 -163
- data/spec/beaker/dsl/test_tagging_spec.rb +94 -95
- data/spec/beaker/dsl/wrappers_spec.rb +39 -40
- data/spec/beaker/host/aix_spec.rb +14 -14
- data/spec/beaker/host/cisco_spec.rb +92 -102
- data/spec/beaker/host/eos_spec.rb +15 -36
- data/spec/beaker/host/freebsd/exec_spec.rb +5 -8
- data/spec/beaker/host/freebsd/pkg_spec.rb +29 -29
- data/spec/beaker/host/mac/exec_spec.rb +4 -5
- data/spec/beaker/host/mac/group_spec.rb +47 -56
- data/spec/beaker/host/mac/user_spec.rb +53 -62
- data/spec/beaker/host/pswindows/exec_spec.rb +36 -35
- data/spec/beaker/host/pswindows/file_spec.rb +21 -18
- data/spec/beaker/host/pswindows/user_spec.rb +17 -23
- data/spec/beaker/host/pswindows_spec.rb +14 -14
- data/spec/beaker/host/unix/exec_spec.rb +87 -92
- data/spec/beaker/host/unix/file_spec.rb +76 -82
- data/spec/beaker/host/unix/pkg_spec.rb +165 -407
- data/spec/beaker/host/unix_spec.rb +11 -207
- data/spec/beaker/host/windows/exec_spec.rb +32 -34
- data/spec/beaker/host/windows/file_spec.rb +22 -23
- data/spec/beaker/host/windows/group_spec.rb +17 -19
- data/spec/beaker/host/windows/pkg_spec.rb +10 -13
- data/spec/beaker/host/windows/user_spec.rb +17 -23
- data/spec/beaker/host/windows_spec.rb +39 -39
- data/spec/beaker/host_prebuilt_steps_spec.rb +193 -341
- data/spec/beaker/host_spec.rb +241 -312
- data/spec/beaker/hypervisor/hypervisor_spec.rb +38 -63
- data/spec/beaker/localhost_connection_spec.rb +14 -13
- data/spec/beaker/logger_junit_spec.rb +22 -34
- data/spec/beaker/logger_spec.rb +174 -155
- data/spec/beaker/network_manager_spec.rb +27 -27
- data/spec/beaker/options/command_line_parser_spec.rb +20 -23
- data/spec/beaker/options/data/hosts_preserved.yml +395 -0
- data/spec/beaker/options/hosts_file_parser_spec.rb +36 -31
- data/spec/beaker/options/options_file_parser_spec.rb +4 -7
- data/spec/beaker/options/options_hash_spec.rb +7 -9
- data/spec/beaker/options/parser_spec.rb +187 -187
- data/spec/beaker/options/presets_spec.rb +8 -10
- data/spec/beaker/options/subcommand_options_parser_spec.rb +15 -15
- data/spec/beaker/options/validator_spec.rb +27 -28
- data/spec/beaker/perf_spec.rb +32 -34
- data/spec/beaker/platform_spec.rb +27 -37
- data/spec/beaker/shared/error_handler_spec.rb +8 -17
- data/spec/beaker/shared/fog_credentials_spec.rb +30 -30
- data/spec/beaker/shared/host_manager_spec.rb +55 -89
- data/spec/beaker/shared/options_resolver_spec.rb +9 -12
- data/spec/beaker/shared/repetition_spec.rb +24 -31
- data/spec/beaker/shared/semvar_spec.rb +21 -26
- data/spec/beaker/ssh_connection_spec.rb +85 -90
- data/spec/beaker/subcommand/subcommand_util_spec.rb +40 -37
- data/spec/beaker/subcommand_spec.rb +89 -89
- data/spec/beaker/test_case_spec.rb +33 -62
- data/spec/beaker/test_suite_spec.rb +153 -160
- data/spec/helpers.rb +48 -53
- data/spec/matchers.rb +9 -8
- data/spec/mocks.rb +6 -11
- data/spec/spec_helper.rb +0 -4
- metadata +60 -85
- data/acceptance/tests/base/dsl/helpers/host_helpers/deploy_package_repo_test.rb +0 -142
- data/acceptance/tests/base/external_resources_test.rb +0 -31
- data/spec/beaker/host/mac_spec.rb +0 -113
- data/spec/mock_fission.rb +0 -60
- data/spec/mock_vsphere.rb +0 -314
- data/spec/mock_vsphere_helper.rb +0 -183
data/spec/beaker/cli_spec.rb
CHANGED
@@ -12,11 +12,16 @@ end
|
|
12
12
|
|
13
13
|
module Beaker
|
14
14
|
describe CLI do
|
15
|
+
let(:cli) do
|
16
|
+
allow(File).to receive(:exist?).and_call_original
|
17
|
+
allow(File).to receive(:exist?).with('.beaker.yml').and_return(false)
|
18
|
+
described_class.new.parse_options
|
19
|
+
end
|
15
20
|
|
16
21
|
context 'initializing and parsing' do
|
17
|
-
let(
|
18
|
-
|
19
|
-
|
22
|
+
let(:cli) do
|
23
|
+
described_class.new
|
24
|
+
end
|
20
25
|
|
21
26
|
describe 'instance variable initialization' do
|
22
27
|
it 'creates a logger for use before parse is called' do
|
@@ -32,7 +37,7 @@ module Beaker
|
|
32
37
|
|
33
38
|
describe '#parse_options' do
|
34
39
|
it 'returns self' do
|
35
|
-
expect(cli.parse_options).to be_instance_of(
|
40
|
+
expect(cli.parse_options).to be_instance_of(described_class)
|
36
41
|
end
|
37
42
|
|
38
43
|
it 'replaces the logger object with a new one' do
|
@@ -54,21 +59,22 @@ module Beaker
|
|
54
59
|
|
55
60
|
it 'prints the version and exits cleanly' do
|
56
61
|
expect(cli.logger).to receive(:notify).once
|
57
|
-
expect{ cli.parse_options(['--version']) }.to raise_exception(SystemExit) { |e| expect(e.success?).to eq(true) }
|
62
|
+
expect { cli.parse_options(['--version']) }.to raise_exception(SystemExit) { |e| expect(e.success?).to eq(true) }
|
58
63
|
end
|
59
64
|
|
60
65
|
it 'prints the help and exits cleanly' do
|
61
66
|
expect(cli.logger).to receive(:notify).once
|
62
|
-
expect{ cli.parse_options(['--help']) }.to raise_exception(SystemExit) { |e| expect(e.success?).to eq(true) }
|
67
|
+
expect { cli.parse_options(['--help']) }.to raise_exception(SystemExit) { |e| expect(e.success?).to eq(true) }
|
63
68
|
end
|
64
69
|
end
|
65
70
|
|
66
71
|
describe '#print_version_and_options' do
|
67
72
|
before do
|
68
|
-
options
|
73
|
+
options = Beaker::Options::OptionsHash.new
|
69
74
|
options[:beaker_version] = 'version_number'
|
70
|
-
cli.instance_variable_set(
|
75
|
+
cli.instance_variable_set(:@options, options)
|
71
76
|
end
|
77
|
+
|
72
78
|
it 'prints the version and dumps the options' do
|
73
79
|
expect(cli.logger).to receive(:info).exactly(3).times
|
74
80
|
cli.print_version_and_options
|
@@ -76,32 +82,26 @@ module Beaker
|
|
76
82
|
end
|
77
83
|
end
|
78
84
|
|
79
|
-
|
80
|
-
allow(File).to receive(:exists?).and_return(true)
|
81
|
-
allow(File).to receive(:exists?).with('.beaker.yml').and_return(false)
|
82
|
-
Beaker::CLI.new.parse_options
|
83
|
-
}
|
84
|
-
|
85
|
-
context '#configured_options' do
|
85
|
+
describe '#configured_options' do
|
86
86
|
it 'returns a list of options that were not presets' do
|
87
87
|
attribution = cli.instance_variable_get(:@attribution)
|
88
88
|
attribution.each do |attribute, setter|
|
89
|
-
if setter == 'preset'
|
90
|
-
expect(cli.configured_options[attribute]).to be_nil
|
91
|
-
end
|
89
|
+
expect(cli.configured_options[attribute]).to be_nil if setter == 'preset'
|
92
90
|
end
|
93
91
|
end
|
94
92
|
end
|
95
93
|
|
96
94
|
describe '#combined_instance_and_options_hosts' do
|
97
|
-
let
|
98
|
-
let
|
99
|
-
[Beaker::Host.create('ubuntu', {:platform => 'host'}, {}
|
100
|
-
|
95
|
+
let(:options_host) { { 'HOSTS' => { 'ubuntu' => { :options_attribute => 'options' } } } }
|
96
|
+
let(:instance_host) do
|
97
|
+
[Beaker::Host.create('ubuntu', { :platform => 'host' }, {})]
|
98
|
+
end
|
99
|
+
|
101
100
|
before do
|
102
101
|
cli.instance_variable_set(:@options, options_host)
|
103
102
|
cli.instance_variable_set(:@hosts, instance_host)
|
104
103
|
end
|
104
|
+
|
105
105
|
it 'combines the options and instance host objects' do
|
106
106
|
merged_host = cli.combined_instance_and_options_hosts
|
107
107
|
expect(merged_host).to have_key('ubuntu')
|
@@ -112,15 +112,15 @@ module Beaker
|
|
112
112
|
end
|
113
113
|
|
114
114
|
context 'when hosts share IP addresses' do
|
115
|
-
let
|
116
|
-
{'HOSTS' => {'host1' => {:options_attribute => 'options'},
|
117
|
-
|
115
|
+
let(:options_host) do
|
116
|
+
{ 'HOSTS' => { 'host1' => { :options_attribute => 'options' },
|
117
|
+
'host2' => { :options_attribute => 'options' }, } }
|
118
118
|
end
|
119
|
-
let
|
119
|
+
let(:instance_host) do
|
120
120
|
[Beaker::Host.create('host1',
|
121
|
-
{:platform => 'host', :ip => '127.0.0.1'}, {}
|
121
|
+
{ :platform => 'host', :ip => '127.0.0.1' }, {}),
|
122
122
|
Beaker::Host.create('host2',
|
123
|
-
{:platform => 'host', :ip => '127.0.0.1'}, {}
|
123
|
+
{ :platform => 'host', :ip => '127.0.0.1' }, {}),]
|
124
124
|
end
|
125
125
|
|
126
126
|
it 'creates separate entries for each host' do
|
@@ -133,8 +133,8 @@ module Beaker
|
|
133
133
|
end
|
134
134
|
|
135
135
|
context 'execute!' do
|
136
|
-
before
|
137
|
-
|
136
|
+
before do
|
137
|
+
stub_const("Beaker::Logger", double.as_null_object)
|
138
138
|
File.open("sample.cfg", "w+") do |file|
|
139
139
|
file.write("HOSTS:\n")
|
140
140
|
file.write(" myhost:\n")
|
@@ -143,9 +143,9 @@ module Beaker
|
|
143
143
|
file.write(" platform: ubuntu-x-x\n")
|
144
144
|
file.write("CONFIG:\n")
|
145
145
|
end
|
146
|
-
allow(
|
147
|
-
allow(
|
148
|
-
allow(
|
146
|
+
allow(cli).to receive(:setup).and_return(true)
|
147
|
+
allow(cli).to receive(:validate).and_return(true)
|
148
|
+
allow(cli).to receive(:provision).and_return(true)
|
149
149
|
end
|
150
150
|
|
151
151
|
describe "test fail mode" do
|
@@ -153,44 +153,41 @@ module Beaker
|
|
153
153
|
options = cli.instance_variable_get(:@options)
|
154
154
|
options[:fail_mode] = 'slow'
|
155
155
|
cli.instance_variable_set(:@options, options)
|
156
|
-
allow(
|
157
|
-
allow(
|
158
|
-
allow(
|
159
|
-
allow(
|
156
|
+
allow(cli).to receive(:run_suite).with(:pre_suite, :fast).and_throw("bad test")
|
157
|
+
allow(cli).to receive(:run_suite).with(:tests, options[:fail_mode])
|
158
|
+
allow(cli).to receive(:run_suite).with(:post_suite).and_return(true)
|
159
|
+
allow(cli).to receive(:run_suite).with(:pre_cleanup).and_return(true)
|
160
160
|
|
161
|
-
expect(
|
162
|
-
expect{ cli.execute! }.to raise_error
|
161
|
+
expect(cli).to receive(:run_suite).twice
|
162
|
+
expect { cli.execute! }.to raise_error
|
163
163
|
expect(cli.instance_variable_get(:@attribution)[:logger]).to be == 'runtime'
|
164
164
|
expect(cli.instance_variable_get(:@attribution)[:timestamp]).to be == 'runtime'
|
165
165
|
expect(cli.instance_variable_get(:@attribution)[:beaker_version]).to be == 'runtime'
|
166
|
-
|
167
166
|
end
|
168
167
|
|
169
168
|
it 'continues testing after failed test if using slow fail_mode' do
|
170
169
|
options = cli.instance_variable_get(:@options)
|
171
170
|
options[:fail_mode] = 'slow'
|
172
171
|
cli.instance_variable_set(:@options, options)
|
173
|
-
allow(
|
174
|
-
allow(
|
175
|
-
allow(
|
176
|
-
allow(
|
177
|
-
|
178
|
-
expect( cli ).to receive(:run_suite).exactly( 4 ).times
|
179
|
-
expect{ cli.execute! }.to raise_error
|
172
|
+
allow(cli).to receive(:run_suite).with(:pre_suite, :fast).and_return(true)
|
173
|
+
allow(cli).to receive(:run_suite).with(:tests, options[:fail_mode]).and_throw("bad test")
|
174
|
+
allow(cli).to receive(:run_suite).with(:post_suite).and_return(true)
|
175
|
+
allow(cli).to receive(:run_suite).with(:pre_cleanup).and_return(true)
|
180
176
|
|
177
|
+
expect(cli).to receive(:run_suite).exactly(4).times
|
178
|
+
expect { cli.execute! }.to raise_error
|
181
179
|
end
|
182
180
|
|
183
181
|
it 'stops testing after failed test if using fast fail_mode' do
|
184
182
|
options = cli.instance_variable_get(:@options)
|
185
183
|
options[:fail_mode] = 'fast'
|
186
184
|
cli.instance_variable_set(:@options, options)
|
187
|
-
allow(
|
188
|
-
allow(
|
189
|
-
allow(
|
190
|
-
|
191
|
-
expect( cli ).to receive(:run_suite).exactly( 3 ).times
|
192
|
-
expect{ cli.execute! }.to raise_error
|
185
|
+
allow(cli).to receive(:run_suite).with(:pre_suite, :fast).and_return(true)
|
186
|
+
allow(cli).to receive(:run_suite).with(:tests, options[:fail_mode]).and_throw("bad test")
|
187
|
+
allow(cli).to receive(:run_suite).with(:pre_cleanup).and_return(true)
|
193
188
|
|
189
|
+
expect(cli).to receive(:run_suite).exactly(3).times
|
190
|
+
expect { cli.execute! }.to raise_error
|
194
191
|
end
|
195
192
|
end
|
196
193
|
|
@@ -200,16 +197,15 @@ module Beaker
|
|
200
197
|
options[:fail_mode] = 'fast'
|
201
198
|
options[:preserve_hosts] = 'never'
|
202
199
|
cli.instance_variable_set(:@options, options)
|
203
|
-
allow(
|
204
|
-
allow(
|
205
|
-
allow(
|
200
|
+
allow(cli).to receive(:run_suite).with(:pre_suite, :fast).and_return(true)
|
201
|
+
allow(cli).to receive(:run_suite).with(:tests, options[:fail_mode]).and_throw("bad test")
|
202
|
+
allow(cli).to receive(:run_suite).with(:pre_cleanup).and_return(true)
|
206
203
|
|
207
204
|
netmanager = double(:netmanager)
|
208
205
|
cli.instance_variable_set(:@network_manager, netmanager)
|
209
|
-
expect(
|
210
|
-
|
211
|
-
expect{ cli.execute! }.to raise_error
|
206
|
+
expect(netmanager).to receive(:cleanup).once
|
212
207
|
|
208
|
+
expect { cli.execute! }.to raise_error
|
213
209
|
end
|
214
210
|
|
215
211
|
it 'cleans up SUTs post testing if no tests fail and preserve_hosts = never' do
|
@@ -217,20 +213,18 @@ module Beaker
|
|
217
213
|
options[:fail_mode] = 'fast'
|
218
214
|
options[:preserve_hosts] = 'never'
|
219
215
|
cli.instance_variable_set(:@options, options)
|
220
|
-
allow(
|
221
|
-
allow(
|
222
|
-
allow(
|
223
|
-
allow(
|
216
|
+
allow(cli).to receive(:run_suite).with(:pre_suite, :fast).and_return(true)
|
217
|
+
allow(cli).to receive(:run_suite).with(:tests, options[:fail_mode]).and_return(true)
|
218
|
+
allow(cli).to receive(:run_suite).with(:post_suite).and_return(true)
|
219
|
+
allow(cli).to receive(:run_suite).with(:pre_cleanup).and_return(true)
|
224
220
|
|
225
221
|
netmanager = double(:netmanager)
|
226
222
|
cli.instance_variable_set(:@network_manager, netmanager)
|
227
|
-
expect(
|
228
|
-
|
229
|
-
expect{ cli.execute! }.to_not raise_error
|
223
|
+
expect(netmanager).to receive(:cleanup).once
|
230
224
|
|
225
|
+
expect { cli.execute! }.not_to raise_error
|
231
226
|
end
|
232
227
|
|
233
|
-
|
234
228
|
it 'preserves SUTs post testing if no tests fail and preserve_hosts = always' do
|
235
229
|
options = cli.instance_variable_get(:@options)
|
236
230
|
options[:fail_mode] = 'fast'
|
@@ -238,18 +232,17 @@ module Beaker
|
|
238
232
|
options[:log_dated_dir] = '.'
|
239
233
|
options[:hosts_file] = 'sample.cfg'
|
240
234
|
cli.instance_variable_set(:@options, options)
|
241
|
-
allow(
|
242
|
-
allow(
|
243
|
-
allow(
|
244
|
-
allow(
|
235
|
+
allow(cli).to receive(:run_suite).with(:pre_suite, :fast).and_return(true)
|
236
|
+
allow(cli).to receive(:run_suite).with(:tests, options[:fail_mode]).and_return(true)
|
237
|
+
allow(cli).to receive(:run_suite).with(:post_suite).and_return(true)
|
238
|
+
allow(cli).to receive(:run_suite).with(:pre_cleanup).and_return(true)
|
245
239
|
cli.instance_variable_set(:@hosts, {})
|
246
240
|
|
247
241
|
netmanager = double(:netmanager)
|
248
242
|
cli.instance_variable_set(:@network_manager, netmanager)
|
249
|
-
expect(
|
250
|
-
|
251
|
-
expect{ cli.execute! }.to_not raise_error
|
243
|
+
expect(netmanager).not_to receive(:cleanup)
|
252
244
|
|
245
|
+
expect { cli.execute! }.not_to raise_error
|
253
246
|
end
|
254
247
|
|
255
248
|
it 'preserves SUTs post testing if no tests fail and preserve_hosts = always' do
|
@@ -257,16 +250,16 @@ module Beaker
|
|
257
250
|
options[:fail_mode] = 'fast'
|
258
251
|
options[:preserve_hosts] = 'always'
|
259
252
|
cli.instance_variable_set(:@options, options)
|
260
|
-
allow(
|
261
|
-
allow(
|
262
|
-
allow(
|
263
|
-
allow(
|
253
|
+
allow(cli).to receive(:run_suite).with(:pre_suite, :fast).and_return(true)
|
254
|
+
allow(cli).to receive(:run_suite).with(:tests, options[:fail_mode]).and_throw("bad test")
|
255
|
+
allow(cli).to receive(:run_suite).with(:post_suite).and_return(true)
|
256
|
+
allow(cli).to receive(:run_suite).with(:pre_cleanup).and_return(true)
|
264
257
|
|
265
258
|
netmanager = double(:netmanager)
|
266
259
|
cli.instance_variable_set(:@network_manager, netmanager)
|
267
|
-
expect(
|
260
|
+
expect(netmanager).not_to receive(:cleanup)
|
268
261
|
|
269
|
-
expect{ cli.execute! }.to raise_error
|
262
|
+
expect { cli.execute! }.to raise_error
|
270
263
|
end
|
271
264
|
|
272
265
|
it 'cleans up SUTs post testing if no tests fail and preserve_hosts = onfail' do
|
@@ -274,17 +267,16 @@ module Beaker
|
|
274
267
|
options[:fail_mode] = 'fast'
|
275
268
|
options[:preserve_hosts] = 'onfail'
|
276
269
|
cli.instance_variable_set(:@options, options)
|
277
|
-
allow(
|
278
|
-
allow(
|
279
|
-
allow(
|
280
|
-
allow(
|
270
|
+
allow(cli).to receive(:run_suite).with(:pre_suite, :fast).and_return(true)
|
271
|
+
allow(cli).to receive(:run_suite).with(:tests, options[:fail_mode]).and_return(true)
|
272
|
+
allow(cli).to receive(:run_suite).with(:post_suite).and_return(true)
|
273
|
+
allow(cli).to receive(:run_suite).with(:pre_cleanup).and_return(true)
|
281
274
|
|
282
275
|
netmanager = double(:netmanager)
|
283
276
|
cli.instance_variable_set(:@network_manager, netmanager)
|
284
|
-
expect(
|
285
|
-
|
286
|
-
expect{ cli.execute! }.to_not raise_error
|
277
|
+
expect(netmanager).to receive(:cleanup).once
|
287
278
|
|
279
|
+
expect { cli.execute! }.not_to raise_error
|
288
280
|
end
|
289
281
|
|
290
282
|
it 'preserves SUTs post testing if tests fail and preserve_hosts = onfail' do
|
@@ -292,17 +284,16 @@ module Beaker
|
|
292
284
|
options[:fail_mode] = 'fast'
|
293
285
|
options[:preserve_hosts] = 'onfail'
|
294
286
|
cli.instance_variable_set(:@options, options)
|
295
|
-
allow(
|
296
|
-
allow(
|
297
|
-
allow(
|
298
|
-
allow(
|
287
|
+
allow(cli).to receive(:run_suite).with(:pre_suite, :fast).and_return(true)
|
288
|
+
allow(cli).to receive(:run_suite).with(:tests, options[:fail_mode]).and_throw("bad test")
|
289
|
+
allow(cli).to receive(:run_suite).with(:post_suite).and_return(true)
|
290
|
+
allow(cli).to receive(:run_suite).with(:pre_cleanup).and_return(true)
|
299
291
|
|
300
292
|
netmanager = double(:netmanager)
|
301
293
|
cli.instance_variable_set(:@network_manager, netmanager)
|
302
|
-
expect(
|
303
|
-
|
304
|
-
expect{ cli.execute! }.to raise_error
|
294
|
+
expect(netmanager).not_to receive(:cleanup)
|
305
295
|
|
296
|
+
expect { cli.execute! }.to raise_error
|
306
297
|
end
|
307
298
|
|
308
299
|
it 'cleans up SUTs post testing if tests fail and preserve_hosts = onpass' do
|
@@ -310,17 +301,16 @@ module Beaker
|
|
310
301
|
options[:fail_mode] = 'fast'
|
311
302
|
options[:preserve_hosts] = 'onpass'
|
312
303
|
cli.instance_variable_set(:@options, options)
|
313
|
-
allow(
|
314
|
-
allow(
|
315
|
-
allow(
|
316
|
-
allow(
|
304
|
+
allow(cli).to receive(:run_suite).with(:pre_suite, :fast).and_return(true)
|
305
|
+
allow(cli).to receive(:run_suite).with(:tests, options[:fail_mode]).and_throw("bad test")
|
306
|
+
allow(cli).to receive(:run_suite).with(:post_suite).and_return(true)
|
307
|
+
allow(cli).to receive(:run_suite).with(:pre_cleanup).and_return(true)
|
317
308
|
|
318
309
|
netmanager = double(:netmanager)
|
319
310
|
cli.instance_variable_set(:@network_manager, netmanager)
|
320
|
-
expect(
|
321
|
-
|
322
|
-
expect{ cli.execute! }.to raise_error
|
311
|
+
expect(netmanager).to receive(:cleanup).once
|
323
312
|
|
313
|
+
expect { cli.execute! }.to raise_error
|
324
314
|
end
|
325
315
|
|
326
316
|
it 'preserves SUTs post testing if no tests fail and preserve_hosts = onpass' do
|
@@ -331,22 +321,22 @@ module Beaker
|
|
331
321
|
options[:hosts_file] = 'sample.cfg'
|
332
322
|
cli.instance_variable_set(:@hosts, {})
|
333
323
|
cli.instance_variable_set(:@options, options)
|
334
|
-
allow(
|
335
|
-
allow(
|
336
|
-
allow(
|
337
|
-
allow(
|
324
|
+
allow(cli).to receive(:run_suite).with(:pre_suite, :fast).and_return(true)
|
325
|
+
allow(cli).to receive(:run_suite).with(:tests, options[:fail_mode]).and_return(true)
|
326
|
+
allow(cli).to receive(:run_suite).with(:post_suite).and_return(true)
|
327
|
+
allow(cli).to receive(:run_suite).with(:pre_cleanup).and_return(true)
|
338
328
|
|
339
329
|
netmanager = double(:netmanager)
|
340
330
|
cli.instance_variable_set(:@network_manager, netmanager)
|
341
|
-
expect(
|
331
|
+
expect(netmanager).not_to receive(:cleanup)
|
342
332
|
|
343
|
-
expect{ cli.execute! }.
|
333
|
+
expect { cli.execute! }.not_to raise_error
|
344
334
|
end
|
345
335
|
end
|
346
336
|
|
347
337
|
describe "#preserve_hosts_file" do
|
348
338
|
it 'removes the pre-suite/post-suite/tests and sets to []' do
|
349
|
-
hosts =
|
339
|
+
hosts = make_hosts
|
350
340
|
options = cli.instance_variable_get(:@options)
|
351
341
|
options[:log_dated_dir] = Dir.mktmpdir
|
352
342
|
File.open("sample.cfg", "w+") do |file|
|
@@ -362,10 +352,10 @@ module Beaker
|
|
362
352
|
file.write("CONFIG:\n")
|
363
353
|
end
|
364
354
|
options[:hosts_file] = 'sample.cfg'
|
365
|
-
options[:pre_suite] = [
|
355
|
+
options[:pre_suite] = %w[pre1 pre2 pre3]
|
366
356
|
options[:post_suite] = ['post1']
|
367
357
|
options[:pre_cleanup] = ['preclean1']
|
368
|
-
options[:tests] = [
|
358
|
+
options[:tests] = %w[test1 test2]
|
369
359
|
|
370
360
|
cli.instance_variable_set(:@options, options)
|
371
361
|
cli.instance_variable_set(:@hosts, hosts)
|
@@ -380,17 +370,16 @@ module Beaker
|
|
380
370
|
end
|
381
371
|
|
382
372
|
describe 'hosts file saving when preserve_hosts should happen' do
|
383
|
-
|
384
|
-
before :each do
|
373
|
+
before do
|
385
374
|
options = cli.instance_variable_get(:@options)
|
386
375
|
options[:fail_mode] = 'fast'
|
387
376
|
options[:preserve_hosts] = 'onpass'
|
388
377
|
options[:hosts_file] = 'sample.cfg'
|
389
378
|
cli.instance_variable_set(:@options, options)
|
390
|
-
allow(
|
391
|
-
allow(
|
392
|
-
allow(
|
393
|
-
allow(
|
379
|
+
allow(cli).to receive(:run_suite).with(:pre_suite, :fast).and_return(true)
|
380
|
+
allow(cli).to receive(:run_suite).with(:tests, options[:fail_mode]).and_return(true)
|
381
|
+
allow(cli).to receive(:run_suite).with(:post_suite).and_return(true)
|
382
|
+
allow(cli).to receive(:run_suite).with(:pre_cleanup).and_return(true)
|
394
383
|
|
395
384
|
hosts = [
|
396
385
|
make_host('petey', { :hypervisor => 'peterPan' }),
|
@@ -400,13 +389,12 @@ module Beaker
|
|
400
389
|
|
401
390
|
netmanager = double(:netmanager)
|
402
391
|
cli.instance_variable_set(:@network_manager, netmanager)
|
403
|
-
expect(
|
392
|
+
expect(netmanager).not_to receive(:cleanup)
|
404
393
|
|
405
|
-
|
406
|
-
allow( cli ).to receive( :print_env_vars_affecting_beaker )
|
394
|
+
allow(cli).to receive(:print_env_vars_affecting_beaker)
|
407
395
|
logger = cli.instance_variable_get(:@logger)
|
408
|
-
expect(
|
409
|
-
expect(
|
396
|
+
expect(logger).to receive(:send).with(anything, anything).ordered
|
397
|
+
expect(logger).to receive(:send).with(anything, anything).ordered
|
410
398
|
end
|
411
399
|
|
412
400
|
it 'executes without error' do
|
@@ -414,7 +402,7 @@ module Beaker
|
|
414
402
|
Dir.mktmpdir do |dir|
|
415
403
|
options[:log_dated_dir] = File.absolute_path(dir)
|
416
404
|
|
417
|
-
expect{ cli.execute! }.
|
405
|
+
expect { cli.execute! }.not_to raise_error
|
418
406
|
end
|
419
407
|
end
|
420
408
|
|
@@ -426,7 +414,7 @@ module Beaker
|
|
426
414
|
cli.execute!
|
427
415
|
|
428
416
|
copied_hosts_file = File.join(File.absolute_path(dir), 'hosts_preserved.yml')
|
429
|
-
expect(
|
417
|
+
expect(File).to exist(copied_hosts_file)
|
430
418
|
end
|
431
419
|
end
|
432
420
|
|
@@ -438,7 +426,7 @@ module Beaker
|
|
438
426
|
cli.execute!
|
439
427
|
|
440
428
|
copied_hosts_file = File.join(File.absolute_path(dir), 'hosts_preserved.yml')
|
441
|
-
expect{ load_yaml_file(copied_hosts_file) }.
|
429
|
+
expect { load_yaml_file(copied_hosts_file) }.not_to raise_error
|
442
430
|
end
|
443
431
|
end
|
444
432
|
|
@@ -451,7 +439,7 @@ module Beaker
|
|
451
439
|
|
452
440
|
copied_hosts_file = File.join(File.absolute_path(dir), 'hosts_preserved.yml')
|
453
441
|
yaml_content = load_yaml_file(copied_hosts_file)
|
454
|
-
expect(
|
442
|
+
expect(yaml_content['CONFIG']['provision']).to be_falsy
|
455
443
|
end
|
456
444
|
end
|
457
445
|
|
@@ -460,17 +448,16 @@ module Beaker
|
|
460
448
|
Dir.mktmpdir do |dir|
|
461
449
|
options[:log_dated_dir] = File.absolute_path(dir)
|
462
450
|
|
463
|
-
expect(
|
451
|
+
expect(options).not_to have_key(:hosts_preserved_yaml_file)
|
464
452
|
cli.execute!
|
465
|
-
expect(
|
453
|
+
expect(options).to have_key(:hosts_preserved_yaml_file)
|
466
454
|
|
467
455
|
copied_hosts_file = File.join(File.absolute_path(dir), 'hosts_preserved.yml')
|
468
|
-
expect(
|
456
|
+
expect(options[:hosts_preserved_yaml_file]).to be === copied_hosts_file
|
469
457
|
end
|
470
458
|
end
|
471
459
|
|
472
460
|
describe 'output text informing the user that re-use is possible' do
|
473
|
-
|
474
461
|
it 'if unsupported, does not output extra text' do
|
475
462
|
options = cli.instance_variable_get(:@options)
|
476
463
|
Dir.mktmpdir do |dir|
|
@@ -478,9 +465,9 @@ module Beaker
|
|
478
465
|
copied_hosts_file = File.join(File.absolute_path(dir), options[:hosts_file])
|
479
466
|
|
480
467
|
logger = cli.instance_variable_get(:@logger)
|
481
|
-
expect(
|
482
|
-
expect(
|
483
|
-
expect(
|
468
|
+
expect(logger).not_to receive(:send).with(anything, "\nYou can re-run commands against the already provisioned SUT(s) by following these steps:\n")
|
469
|
+
expect(logger).not_to receive(:send).with(anything, "- change the hosts file to #{copied_hosts_file}")
|
470
|
+
expect(logger).not_to receive(:send).with(anything, '- use the --no-provision flag')
|
484
471
|
|
485
472
|
cli.execute!
|
486
473
|
end
|
@@ -490,17 +477,16 @@ module Beaker
|
|
490
477
|
options = cli.instance_variable_get(:@options)
|
491
478
|
Dir.mktmpdir do |dir|
|
492
479
|
options[:log_dated_dir] = File.absolute_path(dir)
|
493
|
-
copied_hosts_file = File.join(File.absolute_path(dir), options[:hosts_file])
|
494
480
|
|
495
481
|
hosts = cli.instance_variable_get(:@hosts)
|
496
482
|
hosts << make_host('fusion', { :hypervisor => 'fusion' })
|
497
483
|
|
498
484
|
reproducing_cmd = "the faith of the people"
|
499
|
-
allow(
|
485
|
+
allow(cli).to receive(:build_hosts_preserved_reproducing_command).and_return(reproducing_cmd)
|
500
486
|
|
501
487
|
logger = cli.instance_variable_get(:@logger)
|
502
|
-
expect(
|
503
|
-
expect(
|
488
|
+
expect(logger).to receive(:send).with(anything, "\nYou can re-run commands against the already provisioned SUT(s) with:\n").ordered
|
489
|
+
expect(logger).to receive(:send).with(anything, reproducing_cmd).ordered
|
504
490
|
|
505
491
|
cli.execute!
|
506
492
|
end
|
@@ -510,19 +496,18 @@ module Beaker
|
|
510
496
|
options = cli.instance_variable_get(:@options)
|
511
497
|
Dir.mktmpdir do |dir|
|
512
498
|
options[:log_dated_dir] = File.absolute_path(dir)
|
513
|
-
copied_hosts_file = File.join(File.absolute_path(dir), options[:hosts_file])
|
514
499
|
|
515
500
|
hosts = cli.instance_variable_get(:@hosts)
|
516
501
|
hosts << make_host('fusion', { :hypervisor => 'fusion' })
|
517
502
|
hosts << make_host('docker', { :hypervisor => 'docker' })
|
518
503
|
|
519
504
|
reproducing_cmd = "the crow flies true says the shoe to you"
|
520
|
-
allow(
|
505
|
+
allow(cli).to receive(:build_hosts_preserved_reproducing_command).and_return(reproducing_cmd)
|
521
506
|
|
522
507
|
logger = cli.instance_variable_get(:@logger)
|
523
|
-
expect(
|
524
|
-
expect(
|
525
|
-
expect(
|
508
|
+
expect(logger).to receive(:send).with(anything, "\nYou can re-run commands against the already provisioned SUT(s) with:\n").ordered
|
509
|
+
expect(logger).to receive(:send).with(anything, '(docker support is untested for this feature. please reference the docs for more info)').ordered
|
510
|
+
expect(logger).to receive(:send).with(anything, reproducing_cmd).ordered
|
526
511
|
|
527
512
|
cli.execute!
|
528
513
|
end
|
@@ -538,27 +523,25 @@ module Beaker
|
|
538
523
|
hosts << make_host('docker', { :hypervisor => 'docker' })
|
539
524
|
|
540
525
|
logger = cli.instance_variable_get(:@logger)
|
541
|
-
expect(
|
542
|
-
expect(
|
543
|
-
expect(
|
544
|
-
expect(
|
526
|
+
expect(logger).not_to receive(:send).with(anything, "\nYou can re-run commands against the already provisioned SUT(s) with:\n")
|
527
|
+
expect(logger).not_to receive(:send).with(anything, '(docker support is untested for this feature. please reference the docs for more info)')
|
528
|
+
expect(logger).not_to receive(:send).with(anything, "- change the hosts file to #{copied_hosts_file}")
|
529
|
+
expect(logger).not_to receive(:send).with(anything, '- use the --no-provision flag')
|
545
530
|
|
546
531
|
cli.execute!
|
547
532
|
end
|
548
533
|
end
|
549
|
-
|
550
|
-
|
551
534
|
end
|
552
535
|
end
|
553
|
-
describe '#build_hosts_preserved_reproducing_command' do
|
554
536
|
|
537
|
+
describe '#build_hosts_preserved_reproducing_command' do
|
555
538
|
it 'replaces the hosts file' do
|
556
539
|
new_hosts_file = 'john/deer/was/here.txt'
|
557
540
|
command_to_sub = 'p --log-level debug --hosts pants/of/plan.poo jam --jankies --flag-business'
|
558
541
|
command_correct = "p --log-level debug --hosts #{new_hosts_file} jam --jankies --flag-business"
|
559
542
|
|
560
543
|
answer = cli.build_hosts_preserved_reproducing_command(command_to_sub, new_hosts_file)
|
561
|
-
expect(
|
544
|
+
expect(answer).to be_start_with(command_correct)
|
562
545
|
end
|
563
546
|
|
564
547
|
it 'doesn\'t replace an entry if no --hosts key is found' do
|
@@ -566,7 +549,7 @@ module Beaker
|
|
566
549
|
command_correct = 'p --log-level debug johnnypantaloons7 --jankies --flag-business'
|
567
550
|
|
568
551
|
answer = cli.build_hosts_preserved_reproducing_command(command_to_sub, 'john/deer/plans.txt')
|
569
|
-
expect(
|
552
|
+
expect(answer).to be_start_with(command_correct)
|
570
553
|
end
|
571
554
|
|
572
555
|
it 'removes any old --provision flags' do
|
@@ -574,7 +557,7 @@ module Beaker
|
|
574
557
|
command_correct = 'jam --jankies --flag-business'
|
575
558
|
|
576
559
|
answer = cli.build_hosts_preserved_reproducing_command(command_to_sub, 'can/talk/to/pigs.yml')
|
577
|
-
expect(
|
560
|
+
expect(answer).to be_start_with(command_correct)
|
578
561
|
end
|
579
562
|
|
580
563
|
it 'removes any old --no-provision flags' do
|
@@ -582,10 +565,9 @@ module Beaker
|
|
582
565
|
command_correct = 'jam --jankoos --flag-businesses'
|
583
566
|
|
584
567
|
answer = cli.build_hosts_preserved_reproducing_command(command_to_sub, 'can/talk/to/bears.yml')
|
585
|
-
expect(
|
568
|
+
expect(answer).to be_start_with(command_correct)
|
586
569
|
end
|
587
570
|
end
|
588
|
-
|
589
571
|
end
|
590
572
|
end
|
591
573
|
end
|