Welcome to mirror list, hosted at ThFree Co, Russian Federation.

gitlab.com/gitlab-org/gitlab-foss.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
path: root/spec/db
diff options
context:
space:
mode:
authorGitLab Bot <gitlab-bot@gitlab.com>2022-05-19 10:33:21 +0300
committerGitLab Bot <gitlab-bot@gitlab.com>2022-05-19 10:33:21 +0300
commit36a59d088eca61b834191dacea009677a96c052f (patch)
treee4f33972dab5d8ef79e3944a9f403035fceea43f /spec/db
parenta1761f15ec2cae7c7f7bbda39a75494add0dfd6f (diff)
Add latest changes from gitlab-org/gitlab@15-0-stable-eev15.0.0-rc42
Diffstat (limited to 'spec/db')
-rw-r--r--spec/db/docs_spec.rb131
-rw-r--r--spec/db/schema_spec.rb5
2 files changed, 133 insertions, 3 deletions
diff --git a/spec/db/docs_spec.rb b/spec/db/docs_spec.rb
new file mode 100644
index 00000000000..20746e107fb
--- /dev/null
+++ b/spec/db/docs_spec.rb
@@ -0,0 +1,131 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe 'Database Documentation' do
+ context 'for each table' do
+ let(:all_tables) do
+ Gitlab::Database.database_base_models.flat_map { |_, m| m.connection.tables }.sort.uniq
+ end
+
+ let(:metadata_required_fields) do
+ %i(
+ feature_categories
+ table_name
+ )
+ end
+
+ let(:metadata_allowed_fields) do
+ metadata_required_fields + %i(
+ classes
+ description
+ introduced_by_url
+ milestone
+ )
+ end
+
+ let(:metadata) do
+ all_tables.each_with_object({}) do |table_name, hash|
+ next unless File.exist?(table_metadata_file_path(table_name))
+
+ hash[table_name] ||= load_table_metadata(table_name)
+ end
+ end
+
+ let(:tables_without_metadata) do
+ all_tables.reject { |t| metadata.has_key?(t) }
+ end
+
+ let(:tables_without_valid_metadata) do
+ metadata.select { |_, t| t.has_key?(:error) }.keys
+ end
+
+ let(:tables_with_disallowed_fields) do
+ metadata.select { |_, t| t.has_key?(:disallowed_fields) }.keys
+ end
+
+ let(:tables_with_missing_required_fields) do
+ metadata.select { |_, t| t.has_key?(:missing_required_fields) }.keys
+ end
+
+ it 'has a metadata file' do
+ expect(tables_without_metadata).to be_empty, multiline_error(
+ 'Missing metadata files',
+ tables_without_metadata.map { |t| " #{table_metadata_file(t)}" }
+ )
+ end
+
+ it 'has a valid metadata file' do
+ expect(tables_without_valid_metadata).to be_empty, table_metadata_errors(
+ 'Table metadata files with errors',
+ :error,
+ tables_without_valid_metadata
+ )
+ end
+
+ it 'has a valid metadata file with allowed fields' do
+ expect(tables_with_disallowed_fields).to be_empty, table_metadata_errors(
+ 'Table metadata files with disallowed fields',
+ :disallowed_fields,
+ tables_with_disallowed_fields
+ )
+ end
+
+ it 'has a valid metadata file without missing fields' do
+ expect(tables_with_missing_required_fields).to be_empty, table_metadata_errors(
+ 'Table metadata files with missing fields',
+ :missing_required_fields,
+ tables_with_missing_required_fields
+ )
+ end
+ end
+
+ private
+
+ def table_metadata_file(table_name)
+ File.join('db', 'docs', "#{table_name}.yml")
+ end
+
+ def table_metadata_file_path(table_name)
+ Rails.root.join(table_metadata_file(table_name))
+ end
+
+ def load_table_metadata(table_name)
+ result = {}
+ begin
+ result[:metadata] = YAML.safe_load(File.read(table_metadata_file_path(table_name))).deep_symbolize_keys
+
+ disallowed_fields = (result[:metadata].keys - metadata_allowed_fields)
+ unless disallowed_fields.empty?
+ result[:disallowed_fields] = "fields not allowed: #{disallowed_fields.join(', ')}"
+ end
+
+ missing_required_fields = (metadata_required_fields - result[:metadata].reject { |_, v| v.blank? }.keys)
+ unless missing_required_fields.empty?
+ result[:missing_required_fields] = "missing required fields: #{missing_required_fields.join(', ')}"
+ end
+ rescue Psych::SyntaxError => ex
+ result[:error] = ex.message
+ end
+ result
+ end
+
+ def table_metadata_errors(title, field, tables)
+ lines = tables.map do |table_name|
+ <<~EOM
+ #{table_metadata_file(table_name)}
+ #{metadata[table_name][field]}
+ EOM
+ end
+
+ multiline_error(title, lines)
+ end
+
+ def multiline_error(title, lines)
+ <<~EOM
+ #{title}:
+
+ #{lines.join("\n")}
+ EOM
+ end
+end
diff --git a/spec/db/schema_spec.rb b/spec/db/schema_spec.rb
index 04f73050ea5..e21c73976a8 100644
--- a/spec/db/schema_spec.rb
+++ b/spec/db/schema_spec.rb
@@ -22,7 +22,7 @@ RSpec.describe 'Database schema' do
approvals: %w[user_id],
approver_groups: %w[target_id],
approvers: %w[target_id user_id],
- analytics_cycle_analytics_aggregations: %w[last_full_issues_id last_full_merge_requests_id last_incremental_issues_id last_full_run_issues_id last_full_run_merge_requests_id last_incremental_merge_requests_id],
+ analytics_cycle_analytics_aggregations: %w[last_full_issues_id last_full_merge_requests_id last_incremental_issues_id last_full_run_issues_id last_full_run_merge_requests_id last_incremental_merge_requests_id last_consistency_check_issues_stage_event_hash_id last_consistency_check_issues_issuable_id last_consistency_check_merge_requests_stage_event_hash_id last_consistency_check_merge_requests_issuable_id],
analytics_cycle_analytics_merge_request_stage_events: %w[author_id group_id merge_request_id milestone_id project_id stage_event_hash_id state_id],
analytics_cycle_analytics_issue_stage_events: %w[author_id group_id issue_id milestone_id project_id stage_event_hash_id state_id],
audit_events: %w[author_id entity_id target_id],
@@ -47,7 +47,6 @@ RSpec.describe 'Database schema' do
events: %w[target_id],
forked_project_links: %w[forked_from_project_id],
geo_event_log: %w[hashed_storage_attachments_event_id],
- geo_job_artifact_deleted_events: %w[job_artifact_id],
geo_lfs_object_deleted_events: %w[lfs_object_id],
geo_node_statuses: %w[last_event_id cursor_last_event_id],
geo_nodes: %w[oauth_application_id],
@@ -79,7 +78,7 @@ RSpec.describe 'Database schema' do
repository_languages: %w[programming_language_id],
routes: %w[source_id],
sent_notifications: %w[project_id noteable_id recipient_id commit_id in_reply_to_discussion_id],
- slack_integrations: %w[team_id user_id],
+ slack_integrations: %w[team_id user_id bot_user_id], # these are external Slack IDs
snippets: %w[author_id],
spam_logs: %w[user_id],
status_check_responses: %w[external_approval_rule_id],