2021-10-27 15:23:28 +05:30
|
|
|
# frozen_string_literal: true
|
|
|
|
|
|
|
|
require 'spec_helper'
|
|
|
|
|
2023-03-04 22:38:38 +05:30
|
|
|
RSpec.describe Ci::BuildTraceMetadata, feature_category: :continuous_integration do
|
2021-10-27 15:23:28 +05:30
|
|
|
it { is_expected.to belong_to(:build) }
|
|
|
|
it { is_expected.to belong_to(:trace_artifact) }
|
|
|
|
|
|
|
|
it { is_expected.to validate_presence_of(:build) }
|
2021-11-11 11:23:49 +05:30
|
|
|
it { is_expected.to validate_presence_of(:archival_attempts) }
|
|
|
|
|
|
|
|
describe '#can_attempt_archival_now?' do
|
|
|
|
let(:metadata) do
|
|
|
|
build(:ci_build_trace_metadata,
|
|
|
|
archival_attempts: archival_attempts,
|
|
|
|
last_archival_attempt_at: last_archival_attempt_at)
|
|
|
|
end
|
|
|
|
|
|
|
|
subject { metadata.can_attempt_archival_now? }
|
|
|
|
|
|
|
|
context 'when archival_attempts is over the limit' do
|
|
|
|
let(:archival_attempts) { described_class::MAX_ATTEMPTS + 1 }
|
|
|
|
let(:last_archival_attempt_at) {}
|
|
|
|
|
|
|
|
it { is_expected.to be_falsey }
|
|
|
|
end
|
|
|
|
|
|
|
|
context 'when last_archival_attempt_at is not set' do
|
|
|
|
let(:archival_attempts) { described_class::MAX_ATTEMPTS }
|
|
|
|
let(:last_archival_attempt_at) {}
|
|
|
|
|
|
|
|
it { is_expected.to be_truthy }
|
|
|
|
end
|
|
|
|
|
|
|
|
context 'when last_archival_attempt_at is set' do
|
|
|
|
let(:archival_attempts) { described_class::MAX_ATTEMPTS }
|
|
|
|
let(:last_archival_attempt_at) { 6.days.ago }
|
|
|
|
|
|
|
|
it { is_expected.to be_truthy }
|
|
|
|
end
|
|
|
|
|
|
|
|
context 'when last_archival_attempt_at is too close' do
|
|
|
|
let(:archival_attempts) { described_class::MAX_ATTEMPTS }
|
|
|
|
let(:last_archival_attempt_at) { 1.hour.ago }
|
|
|
|
|
|
|
|
it { is_expected.to be_falsey }
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
describe '#archival_attempts_available?' do
|
|
|
|
let(:metadata) do
|
|
|
|
build(:ci_build_trace_metadata, archival_attempts: archival_attempts)
|
|
|
|
end
|
|
|
|
|
|
|
|
subject { metadata.archival_attempts_available? }
|
|
|
|
|
|
|
|
context 'when archival_attempts is over the limit' do
|
|
|
|
let(:archival_attempts) { described_class::MAX_ATTEMPTS + 1 }
|
|
|
|
|
|
|
|
it { is_expected.to be_falsey }
|
|
|
|
end
|
|
|
|
|
|
|
|
context 'when archival_attempts is at the limit' do
|
|
|
|
let(:archival_attempts) { described_class::MAX_ATTEMPTS }
|
|
|
|
|
|
|
|
it { is_expected.to be_truthy }
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
describe '#increment_archival_attempts!' do
|
|
|
|
let_it_be(:metadata) do
|
|
|
|
create(:ci_build_trace_metadata,
|
|
|
|
archival_attempts: 2,
|
|
|
|
last_archival_attempt_at: 1.day.ago)
|
|
|
|
end
|
|
|
|
|
|
|
|
it 'increments the attempts' do
|
|
|
|
expect { metadata.increment_archival_attempts! }
|
|
|
|
.to change { metadata.reload.archival_attempts }
|
|
|
|
end
|
|
|
|
|
|
|
|
it 'updates the last_archival_attempt_at timestamp' do
|
|
|
|
expect { metadata.increment_archival_attempts! }
|
|
|
|
.to change { metadata.reload.last_archival_attempt_at }
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
describe '#track_archival!' do
|
|
|
|
let(:trace_artifact) { create(:ci_job_artifact) }
|
|
|
|
let(:metadata) { create(:ci_build_trace_metadata) }
|
2021-11-18 22:05:49 +05:30
|
|
|
let(:checksum) { SecureRandom.hex }
|
2021-11-11 11:23:49 +05:30
|
|
|
|
|
|
|
it 'stores the artifact id and timestamp' do
|
|
|
|
expect(metadata.trace_artifact_id).to be_nil
|
|
|
|
|
2021-11-18 22:05:49 +05:30
|
|
|
metadata.track_archival!(trace_artifact.id, checksum)
|
2021-11-11 11:23:49 +05:30
|
|
|
metadata.reload
|
|
|
|
|
|
|
|
expect(metadata.trace_artifact_id).to eq(trace_artifact.id)
|
2021-11-18 22:05:49 +05:30
|
|
|
expect(metadata.checksum).to eq(checksum)
|
2021-11-11 11:23:49 +05:30
|
|
|
expect(metadata.archived_at).to be_like_time(Time.current)
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
describe '.find_or_upsert_for!' do
|
|
|
|
let_it_be(:build) { create(:ci_build) }
|
|
|
|
|
|
|
|
subject(:execute) do
|
2023-03-04 22:38:38 +05:30
|
|
|
described_class.find_or_upsert_for!(build.id, build.partition_id)
|
2021-11-11 11:23:49 +05:30
|
|
|
end
|
|
|
|
|
|
|
|
it 'creates a new record' do
|
|
|
|
metadata = execute
|
|
|
|
|
|
|
|
expect(metadata).to be_a(described_class)
|
|
|
|
expect(metadata.id).to eq(build.id)
|
|
|
|
expect(metadata.archival_attempts).to eq(0)
|
|
|
|
end
|
|
|
|
|
|
|
|
context 'with existing records' do
|
|
|
|
before do
|
|
|
|
create(:ci_build_trace_metadata,
|
|
|
|
build: build,
|
|
|
|
archival_attempts: described_class::MAX_ATTEMPTS)
|
|
|
|
end
|
|
|
|
|
|
|
|
it 'returns the existing record' do
|
|
|
|
metadata = execute
|
|
|
|
|
|
|
|
expect(metadata).to be_a(described_class)
|
|
|
|
expect(metadata.id).to eq(build.id)
|
|
|
|
expect(metadata.archival_attempts).to eq(described_class::MAX_ATTEMPTS)
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
2021-11-18 22:05:49 +05:30
|
|
|
|
|
|
|
describe '#remote_checksum_valid?' do
|
|
|
|
using RSpec::Parameterized::TableSyntax
|
|
|
|
|
|
|
|
let(:metadata) do
|
|
|
|
build(:ci_build_trace_metadata,
|
|
|
|
checksum: checksum,
|
|
|
|
remote_checksum: remote_checksum)
|
|
|
|
end
|
|
|
|
|
|
|
|
subject { metadata.remote_checksum_valid? }
|
|
|
|
|
|
|
|
where(:checksum, :remote_checksum, :result) do
|
|
|
|
nil | nil | false
|
|
|
|
nil | 'a' | false
|
|
|
|
'a' | nil | false
|
|
|
|
'a' | 'b' | false
|
|
|
|
'b' | 'a' | false
|
|
|
|
'a' | 'a' | true
|
|
|
|
end
|
|
|
|
|
|
|
|
with_them do
|
|
|
|
it { is_expected.to eq(result) }
|
|
|
|
end
|
|
|
|
end
|
2023-03-04 22:38:38 +05:30
|
|
|
|
2023-06-20 00:43:36 +05:30
|
|
|
describe 'partitioning', :ci_partitionable do
|
2023-03-04 22:38:38 +05:30
|
|
|
include Ci::PartitioningHelpers
|
|
|
|
|
|
|
|
let_it_be(:pipeline) { create(:ci_pipeline) }
|
|
|
|
let_it_be(:build) { create(:ci_build, pipeline: pipeline) }
|
|
|
|
let(:new_pipeline) { create(:ci_pipeline) }
|
|
|
|
let(:new_build) { create(:ci_build, pipeline: new_pipeline) }
|
|
|
|
let(:metadata) { create(:ci_build_trace_metadata, build: new_build) }
|
|
|
|
|
|
|
|
before do
|
|
|
|
stub_current_partition_id
|
|
|
|
end
|
|
|
|
|
|
|
|
it 'assigns the same partition id as the one that build has' do
|
|
|
|
expect(metadata.partition_id).to eq(ci_testing_partition_id)
|
|
|
|
end
|
|
|
|
end
|
2021-10-27 15:23:28 +05:30
|
|
|
end
|