Commit 8fc00aea authored by James Fargher's avatar James Fargher

Merge branch '349315_implement_model_schema_lock' into 'master'

Implement `SchemaLock` to prevent breaking the dependent tables

See merge request gitlab-org/gitlab!79623
parents 444650e4 a2c6c9cd
......@@ -29,6 +29,8 @@ RSpec.describe Vulnerability do
let_it_be(:vulnerability) { create(:vulnerability, :sast, :confirmed, :low, project: project) }
let_it_be(:finding) { create(:vulnerabilities_finding, vulnerability: vulnerability) }
it { is_expected.to have_locked_schema('f2d19034bdc7733dad8451dbb26250298f7de27895e99a2a0932f6d728f3cc27').reference('https://gitlab.com/gitlab-org/gitlab/-/issues/349315') }
describe 'enums' do
it { is_expected.to define_enum_for(:state).with_values(state_values) }
it { is_expected.to define_enum_for(:severity).with_values(severity_values).with_prefix(:severity) }
......
......@@ -7,6 +7,8 @@ RSpec.describe Vulnerabilities::Finding do
it { is_expected.to define_enum_for(:severity) }
it { is_expected.to define_enum_for(:detection_method) }
it { is_expected.to have_locked_schema('be0977fb3642f60c0c04b2197fe55d109d27f9630a011f9a64fd31b9716a7c7f').reference('https://gitlab.com/gitlab-org/gitlab/-/issues/349315') }
where(vulnerability_finding_signatures: [true, false])
with_them do
before do
......
# frozen_string_literal: true
class SchemaVersion # rubocop:disable Gitlab/NamespacedClass
def initialize(model)
@model = model
end
def current
(column_names + index_names).sort
.join('-')
.then { |s| Digest::SHA256.hexdigest(s) }
end
private
attr_reader :model
delegate :table_name, :connection, to: :model, private: true
def column_names
connection.columns(table_name).map(&:name)
end
def index_names
connection.indexes(table_name).map(&:name)
end
end
RSpec::Matchers.define :have_locked_schema do |locked_version|
LOCKED_SCHEMA_ERROR_MESSAGE = <<~TEXT
Schema of the "%<table_name>s" table has been locked and does not match
with the current version "%<current_schema_version>s".
Please see "%<reference>s" for more details.
TEXT
chain(:reference) do |value|
@reference = value
end
match do
@table_name = described_class.table_name
@current_schema_version = SchemaVersion.new(described_class).current
@current_schema_version == locked_version
end
failure_message do
format(LOCKED_SCHEMA_ERROR_MESSAGE, table_name: @table_name, current_schema_version: @current_schema_version, reference: @reference)
end
end
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment