Commit 724bafee authored by Fabio Pitino's avatar Fabio Pitino Committed by Sean McGivern

Make Plan#name unique

* Add unique index
* Add model validation
* Ensure data migration leverages the index
parent 1d8f7f5c
# frozen_string_literal: true
class CreatePlanLimits < ActiveRecord::Migration[5.2]
DOWNTIME = false
def change
create_table :plan_limits, id: false do |t|
t.references :plan, foreign_key: { on_delete: :cascade }, null: false, index: { unique: true }
t.integer :ci_active_pipelines, null: false, default: 0
t.integer :ci_pipeline_size, null: false, default: 0
t.integer :ci_active_jobs, null: false, default: 0
end
end
end
# frozen_string_literal: true
class MoveLimitsFromPlans < ActiveRecord::Migration[5.2]
DOWNTIME = false
def up
execute <<~SQL
INSERT INTO plan_limits (plan_id, ci_active_pipelines, ci_pipeline_size, ci_active_jobs)
SELECT id, COALESCE(active_pipelines_limit, 0), COALESCE(pipeline_size_limit, 0), COALESCE(active_jobs_limit, 0)
FROM plans
SQL
end
def down
execute 'DELETE FROM plan_limits'
end
end
# frozen_string_literal: true
class RemoveLimitsFromPlans < ActiveRecord::Migration[5.2]
DOWNTIME = false
def up
remove_column :plans, :active_pipelines_limit
remove_column :plans, :pipeline_size_limit
remove_column :plans, :active_jobs_limit
end
def down
add_column :plans, :active_pipelines_limit, :integer
add_column :plans, :pipeline_size_limit, :integer
add_column :plans, :active_jobs_limit, :integer
end
end
......@@ -2802,14 +2802,19 @@ ActiveRecord::Schema.define(version: 2019_11_12_115317) do
t.index ["user_id"], name: "index_personal_access_tokens_on_user_id"
end
create_table "plan_limits", force: :cascade do |t|
t.bigint "plan_id", null: false
t.integer "ci_active_pipelines", default: 0, null: false
t.integer "ci_pipeline_size", default: 0, null: false
t.integer "ci_active_jobs", default: 0, null: false
t.index ["plan_id"], name: "index_plan_limits_on_plan_id", unique: true
end
create_table "plans", id: :serial, force: :cascade do |t|
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
t.string "name"
t.string "title"
t.integer "active_pipelines_limit"
t.integer "pipeline_size_limit"
t.integer "active_jobs_limit", default: 0
t.index ["name"], name: "index_plans_on_name"
end
......@@ -4389,6 +4394,7 @@ ActiveRecord::Schema.define(version: 2019_11_12_115317) do
add_foreign_key "path_locks", "projects", name: "fk_5265c98f24", on_delete: :cascade
add_foreign_key "path_locks", "users"
add_foreign_key "personal_access_tokens", "users"
add_foreign_key "plan_limits", "plans", on_delete: :cascade
add_foreign_key "pool_repositories", "projects", column: "source_project_id", on_delete: :nullify
add_foreign_key "pool_repositories", "shards", on_delete: :restrict
add_foreign_key "project_alerting_settings", "projects", on_delete: :cascade
......
......@@ -148,6 +148,13 @@ module EE
end
end
def actual_limits
# We default to PlanLimits.new otherwise a lot of specs would fail
# On production each plan should already have associated limits record
# https://gitlab.com/gitlab-org/gitlab/issues/36037
actual_plan&.limits || PlanLimits.new
end
def actual_plan_name
actual_plan&.name || Plan::FREE
end
......@@ -208,20 +215,6 @@ module EE
end
end
# TODO, CI/CD Quotas feature check
#
def max_active_pipelines
actual_plan&.active_pipelines_limit.to_i
end
def max_pipeline_size
actual_plan&.pipeline_size_limit.to_i
end
def max_active_jobs
actual_plan&.active_jobs_limit.to_i
end
def memoized_plans=(plans)
@plans = plans # rubocop: disable Gitlab/ModuleWithInstanceVariables
end
......
# frozen_string_literal: true
class Plan < ApplicationRecord
# Remove these in version >= 12.6
self.ignored_columns += %i[active_pipelines_limit pipeline_size_limit active_jobs_limit]
DEFAULT = 'default'.freeze
FREE = 'free'.freeze
BRONZE = 'bronze'.freeze
......@@ -15,6 +18,7 @@ class Plan < ApplicationRecord
has_many :namespaces
has_many :hosted_subscriptions, class_name: 'GitlabSubscription', foreign_key: 'hosted_plan_id'
has_one :limits, class_name: 'PlanLimits'
def self.default
Gitlab::SafeRequestStore[:plan_default] ||= find_by(name: DEFAULT)
......
# frozen_string_literal: true
class PlanLimits < ApplicationRecord
self.primary_key = :plan_id
belongs_to :plan
end
......@@ -6,6 +6,7 @@ module EE
module Pipeline
module Quota
class Activity < Ci::Limit
include ::Gitlab::Utils::StrongMemoize
include ActionView::Helpers::TextHelper
def initialize(namespace, project)
......@@ -14,7 +15,7 @@ module EE
end
def enabled?
@namespace.max_active_pipelines > 0
ci_active_pipelines_limit > 0
end
def exceeded?
......@@ -33,15 +34,17 @@ module EE
private
def excessive_pipelines_count
@excessive ||= alive_pipelines_count - max_active_pipelines_count
@excessive ||= alive_pipelines_count - ci_active_pipelines_limit
end
def alive_pipelines_count
@project.ci_pipelines.alive.count
end
def max_active_pipelines_count
@namespace.max_active_pipelines
def ci_active_pipelines_limit
strong_memoize(:ci_active_pipelines_limit) do
@namespace.actual_limits.ci_active_pipelines
end
end
end
end
......
......@@ -15,9 +15,7 @@ module EE
end
def enabled?
strong_memoize(:enabled) do
@namespace.max_active_jobs > 0
end
ci_active_jobs_limit > 0
end
def exceeded?
......@@ -36,7 +34,7 @@ module EE
private
def excessive_jobs_count
@excessive ||= jobs_in_alive_pipelines_count - max_active_jobs_count
@excessive ||= jobs_in_alive_pipelines_count - ci_active_jobs_limit
end
# rubocop: disable CodeReuse/ActiveRecord
......@@ -45,8 +43,10 @@ module EE
end
# rubocop: enable CodeReuse/ActiveRecord
def max_active_jobs_count
@namespace.max_active_jobs
def ci_active_jobs_limit
strong_memoize(:ci_active_jobs_limit) do
@namespace.actual_limits.ci_active_jobs
end
end
end
end
......
......@@ -6,6 +6,7 @@ module EE
module Pipeline
module Quota
class Size < Ci::Limit
include ::Gitlab::Utils::StrongMemoize
include ActionView::Helpers::TextHelper
def initialize(namespace, pipeline)
......@@ -14,7 +15,7 @@ module EE
end
def enabled?
@namespace.max_pipeline_size > 0
ci_pipeline_size_limit > 0
end
def exceeded?
......@@ -33,7 +34,13 @@ module EE
private
def excessive_seeds_count
@excessive ||= @pipeline.seeds_size - @namespace.max_pipeline_size
@excessive ||= @pipeline.seeds_size - ci_pipeline_size_limit
end
def ci_pipeline_size_limit
strong_memoize(:ci_pipeline_size_limit) do
@namespace.actual_limits.ci_pipeline_size
end
end
end
end
......
# frozen_string_literal: true
# EE-only
FactoryBot.define do
factory :plan_limits do
plan
end
end
......@@ -4,14 +4,12 @@ require 'spec_helper'
describe EE::Gitlab::Ci::Pipeline::Quota::Activity do
set(:namespace) { create(:namespace) }
set(:gold_plan) { create(:gold_plan) }
set(:project) { create(:project, namespace: namespace) }
set(:gold_plan) { create(:gold_plan) }
let(:plan_limits) { create(:plan_limits, plan: gold_plan) }
let!(:subscription) { create(:gitlab_subscription, namespace: namespace, hosted_plan: gold_plan) }
let(:limit) { described_class.new(namespace, project) }
before do
create(:gitlab_subscription, namespace: namespace, hosted_plan: gold_plan)
end
subject { described_class.new(namespace, project) }
shared_context 'pipeline activity limit exceeded' do
before do
......@@ -19,34 +17,44 @@ describe EE::Gitlab::Ci::Pipeline::Quota::Activity do
create(:ci_pipeline, project: project, status: 'pending')
create(:ci_pipeline, project: project, status: 'running')
gold_plan.update_column(:active_pipelines_limit, 1)
plan_limits.update(ci_active_pipelines: 1)
end
end
shared_context 'pipeline activity limit not exceeded' do
before do
gold_plan.update_column(:active_pipelines_limit, 2)
plan_limits.update!(ci_active_pipelines: 2)
end
end
describe '#enabled?' do
context 'when limit is enabled in plan' do
before do
gold_plan.update_column(:active_pipelines_limit, 10)
plan_limits.update!(ci_active_pipelines: 10)
end
it 'is enabled' do
expect(limit).to be_enabled
expect(subject).to be_enabled
end
end
context 'when limit is not enabled' do
before do
gold_plan.update_column(:active_pipelines_limit, 0)
plan_limits.update!(ci_active_pipelines: 0)
end
it 'is not enabled' do
expect(subject).not_to be_enabled
end
end
context 'when limit does not exist' do
before do
allow(namespace).to receive(:actual_plan) { create(:default_plan) }
end
it 'is not enabled' do
expect(limit).not_to be_enabled
expect(subject).not_to be_enabled
end
end
end
......@@ -56,7 +64,7 @@ describe EE::Gitlab::Ci::Pipeline::Quota::Activity do
include_context 'pipeline activity limit exceeded'
it 'is exceeded' do
expect(limit).to be_exceeded
expect(subject).to be_exceeded
end
end
......@@ -64,7 +72,7 @@ describe EE::Gitlab::Ci::Pipeline::Quota::Activity do
include_context 'pipeline activity limit not exceeded'
it 'is not exceeded' do
expect(limit).not_to be_exceeded
expect(subject).not_to be_exceeded
end
end
end
......@@ -74,7 +82,7 @@ describe EE::Gitlab::Ci::Pipeline::Quota::Activity do
include_context 'pipeline activity limit exceeded'
it 'returns info about pipeline activity limit exceeded' do
expect(limit.message)
expect(subject.message)
.to eq "Active pipelines limit exceeded by 2 pipelines!"
end
end
......
......@@ -5,34 +5,48 @@ require 'spec_helper'
describe EE::Gitlab::Ci::Pipeline::Quota::JobActivity do
let_it_be(:namespace, refind: true) { create(:namespace) }
let_it_be(:project, refind: true) { create(:project, namespace: namespace) }
let(:gold_plan) { create(:gold_plan, active_jobs_limit: active_jobs_limit) }
set(:gold_plan) { create(:gold_plan) }
set(:plan_limits) { create(:plan_limits, plan: gold_plan) }
let!(:subscription) { create(:gitlab_subscription, namespace: namespace, hosted_plan: gold_plan) }
let(:limit) { described_class.new(namespace, project) }
before do
create(:gitlab_subscription, namespace: namespace, hosted_plan: gold_plan)
end
subject { described_class.new(namespace, project) }
describe '#enabled?' do
context 'when limit is enabled in plan' do
let(:active_jobs_limit) { 10 }
before do
plan_limits.update!(ci_active_jobs: 10)
end
it 'is enabled' do
expect(limit).to be_enabled
expect(subject).to be_enabled
end
end
context 'when limit is not enabled' do
let(:active_jobs_limit) { 0 }
before do
plan_limits.update!(ci_active_jobs: 0)
end
it 'is not enabled' do
expect(subject).not_to be_enabled
end
end
context 'when limit does not exist' do
before do
allow(namespace).to receive(:actual_plan) { create(:default_plan) }
end
it 'is not enabled' do
expect(limit).not_to be_enabled
expect(subject).not_to be_enabled
end
end
end
describe '#exceeded?' do
let(:active_jobs_limit) { 2 }
before do
plan_limits.update!(ci_active_jobs: 2)
end
context 'when pipelines created recently' do
context 'and pipelines are running' do
......@@ -46,7 +60,7 @@ describe EE::Gitlab::Ci::Pipeline::Quota::JobActivity do
context 'when count of jobs in alive pipelines is below the limit' do
it 'is not exceeded' do
expect(limit).not_to be_exceeded
expect(subject).not_to be_exceeded
end
end
......@@ -56,7 +70,7 @@ describe EE::Gitlab::Ci::Pipeline::Quota::JobActivity do
end
it 'is exceeded' do
expect(limit).to be_exceeded
expect(subject).to be_exceeded
end
end
end
......@@ -71,7 +85,7 @@ describe EE::Gitlab::Ci::Pipeline::Quota::JobActivity do
end
it 'is not exceeded' do
expect(limit).not_to be_exceeded
expect(subject).not_to be_exceeded
end
end
end
......@@ -86,16 +100,16 @@ describe EE::Gitlab::Ci::Pipeline::Quota::JobActivity do
end
it 'is not exceeded' do
expect(limit).not_to be_exceeded
expect(subject).not_to be_exceeded
end
end
end
describe '#message' do
context 'when limit is exceeded' do
let(:active_jobs_limit) { 1 }
before do
plan_limits.update!(ci_active_jobs: 1)
create(:ci_pipeline, project: project, status: 'created', created_at: Time.now).tap do |pipeline|
create(:ci_build, pipeline: pipeline)
create(:ci_build, pipeline: pipeline)
......@@ -104,7 +118,7 @@ describe EE::Gitlab::Ci::Pipeline::Quota::JobActivity do
end
it 'returns info about pipeline activity limit exceeded' do
expect(limit.message)
expect(subject.message)
.to eq "Active jobs limit exceeded by 2 jobs in the past 24 hours!"
end
end
......
......@@ -6,13 +6,12 @@ describe EE::Gitlab::Ci::Pipeline::Quota::Size do
set(:namespace) { create(:namespace) }
set(:gold_plan) { create(:gold_plan) }
set(:project) { create(:project, :repository, namespace: namespace) }
set(:plan_limits) { create(:plan_limits, plan: gold_plan) }
let!(:subscription) { create(:gitlab_subscription, namespace: namespace, hosted_plan: gold_plan) }
let(:pipeline) { build_stubbed(:ci_pipeline, project: project) }
let(:limit) { described_class.new(namespace, pipeline) }
before do
create(:gitlab_subscription, namespace: namespace, hosted_plan: gold_plan)
end
subject { described_class.new(namespace, pipeline) }
shared_context 'pipeline size limit exceeded' do
let(:pipeline) do
......@@ -23,7 +22,7 @@ describe EE::Gitlab::Ci::Pipeline::Quota::Size do
end
before do
gold_plan.update_column(:pipeline_size_limit, 1)
plan_limits.update!(ci_pipeline_size: 1)
end
end
......@@ -31,28 +30,38 @@ describe EE::Gitlab::Ci::Pipeline::Quota::Size do
let(:pipeline) { build(:ci_pipeline_with_one_job, project: project) }
before do
gold_plan.update_column(:pipeline_size_limit, 2)
plan_limits.update!(ci_pipeline_size: 2)
end
end
describe '#enabled?' do
context 'when limit is enabled in plan' do
before do
gold_plan.update_column(:pipeline_size_limit, 10)
plan_limits.update!(ci_pipeline_size: 10)
end
it 'is enabled' do
expect(limit).to be_enabled
expect(subject).to be_enabled
end
end
context 'when limit is not enabled' do
before do
gold_plan.update_column(:pipeline_size_limit, 0)
plan_limits.update!(ci_pipeline_size: 0)
end
it 'is not enabled' do
expect(subject).not_to be_enabled
end
end
context 'when limit does not exist' do
before do
allow(namespace).to receive(:actual_plan) { create(:default_plan) }
end
it 'is not enabled' do
expect(limit).not_to be_enabled
expect(subject).not_to be_enabled
end
end
end
......@@ -62,7 +71,7 @@ describe EE::Gitlab::Ci::Pipeline::Quota::Size do
include_context 'pipeline size limit exceeded'
it 'is exceeded' do
expect(limit).to be_exceeded
expect(subject).to be_exceeded
end
end
......@@ -70,7 +79,7 @@ describe EE::Gitlab::Ci::Pipeline::Quota::Size do
include_context 'pipeline size limit not exceeded'
it 'is not exceeded' do
expect(limit).not_to be_exceeded
expect(subject).not_to be_exceeded
end
end
end
......@@ -80,7 +89,7 @@ describe EE::Gitlab::Ci::Pipeline::Quota::Size do
include_context 'pipeline size limit exceeded'
it 'returns infor about pipeline size limit exceeded' do
expect(limit.message)
expect(subject.message)
.to eq "Pipeline size limit exceeded by 1 job!"
end
end
......
......@@ -21,7 +21,8 @@ describe ::Gitlab::Ci::Pipeline::Chain::Limit::Activity do
context 'when active pipelines limit is exceeded' do
before do
gold_plan = create(:gold_plan, active_pipelines_limit: 1)
gold_plan = create(:gold_plan)
create(:plan_limits, plan: gold_plan, ci_active_pipelines: 1)
create(:gitlab_subscription, namespace: namespace, hosted_plan: gold_plan)
create(:ci_pipeline, project: project, status: 'pending')
......@@ -63,6 +64,12 @@ describe ::Gitlab::Ci::Pipeline::Chain::Limit::Activity do
end
context 'when pipeline activity limit is not exceeded' do
before do
gold_plan = create(:gold_plan)
create(:plan_limits, plan: gold_plan, ci_active_pipelines: 100)
create(:gitlab_subscription, namespace: namespace, hosted_plan: gold_plan)
end
it 'does not break the chain' do
subject
......
......@@ -21,7 +21,8 @@ describe ::Gitlab::Ci::Pipeline::Chain::Limit::JobActivity do
context 'when active jobs limit is exceeded' do
before do
gold_plan = create(:gold_plan, active_jobs_limit: 2)
gold_plan = create(:gold_plan)
create(:plan_limits, plan: gold_plan, ci_active_jobs: 2)
create(:gitlab_subscription, namespace: namespace, hosted_plan: gold_plan)
pipeline = create(:ci_pipeline, project: project, status: 'running', created_at: Time.now)
......@@ -65,6 +66,12 @@ describe ::Gitlab::Ci::Pipeline::Chain::Limit::JobActivity do
end
context 'when job activity limit is not exceeded' do
before do
gold_plan = create(:gold_plan)
create(:plan_limits, plan: gold_plan, ci_active_jobs: 100)
create(:gitlab_subscription, namespace: namespace, hosted_plan: gold_plan)
end
it 'does not break the chain' do
subject
......
......@@ -23,7 +23,8 @@ describe ::Gitlab::Ci::Pipeline::Chain::Limit::Size do
context 'when pipeline size limit is exceeded' do
before do
gold_plan = create(:gold_plan, pipeline_size_limit: 1)
gold_plan = create(:gold_plan)
create(:plan_limits, plan: gold_plan, ci_pipeline_size: 1)
create(:gitlab_subscription, namespace: namespace, hosted_plan: gold_plan)
end
......@@ -104,6 +105,12 @@ describe ::Gitlab::Ci::Pipeline::Chain::Limit::Size do
end
context 'when pipeline size limit is not exceeded' do
before do
gold_plan = create(:gold_plan)
create(:plan_limits, plan: gold_plan, ci_pipeline_size: 100)
create(:gitlab_subscription, namespace: namespace, hosted_plan: gold_plan)
end
it 'does not break the chain' do
subject
......
......@@ -270,119 +270,84 @@ describe Namespace do
end
end
describe '#max_active_pipelines' do
context 'when there is no limit defined' do
it 'returns zero' do
expect(namespace.max_active_pipelines).to be_zero
end
end
describe '#actual_limits' do
subject { namespace.actual_limits }
context 'when free plan has limit defined' do
before do
free_plan.update_column(:active_pipelines_limit, 40)
shared_examples 'uses an implied configuration' do
it 'is a non persisted PlanLimits' do
expect(subject.id).to be_nil
expect(subject).to be_kind_of(PlanLimits)
end
it 'returns a free plan limits' do
expect(namespace.max_active_pipelines).to be 40
it 'has all limits disabled' do
limits = subject.attributes.except('id', 'plan_id')
limits.each do |_attribute, limit|
expect(limit).to be_zero
end
end
context 'when associated plan has no limit defined' do
before do
create(:gitlab_subscription, namespace: namespace, hosted_plan: gold_plan)
end
it 'returns zero' do
expect(namespace.max_active_pipelines).to be_zero
end
context 'when no limits are defined in the system' do
it_behaves_like 'uses an implied configuration'
end
context 'when limit is defined' do
before do
gold_plan.update_column(:active_pipelines_limit, 10)
create(:gitlab_subscription, namespace: namespace, hosted_plan: gold_plan)
end
context 'when "default" plan is defined in the system' do
let!(:default_plan) { create(:default_plan) }
it 'returns a number of maximum active pipelines' do
expect(namespace.max_active_pipelines).to eq 10
end
end
context 'when no limits are set' do
it_behaves_like 'uses an implied configuration'
end
describe '#max_pipeline_size' do
context 'when there are no limits defined' do
it 'returns zero' do
expect(namespace.max_pipeline_size).to be_zero
end
context 'when limits are set for the default plan' do
let!(:default_limits) do
create(:plan_limits,
plan: default_plan,
ci_active_pipelines: 1,
ci_pipeline_size: 2,
ci_active_jobs: 3)
end
context 'when free plan has limit defined' do
before do
free_plan.update_column(:pipeline_size_limit, 40)
it { is_expected.to eq(default_limits) }
end
it 'returns a free plan limits' do
expect(namespace.max_pipeline_size).to be 40
end
end
context 'when "free" plan is defined in the system' do
let!(:free_plan) { create(:free_plan) }
context 'when associated plan has no limits defined' do
before do
create(:gitlab_subscription, namespace: namespace, hosted_plan: gold_plan)
context 'when no limits are set' do
it_behaves_like 'uses an implied configuration'
end
it 'returns zero' do
expect(namespace.max_pipeline_size).to be_zero
end
context 'when limits are set for the free plan' do
let!(:free_limits) do
create(:plan_limits,
plan: free_plan,
ci_active_pipelines: 3,
ci_pipeline_size: 4,
ci_active_jobs: 5)
end
context 'when limit is defined' do
before do
gold_plan.update_column(:pipeline_size_limit, 15)
create(:gitlab_subscription, namespace: namespace, hosted_plan: gold_plan)
end
it 'returns a number of maximum pipeline size' do
expect(namespace.max_pipeline_size).to eq 15
end
end
it { is_expected.to eq(free_limits) }
end
describe '#max_active_jobs' do
context 'when there is no limit defined' do
it 'returns zero' do
expect(namespace.max_active_jobs).to be_zero
end
end
context 'when free plan has limit defined' do
before do
free_plan.update_column(:active_jobs_limit, 100)
end
context 'when subscription plan is defined in the system' do
let!(:subscription) { create(:gitlab_subscription, namespace: namespace, hosted_plan: gold_plan) }
it 'returns a free plan limits' do
expect(namespace.max_active_jobs).to be 100
end
context 'when limits are not set for the plan' do
it_behaves_like 'uses an implied configuration'
end
context 'when associated plan has no limit defined' do
before do
create(:gitlab_subscription, namespace: namespace, hosted_plan: gold_plan)
context 'when limits are set for the plan' do
let!(:subscription_limits) do
create(:plan_limits,
plan: gold_plan,
ci_active_pipelines: 5,
ci_pipeline_size: 6,
ci_active_jobs: 7)
end
it 'returns zero' do
expect(namespace.max_active_jobs).to be_zero
end
it { is_expected.to eq(subscription_limits) }
end
context 'when limit is defined' do
before do
gold_plan.update_column(:active_jobs_limit, 10)
create(:gitlab_subscription, namespace: namespace, hosted_plan: gold_plan)
end
it 'returns a number of maximum active jobs' do
expect(namespace.max_active_jobs).to eq 10
end
end
end
......
......@@ -5,6 +5,7 @@ require 'spec_helper'
describe Ci::CreatePipelineService, '#execute' do
set(:namespace) { create(:namespace) }
set(:gold_plan) { create(:gold_plan) }
set(:plan_limits) { create(:plan_limits, plan: gold_plan) }
set(:project) { create(:project, :repository, namespace: namespace) }
set(:user) { create(:user) }
......@@ -36,7 +37,7 @@ describe Ci::CreatePipelineService, '#execute' do
context 'when pipeline activity limit is exceeded' do
before do
gold_plan.update_column(:active_pipelines_limit, 2)
plan_limits.update_column(:ci_active_pipelines, 2)
create(:ci_pipeline, project: project, status: 'pending')
create(:ci_pipeline, project: project, status: 'running')
......@@ -55,7 +56,7 @@ describe Ci::CreatePipelineService, '#execute' do
context 'when pipeline size limit is exceeded' do
before do
gold_plan.update_column(:pipeline_size_limit, 2)
plan_limits.update_column(:ci_pipeline_size, 2)
end
it 'drops pipeline without creating jobs' do
......
# frozen_string_literal: true
require 'spec_helper'
require Rails.root.join('db', 'migrate', '20191030152934_move_limits_from_plans.rb')
describe MoveLimitsFromPlans, :migration do
let(:plans) { table(:plans) }
let(:plan_limits) { table(:plan_limits) }
let!(:early_adopter_plan) { plans.create(name: 'early_adopter', title: 'Early adopter', active_pipelines_limit: 10, pipeline_size_limit: 11, active_jobs_limit: 12) }
let!(:gold_plan) { plans.create(name: 'gold', title: 'Gold', active_pipelines_limit: 20, pipeline_size_limit: 21, active_jobs_limit: 22) }
let!(:silver_plan) { plans.create(name: 'silver', title: 'Silver', active_pipelines_limit: 30, pipeline_size_limit: 31, active_jobs_limit: 32) }
let!(:bronze_plan) { plans.create(name: 'bronze', title: 'Bronze', active_pipelines_limit: 40, pipeline_size_limit: 41, active_jobs_limit: 42) }
let!(:free_plan) { plans.create(name: 'free', title: 'Free', active_pipelines_limit: 50, pipeline_size_limit: 51, active_jobs_limit: 52) }
let!(:other_plan) { plans.create(name: 'other', title: 'Other', active_pipelines_limit: nil, pipeline_size_limit: nil, active_jobs_limit: 0) }
describe 'migrate' do
it 'populates plan_limits from all the records in plans' do
expect { migrate! }.to change { plan_limits.count }.by 6
end
it 'copies plan limits and plan.id into to plan_limits table' do
migrate!
new_data = plan_limits.pluck(:plan_id, :ci_active_pipelines, :ci_pipeline_size, :ci_active_jobs)
expected_data = [
[early_adopter_plan.id, 10, 11, 12],
[gold_plan.id, 20, 21, 22],
[silver_plan.id, 30, 31, 32],
[bronze_plan.id, 40, 41, 42],
[free_plan.id, 50, 51, 52],
[other_plan.id, 0, 0, 0]
]
expect(new_data).to contain_exactly(*expected_data)
end
end
end
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment