summaryrefslogtreecommitdiff
path: root/spec/lib/gitlab/ci/trace/checksum_spec.rb
blob: 794794c3f697b524fd5436bb8e0cdd194c22680a (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe Gitlab::Ci::Trace::Checksum do
  let(:build) { create(:ci_build, :running) }

  subject { described_class.new(build) }

  context 'when build pending state exists' do
    before do
      create(:ci_build_pending_state, build: build, trace_checksum: 'crc32:d4777540')
    end

    context 'when matching persisted trace chunks exist' do
      before do
        create_chunk(index: 0, data: 'a' * 128.kilobytes)
        create_chunk(index: 1, data: 'b' * 128.kilobytes)
        create_chunk(index: 2, data: 'ccccccccccccccccc')
      end

      it 'calculates combined trace chunks CRC32 correctly' do
        expect(subject.chunks_crc32).to eq 3564598592
        expect(subject).to be_valid
      end
    end

    context 'when trace chunks were persisted in a wrong order' do
      before do
        create_chunk(index: 0, data: 'b' * 128.kilobytes)
        create_chunk(index: 1, data: 'a' * 128.kilobytes)
        create_chunk(index: 2, data: 'ccccccccccccccccc')
      end

      it 'makes trace checksum invalid' do
        expect(subject).not_to be_valid
      end
    end

    context 'when one of the trace chunks is missing' do
      before do
        create_chunk(index: 0, data: 'a' * 128.kilobytes)
        create_chunk(index: 2, data: 'ccccccccccccccccc')
      end

      it 'makes trace checksum invalid' do
        expect(subject).not_to be_valid
      end
    end

    context 'when checksums of persisted trace chunks do not match' do
      before do
        create_chunk(index: 0, data: 'a' * 128.kilobytes)
        create_chunk(index: 1, data: 'X' * 128.kilobytes)
        create_chunk(index: 2, data: 'ccccccccccccccccc')
      end

      it 'makes trace checksum invalid' do
        expect(subject).not_to be_valid
      end
    end

    context 'when persisted trace chunks are missing' do
      it 'makes trace checksum invalid' do
        expect(subject.state_crc32).to eq 3564598592
        expect(subject).not_to be_valid
      end
    end
  end

  context 'when build pending state is missing' do
    describe '#state_crc32' do
      it 'returns nil' do
        expect(subject.state_crc32).to be_nil
      end
    end

    describe '#valid?' do
      it { is_expected.not_to be_valid }
    end
  end

  describe '#trace_chunks' do
    before do
      create_chunk(index: 0, data: 'abcdefg')
    end

    it 'does not load raw_data from a database store' do
      subject.trace_chunks.first.then do |chunk|
        expect(chunk).to be_database
        expect { chunk.raw_data }
          .to raise_error ActiveModel::MissingAttributeError
      end
    end
  end

  describe '#last_chunk' do
    context 'when there are no chunks' do
      it 'returns nil' do
        expect(subject.last_chunk).to be_nil
      end
    end

    context 'when there are multiple chunks' do
      before do
        create_chunk(index: 1, data: '1234')
        create_chunk(index: 0, data: 'abcd')
      end

      it 'returns chunk with the highest index' do
        expect(subject.last_chunk.chunk_index).to eq 1
      end
    end
  end

  def create_chunk(index:, data:)
    create(:ci_build_trace_chunk, :persisted, build: build,
                                              chunk_index: index,
                                              initial_data: data)
  end
end