beaker 2.29.1 → 2.30.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,5 +1,5 @@
1
1
  module Beaker
2
2
  module Version
3
- STRING = '2.29.1'
3
+ STRING = '2.30.0'
4
4
  end
5
5
  end
@@ -87,6 +87,8 @@ describe ClassMixedWithDSLInstallUtils do
87
87
 
88
88
  it 'uses aio paths for hosts with aio type (backwards compatability)' do
89
89
  hosts.each do |host|
90
+ host[:pe_ver] = nil
91
+ host[:version] = nil
90
92
  host[:type] = 'aio'
91
93
  end
92
94
  expect(subject).to receive(:add_aio_defaults_on).exactly(hosts.length).times
@@ -49,6 +49,8 @@ describe ClassMixedWithDSLInstallUtils do
49
49
  context '#configure_pe_defaults_on' do
50
50
  it 'uses aio paths for hosts of role aio' do
51
51
  hosts.each do |host|
52
+ host[:pe_ver] = nil
53
+ host[:version] = nil
52
54
  host[:roles] = host[:roles] | ['aio']
53
55
  end
54
56
  expect(subject).to receive(:add_pe_defaults_on).exactly(hosts.length).times
@@ -71,6 +73,8 @@ describe ClassMixedWithDSLInstallUtils do
71
73
 
72
74
  it 'uses aio paths for hosts of type aio' do
73
75
  hosts.each do |host|
76
+ host[:pe_ver] = nil
77
+ host[:version] = nil
74
78
  host[:type] = 'aio'
75
79
  end
76
80
  expect(subject).to receive(:add_aio_defaults_on).exactly(hosts.length).times
@@ -83,6 +83,8 @@ describe ClassMixedWithDSLInstallUtils do
83
83
 
84
84
  it "adds aio defaults to foss hosts when they have an aio foss puppet version" do
85
85
  hosts.each do |host|
86
+ host[:pe_ver] = nil
87
+ host[:version] = nil
86
88
  host['type'] = 'foss'
87
89
  host['version'] = '4.0'
88
90
  end
@@ -93,6 +95,8 @@ describe ClassMixedWithDSLInstallUtils do
93
95
 
94
96
  it "adds aio defaults to foss hosts when they have type foss-aio" do
95
97
  hosts.each do |host|
98
+ host[:pe_ver] = nil
99
+ host[:version] = nil
96
100
  host['type'] = 'foss-aio'
97
101
  end
98
102
  expect(subject).to receive(:add_foss_defaults_on).exactly(hosts.length).times
@@ -102,6 +106,8 @@ describe ClassMixedWithDSLInstallUtils do
102
106
 
103
107
  it "can set aio defaults for aio type (backwards compatability)" do
104
108
  hosts.each do |host|
109
+ host[:pe_ver] = nil
110
+ host[:version] = nil
105
111
  host['type'] = 'aio'
106
112
  end
107
113
  expect(subject).to receive(:add_aio_defaults_on).exactly(hosts.length).times
@@ -163,6 +163,124 @@ describe ClassMixedWithDSLRoles do
163
163
  agent1[:type] = 'aio-foss'
164
164
  expect( subject.aio_version?(agent1) ).to be === true
165
165
  end
