beaker 2.30.0 → 2.30.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +8 -8
- data/HISTORY.md +19 -2
- data/lib/beaker/cli.rb +1 -7
- data/lib/beaker/options/command_line_parser.rb +0 -6
- data/lib/beaker/options/presets.rb +0 -1
- data/lib/beaker/test_case.rb +176 -2
- data/lib/beaker/test_suite.rb +399 -9
- data/lib/beaker/version.rb +1 -1
- data/spec/beaker/test_suite_spec.rb +306 -9
- metadata +2 -8
- data/lib/beaker/runner/mini_test/test_suite.rb +0 -58
- data/lib/beaker/runner/native/test_case.rb +0 -193
- data/lib/beaker/runner/native/test_suite.rb +0 -410
- data/spec/beaker/options/beaker_options_spec.rb +0 -34
- data/spec/beaker/runner/native/test_case_spec.rb +0 -147
- data/spec/beaker/runner/native/test_suite_spec.rb +0 -303
data/lib/beaker/version.rb
CHANGED
@@ -1,20 +1,317 @@
|
|
1
|
-
require
|
2
|
-
require
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'fileutils'
|
3
3
|
|
4
4
|
module Beaker
|
5
5
|
describe TestSuite do
|
6
|
-
|
7
|
-
|
8
|
-
|
6
|
+
|
7
|
+
context 'new' do
|
8
|
+
let(:test_dir) { 'tmp/tests' }
|
9
|
+
|
10
|
+
let(:options) { {'name' => create_files(@files)} }
|
11
|
+
let(:rb_test) { File.expand_path(test_dir + '/my_ruby_file.rb') }
|
12
|
+
let(:pl_test) { File.expand_path(test_dir + '/my_perl_file.pl') }
|
13
|
+
let(:sh_test) { File.expand_path(test_dir + '/my_shell_file.sh') }
|
14
|
+
|
15
|
+
it 'fails without test files' do
|
16
|
+
expect { Beaker::TestSuite.new('name', 'hosts', Hash.new, Time.now, :stop_on_error) }.to raise_error
|
17
|
+
end
|
18
|
+
|
19
|
+
it 'includes specific files as test file when explicitly passed' do
|
20
|
+
@files = [ rb_test ]
|
21
|
+
ts = Beaker::TestSuite.new('name', 'hosts', options, Time.now, :stop_on_error)
|
22
|
+
|
23
|
+
tfs = ts.instance_variable_get(:@test_files)
|
24
|
+
expect(tfs).to include rb_test
|
25
|
+
end
|
26
|
+
|
27
|
+
it 'defaults to :slow fail_mode if not provided through parameter or options' do
|
28
|
+
@files = [ rb_test ]
|
29
|
+
ts = Beaker::TestSuite.new('name', 'hosts', options, Time.now)
|
30
|
+
tfm = ts.instance_variable_get(:@fail_mode)
|
31
|
+
expect(tfm).to be == :slow
|
9
32
|
end
|
10
33
|
|
11
|
-
it
|
12
|
-
|
34
|
+
it 'uses provided parameter fail_mode' do
|
35
|
+
@files = [ rb_test ]
|
36
|
+
ts = Beaker::TestSuite.new('name', 'hosts', options, Time.now, :fast)
|
37
|
+
tfm = ts.instance_variable_get(:@fail_mode)
|
38
|
+
expect(tfm).to be == :fast
|
13
39
|
end
|
14
40
|
|
15
|
-
it
|
16
|
-
|
41
|
+
it 'uses options fail_mode if fail_mode parameter is not provided' do
|
42
|
+
@files = [ rb_test ]
|
43
|
+
options[:fail_mode] = :fast
|
44
|
+
ts = Beaker::TestSuite.new('name', 'hosts', options, Time.now)
|
45
|
+
tfm = ts.instance_variable_get(:@fail_mode)
|
46
|
+
expect(tfm).to be == :fast
|
17
47
|
end
|
18
48
|
end
|
49
|
+
|
50
|
+
context 'run' do
|
51
|
+
|
52
|
+
let( :options ) { make_opts.merge({ :logger => double().as_null_object, 'name' => create_files(@files), :log_dated_dir => '.', :xml_dated_dir => '.'}) }
|
53
|
+
let(:broken_script) { "raise RuntimeError" }
|
54
|
+
let(:fail_script) { "raise Beaker::DSL::Outcomes::FailTest" }
|
55
|
+
let(:okay_script) { "true" }
|
56
|
+
let(:rb_test) { 'my_ruby_file.rb' }
|
57
|
+
let(:pl_test) { '/my_perl_file.pl' }
|
58
|
+
let(:sh_test) { '/my_shell_file.sh' }
|
59
|
+
let(:hosts) { make_hosts() }
|
60
|
+
|
61
|
+
it 'fails fast if fail_mode != :slow and runtime error is raised' do
|
62
|
+
allow( Logger ).to receive('new')
|
63
|
+
@files = [ rb_test, pl_test, sh_test]
|
64
|
+
File.open(rb_test, 'w') { |file| file.write(broken_script) }
|
65
|
+
File.open(pl_test, 'w') { |file| file.write(okay_script) }
|
66
|
+
File.open(sh_test, 'w') { |file| file.write(okay_script) }
|
67
|
+
|
68
|
+
ts = Beaker::TestSuite.new( 'name', hosts, options, Time.now, :stop )
|
69
|
+
tsr = ts.instance_variable_get( :@test_suite_results )
|
70
|
+
allow( tsr ).to receive(:write_junit_xml).and_return( true )
|
71
|
+
allow( tsr ).to receive(:summarize).and_return( true )
|
72
|
+
|
73
|
+
ts.run
|
74
|
+
expect( tsr.errored_tests ).to be === 1
|
75
|
+
expect( tsr.failed_tests ).to be === 0
|
76
|
+
expect( tsr.test_count ).to be === 1
|
77
|
+
expect( tsr.passed_tests).to be === 0
|
78
|
+
|
79
|
+
end
|
80
|
+
|
81
|
+
it 'fails fast if fail_mode != :slow and fail test is raised' do
|
82
|
+
allow( Logger ).to receive('new')
|
83
|
+
@files = [ rb_test, pl_test, sh_test]
|
84
|
+
File.open(rb_test, 'w') { |file| file.write(fail_script) }
|
85
|
+
File.open(pl_test, 'w') { |file| file.write(okay_script) }
|
86
|
+
File.open(sh_test, 'w') { |file| file.write(okay_script) }
|
87
|
+
|
88
|
+
ts = Beaker::TestSuite.new( 'name', hosts, options, Time.now, :stop )
|
89
|
+
tsr = ts.instance_variable_get( :@test_suite_results )
|
90
|
+
allow( tsr ).to receive(:write_junit_xml).and_return( true )
|
91
|
+
allow( tsr ).to receive(:summarize).and_return( true )
|
92
|
+
|
93
|
+
ts.run
|
94
|
+
expect( tsr.errored_tests ).to be === 0
|
95
|
+
expect( tsr.failed_tests ).to be === 1
|
96
|
+
expect( tsr.test_count ).to be === 1
|
97
|
+
expect( tsr.passed_tests).to be === 0
|
98
|
+
|
99
|
+
end
|
100
|
+
|
101
|
+
it 'fails slow if fail_mode = :slow, even if a test fails and there is a runtime error' do
|
102
|
+
allow( Logger ).to receive('new')
|
103
|
+
@files = [ rb_test, pl_test, sh_test]
|
104
|
+
File.open(rb_test, 'w') { |file| file.write(broken_script) }
|
105
|
+
File.open(pl_test, 'w') { |file| file.write(fail_script) }
|
106
|
+
File.open(sh_test, 'w') { |file| file.write(okay_script) }
|
107
|
+
|
108
|
+
ts = Beaker::TestSuite.new( 'name', hosts, options, Time.now, :slow )
|
109
|
+
tsr = ts.instance_variable_get( :@test_suite_results )
|
110
|
+
allow( tsr ).to receive(:write_junit_xml).and_return( true )
|
111
|
+
allow( tsr ).to receive(:summarize).and_return( true )
|
112
|
+
|
113
|
+
ts.run
|
114
|
+
expect( tsr.errored_tests ).to be === 1
|
115
|
+
expect( tsr.failed_tests ).to be === 1
|
116
|
+
expect( tsr.test_count ).to be === 3
|
117
|
+
expect( tsr.passed_tests).to be === 1
|
118
|
+
|
119
|
+
end
|
120
|
+
|
121
|
+
|
122
|
+
end
|
123
|
+
|
124
|
+
describe TestSuite::TestSuiteResult do
|
125
|
+
|
126
|
+
let( :options ) { make_opts.merge({ :logger => double().as_null_object }) }
|
127
|
+
let( :hosts ) { make_hosts() }
|
128
|
+
let( :testcase1 ) { Beaker::TestCase.new( hosts, options[:logger], options) }
|
129
|
+
let( :testcase2 ) { Beaker::TestCase.new( hosts, options[:logger], options) }
|
130
|
+
let( :testcase3 ) { Beaker::TestCase.new( hosts, options[:logger], options) }
|
131
|
+
let( :test_suite_result ) { TestSuite::TestSuiteResult.new( options, "my_suite") }
|
132
|
+
|
133
|
+
it 'supports adding test cases' do
|
134
|
+
expect( test_suite_result.test_count ).to be === 0
|
135
|
+
test_suite_result.add_test_case( testcase1 )
|
136
|
+
expect( test_suite_result.test_count ).to be === 1
|
137
|
+
end
|
138
|
+
|
139
|
+
it 'calculates passed tests' do
|
140
|
+
testcase1.instance_variable_set(:@test_status, :pass)
|
141
|
+
testcase2.instance_variable_set(:@test_status, :pass)
|
142
|
+
testcase3.instance_variable_set(:@test_status, :fail)
|
143
|
+
test_suite_result.add_test_case( testcase1 )
|
144
|
+
test_suite_result.add_test_case( testcase2 )
|
145
|
+
test_suite_result.add_test_case( testcase3 )
|
146
|
+
expect( test_suite_result.passed_tests ).to be == 2
|
147
|
+
end
|
148
|
+
|
149
|
+
it 'calculates failed tests' do
|
150
|
+
testcase1.instance_variable_set(:@test_status, :pass)
|
151
|
+
testcase2.instance_variable_set(:@test_status, :pass)
|
152
|
+
testcase3.instance_variable_set(:@test_status, :fail)
|
153
|
+
test_suite_result.add_test_case( testcase1 )
|
154
|
+
test_suite_result.add_test_case( testcase2 )
|
155
|
+
test_suite_result.add_test_case( testcase3 )
|
156
|
+
expect( test_suite_result.failed_tests ).to be == 1
|
157
|
+
end
|
158
|
+
|
159
|
+
it 'calculates errored tests' do
|
160
|
+
testcase1.instance_variable_set(:@test_status, :error)
|
161
|
+
testcase2.instance_variable_set(:@test_status, :pass)
|
162
|
+
testcase3.instance_variable_set(:@test_status, :fail)
|
163
|
+
test_suite_result.add_test_case( testcase1 )
|
164
|
+
test_suite_result.add_test_case( testcase2 )
|
165
|
+
test_suite_result.add_test_case( testcase3 )
|
166
|
+
expect( test_suite_result.errored_tests ).to be == 1
|
167
|
+
end
|
168
|
+
|
169
|
+
it 'calculates skipped tests' do
|
170
|
+
testcase1.instance_variable_set(:@test_status, :error)
|
171
|
+
testcase2.instance_variable_set(:@test_status, :skip)
|
172
|
+
testcase3.instance_variable_set(:@test_status, :fail)
|
173
|
+
test_suite_result.add_test_case( testcase1 )
|
174
|
+
test_suite_result.add_test_case( testcase2 )
|
175
|
+
test_suite_result.add_test_case( testcase3 )
|
176
|
+
expect( test_suite_result.skipped_tests ).to be == 1
|
177
|
+
end
|
178
|
+
|
179
|
+
it 'calculates pending tests' do
|
180
|
+
testcase1.instance_variable_set(:@test_status, :error)
|
181
|
+
testcase2.instance_variable_set(:@test_status, :pending)
|
182
|
+
testcase3.instance_variable_set(:@test_status, :fail)
|
183
|
+
test_suite_result.add_test_case( testcase1 )
|
184
|
+
test_suite_result.add_test_case( testcase2 )
|
185
|
+
test_suite_result.add_test_case( testcase3 )
|
186
|
+
expect( test_suite_result.pending_tests ).to be == 1
|
187
|
+
end
|
188
|
+
|
189
|
+
it 'calculates sum_failed as a sum of errored and failed TestCases' do
|
190
|
+
testcase1.instance_variable_set(:@test_status, :error)
|
191
|
+
testcase2.instance_variable_set(:@test_status, :pending)
|
192
|
+
testcase3.instance_variable_set(:@test_status, :fail)
|
193
|
+
test_suite_result.add_test_case( testcase1 )
|
194
|
+
test_suite_result.add_test_case( testcase2 )
|
195
|
+
test_suite_result.add_test_case( testcase3 )
|
196
|
+
expect( test_suite_result.sum_failed ).to be == 2
|
197
|
+
end
|
198
|
+
|
199
|
+
it 'reports success with no errors/failures' do
|
200
|
+
testcase1.instance_variable_set(:@test_status, :pass)
|
201
|
+
testcase2.instance_variable_set(:@test_status, :pending)
|
202
|
+
testcase3.instance_variable_set(:@test_status, :fail)
|
203
|
+
test_suite_result.add_test_case( testcase1 )
|
204
|
+
test_suite_result.add_test_case( testcase2 )
|
205
|
+
test_suite_result.add_test_case( testcase3 )
|
206
|
+
expect( test_suite_result.success? ).to be == false
|
207
|
+
end
|
208
|
+
|
209
|
+
it 'reports failed if any tests error/fail' do
|
210
|
+
testcase1.instance_variable_set(:@test_status, :pass)
|
211
|
+
testcase2.instance_variable_set(:@test_status, :pending)
|
212
|
+
testcase3.instance_variable_set(:@test_status, :fail)
|
213
|
+
test_suite_result.add_test_case( testcase1 )
|
214
|
+
test_suite_result.add_test_case( testcase2 )
|
215
|
+
test_suite_result.add_test_case( testcase3 )
|
216
|
+
expect( test_suite_result.failed? ).to be == true
|
217
|
+
end
|
218
|
+
|
219
|
+
it 'can calculate the sum of all TestCase runtimes' do
|
220
|
+
testcase1.instance_variable_set(:@runtime, 1)
|
221
|
+
testcase2.instance_variable_set(:@runtime, 10)
|
222
|
+
testcase3.instance_variable_set(:@runtime, 100)
|
223
|
+
test_suite_result.add_test_case( testcase1 )
|
224
|
+
test_suite_result.add_test_case( testcase2 )
|
225
|
+
test_suite_result.add_test_case( testcase3 )
|
226
|
+
expect( test_suite_result.elapsed_time ).to be == 111
|
227
|
+
end
|
228
|
+
|
229
|
+
describe '#write_junit_xml' do
|
230
|
+
let( :options ) { make_opts.merge({ :logger => double().as_null_object, 'name' => create_files(@files), :log_dated_dir => '.', :xml_dated_dir => '.'}) }
|
231
|
+
let(:rb_test) { 'my_ruby_file.rb' }
|
232
|
+
|
233
|
+
it 'doesn\'t re-order test cases themselves on time_sort' do
|
234
|
+
nokogiri_mock = Hash.new
|
235
|
+
allow( nokogiri_mock ).to receive( :add_child )
|
236
|
+
allow( Nokogiri::XML::Node ).to receive( :new ) { nokogiri_mock }
|
237
|
+
allow( LoggerJunit ).to receive( :write_xml ).and_yield( Object.new, nokogiri_mock )
|
238
|
+
|
239
|
+
@files = [ rb_test, rb_test, rb_test]
|
240
|
+
ts = Beaker::TestSuite.new( 'name', hosts, options, Time.now, :fast )
|
241
|
+
tsr = ts.instance_variable_get( :@test_suite_results )
|
242
|
+
|
243
|
+
allow( tsr ).to receive( :start_time ).and_return(0)
|
244
|
+
allow( tsr ).to receive( :stop_time ).and_return(10)
|
245
|
+
expect( tsr.instance_variable_get( :@logger ) ).to receive( :error ).never
|
246
|
+
|
247
|
+
test_cases = []
|
248
|
+
3.times do
|
249
|
+
tc = Beaker::TestCase.new( hosts, options[:logger], options, rb_test)
|
250
|
+
allow( tc ).to receive( :sublog ).and_return( false )
|
251
|
+
test_cases << tc
|
252
|
+
end
|
253
|
+
test_cases[0].instance_variable_set(:@runtime, 3)
|
254
|
+
test_cases[1].instance_variable_set(:@runtime, 301)
|
255
|
+
test_cases[2].instance_variable_set(:@runtime, 101)
|
256
|
+
test_cases.map { |tc| tsr.add_test_case( tc ) }
|
257
|
+
|
258
|
+
original_testcase_order = test_suite_result.instance_variable_get( :@test_cases ).dup
|
259
|
+
tsr.write_junit_xml( 'fakeFilePath07', 'fakeFileToLink09', true )
|
260
|
+
after_testcase_order = test_suite_result.instance_variable_get( :@test_cases ).dup
|
261
|
+
expect( after_testcase_order ).to be === original_testcase_order
|
262
|
+
end
|
263
|
+
|
264
|
+
end
|
265
|
+
|
266
|
+
|
267
|
+
end
|
268
|
+
|
269
|
+
describe '#log_path' do
|
270
|
+
let( :sh_test ) { '/my_shell_file.sh' }
|
271
|
+
let( :files ) { @files ? @files : [sh_test] }
|
272
|
+
let( :options ) { make_opts.merge({ :logger => double().as_null_object, 'name' => create_files(files) }) }
|
273
|
+
let( :hosts ) { make_hosts() }
|
274
|
+
let( :testsuite ) { Beaker::TestSuite.new( 'name', hosts, options, Time.now, :stop ) }
|
275
|
+
|
276
|
+
it 'returns the simple joining of the log dir & file as required' do
|
277
|
+
expect(testsuite.log_path('foo.txt', 'man/date')).to be === 'man/date/foo.txt'
|
278
|
+
end
|
279
|
+
|
280
|
+
describe 'builds the base directory correctly' do
|
281
|
+
# the base directory is where the latest symlink itself should live
|
282
|
+
|
283
|
+
it 'in the usual case' do
|
284
|
+
expect( File.symlink?('man/latest') ).to be_falsy
|
285
|
+
testsuite.log_path('foo.txt', 'man/date')
|
286
|
+
expect( File.symlink?('man/latest') ).to be_truthy
|
287
|
+
end
|
288
|
+
|
289
|
+
it 'if given a nested directory' do
|
290
|
+
expect( File.symlink?('a/latest') ).to be_falsy
|
291
|
+
testsuite.log_path('foo.txt', 'a/b/c/d/e/f')
|
292
|
+
expect( File.symlink?('a/latest') ).to be_truthy
|
293
|
+
end
|
294
|
+
|
295
|
+
end
|
296
|
+
|
297
|
+
describe 'builds the symlink directory correctly' do
|
298
|
+
# the symlink directory is where the symlink points to
|
299
|
+
|
300
|
+
it 'in the usual case' do
|
301
|
+
expect( File.symlink?('d/latest') ).to be_falsy
|
302
|
+
testsuite.log_path('foo.txt', 'd/e')
|
303
|
+
expect( File.readlink('d/latest') ).to be === 'e'
|
304
|
+
end
|
305
|
+
|
306
|
+
it 'if given a nested directory' do
|
307
|
+
expect( File.symlink?('f/latest') ).to be_falsy
|
308
|
+
testsuite.log_path('foo.txt', 'f/g/h/i/j/k')
|
309
|
+
expect( File.readlink('f/latest') ).to be === 'g/h/i/j/k'
|
310
|
+
end
|
311
|
+
|
312
|
+
end
|
313
|
+
|
314
|
+
end
|
315
|
+
|
19
316
|
end
|
20
317
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: beaker
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 2.30.
|
4
|
+
version: 2.30.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Puppetlabs
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2015-12-
|
11
|
+
date: 2015-12-03 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rspec
|
@@ -662,9 +662,6 @@ files:
|
|
662
662
|
- lib/beaker/perf.rb
|
663
663
|
- lib/beaker/platform.rb
|
664
664
|
- lib/beaker/result.rb
|
665
|
-
- lib/beaker/runner/mini_test/test_suite.rb
|
666
|
-
- lib/beaker/runner/native/test_case.rb
|
667
|
-
- lib/beaker/runner/native/test_suite.rb
|
668
665
|
- lib/beaker/shared.rb
|
669
666
|
- lib/beaker/shared/error_handler.rb
|
670
667
|
- lib/beaker/shared/host_manager.rb
|
@@ -728,7 +725,6 @@ files:
|
|
728
725
|
- spec/beaker/logger_junit_spec.rb
|
729
726
|
- spec/beaker/logger_spec.rb
|
730
727
|
- spec/beaker/network_manager_spec.rb
|
731
|
-
- spec/beaker/options/beaker_options_spec.rb
|
732
728
|
- spec/beaker/options/command_line_parser_spec.rb
|
733
729
|
- spec/beaker/options/data/badyaml.cfg
|
734
730
|
- spec/beaker/options/data/hosts.cfg
|
@@ -741,8 +737,6 @@ files:
|
|
741
737
|
- spec/beaker/options/presets_spec.rb
|
742
738
|
- spec/beaker/perf_spec.rb
|
743
739
|
- spec/beaker/platform_spec.rb
|
744
|
-
- spec/beaker/runner/native/test_case_spec.rb
|
745
|
-
- spec/beaker/runner/native/test_suite_spec.rb
|
746
740
|
- spec/beaker/shared/error_handler_spec.rb
|
747
741
|
- spec/beaker/shared/host_manager_spec.rb
|
748
742
|
- spec/beaker/shared/repetition_spec.rb
|
@@ -1,58 +0,0 @@
|
|
1
|
-
module Beaker
|
2
|
-
module Runner
|
3
|
-
module MiniTest
|
4
|
-
class TestSuite
|
5
|
-
attr_reader :name, :options, :fail_mode # TODO ?
|
6
|
-
|
7
|
-
#Create {TestSuite} instance
|
8
|
-
#@param [String] name The name of the {TestSuite}
|
9
|
-
#@param [Array<Host>] hosts An Array of Hosts to act upon.
|
10
|
-
#@param [Hash{Symbol=>String}] options Options for this object
|
11
|
-
#@option options [Logger] :logger The Logger object to report information to
|
12
|
-
#@option options [String] :log_dir The directory where text run logs will be written
|
13
|
-
#@option options [String] :xml_dir The directory where JUnit XML file will be written
|
14
|
-
#@option options [String] :xml_file The name of the JUnit XML file to be written to
|
15
|
-
#@option options [String] :project_root The full path to the Beaker lib directory
|
16
|
-
#@option options [String] :xml_stylesheet The path to a stylesheet to be applied to the generated XML output
|
17
|
-
#@param [Symbol] fail_mode One of :slow, :fast
|
18
|
-
#@param [Time] timestamp Beaker execution start time
|
19
|
-
def initialize(name, hosts, options, timestamp, fail_mode=nil)
|
20
|
-
# TODO ?
|
21
|
-
end
|
22
|
-
|
23
|
-
def run
|
24
|
-
# TODO ?
|
25
|
-
end
|
26
|
-
|
27
|
-
#Execute all the TestCases in this suite.
|
28
|
-
#This is a wrapper that catches any failures generated during TestSuite::run.
|
29
|
-
def run_and_raise_on_failure
|
30
|
-
# TODO ?
|
31
|
-
end
|
32
|
-
|
33
|
-
# Gives a full file path for output to be written to, maintaining the latest symlink
|
34
|
-
# @param [String] name The file name that we want to write to.
|
35
|
-
# @param [String] log_dir The desired output directory.
|
36
|
-
# A symlink will be made from ./basedir/latest to that.
|
37
|
-
# @example
|
38
|
-
# log_path('output.txt', 'log/2014-06-02_16_31_22')
|
39
|
-
#
|
40
|
-
# This will create the structure:
|
41
|
-
#
|
42
|
-
# ./log/2014-06-02_16_31_22/output.txt
|
43
|
-
# ./log/latest -> 2014-06-02_16_31_22
|
44
|
-
#
|
45
|
-
# @example
|
46
|
-
# log_path('foo.log', 'log/man/date')
|
47
|
-
#
|
48
|
-
# This will create the structure:
|
49
|
-
#
|
50
|
-
# ./log/man/date/foo.log
|
51
|
-
# ./log/latest -> man/date
|
52
|
-
def log_path(name, log_dir)
|
53
|
-
# TODO ?
|
54
|
-
end
|
55
|
-
end
|
56
|
-
end
|
57
|
-
end
|
58
|
-
end
|
@@ -1,193 +0,0 @@
|
|
1
|
-
[ 'host', 'dsl' ].each do |lib|
|
2
|
-
require "beaker/#{lib}"
|
3
|
-
end
|
4
|
-
|
5
|
-
require 'tempfile'
|
6
|
-
require 'benchmark'
|
7
|
-
require 'stringio'
|
8
|
-
require 'rbconfig'
|
9
|
-
|
10
|
-
module Beaker
|
11
|
-
module Runner
|
12
|
-
module Native
|
13
|
-
# This class represents a single test case. A test case is necessarily
|
14
|
-
# contained all in one file though may have multiple dependent examples.
|
15
|
-
# They are executed in order (save for any teardown procs registered
|
16
|
-
# through {Beaker::DSL::Structure#teardown}) and once completed
|
17
|
-
# the status of the TestCase is saved. Instance readers/accessors provide
|
18
|
-
# the test case access to various details of the environment and suite
|
19
|
-
# the test case is running within.
|
20
|
-
#
|
21
|
-
# See {Beaker::DSL} for more information about writing tests
|
22
|
-
# using the DSL.
|
23
|
-
class TestCase
|
24
|
-
include ::Beaker::DSL
|
25
|
-
|
26
|
-
# The Exception raised by Ruby's STDLIB's test framework (Ruby 1.9)
|
27
|
-
TEST_EXCEPTION_CLASS = ::MiniTest::Assertion
|
28
|
-
|
29
|
-
# Necessary for implementing {Beaker::DSL::Helpers#confine}.
|
30
|
-
# Assumed to be an array of valid {Beaker::Host} objects for
|
31
|
-
# this test case.
|
32
|
-
attr_accessor :hosts
|
33
|
-
|
34
|
-
# Necessary for many methods in {Beaker::DSL}. Assumed to be
|
35
|
-
# an instance of {Beaker::Logger}.
|
36
|
-
attr_accessor :logger
|
37
|
-
|
38
|
-
# Necessary for many methods in {Beaker::DSL::Helpers}. Assumed to be
|
39
|
-
# a hash.
|
40
|
-
attr_accessor :metadata
|
41
|
-
|
42
|
-
#The full log for this test
|
43
|
-
attr_accessor :sublog
|
44
|
-
|
45
|
-
#The result for the last command run
|
46
|
-
attr_accessor :last_result
|
47
|
-
|
48
|
-
# A Hash of 'product name' => 'version installed', only set when
|
49
|
-
# products are installed via git or PE install steps. See the 'git' or
|
50
|
-
# 'pe' directories within 'ROOT/setup' for examples.
|
51
|
-
attr_reader :version
|
52
|
-
|
53
|
-
# Parsed command line options.
|
54
|
-
attr_reader :options
|
55
|
-
|
56
|
-
# The path to the file which contains this test case.
|
57
|
-
attr_reader :path
|
58
|
-
|
59
|
-
# I don't know why this is here
|
60
|
-
attr_reader :fail_flag
|
61
|
-
|
62
|
-
# The user that is running this tests home directory, needed by 'net/ssh'.
|
63
|
-
attr_reader :usr_home
|
64
|
-
|
65
|
-
# A Symbol denoting the status of this test (:fail, :pending,
|
66
|
-
# :skipped, :pass).
|
67
|
-
attr_reader :test_status
|
68
|
-
|
69
|
-
# The exception that may have stopped this test's execution.
|
70
|
-
attr_reader :exception
|
71
|
-
|
72
|
-
# @deprecated
|
73
|
-
# The amount of time taken to execute the test. Unused, probably soon
|
74
|
-
# to be removed or refactored.
|
75
|
-
attr_reader :runtime
|
76
|
-
|
77
|
-
# An Array of Procs to be called after test execution has stopped
|
78
|
-
# (whether by exception or not).
|
79
|
-
attr_reader :teardown_procs
|
80
|
-
|
81
|
-
# @deprecated
|
82
|
-
# Legacy accessor from when test files would only contain one remote
|
83
|
-
# action. Contains the Result of the last call to utilize
|
84
|
-
# {Beaker::DSL::Helpers#on}. Do not use as it is not safe
|
85
|
-
# in test files that use multiple calls to
|
86
|
-
# {Beaker::DSL::Helpers#on}.
|
87
|
-
attr_accessor :result
|
88
|
-
|
89
|
-
# @param [Hosts,Array<Host>] these_hosts The hosts to execute this test
|
90
|
-
# against/on.
|
91
|
-
# @param [Logger] logger A logger that implements
|
92
|
-
# {Beaker::Logger}'s interface.
|
93
|
-
# @param [Hash{Symbol=>String}] options Parsed command line options.
|
94
|
-
# @param [String] path The local path to a test file to be executed.
|
95
|
-
def initialize(these_hosts, logger, options={}, path=nil)
|
96
|
-
@hosts = these_hosts
|
97
|
-
@logger = logger
|
98
|
-
@sublog = ""
|
99
|
-
@options = options
|
100
|
-
@path = path
|
101
|
-
@usr_home = options[:home]
|
102
|
-
@test_status = :pass
|
103
|
-
@exception = nil
|
104
|
-
@runtime = nil
|
105
|
-
@teardown_procs = []
|
106
|
-
@metadata = {}
|
107
|
-
set_current_test_filename(@path ? File.basename(@path, '.rb') : nil)
|
108
|
-
|
109
|
-
|
110
|
-
#
|
111
|
-
# We put this on each wrapper (rather than the class) so that methods
|
112
|
-
# defined in the tests don't leak out to other tests.
|
113
|
-
class << self
|
114
|
-
def run_test
|
115
|
-
@logger.start_sublog
|
116
|
-
@logger.last_result = nil
|
117
|
-
|
118
|
-
set_current_step_name(nil)
|
119
|
-
|
120
|
-
#add arbitrary role methods
|
121
|
-
roles = []
|
122
|
-
@hosts.each do |host|
|
123
|
-
roles << host[:roles]
|
124
|
-
end
|
125
|
-
add_role_def( roles.flatten.uniq )
|
126
|
-
|
127
|
-
@runtime = Benchmark.realtime do
|
128
|
-
begin
|
129
|
-
test = File.read(path)
|
130
|
-
eval test,nil,path,1
|
131
|
-
rescue FailTest, TEST_EXCEPTION_CLASS => e
|
132
|
-
@test_status = :fail
|
133
|
-
@exception = e
|
134
|
-
rescue PendingTest
|
135
|
-
@test_status = :pending
|
136
|
-
rescue SkipTest
|
137
|
-
@test_status = :skip
|
138
|
-
rescue StandardError, ScriptError, SignalException => e
|
139
|
-
log_and_fail_test(e)
|
140
|
-
ensure
|
141
|
-
@teardown_procs.each do |teardown|
|
142
|
-
begin
|
143
|
-
teardown.call
|
144
|
-
rescue StandardError, SignalException, TEST_EXCEPTION_CLASS => e
|
145
|
-
log_and_fail_test(e)
|
146
|
-
end
|
147
|
-
end
|
148
|
-
end
|
149
|
-
end
|
150
|
-
@sublog = @logger.get_sublog
|
151
|
-
@last_result = @logger.last_result
|
152
|
-
return self
|
153
|
-
end
|
154
|
-
|
155
|
-
private
|
156
|
-
|
157
|
-
# Log an error and mark the test as failed, passing through an
|
158
|
-
# exception so it can be displayed at the end of the total run.
|
159
|
-
#
|
160
|
-
# We break out the complete exception backtrace and log each line
|
161
|
-
# individually as well.
|
162
|
-
#
|
163
|
-
# @param exception [Exception] exception to fail with
|
164
|
-
def log_and_fail_test(exception)
|
165
|
-
logger.error("#{exception.class}: #{exception.message}")
|
166
|
-
bt = exception.backtrace
|
167
|
-
logger.pretty_backtrace(bt).each_line do |line|
|
168
|
-
logger.error(line)
|
169
|
-
end
|
170
|
-
@test_status = :error
|
171
|
-
@exception = exception
|
172
|
-
end
|
173
|
-
end
|
174
|
-
end
|
175
|
-
|
176
|
-
# The TestCase as a hash
|
177
|
-
# @api public
|
178
|
-
# @note The visibility and semantics of this method are valid, but the
|
179
|
-
# structure of the Hash it returns may change without notice
|
180
|
-
#
|
181
|
-
# @return [Hash] A Hash representation of this test.
|
182
|
-
def to_hash
|
183
|
-
hash = {}
|
184
|
-
hash['HOSTS'] = {}
|
185
|
-
@hosts.each do |host|
|
186
|
-
hash['HOSTS'][host.name] = host.overrides
|
187
|
-
end
|
188
|
-
hash
|
189
|
-
end
|
190
|
-
end
|
191
|
-
end
|
192
|
-
end
|
193
|
-
end
|