summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKamil Trzciński <ayufan@ayufan.eu>2017-05-26 09:16:50 +0000
committerKamil Trzciński <ayufan@ayufan.eu>2017-05-26 09:16:50 +0000
commit7a509c26dd9972f74d030504c292f36b480511f0 (patch)
treecabad223e63bf3f3f01ae48a29217d1fde70b246
parentce6bc061b1375e85a984887606eccb506b1c44f9 (diff)
parentf9c9daac780666dbd2ce4ad6270c66e1ee32545a (diff)
downloadgitlab-ce-7a509c26dd9972f74d030504c292f36b480511f0.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.yml4
-rw-r--r--lib/gitlab/ci/trace/stream.rb51
-rw-r--r--spec/lib/gitlab/ci/trace/stream_spec.rb43
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