Add system check for missing database indexes (#30888)
This commit is contained in:
parent
1fc14e324b
commit
ebd8e1bbb6
8 changed files with 248 additions and 0 deletions
49
spec/lib/admin/db/schema_parser_spec.rb
Normal file
49
spec/lib/admin/db/schema_parser_spec.rb
Normal file
|
@ -0,0 +1,49 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
require 'rails_helper'
|
||||
|
||||
describe Admin::Db::SchemaParser do
|
||||
let(:dummy_schema) do
|
||||
<<~SCHEMA
|
||||
# Comment
|
||||
ActiveRecord::Schema[7.1].define(version: 23) do
|
||||
create_table "people", force: :cascade do |t|
|
||||
t.string "name"
|
||||
end
|
||||
|
||||
create_table "posts", force: :cascade do |t|
|
||||
t.string "title", null: false
|
||||
t.bigint "size", null: false
|
||||
t.string "description"
|
||||
# t.index ["size", "title"], name: "index_posts_on_size_and_title"
|
||||
t.index ["title"], name: "index_posts_on_title", unique: true
|
||||
t.index ["size"], name: "index_posts_on_size"
|
||||
end
|
||||
|
||||
# add_index "people", ["name"], name: "commented_out_index"
|
||||
add_index "people", ["name"], name: "index_people_on_name"
|
||||
end
|
||||
SCHEMA
|
||||
end
|
||||
let(:schema_parser) { described_class.new(dummy_schema) }
|
||||
|
||||
describe '#indexes_by_table' do
|
||||
subject { schema_parser.indexes_by_table }
|
||||
|
||||
it 'returns index info for all affected tables' do
|
||||
expect(subject.keys).to match_array(%w(people posts))
|
||||
end
|
||||
|
||||
it 'returns all index information for the `people` table' do
|
||||
people_info = subject['people']
|
||||
expect(people_info.map(&:name)).to contain_exactly('index_people_on_name')
|
||||
end
|
||||
|
||||
it 'returns all index information for the `posts` table' do
|
||||
posts_info = subject['posts']
|
||||
expect(posts_info.map(&:name)).to contain_exactly(
|
||||
'index_posts_on_title', 'index_posts_on_size'
|
||||
)
|
||||
end
|
||||
end
|
||||
end
|
65
spec/lib/admin/system_check/missing_indexes_check_spec.rb
Normal file
65
spec/lib/admin/system_check/missing_indexes_check_spec.rb
Normal file
|
@ -0,0 +1,65 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
require 'rails_helper'
|
||||
|
||||
describe Admin::SystemCheck::MissingIndexesCheck do
|
||||
subject(:check) { described_class.new(user) }
|
||||
|
||||
let(:user) { Fabricate(:user) }
|
||||
let(:schema_parser) do
|
||||
instance_double(Admin::Db::SchemaParser, indexes_by_table: index_info)
|
||||
end
|
||||
let(:index_info) do
|
||||
{
|
||||
'users' => [instance_double(Admin::Db::SchemaParser::Index, name: 'index_users_on_profile_id')],
|
||||
'posts' => [instance_double(Admin::Db::SchemaParser::Index, name: 'index_posts_on_user_id')],
|
||||
}
|
||||
end
|
||||
let(:posts_indexes) { [] }
|
||||
let(:users_indexes) { [] }
|
||||
|
||||
before do
|
||||
allow(Admin::Db::SchemaParser).to receive(:new).and_return(schema_parser)
|
||||
allow(ActiveRecord::Base.connection).to receive(:indexes).with('posts').and_return(posts_indexes)
|
||||
allow(ActiveRecord::Base.connection).to receive(:indexes).with('users').and_return(users_indexes)
|
||||
end
|
||||
|
||||
it_behaves_like 'a check available to devops users'
|
||||
|
||||
describe '#pass?' do
|
||||
context 'when indexes are missing' do
|
||||
let(:posts_indexes) do
|
||||
[instance_double(ActiveRecord::ConnectionAdapters::IndexDefinition, name: 'index_posts_on_user_id')]
|
||||
end
|
||||
|
||||
it 'returns false' do
|
||||
expect(check.pass?).to be false
|
||||
end
|
||||
end
|
||||
|
||||
context 'when all expected indexes are present' do
|
||||
let(:posts_indexes) do
|
||||
[instance_double(ActiveRecord::ConnectionAdapters::IndexDefinition, name: 'index_posts_on_user_id')]
|
||||
end
|
||||
let(:users_indexes) do
|
||||
[instance_double(ActiveRecord::ConnectionAdapters::IndexDefinition, name: 'index_users_on_profile_id')]
|
||||
end
|
||||
|
||||
it 'returns true' do
|
||||
expect(check.pass?).to be true
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe '#message' do
|
||||
subject { check.message }
|
||||
|
||||
it 'sets the class name as the message key' do
|
||||
expect(subject.key).to eq(:missing_indexes_check)
|
||||
end
|
||||
|
||||
it 'sets a list of missing indexes as message value' do
|
||||
expect(subject.value).to eq('index_users_on_profile_id, index_posts_on_user_id')
|
||||
end
|
||||
end
|
||||
end
|
Loading…
Add table
Add a link
Reference in a new issue