166
+ it 'can take an empty string for pe_ver' do
167
+ agent1[:pe_ver] = ''
168
+ expect{ subject.aio_version?(agent1) }.not_to raise_error
169
+ end
170
+ it 'can take an empty string for FOSS version' do
171
+ agent1[:version] = ''
172
+ expect{ subject.aio_version?(agent1) }.not_to raise_error
173
+ end
174
+
175
+ context 'truth table-type testing' do
176
+
177
+ before :each do
178
+ @old_pe_ver = agent1[:pe_ver]
179
+ @old_version = agent1[:version]
180
+ @old_roles = agent1[:roles]
181
+ @old_type = agent1[:type]
182
+ end
183
+
184
+ after :each do
185
+ agent1[:pe_ver] = @old_pe_ver
186
+ agent1[:version] = @old_version
187
+ agent1[:roles] = @old_roles
188
+ agent1[:type] = @old_type
189
+ end
190
+
191
+ context 'version values table' do
192
+ # pe_ver, version, answer
193
+ versions_table = [
194
+ [nil, nil, false],
195
+ [nil, '', false],
196
+ [nil, '3.9', false],
197
+ [nil, '4.0', true ],
198
+ [nil, '2015.1', true ],
199
+ \
200
+ ['', nil, false],
201
+ ['', '', false],
202
+ ['', '3.9', false],
203
+ ['', '4.0', true ],
204
+ ['', '2015.1', true ],
205
+ \
206
+ ['3.9', nil, false],
207
+ ['3.9', '', false],
208
+ ['3.9', '3.9', false],
209
+ ['3.9', '4.0', false],
210
+ ['3.9', '2015.1', false],
211
+ \
212
+ ['4.0', nil, true],
213
+ ['4.0', '', true],
214
+ ['4.0', '3.9', true],
215
+ ['4.0', '4.0', true],
216
+ ['4.0', '2015.1', true],
217
+ \
218
+ ['2015.1', nil, true],
219
+ ['2015.1', '', true],
220
+ ['2015.1', '3.9', true],
221
+ ['2015.1', '4.0', true],
222
+ ['2015.1', '2015.1', true],
223
+ ]
224
+
225
+ versions_table.each do |answers_row|
226
+ it "acts with values #{answers_row} correctly" do
227
+ agent1[:pe_ver] = answers_row[0]
228
+ agent1[:version] = answers_row[1]
229
+ agent1[:roles] = nil
230
+ agent1[:type] = nil
231
+ expect( subject.aio_version?(agent1) ).to be === answers_row[2]
232
+ end
233
+ end
234
+ end
235
+
236
+ context 'roles values table' do
237
+ roles_table = [
238
+ [nil, false],
239
+ [[], false],
240
+ [['aio'], true ],
241
+ [['gun'], false],
242
+ [['a', 'b'], false],
243
+ [['c', 'aio'], true ],
244
+ ]
245
+
246
+ roles_table.each do |answers_row|
247
+ it "acts with values #{answers_row} correctly" do
248
+ agent1[:pe_ver] = nil
249
+ agent1[:version] = nil
250
+ agent1[:roles] = answers_row[0]
251
+ agent1[:type] = nil
252
+ expect( subject.aio_version?(agent1) ).to be === answers_row[1]
253
+ end
254
+ end
255
+ end
256
+
257
+ context 'type values table' do
258
+ type_table = [
259
+ [nil, false],
260
+ ['', false],
261
+ ['cheese', false],
262
+ ['paionts', false],
263
+ ['aioch', false],
264
+ ['chaio', false],
265
+ ['aio', true ],
266
+ ['aio-', true ],
267
+ ['ew-aio-ji', true ],
268
+ ['id-aiot', false],
269
+ ]
270
+
271
+ type_table.each do |answers_row|
272
+ it "acts with values #{answers_row} correctly" do
273
+ agent1[:pe_ver] = nil
274
+ agent1[:version] = nil
275
+ agent1[:roles] = nil
276
+ agent1[:type] = answers_row[0]
277
+ expect( subject.aio_version?(agent1) ).to be === answers_row[1]
278
+ end
279
+ end
280
+ end
281
+
282
+ end
283
+
166
284
  end
167
285
  describe '#aio_agent?' do
168
286
  it 'returns false if agent_only check doesn\'t pass' do
@@ -37,12 +37,13 @@ module Beaker
37
37
  vagrant.make_vfile( @hosts )
38
38
 
39
39
  vagrantfile = File.read( File.expand_path( File.join( path, "Vagrantfile")))
40
+ puts "file is #{path}\n"
40
41
  expect( vagrantfile ).to be === <<-EOF
41
42
  Vagrant.configure("2") do |c|
42
43
  c.ssh.insert_key = false
43
44
  c.vm.define 'vm1' do |v|
44
45
  v.vm.hostname = 'vm1'
45
- v.vm.box = 'vm1_of_my_box'
46
+ v.vm.box = 'vm2vm1_of_my_box'
46
47
  v.vm.box_url = 'http://address.for.my.box.vm1'
