diff options
author | Kamil Trzciński <ayufan@ayufan.eu> | 2017-05-26 09:16:50 +0000 |
---|---|---|
committer | Timothy Andrew <mail@timothyandrew.net> | 2017-06-08 10:29:36 +0000 |
commit | aa28fa4e859ff9d6eaac94e2303da4080eb9d498 (patch) | |
tree | d45770abda8655f9f26d10dcd5d8fc83a016ac2b | |
parent | 65144f701c137a07f686e228a375121cd1fc0061 (diff) | |
download | gitlab-ce-aa28fa4e859ff9d6eaac94e2303da4080eb9d498.tar.gz |
Merge branch '31556-ci-coverage-paralel-rspec' into 'master'
Return the last coverage in trace stream
Closes #31556
See merge request !11128
-rw-r--r-- | changelogs/unreleased/31556-ci-coverage-paralel-rspec.yml | 4 | ||||
-rw-r--r-- | lib/gitlab/ci/trace/stream.rb | 51 | ||||
-rw-r--r-- | spec/lib/gitlab/ci/trace/stream_spec.rb | 43 |
3 files changed, 74 insertions, 24 deletions
diff --git a/changelogs/unreleased/31556-ci-coverage-paralel-rspec.yml b/changelogs/unreleased/31556-ci-coverage-paralel-rspec.yml new file mode 100644 index 00000000000..4137050a077 --- /dev/null +++ b/changelogs/unreleased/31556-ci-coverage-paralel-rspec.yml @@ -0,0 +1,4 @@ +--- +title: Fix the last coverage in trace log should be extracted +merge_request: 11128 +author: dosuken123 diff --git a/lib/gitlab/ci/trace/stream.rb b/lib/gitlab/ci/trace/stream.rb index fa462cbe095..c4c0623df6c 100644 --- a/lib/gitlab/ci/trace/stream.rb +++ b/lib/gitlab/ci/trace/stream.rb @@ -73,7 +73,7 @@ module Gitlab match = "" - stream.each_line do |line| + reverse_line do |line| matches = line.scan(regex) next unless matches.is_a?(Array) next if matches.empty? @@ -86,34 +86,39 @@ module Gitlab nil rescue # if bad regex or something goes wrong we dont want to interrupt transition - # so we just silentrly ignore error for now + # so we just silently ignore error for now end private - def read_last_lines(last_lines) - chunks = [] - pos = lines = 0 - max = stream.size - - # We want an extra line to make sure fist line has full contents - while lines <= last_lines && pos < max - pos += BUFFER_SIZE - - buf = - if pos <= max - stream.seek(-pos, IO::SEEK_END) - stream.read(BUFFER_SIZE) - else # Reached the head, read only left - stream.seek(0) - stream.read(BUFFER_SIZE - (pos - max)) - end - - lines += buf.count("\n") - chunks.unshift(buf) + def read_last_lines(limit) + to_enum(:reverse_line).first(limit).reverse.join + end + + def reverse_line + stream.seek(0, IO::SEEK_END) + debris = '' + + until (buf = read_backward(BUFFER_SIZE)).empty? + buf += debris + debris, *lines = buf.each_line.to_a + lines.reverse_each do |line| + yield(line.force_encoding('UTF-8')) + end end - chunks.join.lines.last(last_lines).join + yield(debris.force_encoding('UTF-8')) unless debris.empty? + end + + def read_backward(length) + cur_offset = stream.tell + start = cur_offset - length + start = 0 if start < 0 + + stream.seek(start, IO::SEEK_SET) + stream.read(cur_offset - start).tap do + stream.seek(start, IO::SEEK_SET) + end end end end diff --git a/spec/lib/gitlab/ci/trace/stream_spec.rb b/spec/lib/gitlab/ci/trace/stream_spec.rb index 40ac5a3ed37..bbb3f9912a3 100644 --- a/spec/lib/gitlab/ci/trace/stream_spec.rb +++ b/spec/lib/gitlab/ci/trace/stream_spec.rb @@ -240,9 +240,50 @@ describe Gitlab::Ci::Trace::Stream do end context 'multiple results in content & regex' do - let(:data) { ' (98.39%) covered. (98.29%) covered' } + let(:data) do + <<~HEREDOC + (98.39%) covered + (98.29%) covered + HEREDOC + end + + let(:regex) { '\(\d+.\d+\%\) covered' } + + it 'returns the last matched coverage' do + is_expected.to eq("98.29") + end + end + + context 'when BUFFER_SIZE is smaller than stream.size' do + let(:data) { 'Coverage 1033 / 1051 LOC (98.29%) covered\n' } + let(:regex) { '\(\d+.\d+\%\) covered' } + + before do + stub_const('Gitlab::Ci::Trace::Stream::BUFFER_SIZE', 5) + end + + it { is_expected.to eq("98.29") } + end + + context 'when regex is multi-byte char' do + let(:data) { '95.0 ゴッドファット\n' } + let(:regex) { '\d+\.\d+ ゴッドファット' } + + before do + stub_const('Gitlab::Ci::Trace::Stream::BUFFER_SIZE', 5) + end + + it { is_expected.to eq('95.0') } + end + + context 'when BUFFER_SIZE is equal to stream.size' do + let(:data) { 'Coverage 1033 / 1051 LOC (98.29%) covered\n' } let(:regex) { '\(\d+.\d+\%\) covered' } + before do + stub_const('Gitlab::Ci::Trace::Stream::BUFFER_SIZE', data.length) + end + it { is_expected.to eq("98.29") } end |