2021-03-11 19:13:27 +05:30
# frozen_string_literal: true
require 'spec_helper'
RSpec . describe Gitlab :: Database :: Migrations :: Instrumentation do
2021-11-18 22:05:49 +05:30
let ( :result_dir ) { Dir . mktmpdir }
2022-01-26 12:08:38 +05:30
let ( :connection ) { ActiveRecord :: Migration . connection }
2021-11-18 22:05:49 +05:30
after do
FileUtils . rm_rf ( result_dir )
end
2021-03-11 19:13:27 +05:30
describe '#observe' do
2021-11-18 22:05:49 +05:30
subject { described_class . new ( result_dir : result_dir ) }
2021-03-11 19:13:27 +05:30
2021-10-27 15:23:28 +05:30
let ( :migration_name ) { 'test' }
let ( :migration_version ) { '12345' }
2021-03-11 19:13:27 +05:30
it 'executes the given block' do
2022-01-26 12:08:38 +05:30
expect { | b | subject . observe ( version : migration_version , name : migration_name , connection : connection , & b ) } . to yield_control
2021-03-11 19:13:27 +05:30
end
context 'behavior with observers' do
2022-01-26 12:08:38 +05:30
subject { described_class . new ( observer_classes : [ Gitlab :: Database :: Migrations :: Observers :: MigrationObserver ] , result_dir : result_dir ) . observe ( version : migration_version , name : migration_name , connection : connection ) { } }
2021-03-11 19:13:27 +05:30
let ( :observer ) { instance_double ( 'Gitlab::Database::Migrations::Observers::MigrationObserver' , before : nil , after : nil , record : nil ) }
2021-10-27 15:23:28 +05:30
before do
allow ( Gitlab :: Database :: Migrations :: Observers :: MigrationObserver ) . to receive ( :new ) . and_return ( observer )
end
it 'instantiates observer with observation' do
expect ( Gitlab :: Database :: Migrations :: Observers :: MigrationObserver )
. to receive ( :new )
2022-01-26 12:08:38 +05:30
. with ( instance_of ( Gitlab :: Database :: Migrations :: Observation ) , anything , connection ) { | observation | expect ( observation . version ) . to eq ( migration_version ) }
2021-10-27 15:23:28 +05:30
. and_return ( observer )
subject
end
2021-03-11 19:13:27 +05:30
it 'calls #before, #after, #record on given observers' do
expect ( observer ) . to receive ( :before ) . ordered
expect ( observer ) . to receive ( :after ) . ordered
2021-10-27 15:23:28 +05:30
expect ( observer ) . to receive ( :record ) . ordered
2021-03-11 19:13:27 +05:30
subject
end
it 'ignores errors coming from observers #before' do
expect ( observer ) . to receive ( :before ) . and_raise ( 'some error' )
subject
end
it 'ignores errors coming from observers #after' do
expect ( observer ) . to receive ( :after ) . and_raise ( 'some error' )
subject
end
it 'ignores errors coming from observers #record' do
expect ( observer ) . to receive ( :record ) . and_raise ( 'some error' )
subject
end
end
context 'on successful execution' do
2022-01-26 12:08:38 +05:30
subject { described_class . new ( result_dir : result_dir ) . observe ( version : migration_version , name : migration_name , connection : connection ) { } }
2021-03-11 19:13:27 +05:30
it 'records walltime' do
expect ( subject . walltime ) . not_to be_nil
end
it 'records success' do
expect ( subject . success ) . to be_truthy
end
it 'records the migration version' do
2021-10-27 15:23:28 +05:30
expect ( subject . version ) . to eq ( migration_version )
end
it 'records the migration name' do
expect ( subject . name ) . to eq ( migration_name )
2021-03-11 19:13:27 +05:30
end
end
context 'upon failure' do
2022-01-26 12:08:38 +05:30
subject { described_class . new ( result_dir : result_dir ) . observe ( version : migration_version , name : migration_name , connection : connection ) { raise 'something went wrong' } }
2021-03-11 19:13:27 +05:30
it 'raises the exception' do
expect { subject } . to raise_error ( / something went wrong / )
end
context 'retrieving observations' do
subject { instance . observations . first }
before do
2022-01-26 12:08:38 +05:30
instance . observe ( version : migration_version , name : migration_name , connection : connection ) { raise 'something went wrong' }
2021-06-08 01:23:25 +05:30
rescue StandardError
2021-03-11 19:13:27 +05:30
# ignore
end
2021-11-18 22:05:49 +05:30
let ( :instance ) { described_class . new ( result_dir : result_dir ) }
2021-03-11 19:13:27 +05:30
it 'records walltime' do
expect ( subject . walltime ) . not_to be_nil
end
it 'records failure' do
expect ( subject . success ) . to be_falsey
end
it 'records the migration version' do
2021-10-27 15:23:28 +05:30
expect ( subject . version ) . to eq ( migration_version )
end
it 'records the migration name' do
expect ( subject . name ) . to eq ( migration_name )
2021-03-11 19:13:27 +05:30
end
end
end
context 'sequence of migrations with failures' do
2021-11-18 22:05:49 +05:30
subject { described_class . new ( result_dir : result_dir ) }
2021-03-11 19:13:27 +05:30
let ( :migration1 ) { double ( 'migration1' , call : nil ) }
let ( :migration2 ) { double ( 'migration2' , call : nil ) }
it 'records observations for all migrations' do
2022-01-26 12:08:38 +05:30
subject . observe ( version : migration_version , name : migration_name , connection : connection ) { }
subject . observe ( version : migration_version , name : migration_name , connection : connection ) { raise 'something went wrong' } rescue nil
2021-03-11 19:13:27 +05:30
expect ( subject . observations . size ) . to eq ( 2 )
end
end
end
end