47
48
  v.vm.box_check_update = 'true'
48
49
  v.vm.network :private_network, ip: "ip.address.for.vm1", :netmask => "255.255.0.0", :mac => "0123456789"
@@ -54,7 +55,7 @@ Vagrant.configure("2") do |c|
54
55
  end
55
56
  c.vm.define 'vm2' do |v|
56
57
  v.vm.hostname = 'vm2'
57
- v.vm.box = 'vm2_of_my_box'
58
+ v.vm.box = 'vm2vm2_of_my_box'
58
59
  v.vm.box_url = 'http://address.for.my.box.vm2'
59
60
  v.vm.box_check_update = 'true'
60
61
  v.vm.network :private_network, ip: "ip.address.for.vm2", :netmask => "255.255.0.0", :mac => "0123456789"
@@ -66,7 +67,7 @@ Vagrant.configure("2") do |c|
66
67
  end
67
68
  c.vm.define 'vm3' do |v|
68
69
  v.vm.hostname = 'vm3'
69
- v.vm.box = 'vm3_of_my_box'
70
+ v.vm.box = 'vm2vm3_of_my_box'
70
71
  v.vm.box_url = 'http://address.for.my.box.vm3'
71
72
  v.vm.box_check_update = 'true'
72
73
  v.vm.network :private_network, ip: "ip.address.for.vm3", :netmask => "255.255.0.0", :mac => "0123456789"
@@ -246,7 +247,6 @@ EOF
246
247
  expect{ vagrant.get_ip_from_vagrant_file(host.name) }.to raise_error
247
248
  end
248
249
  end
249
-
250
250
  end
251
251
 
252
252
  describe "provisioning and cleanup" do
@@ -0,0 +1,34 @@
1
+ require "spec_helper"
2
+
3
+ # safely set values for ARGV in block, restoring original value on block leave
4
+ def with_ARGV(value, &block)
5
+ if defined? ARGV
6
+ defined_ARGV, old_ARGV = true, ARGV
7
+ Object.send(:remove_const, :ARGV)
8
+ else
9
+ defined_ARGV, old_ARGV = false, nil
10
+ end
11
+
12
+ Object.send(:const_set, :ARGV, value)
13
+
14
+ yield
15
+ ensure
16
+ Object.send(:remove_const, :ARGV)
17
+ Object.send(:const_set, :ARGV, old_ARGV) if defined_ARGV
18
+ end
19
+
20
+ describe "Beaker Options" do
21
+ let (:parser) { Beaker::Options::Parser.new }
22
+
23
+ it "defaults :runner to 'native'" do
24
+ with_ARGV([]) do
25
+ expect(parser.parse_args[:runner]).to be == "native"
26
+ end
27
+ end
28
+
29
+ it "accepts :runner from command-line" do
30
+ with_ARGV(["--runner", "minitest"]) do
31
+ expect(parser.parse_args[:runner]).to be == "minitest"
32
+ end
33
+ end
34
+ end
@@ -128,6 +128,22 @@ module Beaker
128
128
 
129
129
  end
130
130
 
131
- end
131
+ context 'round tripping from yaml', if: RUBY_VERSION =~ /^1\.9/ do
132
+ before do
133
+ @name = 'ubuntu-14.04-x86_64'
134
+ end
135
+
136
+ let(:round_tripped) { YAML.load(YAML.dump(platform)) }
132
137
 
138
+ [:variant, :arch, :version, :codename].each do |field|
139
+ it "deserializes the '#{field}' field" do
140
+ expect(round_tripped.send(field)).to eq platform.send(field)
141
+ end
142
+ end
143
+
144
+ it 'properly sets the string contents' do
145
+ expect(round_tripped.to_s).to eq @name
146
+ end
147
+ end
148
+ end
133
149
  end
