From 6d8963e33657b80821900a60f66d0a51416dc59a Mon Sep 17 00:00:00 2001 From: Grzegorz Bizon Date: Thu, 25 May 2017 15:35:09 +0200 Subject: [PATCH] Add PoC of ActiveRecord migration testing --- config/database.yml.postgresql | 11 ++ .../20170525132202_migrate_pipeline_stages.rb | 14 ++ .../migrate_pipeline_stages_spec.rb | 127 ++++++++++++++++++ spec/migrations_helper.rb | 36 +++++ 4 files changed, 188 insertions(+) create mode 100644 db/migrate/20170525132202_migrate_pipeline_stages.rb create mode 100644 spec/migrations/migrate_pipeline_stages_spec.rb create mode 100644 spec/migrations_helper.rb diff --git a/config/database.yml.postgresql b/config/database.yml.postgresql index c517a4c0cb8..3dd96015577 100644 --- a/config/database.yml.postgresql +++ b/config/database.yml.postgresql @@ -46,3 +46,14 @@ test: &test username: postgres password: # host: localhost + +# Warning: The database defined as "migrate" might erased. +# Do not set this db to the same as development or production. +migrate: &test + adapter: postgresql + encoding: unicode + database: gitlabhq_migrate + pool: 5 + username: postgres + password: + # host: localhost diff --git a/db/migrate/20170525132202_migrate_pipeline_stages.rb b/db/migrate/20170525132202_migrate_pipeline_stages.rb new file mode 100644 index 00000000000..8f7da8662ec --- /dev/null +++ b/db/migrate/20170525132202_migrate_pipeline_stages.rb @@ -0,0 +1,14 @@ +class MigratePipelineStages < ActiveRecord::Migration + include Gitlab::Database::MigrationHelpers + + DOWNTIME = false + + def change + create_table :ci_stages do |t| + t.integer :project_id + t.integer :pipeline_id + t.string :name + t.timestamps + end + end +end diff --git a/spec/migrations/migrate_pipeline_stages_spec.rb b/spec/migrations/migrate_pipeline_stages_spec.rb new file mode 100644 index 00000000000..95c15d53a68 --- /dev/null +++ b/spec/migrations/migrate_pipeline_stages_spec.rb @@ -0,0 +1,127 @@ +require 'migrations_helper' +require Rails.root.join('db', 'migrate', '20170525132202_migrate_pipeline_stages.rb') + +describe MigratePipelineStages, :migration do + ## + # Create tables using schema from which we will migrate stuff. + # + before do + ActiveRecord::Schema.define(version: 20170523091700) do + enable_extension "plpgsql" + enable_extension "pg_trgm" + + create_table "ci_pipelines", force: :cascade do |t| + t.string "ref" + t.string "sha" + t.string "before_sha" + t.datetime "created_at" + t.datetime "updated_at" + t.boolean "tag", default: false + t.text "yaml_errors" + t.datetime "committed_at" + t.integer "project_id" + t.string "status" + t.datetime "started_at" + t.datetime "finished_at" + t.integer "duration" + t.integer "user_id" + t.integer "lock_version" + t.integer "auto_canceled_by_id" + t.integer "pipeline_schedule_id" + end + + add_index "ci_pipelines", ["auto_canceled_by_id"], name: "index_ci_pipelines_on_auto_canceled_by_id", using: :btree + add_index "ci_pipelines", ["pipeline_schedule_id"], name: "index_ci_pipelines_on_pipeline_schedule_id", using: :btree + add_index "ci_pipelines", ["project_id", "ref", "status"], name: "index_ci_pipelines_on_project_id_and_ref_and_status", using: :btree + add_index "ci_pipelines", ["project_id", "sha"], name: "index_ci_pipelines_on_project_id_and_sha", using: :btree + add_index "ci_pipelines", ["project_id"], name: "index_ci_pipelines_on_project_id", using: :btree + add_index "ci_pipelines", ["status"], name: "index_ci_pipelines_on_status", using: :btree + add_index "ci_pipelines", ["user_id"], name: "index_ci_pipelines_on_user_id", using: :btree + + create_table "ci_builds", force: :cascade do |t| + t.string "status" + t.datetime "finished_at" + t.text "trace" + t.datetime "created_at" + t.datetime "updated_at" + t.datetime "started_at" + t.integer "runner_id" + t.float "coverage" + t.integer "commit_id" + t.text "commands" + t.string "name" + t.text "options" + t.boolean "allow_failure", default: false, null: false + t.string "stage" + t.integer "trigger_request_id" + t.integer "stage_idx" + t.boolean "tag" + t.string "ref" + t.integer "user_id" + t.string "type" + t.string "target_url" + t.string "description" + t.text "artifacts_file" + t.integer "project_id" + t.text "artifacts_metadata" + t.integer "erased_by_id" + t.datetime "erased_at" + t.datetime "artifacts_expire_at" + t.string "environment" + t.integer "artifacts_size", limit: 8 + t.string "when" + t.text "yaml_variables" + t.datetime "queued_at" + t.string "token" + t.integer "lock_version" + t.string "coverage_regex" + t.integer "auto_canceled_by_id" + t.boolean "retried" + end + + add_index "ci_builds", ["auto_canceled_by_id"], name: "index_ci_builds_on_auto_canceled_by_id", using: :btree + add_index "ci_builds", ["commit_id", "stage_idx", "created_at"], name: "index_ci_builds_on_commit_id_and_stage_idx_and_created_at", using: :btree + add_index "ci_builds", ["commit_id", "status", "type"], name: "index_ci_builds_on_commit_id_and_status_and_type", using: :btree + add_index "ci_builds", ["commit_id", "type", "name", "ref"], name: "index_ci_builds_on_commit_id_and_type_and_name_and_ref", using: :btree + add_index "ci_builds", ["commit_id", "type", "ref"], name: "index_ci_builds_on_commit_id_and_type_and_ref", using: :btree + add_index "ci_builds", ["project_id"], name: "index_ci_builds_on_project_id", using: :btree + add_index "ci_builds", ["runner_id"], name: "index_ci_builds_on_runner_id", using: :btree + add_index "ci_builds", ["status", "type", "runner_id"], name: "index_ci_builds_on_status_and_type_and_runner_id", using: :btree + add_index "ci_builds", ["status"], name: "index_ci_builds_on_status", using: :btree + add_index "ci_builds", ["token"], name: "index_ci_builds_on_token", unique: true, using: :btree + add_index "ci_builds", ["updated_at"], name: "index_ci_builds_on_updated_at", using: :btree + add_index "ci_builds", ["user_id"], name: "index_ci_builds_on_user_id", using: :btree + end + end + + let(:pipeline) do + Class.new(ActiveRecord::Base) do + self.table_name = 'ci_pipelines' + end + end + + let(:build) do + Class.new(ActiveRecord::Base) do + self.table_name = 'ci_builds' + end + end + + let(:stage) do + Class.new(ActiveRecord::Base) do + self.table_name = 'ci_stages' + end + end + + ## + # Create test data + # + before do + pipeline.create!(ref: 'master', sha: 'adf43c3a') + end + + it 'correctly migrates pipeline stages' do + described_class.new.change + + expect(stage.table_exists?).to be true + end +end diff --git a/spec/migrations_helper.rb b/spec/migrations_helper.rb new file mode 100644 index 00000000000..bbb810556da --- /dev/null +++ b/spec/migrations_helper.rb @@ -0,0 +1,36 @@ +require File.expand_path("../../config/environment", __FILE__) +require 'rspec/rails' +require 'shoulda/matchers' + +ActiveRecord::Base.establish_connection(:migrate) + +RSpec.configure do |config| + config.mock_with :rspec + config.verbose_retry = true + config.display_try_failure_messages = true + config.use_transactional_fixtures = true + config.infer_spec_type_from_file_location! + config.raise_errors_for_deprecations! + + config.around(:each, :migration) do |example| + ActiveRecord::Tasks::DatabaseTasks.purge_current + + example.run + + ActiveRecord::Tasks::DatabaseTasks.purge_current + end + + config.around(:each, :redis) do |example| + Gitlab::Redis.with(&:flushall) + Sidekiq.redis(&:flushall) + + example.run + + Gitlab::Redis.with(&:flushall) + Sidekiq.redis(&:flushall) + end +end + + +puts "Rails environment: #{Rails.env}" +puts "Database connection: #{ActiveRecord::Base.connection_config[:database]}"