summaryrefslogtreecommitdiff
path: root/spec/lib/gitlab/background_migration
diff options
context:
space:
mode:
authorNick Thomas <nick@gitlab.com>2018-11-22 16:17:08 +0000
committerNick Thomas <nick@gitlab.com>2018-11-27 18:24:18 +0000
commit6ddefe7cada5268469561c70a8557cf1545684b2 (patch)
tree3f54240e3472da4c4f6004ae19da20f78ba476f3 /spec/lib/gitlab/background_migration
parent0afce35d65aa433d221e41632c6d8095ab68c39f (diff)
downloadgitlab-ce-6ddefe7cada5268469561c70a8557cf1545684b2.tar.gz
Correctly handle data-loss scenarios when encrypting columns
If the EncryptColumns background migration runs in a sidekiq with a stale view of the database schema, or when the purported destination columns don't actually exist, data loss can result. Attempt to work around these issues by reloading schema information before running the migration, and raising errors if the model reports that any of its source or destination columns are missing.
Diffstat (limited to 'spec/lib/gitlab/background_migration')
-rw-r--r--spec/lib/gitlab/background_migration/encrypt_columns_spec.rb25
1 files changed, 25 insertions, 0 deletions
diff --git a/spec/lib/gitlab/background_migration/encrypt_columns_spec.rb b/spec/lib/gitlab/background_migration/encrypt_columns_spec.rb
index 2a869446753..1d9bac79dcd 100644
--- a/spec/lib/gitlab/background_migration/encrypt_columns_spec.rb
+++ b/spec/lib/gitlab/background_migration/encrypt_columns_spec.rb
@@ -65,5 +65,30 @@ describe Gitlab::BackgroundMigration::EncryptColumns, :migration, schema: 201809
expect(hook).to have_attributes(values)
end
+
+ it 'reloads the model column information' do
+ expect(model).to receive(:reset_column_information).and_call_original
+ expect(model).to receive(:define_attribute_methods).and_call_original
+
+ subject.perform(model, [:token, :url], 1, 1)
+ end
+
+ it 'fails if a source column is not present' do
+ columns = model.columns.reject { |c| c.name == 'url' }
+ allow(model).to receive(:columns) { columns }
+
+ expect do
+ subject.perform(model, [:token, :url], 1, 1)
+ end.to raise_error(/source column: url is missing/)
+ end
+
+ it 'fails if a destination column is not present' do
+ columns = model.columns.reject { |c| c.name == 'encrypted_url' }
+ allow(model).to receive(:columns) { columns }
+
+ expect do
+ subject.perform(model, [:token, :url], 1, 1)
+ end.to raise_error(/destination column: encrypted_url is missing/)
+ end
end
end