Merge branch '31556-ci-coverage-paralel-rspec' into 'master'
Return the last coverage in trace stream Closes #31556 See merge request !11128
This commit is contained in:
		
						commit
						7a509c26dd
					
				| 
						 | 
					@ -0,0 +1,4 @@
 | 
				
			||||||
 | 
					---
 | 
				
			||||||
 | 
					title: Fix the last coverage in trace log should be extracted
 | 
				
			||||||
 | 
					merge_request: 11128
 | 
				
			||||||
 | 
					author: dosuken123
 | 
				
			||||||
| 
						 | 
					@ -73,7 +73,7 @@ module Gitlab
 | 
				
			||||||
 | 
					
 | 
				
			||||||
          match = ""
 | 
					          match = ""
 | 
				
			||||||
 | 
					
 | 
				
			||||||
          stream.each_line do |line|
 | 
					          reverse_line do |line|
 | 
				
			||||||
            matches = line.scan(regex)
 | 
					            matches = line.scan(regex)
 | 
				
			||||||
            next unless matches.is_a?(Array)
 | 
					            next unless matches.is_a?(Array)
 | 
				
			||||||
            next if matches.empty?
 | 
					            next if matches.empty?
 | 
				
			||||||
| 
						 | 
					@ -86,34 +86,39 @@ module Gitlab
 | 
				
			||||||
          nil
 | 
					          nil
 | 
				
			||||||
        rescue
 | 
					        rescue
 | 
				
			||||||
          # if bad regex or something goes wrong we dont want to interrupt transition
 | 
					          # 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
 | 
					        end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        private
 | 
					        private
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        def read_last_lines(last_lines)
 | 
					        def read_last_lines(limit)
 | 
				
			||||||
          chunks = []
 | 
					          to_enum(:reverse_line).first(limit).reverse.join
 | 
				
			||||||
          pos = lines = 0
 | 
					        end
 | 
				
			||||||
          max = stream.size
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
          # We want an extra line to make sure fist line has full contents
 | 
					        def reverse_line
 | 
				
			||||||
          while lines <= last_lines && pos < max
 | 
					          stream.seek(0, IO::SEEK_END)
 | 
				
			||||||
            pos += BUFFER_SIZE
 | 
					          debris = ''
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            buf =
 | 
					          until (buf = read_backward(BUFFER_SIZE)).empty?
 | 
				
			||||||
              if pos <= max
 | 
					            buf += debris
 | 
				
			||||||
                stream.seek(-pos, IO::SEEK_END)
 | 
					            debris, *lines = buf.each_line.to_a
 | 
				
			||||||
                stream.read(BUFFER_SIZE)
 | 
					            lines.reverse_each do |line|
 | 
				
			||||||
              else # Reached the head, read only left
 | 
					              yield(line.force_encoding('UTF-8'))
 | 
				
			||||||
                stream.seek(0)
 | 
					            end
 | 
				
			||||||
                stream.read(BUFFER_SIZE - (pos - max))
 | 
					 | 
				
			||||||
              end
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            lines += buf.count("\n")
 | 
					 | 
				
			||||||
            chunks.unshift(buf)
 | 
					 | 
				
			||||||
          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
 | 
					      end
 | 
				
			||||||
    end
 | 
					    end
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -240,9 +240,50 @@ describe Gitlab::Ci::Trace::Stream do
 | 
				
			||||||
    end
 | 
					    end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    context 'multiple results in content & regex' do
 | 
					    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' }
 | 
					      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") }
 | 
					      it { is_expected.to eq("98.29") }
 | 
				
			||||||
    end
 | 
					    end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
		Reference in New Issue