diff --git a/lib/gitlab/ci/trace/stream.rb b/lib/gitlab/ci/trace/stream.rb index 72a0d669de01b130684ed3673053aea6ae8c0d76..546f6788a78cd88d03c056c821043ab576f9a334 100644 --- a/lib/gitlab/ci/trace/stream.rb +++ b/lib/gitlab/ci/trace/stream.rb @@ -119,16 +119,31 @@ module Gitlab def reverse_line pos = BUFFER_SIZE max = stream.size + debris = '' while pos < max stream.seek(-pos, IO::SEEK_END) - yield(stream.read(BUFFER_SIZE)) + stream.read(BUFFER_SIZE).tap do |buf| + buf = buf + debris + lines = buf.split("\n") + lines.reverse.each do |line| + yield(line) + end + debris = lines.count > 0 ? lines[0] : '' + end pos += BUFFER_SIZE end # Reached the head, read only left stream.seek(0) - yield(stream.read(BUFFER_SIZE - (pos - max))) + last = (max > BUFFER_SIZE) ? (max % BUFFER_SIZE) : max + stream.read(last).tap do |buf| + buf = buf + debris + lines = buf.split("\n") + lines.reverse.each do |line| + yield(line) + end + 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 a607f000431a0d5396d5df4211e7535b5ff4e694..d90ccf4f799f7f85bd752f15506a7ad77eacdc9b 100644 --- a/spec/lib/gitlab/ci/trace/stream_spec.rb +++ b/spec/lib/gitlab/ci/trace/stream_spec.rb @@ -254,6 +254,28 @@ describe Gitlab::Ci::Trace::Stream do 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 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 + context 'using a regex capture' do let(:data) { 'TOTAL 9926 3489 65%' } let(:regex) { 'TOTAL\s+\d+\s+\d+\s+(\d{1,3}\%)' }