@@ -0,0 +1,147 @@
1
+ require 'spec_helper'
2
+
3
+ module Beaker
4
+ module Runner
5
+ module Native
6
+ describe TestCase do
7
+ let(:logger) { double('logger').as_null_object }
8
+ let(:path) { @path || '/tmp/nope' }
9
+ let(:testcase) { TestCase.new({}, logger, {}, path) }
10
+
11
+ context 'run_test' do
12
+ it 'defaults to test_status :pass on success' do
13
+ path = 'test.rb'
14
+ File.open(path, 'w') do |f|
15
+ f.write ""
16
+ end
17
+ @path = path
18
+ expect( testcase ).to_not receive( :log_and_fail_test )
19
+ testcase.run_test
20
+ status = testcase.instance_variable_get(:@test_status)
21
+ expect(status).to be === :pass
22
+ end
23
+
24
+ it 'updates test_status to :skip on SkipTest' do
25
+ path = 'test.rb'
26
+ File.open(path, 'w') do |f|
27
+ f.write "raise SkipTest"
28
+ end
29
+ @path = path
30
+ expect( testcase ).to_not receive( :log_and_fail_test )
31
+ testcase.run_test
32
+ status = testcase.instance_variable_get(:@test_status)
33
+ expect(status).to be === :skip
34
+ end
35
+
36
+ it 'updates test_status to :pending on PendingTest' do
37
+ path = 'test.rb'
38
+ File.open(path, 'w') do |f|
39
+ f.write "raise PendingTest"
40
+ end
41
+ @path = path
42
+ expect( testcase ).to_not receive( :log_and_fail_test )
43
+ testcase.run_test
44
+ status = testcase.instance_variable_get(:@test_status)
45
+ expect(status).to be === :pending
46
+ end
47
+
48
+ it 'updates test_status to :fail on FailTest' do
49
+ path = 'test.rb'
50
+ File.open(path, 'w') do |f|
51
+ f.write "raise FailTest"
52
+ end
53
+ @path = path
54
+ expect( testcase ).to_not receive( :log_and_fail_test )
55
+ testcase.run_test
56
+ status = testcase.instance_variable_get(:@test_status)
57
+ expect(status).to be === :fail
58
+ end
59
+
60
+ it 'correctly handles RuntimeError' do
61
+ path = 'test.rb'
62
+ File.open(path, 'w') do |f|
63
+ f.write "raise RuntimeError"
64
+ end
65
+ @path = path
66
+ expect( testcase ).to receive( :log_and_fail_test ).once.with(kind_of(RuntimeError))
67
+ testcase.run_test
68
+ end
69
+
70
+ it 'correctly handles ScriptError' do
71
+ path = 'test.rb'
72
+ File.open(path, 'w') do |f|
73
+ f.write "raise ScriptError"
74
+ end
75
+ @path = path
76
+ expect( testcase ).to receive( :log_and_fail_test ).once.with(kind_of(ScriptError))
77
+ testcase.run_test
78
+ end
79
+
80
+ it 'correctly handles Timeout::Error' do
81
+ path = 'test.rb'
82
+ File.open(path, 'w') do |f|
83
+ f.write "raise Timeout::Error"
84
+ end
85
+ @path = path
86
+ expect( testcase ).to receive( :log_and_fail_test ).once.with(kind_of(Timeout::Error))
87
+ testcase.run_test
88
+ end
89
+
90
+ it 'correctly handles CommandFailure' do
91
+ path = 'test.rb'
92
+ File.open(path, 'w') do |f|
93
+ f.write "raise Host::CommandFailure"
94
+ end
95
+ @path = path
96
+ expect( testcase ).to receive( :log_and_fail_test ).once.with(kind_of(Host::CommandFailure))
97
+ testcase.run_test
98
+ end
99
+
100
+ it 'records a test failure if an assertion fails in a teardown block' do
101
+ path = 'test.rb'
102
+ File.open(path, 'w') do |f|
103
+ f.write <<-EOF
104
+ teardown do
105
+ assert_equal(1, 2, 'Oh noes!')
106
+ end
107
+ EOF
108
+ end
109
+ @path = path
110
+ expect( testcase ).to receive( :log_and_fail_test ).once.with(kind_of(Minitest::Assertion))
111
+ testcase.run_test
112
+ end
113
+ end
114
+
115
+ context 'metadata' do
116
+ it 'sets the filename correctly from the path' do
117
+ answer = 'jacket'
118
+ path = "#{answer}.rb"
119
+ File.open(path, 'w') do |f|
120
+ f.write ""
121
+ end
122
+ @path = path
123
+ testcase.run_test
124
+ metadata = testcase.instance_variable_get(:@metadata)
125
+ expect(metadata[:case][:file_name]).to be === answer
126
+ end
127
+
128
+ it 'resets the step name' do
129
+ path = 'test.rb'
130
+ File.open(path, 'w') do |f|
131
+ f.write ""
132
+ end
133
+ @path = path
134
+ # we have to create a TestCase by hand, so that we can set old
135
+ tc = TestCase.new({}, logger, {}, path)
136
+ # metadata on it, so that we can test that it's being reset correctly
137
+ old_metadata = { :step => { :name => 'CharlieBrown' } }
138
+ tc.instance_variable_set(:@metadata, old_metadata)
139
+ tc.run_test
140
+ metadata = tc.instance_variable_get(:@metadata)
141
+ expect(metadata[:step][:name]).to be_nil
142
+ end
143
+ end
144
+ end
145
+ end
146
+ end
147
+ end
@@ -0,0 +1,303 @@
1
+ require 'spec_helper'
2
+ require 'fileutils'
3
+
4
+ module Beaker
5
+ module Runner
6
+ module Native
7
+ describe TestSuite do
8
+ context 'new' do
9
+ let(:test_dir) { 'tmp/tests' }
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::Runner::Native::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::Runner::Native::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::Runner::Native::TestSuite.new('name', 'hosts', options, Time.now)
30
+ tfm = ts.instance_variable_get(:@fail_mode)
31
+ expect(tfm).to be == :slow
32
+ end
33
+
34
+ it 'uses provided parameter fail_mode' do
35
+ @files = [ rb_test ]
36
+ ts = Beaker::Runner::Native::TestSuite.new('name', 'hosts', options, Time.now, :fast)
37
+ tfm = ts.instance_variable_get(:@fail_mode)
38
+ expect(tfm).to be == :fast
39
+ end
40
+
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::Runner::Native::TestSuite.new('name', 'hosts', options, Time.now)
45
+ tfm = ts.instance_variable_get(:@fail_mode)
46
+ expect(tfm).to be == :fast
47
+ end
48
+ end
49
+
50
+ context 'run' do
51
+ let( :options ) { make_opts.merge({ :logger => double().as_null_object, 'name' => create_files(@files), :log_dated_dir => '.', :xml_dated_dir => '.'}) }
52
+ let(:broken_script) { "raise RuntimeError" }
53
+ let(:fail_script) { "raise Beaker::DSL::Outcomes::FailTest" }
54
+ let(:okay_script) { "true" }
55
+ let(:rb_test) { 'my_ruby_file.rb' }
56
+ let(:pl_test) { '/my_perl_file.pl' }
57
+ let(:sh_test) { '/my_shell_file.sh' }
58
+ let(:hosts) { make_hosts() }
59
+
60
+ it 'fails fast if fail_mode != :slow and runtime error is raised' do
61
+ allow( Logger ).to receive('new')
62
+ @files = [ rb_test, pl_test, sh_test]
63
+ File.open(rb_test, 'w') { |file| file.write(broken_script) }
64
+ File.open(pl_test, 'w') { |file| file.write(okay_script) }
65
+ File.open(sh_test, 'w') { |file| file.write(okay_script) }
66
+
67
+ ts = Beaker::Runner::Native::TestSuite.new( 'name', hosts, options, Time.now, :stop )
68
+ tsr = ts.instance_variable_get( :@test_suite_results )
69
+ allow( tsr ).to receive(:write_junit_xml).and_return( true )
70
+ allow( tsr ).to receive(:summarize).and_return( true )
71
+
72
+ ts.run
73
+ expect( tsr.errored_tests ).to be === 1
74
+ expect( tsr.failed_tests ).to be === 0
75
+ expect( tsr.test_count ).to be === 1
76
+ expect( tsr.passed_tests).to be === 0
77
+ end
78
+
79
+ it 'fails fast if fail_mode != :slow and fail test is raised' do
80
+ allow( Logger ).to receive('new')
81
+ @files = [ rb_test, pl_test, sh_test]
82
+ File.open(rb_test, 'w') { |file| file.write(fail_script) }
83
+ File.open(pl_test, 'w') { |file| file.write(okay_script) }
84
+ File.open(sh_test, 'w') { |file| file.write(okay_script) }
85
+
86
+ ts = Beaker::Runner::Native::TestSuite.new( 'name', hosts, options, Time.now, :stop )
87
+ tsr = ts.instance_variable_get( :@test_suite_results )
88
+ allow( tsr ).to receive(:write_junit_xml).and_return( true )
89
+ allow( tsr ).to receive(:summarize).and_return( true )
90
+
91
+ ts.run
92
+ expect( tsr.errored_tests ).to be === 0
93
+ expect( tsr.failed_tests ).to be === 1
94
+ expect( tsr.test_count ).to be === 1
95
+ expect( tsr.passed_tests).to be === 0
96
+ end
97
+
98
+ it 'fails slow if fail_mode = :slow, even if a test fails and there is a runtime error' do
99
+ allow( Logger ).to receive('new')
100
+ @files = [ rb_test, pl_test, sh_test]
101
+ File.open(rb_test, 'w') { |file| file.write(broken_script) }
102
+ File.open(pl_test, 'w') { |file| file.write(fail_script) }
103
+ File.open(sh_test, 'w') { |file| file.write(okay_script) }
104
+
105
+ ts = Beaker::Runner::Native::TestSuite.new( 'name', hosts, options, Time.now, :slow )
106
+ tsr = ts.instance_variable_get( :@test_suite_results )
107
+ allow( tsr ).to receive(:write_junit_xml).and_return( true )
108
+ allow( tsr ).to receive(:summarize).and_return( true )
109
+
110
+ ts.run
111
+ expect( tsr.errored_tests ).to be === 1
112
+ expect( tsr.failed_tests ).to be === 1
113
+ expect( tsr.test_count ).to be === 3
114
+ expect( tsr.passed_tests).to be === 1
115
+ end
116
+ end
117
+
118
+ describe TestSuite::TestSuiteResult do
119
+ let( :options ) { make_opts.merge({ :logger => double().as_null_object }) }
120
+ let( :hosts ) { make_hosts() }
121
+ let( :testcase1 ) { Beaker::Runner::Native::TestCase.new( hosts, options[:logger], options) }
122
+ let( :testcase2 ) { Beaker::Runner::Native::TestCase.new( hosts, options[:logger], options) }
123
+ let( :testcase3 ) { Beaker::Runner::Native::TestCase.new( hosts, options[:logger], options) }
124
+ let( :test_suite_result ) { TestSuite::TestSuiteResult.new( options, "my_suite") }
125
+
126
+ it 'supports adding test cases' do
127
+ expect( test_suite_result.test_count ).to be === 0
128
+ test_suite_result.add_test_case( testcase1 )
129
+ expect( test_suite_result.test_count ).to be === 1
130
+ end
131
+
132
+ it 'calculates passed tests' do
133
+ testcase1.instance_variable_set(:@test_status, :pass)
134
+ testcase2.instance_variable_set(:@test_status, :pass)
135
+ testcase3.instance_variable_set(:@test_status, :fail)
136
+ test_suite_result.add_test_case( testcase1 )
137
+ test_suite_result.add_test_case( testcase2 )
138
+ test_suite_result.add_test_case( testcase3 )
139
+ expect( test_suite_result.passed_tests ).to be == 2
140
+ end
141
+
142
+ it 'calculates failed tests' do
143
+ testcase1.instance_variable_set(:@test_status, :pass)
144
+ testcase2.instance_variable_set(:@test_status, :pass)
145
+ testcase3.instance_variable_set(:@test_status, :fail)
146
+ test_suite_result.add_test_case( testcase1 )
147
+ test_suite_result.add_test_case( testcase2 )
148
+ test_suite_result.add_test_case( testcase3 )
149
+ expect( test_suite_result.failed_tests ).to be == 1
150
+ end
151
+
152
+ it 'calculates errored tests' do
153
+ testcase1.instance_variable_set(:@test_status, :error)
154
+ testcase2.instance_variable_set(:@test_status, :pass)
155
+ testcase3.instance_variable_set(:@test_status, :fail)
156
+ test_suite_result.add_test_case( testcase1 )
157
+ test_suite_result.add_test_case( testcase2 )
158
+ test_suite_result.add_test_case( testcase3 )
159
+ expect( test_suite_result.errored_tests ).to be == 1
160
+ end
161
+
162
+ it 'calculates skipped tests' do
163
+ testcase1.instance_variable_set(:@test_status, :error)
164
+ testcase2.instance_variable_set(:@test_status, :skip)
165
+ testcase3.instance_variable_set(:@test_status, :fail)
166
+ test_suite_result.add_test_case( testcase1 )
167
+ test_suite_result.add_test_case( testcase2 )
168
+ test_suite_result.add_test_case( testcase3 )
169
+ expect( test_suite_result.skipped_tests ).to be == 1
170
+ end
171
+
172
+ it 'calculates pending tests' do
173
+ testcase1.instance_variable_set(:@test_status, :error)
174
+ testcase2.instance_variable_set(:@test_status, :pending)
175
+ testcase3.instance_variable_set(:@test_status, :fail)
176
+ test_suite_result.add_test_case( testcase1 )
177
+ test_suite_result.add_test_case( testcase2 )
178
+ test_suite_result.add_test_case( testcase3 )
179
+ expect( test_suite_result.pending_tests ).to be == 1
180
+ end
181
+
182
+ it 'calculates sum_failed as a sum of errored and failed TestCases' do
183
+ testcase1.instance_variable_set(:@test_status, :error)
184
+ testcase2.instance_variable_set(:@test_status, :pending)
185
+ testcase3.instance_variable_set(:@test_status, :fail)
186
+ test_suite_result.add_test_case( testcase1 )
187
+ test_suite_result.add_test_case( testcase2 )
188
+ test_suite_result.add_test_case( testcase3 )
189
+ expect( test_suite_result.sum_failed ).to be == 2
190
+ end
191
+
192
+ it 'reports success with no errors/failures' do
193
+ testcase1.instance_variable_set(:@test_status, :pass)
194
+ testcase2.instance_variable_set(:@test_status, :pending)
195
+ testcase3.instance_variable_set(:@test_status, :fail)
196
+ test_suite_result.add_test_case( testcase1 )
197
+ test_suite_result.add_test_case( testcase2 )
198
+ test_suite_result.add_test_case( testcase3 )
199
+ expect( test_suite_result.success? ).to be == false
200
+ end
201
+
202
+ it 'reports failed if any tests error/fail' do
203
+ testcase1.instance_variable_set(:@test_status, :pass)
204
+ testcase2.instance_variable_set(:@test_status, :pending)
205
+ testcase3.instance_variable_set(:@test_status, :fail)
206
+ test_suite_result.add_test_case( testcase1 )
207
+ test_suite_result.add_test_case( testcase2 )
208
+ test_suite_result.add_test_case( testcase3 )
209
+ expect( test_suite_result.failed? ).to be == true
210
+ end
211
+
212
+ it 'can calculate the sum of all TestCase runtimes' do
213
+ testcase1.instance_variable_set(:@runtime, 1)
214
+ testcase2.instance_variable_set(:@runtime, 10)
215
+ testcase3.instance_variable_set(:@runtime, 100)
216
+ test_suite_result.add_test_case( testcase1 )
217
+ test_suite_result.add_test_case( testcase2 )
218
+ test_suite_result.add_test_case( testcase3 )
219
+ expect( test_suite_result.elapsed_time ).to be == 111
220
+ end
221
+
222
+ describe '#write_junit_xml' do
223
+ let( :options ) { make_opts.merge({ :logger => double().as_null_object, 'name' => create_files(@files), :log_dated_dir => '.', :xml_dated_dir => '.'}) }
224
+ let(:rb_test) { 'my_ruby_file.rb' }
225
+
226
+ it 'doesn\'t re-order test cases themselves on time_sort' do
227
+ nokogiri_mock = Hash.new
228
+ allow( nokogiri_mock ).to receive( :add_child )
229
+ allow( Nokogiri::XML::Node ).to receive( :new ) { nokogiri_mock }
230
+ allow( LoggerJunit ).to receive( :write_xml ).and_yield( Object.new, nokogiri_mock )
231
+
232
+ @files = [ rb_test, rb_test, rb_test]
233
+ ts = Beaker::Runner::Native::TestSuite.new( 'name', hosts, options, Time.now, :fast )
234
+ tsr = ts.instance_variable_get( :@test_suite_results )
235
+
236
+ allow( tsr ).to receive( :start_time ).and_return(0)
237
+ allow( tsr ).to receive( :stop_time ).and_return(10)
238
+ expect( tsr.instance_variable_get( :@logger ) ).to receive( :error ).never
239
+
240
+ test_cases = []
241
+ 3.times do
242
+ tc = Beaker::Runner::Native::TestCase.new( hosts, options[:logger], options, rb_test)
243
+ allow( tc ).to receive( :sublog ).and_return( false )
244
+ test_cases << tc
245
+ end
246
+ test_cases[0].instance_variable_set(:@runtime, 3)
247
+ test_cases[1].instance_variable_set(:@runtime, 301)
248
+ test_cases[2].instance_variable_set(:@runtime, 101)
249
+ test_cases.map { |tc| tsr.add_test_case( tc ) }
250
+
251
+ original_testcase_order = test_suite_result.instance_variable_get( :@test_cases ).dup
252
+ tsr.write_junit_xml( 'fakeFilePath07', 'fakeFileToLink09', true )
253
+ after_testcase_order = test_suite_result.instance_variable_get( :@test_cases ).dup
254
+ expect( after_testcase_order ).to be === original_testcase_order
255
+ end
256
+ end
257
+ end
258
+
259
+ describe '#log_path' do
260
+ let( :sh_test ) { '/my_shell_file.sh' }
261
+ let( :files ) { @files ? @files : [sh_test] }
262
+ let( :options ) { make_opts.merge({ :logger => double().as_null_object, 'name' => create_files(files) }) }
263
+ let( :hosts ) { make_hosts() }
264
+ let( :testsuite ) { Beaker::Runner::Native::TestSuite.new( 'name', hosts, options, Time.now, :stop ) }
265
+
266
+ it 'returns the simple joining of the log dir & file as required' do
267
+ expect(testsuite.log_path('foo.txt', 'man/date')).to be === 'man/date/foo.txt'
268
+ end
269
+
270
+ describe 'builds the base directory correctly' do
271
+ # the base directory is where the latest symlink itself should live
272
+ it 'in the usual case' do
273
+ expect( File.symlink?('man/latest') ).to be_falsy
274
+ testsuite.log_path('foo.txt', 'man/date')
275
+ expect( File.symlink?('man/latest') ).to be_truthy
276
+ end
277
+
278
+ it 'if given a nested directory' do
279
+ expect( File.symlink?('a/latest') ).to be_falsy
280
+ testsuite.log_path('foo.txt', 'a/b/c/d/e/f')
281
+ expect( File.symlink?('a/latest') ).to be_truthy
282
+ end
283
+ end
284
+
285
+ describe 'builds the symlink directory correctly' do
286
+ # the symlink directory is where the symlink points to
287
+ it 'in the usual case' do
288
+ expect( File.symlink?('d/latest') ).to be_falsy
289
+ testsuite.log_path('foo.txt', 'd/e')
290
+ expect( File.readlink('d/latest') ).to be === 'e'
291
+ end
292
+
293
+ it 'if given a nested directory' do
294
+ expect( File.symlink?('f/latest') ).to be_falsy
295
+ testsuite.log_path('foo.txt', 'f/g/h/i/j/k')
296
+ expect( File.readlink('f/latest') ).to be === 'g/h/i/j/k'
297
+ end
298
+ end
299
+ end
300
+ end
301
+ end
302
+ end
303
+ end