Commit 007587cc authored by Andy Soiron's avatar Andy Soiron Committed by Toon Claes

Rename services template to instance migration

It adds a new column `instance` to the
services table and removes the template
column after deployment
parent 108e8eb4
...@@ -7,7 +7,7 @@ class Admin::ServicesController < Admin::ApplicationController ...@@ -7,7 +7,7 @@ class Admin::ServicesController < Admin::ApplicationController
before_action :service, only: [:edit, :update] before_action :service, only: [:edit, :update]
def index def index
@services = services_templates @services = instance_level_services
end end
def edit def edit
...@@ -19,7 +19,7 @@ class Admin::ServicesController < Admin::ApplicationController ...@@ -19,7 +19,7 @@ class Admin::ServicesController < Admin::ApplicationController
def update def update
if service.update(service_params[:service]) if service.update(service_params[:service])
PropagateServiceTemplateWorker.perform_async(service.id) if service.active? PropagateInstanceLevelServiceWorker.perform_async(service.id) if service.active?
redirect_to admin_application_settings_services_path, redirect_to admin_application_settings_services_path,
notice: 'Application settings saved successfully' notice: 'Application settings saved successfully'
...@@ -31,17 +31,17 @@ class Admin::ServicesController < Admin::ApplicationController ...@@ -31,17 +31,17 @@ class Admin::ServicesController < Admin::ApplicationController
private private
# rubocop: disable CodeReuse/ActiveRecord # rubocop: disable CodeReuse/ActiveRecord
def services_templates def instance_level_services
Service.available_services_names.map do |service_name| Service.available_services_names.map do |service_name|
service_template = "#{service_name}_service".camelize.constantize service = "#{service_name}_service".camelize.constantize
service_template.where(template: true).first_or_create service.where(instance: true).first_or_create
end end
end end
# rubocop: enable CodeReuse/ActiveRecord # rubocop: enable CodeReuse/ActiveRecord
# rubocop: disable CodeReuse/ActiveRecord # rubocop: disable CodeReuse/ActiveRecord
def service def service
@service ||= Service.where(id: params[:id], template: true).first @service ||= Service.where(id: params[:id], instance: true).first
end end
# rubocop: enable CodeReuse/ActiveRecord # rubocop: enable CodeReuse/ActiveRecord
......
...@@ -1219,13 +1219,13 @@ class Project < ApplicationRecord ...@@ -1219,13 +1219,13 @@ class Project < ApplicationRecord
service = find_service(services, name) service = find_service(services, name)
return service if service return service if service
# We should check if template for the service exists # We should check if an instance-level service exists
template = find_service(services_templates, name) instance_level_service = find_service(instance_level_services, name)
if template if instance_level_service
Service.build_from_template(id, template) Service.build_from_instance(id, instance_level_service)
else else
# If no template, we should create an instance. Ex `build_gitlab_ci_service` # If no instance-level service exists, we should create a new service. Ex `build_gitlab_ci_service`
public_send("build_#{name}_service") # rubocop:disable GitlabSecurity/PublicSend public_send("build_#{name}_service") # rubocop:disable GitlabSecurity/PublicSend
end end
end end
...@@ -2438,8 +2438,8 @@ class Project < ApplicationRecord ...@@ -2438,8 +2438,8 @@ class Project < ApplicationRecord
end end
end end
def services_templates def instance_level_services
@services_templates ||= Service.where(template: true) @instance_level_services ||= Service.where(instance: true)
end end
def ensure_pages_metadatum def ensure_pages_metadatum
......
...@@ -164,7 +164,7 @@ class IssueTrackerService < Service ...@@ -164,7 +164,7 @@ class IssueTrackerService < Service
end end
def one_issue_tracker def one_issue_tracker
return if template? return if instance?
return if project.blank? return if project.blank?
if project.services.external_issue_trackers.where.not(id: id).any? if project.services.external_issue_trackers.where.not(id: id).any?
......
...@@ -85,7 +85,7 @@ class PrometheusService < MonitoringService ...@@ -85,7 +85,7 @@ class PrometheusService < MonitoringService
end end
def prometheus_available? def prometheus_available?
return false if template? return false if instance?
return false unless project return false unless project
project.all_clusters.enabled.any? { |cluster| cluster.application_prometheus_available? } project.all_clusters.enabled.any? { |cluster| cluster.application_prometheus_available? }
......
...@@ -32,7 +32,7 @@ class Service < ApplicationRecord ...@@ -32,7 +32,7 @@ class Service < ApplicationRecord
belongs_to :project, inverse_of: :services belongs_to :project, inverse_of: :services
has_one :service_hook has_one :service_hook
validates :project_id, presence: true, unless: proc { |service| service.template? } validates :project_id, presence: true, unless: proc { |service| service.instance? }
validates :type, presence: true validates :type, presence: true
scope :visible, -> { where.not(type: 'GitlabIssueTrackerService') } scope :visible, -> { where.not(type: 'GitlabIssueTrackerService') }
...@@ -70,8 +70,8 @@ class Service < ApplicationRecord ...@@ -70,8 +70,8 @@ class Service < ApplicationRecord
true true
end end
def template? def instance?
template instance
end end
def category def category
...@@ -299,15 +299,15 @@ class Service < ApplicationRecord ...@@ -299,15 +299,15 @@ class Service < ApplicationRecord
service_names.sort_by(&:downcase) service_names.sort_by(&:downcase)
end end
def self.build_from_template(project_id, template) def self.build_from_instance(project_id, instance_level_service)
service = template.dup service = instance_level_service.dup
if template.supports_data_fields? if instance_level_service.supports_data_fields?
data_fields = template.data_fields.dup data_fields = instance_level_service.data_fields.dup
data_fields.service = service data_fields.service = service
end end
service.template = false service.instance = false
service.project_id = project_id service.project_id = project_id
service.active = false if service.active? && !service.valid? service.active = false if service.active? && !service.valid?
service service
...@@ -321,10 +321,6 @@ class Service < ApplicationRecord ...@@ -321,10 +321,6 @@ class Service < ApplicationRecord
nil nil
end end
def self.find_by_template
find_by(template: true)
end
# override if needed # override if needed
def supports_data_fields? def supports_data_fields?
false false
......
...@@ -134,7 +134,7 @@ module Projects ...@@ -134,7 +134,7 @@ module Projects
if @project.save if @project.save
unless @project.gitlab_project_import? unless @project.gitlab_project_import?
create_services_from_active_templates(@project) create_services_from_active_instance_level_services(@project)
@project.create_labels @project.create_labels
end end
...@@ -160,9 +160,9 @@ module Projects ...@@ -160,9 +160,9 @@ module Projects
end end
# rubocop: disable CodeReuse/ActiveRecord # rubocop: disable CodeReuse/ActiveRecord
def create_services_from_active_templates(project) def create_services_from_active_instance_level_services(project)
Service.where(template: true, active: true).each do |template| Service.where(instance: true, active: true).each do |template|
service = Service.build_from_template(project.id, template) service = Service.build_from_instance(project.id, template)
service.save! service.save!
end end
end end
......
# frozen_string_literal: true # frozen_string_literal: true
module Projects module Projects
class PropagateServiceTemplate class PropagateInstanceLevelService
BATCH_SIZE = 100 BATCH_SIZE = 100
def self.propagate(*args) def self.propagate(*args)
new(*args).propagate new(*args).propagate
end end
def initialize(template) def initialize(instance_level_service)
@template = template @instance_level_service = instance_level_service
end end
def propagate def propagate
return unless @template.active? return unless @instance_level_service.active?
Rails.logger.info("Propagating services for template #{@template.id}") # rubocop:disable Gitlab/RailsLogger Rails.logger.info("Propagating services for instance_level_service #{@instance_level_service.id}") # rubocop:disable Gitlab/RailsLogger
propagate_projects_with_template propagate_projects_with_instance_level_service
end end
private private
def propagate_projects_with_template def propagate_projects_with_instance_level_service
loop do loop do
batch = Project.uncached { project_ids_batch } batch = Project.uncached { project_ids_batch }
bulk_create_from_template(batch) unless batch.empty? bulk_create_from_instance_level_service(batch) unless batch.empty?
break if batch.size < BATCH_SIZE break if batch.size < BATCH_SIZE
end end
end end
def bulk_create_from_template(batch) def bulk_create_from_instance_level_service(batch)
service_list = batch.map do |project_id| service_list = batch.map do |project_id|
service_hash.values << project_id service_hash.values << project_id
end end
...@@ -52,7 +52,7 @@ module Projects ...@@ -52,7 +52,7 @@ module Projects
SELECT true SELECT true
FROM services FROM services
WHERE services.project_id = projects.id WHERE services.project_id = projects.id
AND services.type = '#{@template.type}' AND services.type = '#{@instance_level_service.type}'
) )
AND projects.pending_delete = false AND projects.pending_delete = false
AND projects.archived = false AND projects.archived = false
...@@ -73,9 +73,9 @@ module Projects ...@@ -73,9 +73,9 @@ module Projects
def service_hash def service_hash
@service_hash ||= @service_hash ||=
begin begin
template_hash = @template.as_json(methods: :type).except('id', 'template', 'project_id') instance_hash = @instance_level_service.as_json(methods: :type).except('id', 'instance', 'project_id')
template_hash.each_with_object({}) do |(key, value), service_hash| instance_hash.each_with_object({}) do |(key, value), service_hash|
value = value.is_a?(Hash) ? value.to_json : value value = value.is_a?(Hash) ? value.to_json : value
service_hash[ActiveRecord::Base.connection.quote_column_name(key)] = service_hash[ActiveRecord::Base.connection.quote_column_name(key)] =
...@@ -97,11 +97,11 @@ module Projects ...@@ -97,11 +97,11 @@ module Projects
# rubocop: enable CodeReuse/ActiveRecord # rubocop: enable CodeReuse/ActiveRecord
def active_external_issue_tracker? def active_external_issue_tracker?
@template.issue_tracker? && !@template.default @instance_level_service.issue_tracker? && !@instance_level_service.default
end end
def active_external_wiki? def active_external_wiki?
@template.type == 'ExternalWikiService' @instance_level_service.type == 'ExternalWikiService'
end end
end end
end end
...@@ -10,8 +10,8 @@ ...@@ -10,8 +10,8 @@
%p.inline %p.inline
= s_("MattermostService|See list of available commands in Mattermost after setting up this service, by entering") = s_("MattermostService|See list of available commands in Mattermost after setting up this service, by entering")
%kbd.inline /&lt;trigger&gt; help %kbd.inline /&lt;trigger&gt; help
- unless enabled || @service.template? - unless enabled || @service.instance?
= render 'projects/services/mattermost_slash_commands/detailed_help', subject: @service = render 'projects/services/mattermost_slash_commands/detailed_help', subject: @service
- if enabled && !@service.template? - if enabled && !@service.instance?
= render 'projects/services/mattermost_slash_commands/installation_info', subject: @service = render 'projects/services/mattermost_slash_commands/installation_info', subject: @service
...@@ -11,7 +11,7 @@ ...@@ -11,7 +11,7 @@
%p.inline %p.inline
= s_("SlackService|See list of available commands in Slack after setting up this service, by entering") = s_("SlackService|See list of available commands in Slack after setting up this service, by entering")
%kbd.inline /&lt;command&gt; help %kbd.inline /&lt;command&gt; help
- unless @service.template? - unless @service.instance?
%p= _("To set up this service:") %p= _("To set up this service:")
%ul.list-unstyled.indent-list %ul.list-unstyled.indent-list
%li %li
......
...@@ -951,7 +951,7 @@ ...@@ -951,7 +951,7 @@
:latency_sensitive: :latency_sensitive:
:resource_boundary: :unknown :resource_boundary: :unknown
:weight: 1 :weight: 1
- :name: propagate_service_template - :name: propagate_instance_level_service
:feature_category: :source_code_management :feature_category: :source_code_management
:has_external_dependencies: :has_external_dependencies:
:latency_sensitive: :latency_sensitive:
......
# frozen_string_literal: true # frozen_string_literal: true
# Worker for updating any project specific caches. # Worker for updating any project specific caches.
class PropagateServiceTemplateWorker class PropagateInstanceLevelServiceWorker
include ApplicationWorker include ApplicationWorker
feature_category :source_code_management feature_category :source_code_management
...@@ -9,18 +9,18 @@ class PropagateServiceTemplateWorker ...@@ -9,18 +9,18 @@ class PropagateServiceTemplateWorker
LEASE_TIMEOUT = 4.hours.to_i LEASE_TIMEOUT = 4.hours.to_i
# rubocop: disable CodeReuse/ActiveRecord # rubocop: disable CodeReuse/ActiveRecord
def perform(template_id) def perform(instance_level_service_id)
return unless try_obtain_lease_for(template_id) return unless try_obtain_lease_for(instance_level_service_id)
Projects::PropagateServiceTemplate.propagate(Service.find_by(id: template_id)) Projects::PropagateInstanceLevelService.propagate(Service.find_by(id: instance_level_service_id))
end end
# rubocop: enable CodeReuse/ActiveRecord # rubocop: enable CodeReuse/ActiveRecord
private private
def try_obtain_lease_for(template_id) def try_obtain_lease_for(instance_level_service_id)
Gitlab::ExclusiveLease Gitlab::ExclusiveLease
.new("propagate_service_template_worker:#{template_id}", timeout: LEASE_TIMEOUT) .new("propagate_instance_level_service_worker:#{instance_level_service_id}", timeout: LEASE_TIMEOUT)
.try_obtain .try_obtain
end end
end end
---
title: 'Service model: Rename template attribute to instance'
merge_request: 23595
author:
type: other
...@@ -194,7 +194,7 @@ ...@@ -194,7 +194,7 @@
- 1 - 1
- - project_update_repository_storage - - project_update_repository_storage
- 1 - 1
- - propagate_service_template - - propagate_instance_level_service
- 1 - 1
- - reactive_caching - - reactive_caching
- 1 - 1
......
# frozen_string_literal: true
class RenameServicesTemplateToInstance < ActiveRecord::Migration[5.2]
include Gitlab::Database::MigrationHelpers
DOWNTIME = false
disable_ddl_transaction!
def up
rename_column_concurrently :services, :template, :instance
end
def down
undo_rename_column_concurrently :services, :template, :instance
end
end
...@@ -23,6 +23,10 @@ class RemoveEmptyGithubServiceTemplates < ActiveRecord::Migration[5.2] ...@@ -23,6 +23,10 @@ class RemoveEmptyGithubServiceTemplates < ActiveRecord::Migration[5.2]
private private
def relationship def relationship
# The column `template` was renamed to `instance`. Column information needs
# to be resetted to avoid cache problems after migrating down.
RemoveEmptyGithubServiceTemplates::Service.reset_column_information
RemoveEmptyGithubServiceTemplates::Service.where(template: true, type: 'GithubService') RemoveEmptyGithubServiceTemplates::Service.where(template: true, type: 'GithubService')
end end
end end
# frozen_string_literal: true
class CleanupRenameServicesTemplateToInstance < ActiveRecord::Migration[5.2]
include Gitlab::Database::MigrationHelpers
DOWNTIME = false
disable_ddl_transaction!
def up
cleanup_concurrent_column_rename :services, :template, :instance
end
def down
undo_cleanup_concurrent_column_rename :services, :template, :instance
end
end
# frozen_string_literal: true
class MigratePropagateServiceTemplateSidekiqQueue < ActiveRecord::Migration[6.0]
include Gitlab::Database::MigrationHelpers
DOWNTIME = false
def up
sidekiq_queue_migrate 'propagate_service_template', to: 'propagate_instance_level_service'
end
def down
sidekiq_queue_migrate 'propagate_instance_level_service', to: 'propagate_service_template'
end
end
...@@ -10,7 +10,7 @@ ...@@ -10,7 +10,7 @@
# #
# It's strongly recommended that you check this file into your version control system. # It's strongly recommended that you check this file into your version control system.
ActiveRecord::Schema.define(version: 2020_02_06_091544) do ActiveRecord::Schema.define(version: 2020_02_06_111847) do
# These are extensions that must be enabled in order to support this database # These are extensions that must be enabled in order to support this database
enable_extension "pg_trgm" enable_extension "pg_trgm"
...@@ -3827,7 +3827,6 @@ ActiveRecord::Schema.define(version: 2020_02_06_091544) do ...@@ -3827,7 +3827,6 @@ ActiveRecord::Schema.define(version: 2020_02_06_091544) do
t.datetime "updated_at" t.datetime "updated_at"
t.boolean "active", default: false, null: false t.boolean "active", default: false, null: false
t.text "properties" t.text "properties"
t.boolean "template", default: false
t.boolean "push_events", default: true t.boolean "push_events", default: true
t.boolean "issues_events", default: true t.boolean "issues_events", default: true
t.boolean "merge_requests_events", default: true t.boolean "merge_requests_events", default: true
...@@ -3844,9 +3843,10 @@ ActiveRecord::Schema.define(version: 2020_02_06_091544) do ...@@ -3844,9 +3843,10 @@ ActiveRecord::Schema.define(version: 2020_02_06_091544) do
t.boolean "deployment_events", default: false, null: false t.boolean "deployment_events", default: false, null: false
t.string "description", limit: 500 t.string "description", limit: 500
t.boolean "comment_on_event_enabled", default: true, null: false t.boolean "comment_on_event_enabled", default: true, null: false
t.boolean "instance", default: false
t.index ["instance"], name: "index_services_on_instance"
t.index ["project_id"], name: "index_services_on_project_id" t.index ["project_id"], name: "index_services_on_project_id"
t.index ["project_id"], name: "tmp_index_on_project_id_partial_with_prometheus_services", where: "((type)::text = 'PrometheusService'::text)" t.index ["project_id"], name: "tmp_index_on_project_id_partial_with_prometheus_services", where: "((type)::text = 'PrometheusService'::text)"
t.index ["template"], name: "index_services_on_template"
t.index ["type"], name: "index_services_on_type" t.index ["type"], name: "index_services_on_type"
end end
......
...@@ -9,5 +9,5 @@ ...@@ -9,5 +9,5 @@
See the list of available commands in Slack after setting up this service See the list of available commands in Slack after setting up this service
by entering by entering
%kbd.inline /gitlab help %kbd.inline /gitlab help
- unless @service.template? - unless @service.instance?
= render "projects/services/#{@service.to_param}/slack_integration_form" = render "projects/services/#{@service.to_param}/slack_integration_form"
...@@ -132,7 +132,7 @@ module API ...@@ -132,7 +132,7 @@ module API
helpers do helpers do
# rubocop: disable CodeReuse/ActiveRecord # rubocop: disable CodeReuse/ActiveRecord
def slash_command_service(project, service_slug, params) def slash_command_service(project, service_slug, params)
project.services.active.where(template: false).find do |service| project.services.active.where(instance: false).find do |service|
service.try(:token) == params[:token] && service.to_param == service_slug.underscore service.try(:token) == params[:token] && service.to_param == service_slug.underscore
end end
end end
......
...@@ -257,7 +257,7 @@ excluded_attributes: ...@@ -257,7 +257,7 @@ excluded_attributes:
- :token - :token
- :token_encrypted - :token_encrypted
services: services:
- :template - :instance
error_tracking_setting: error_tracking_setting:
- :encrypted_token - :encrypted_token
- :encrypted_token_iv - :encrypted_token_iv
......
...@@ -179,7 +179,7 @@ module Gitlab ...@@ -179,7 +179,7 @@ module Gitlab
# rubocop: disable CodeReuse/ActiveRecord # rubocop: disable CodeReuse/ActiveRecord
def services_usage def services_usage
service_counts = count(Service.active.where(template: false).where.not(type: 'JiraService').group(:type), fallback: Hash.new(-1)) service_counts = count(Service.active.where(instance: false).where.not(type: 'JiraService').group(:type), fallback: Hash.new(-1))
results = Service.available_services_names.each_with_object({}) do |service_name, response| results = Service.available_services_names.each_with_object({}) do |service_name, response|
response["projects_#{service_name}_active".to_sym] = service_counts["#{service_name}_service".camelize] || 0 response["projects_#{service_name}_active".to_sym] = service_counts["#{service_name}_service".camelize] || 0
......
...@@ -15,11 +15,11 @@ describe Admin::ServicesController do ...@@ -15,11 +15,11 @@ describe Admin::ServicesController do
Service.available_services_names.each do |service_name| Service.available_services_names.each do |service_name|
context "#{service_name}" do context "#{service_name}" do
let!(:service) do let!(:service) do
service_template = "#{service_name}_service".camelize.constantize service_instance = "#{service_name}_service".camelize.constantize
service_template.where(template: true).first_or_create service_instance.where(instance: true).first_or_create
end end
it 'successfully displays the template' do it 'successfully displays the service' do
get :edit, params: { id: service.id } get :edit, params: { id: service.id }
expect(response).to have_gitlab_http_status(:ok) expect(response).to have_gitlab_http_status(:ok)
...@@ -34,7 +34,7 @@ describe Admin::ServicesController do ...@@ -34,7 +34,7 @@ describe Admin::ServicesController do
RedmineService.create( RedmineService.create(
project: project, project: project,
active: false, active: false,
template: true, instance: true,
properties: { properties: {
project_url: 'http://abc', project_url: 'http://abc',
issues_url: 'http://abc', issues_url: 'http://abc',
...@@ -44,7 +44,7 @@ describe Admin::ServicesController do ...@@ -44,7 +44,7 @@ describe Admin::ServicesController do
end end
it 'calls the propagation worker when service is active' do it 'calls the propagation worker when service is active' do
expect(PropagateServiceTemplateWorker).to receive(:perform_async).with(service.id) expect(PropagateInstanceLevelServiceWorker).to receive(:perform_async).with(service.id)
put :update, params: { id: service.id, service: { active: true } } put :update, params: { id: service.id, service: { active: true } }
...@@ -52,7 +52,7 @@ describe Admin::ServicesController do ...@@ -52,7 +52,7 @@ describe Admin::ServicesController do
end end
it 'does not call the propagation worker when service is not active' do it 'does not call the propagation worker when service is not active' do
expect(PropagateServiceTemplateWorker).not_to receive(:perform_async) expect(PropagateInstanceLevelServiceWorker).not_to receive(:perform_async)
put :update, params: { id: service.id, service: { properties: {} } } put :update, params: { id: service.id, service: { properties: {} } }
......
...@@ -154,12 +154,12 @@ describe Projects::ServicesController do ...@@ -154,12 +154,12 @@ describe Projects::ServicesController do
end end
end end
context 'when activating Jira service from a template' do context 'when activating Jira service from instance level service' do
let(:service) do let(:service) do
create(:jira_service, project: project, template: true) create(:jira_service, project: project, instance: true)
end end
it 'activate Jira service from template' do it 'activate Jira service from instance level service' do
expect(flash[:notice]).to eq 'Jira activated.' expect(flash[:notice]).to eq 'Jira activated.'
end end
end end
......
...@@ -2736,7 +2736,7 @@ Service ...@@ -2736,7 +2736,7 @@ Service
when repository is empty when repository is empty
test runs execute test runs execute
Template Template
.build_from_template .build_from_instance
when template is invalid when template is invalid
sets service template to inactive when template is invalid sets service template to inactive when template is invalid
for pushover service for pushover service
......
...@@ -652,10 +652,10 @@ describe Gitlab::ImportExport::ProjectTreeRestorer do ...@@ -652,10 +652,10 @@ describe Gitlab::ImportExport::ProjectTreeRestorer do
setup_import_export_config('light') setup_import_export_config('light')
end end
it 'does not import any templated services' do it 'does not import any instance-level services' do
expect(restored_project_json).to eq(true) expect(restored_project_json).to eq(true)
expect(project.services.where(template: true).count).to eq(0) expect(project.services.where(instance: true).count).to eq(0)
end end
it 'imports labels' do it 'imports labels' do
......
...@@ -452,7 +452,7 @@ Service: ...@@ -452,7 +452,7 @@ Service:
- updated_at - updated_at
- active - active
- properties - properties
- template - instance
- push_events - push_events
- issues_events - issues_events
- commit_events - commit_events
......
...@@ -18,7 +18,7 @@ describe Gitlab::UsageData do ...@@ -18,7 +18,7 @@ describe Gitlab::UsageData do
create(:service, project: projects[1], type: 'SlackService', active: true) create(:service, project: projects[1], type: 'SlackService', active: true)
create(:service, project: projects[2], type: 'SlackService', active: true) create(:service, project: projects[2], type: 'SlackService', active: true)
create(:service, project: projects[2], type: 'MattermostService', active: false) create(:service, project: projects[2], type: 'MattermostService', active: false)
create(:service, project: projects[2], type: 'MattermostService', active: true, template: true) create(:service, project: projects[2], type: 'MattermostService', active: true, instance: true)
create(:service, project: projects[2], type: 'CustomIssueTrackerService', active: true) create(:service, project: projects[2], type: 'CustomIssueTrackerService', active: true)
create(:project_error_tracking_setting, project: projects[0]) create(:project_error_tracking_setting, project: projects[0])
create(:project_error_tracking_setting, project: projects[1], enabled: false) create(:project_error_tracking_setting, project: projects[1], enabled: false)
......
# frozen_string_literal: true
require 'spec_helper'
require Rails.root.join('db', 'post_migrate', '20200206111847_migrate_propagate_service_template_sidekiq_queue.rb')
describe MigratePropagateServiceTemplateSidekiqQueue, :sidekiq, :redis do
include Gitlab::Database::MigrationHelpers
include StubWorker
context 'when there are jobs in the queue' do
it 'correctly migrates queue when migrating up' do
Sidekiq::Testing.disable! do
stub_worker(queue: 'propagate_service_template').perform_async('Something', [1])
stub_worker(queue: 'propagate_instance_level_service').perform_async('Something', [1])
described_class.new.up
expect(sidekiq_queue_length('propagate_service_template')).to eq 0
expect(sidekiq_queue_length('propagate_instance_level_service')).to eq 2
end
end
end
context 'when there are no jobs in the queues' do
it 'does not raise error when migrating up' do
expect { described_class.new.up }.not_to raise_error
end
end
end
...@@ -97,23 +97,23 @@ describe Service do ...@@ -97,23 +97,23 @@ describe Service do
end end
end end
describe "Template" do describe "Instance" do
let(:project) { create(:project) } let(:project) { create(:project) }
describe '.build_from_template' do describe '.build_from_instance' do
context 'when template is invalid' do context 'when instance level integration is invalid' do
it 'sets service template to inactive when template is invalid' do it 'sets instance level integration to inactive when instance is invalid' do
template = build(:prometheus_service, template: true, active: true, properties: {}) instance = build(:prometheus_service, instance: true, active: true, properties: {})
template.save(validate: false) instance.save(validate: false)
service = described_class.build_from_template(project.id, template) service = described_class.build_from_instance(project.id, instance)
expect(service).to be_valid expect(service).to be_valid
expect(service.active).to be false expect(service.active).to be false
end end
end end
describe 'build issue tracker from a template' do describe 'build issue tracker from a instance level integration' do
let(:title) { 'custom title' } let(:title) { 'custom title' }
let(:description) { 'custom description' } let(:description) { 'custom description' }
let(:url) { 'http://jira.example.com' } let(:url) { 'http://jira.example.com' }
...@@ -127,9 +127,9 @@ describe Service do ...@@ -127,9 +127,9 @@ describe Service do
} }
end end
shared_examples 'service creation from a template' do shared_examples 'integration creation from instance level' do
it 'creates a correct service' do it 'creates a correct service' do
service = described_class.build_from_template(project.id, template) service = described_class.build_from_instance(project.id, instance_level_integration)
expect(service).to be_active expect(service).to be_active
expect(service.title).to eq(title) expect(service.title).to eq(title)
...@@ -144,38 +144,38 @@ describe Service do ...@@ -144,38 +144,38 @@ describe Service do
# this will be removed as part of https://gitlab.com/gitlab-org/gitlab/issues/29404 # this will be removed as part of https://gitlab.com/gitlab-org/gitlab/issues/29404
context 'when data are stored in properties' do context 'when data are stored in properties' do
let(:properties) { data_params.merge(title: title, description: description) } let(:properties) { data_params.merge(title: title, description: description) }
let!(:template) do let!(:instance_level_integration) do
create(:jira_service, :without_properties_callback, template: true, properties: properties.merge(additional: 'something')) create(:jira_service, :without_properties_callback, instance: true, properties: properties.merge(additional: 'something'))
end end
it_behaves_like 'service creation from a template' it_behaves_like 'integration creation from instance level'
end end
context 'when data are stored in separated fields' do context 'when data are stored in separated fields' do
let(:template) do let(:instance_level_integration) do
create(:jira_service, data_params.merge(properties: {}, title: title, description: description, template: true)) create(:jira_service, data_params.merge(properties: {}, title: title, description: description, instance: true))
end end
it_behaves_like 'service creation from a template' it_behaves_like 'integration creation from instance level'
end end
context 'when data are stored in both properties and separated fields' do context 'when data are stored in both properties and separated fields' do
let(:properties) { data_params.merge(title: title, description: description) } let(:properties) { data_params.merge(title: title, description: description) }
let(:template) do let(:instance_level_integration) do
create(:jira_service, :without_properties_callback, active: true, template: true, properties: properties).tap do |service| create(:jira_service, :without_properties_callback, active: true, instance: true, properties: properties).tap do |service|
create(:jira_tracker_data, data_params.merge(service: service)) create(:jira_tracker_data, data_params.merge(service: service))
end end
end end
it_behaves_like 'service creation from a template' it_behaves_like 'integration creation from instance level'
end end
end end
end end
describe "for pushover service" do describe "for pushover service" do
let!(:service_template) do let!(:instance_level_integration) do
PushoverService.create( PushoverService.create(
template: true, instance: true,
properties: { properties: {
device: 'MyDevice', device: 'MyDevice',
sound: 'mic', sound: 'mic',
...@@ -188,7 +188,7 @@ describe Service do ...@@ -188,7 +188,7 @@ describe Service do
it "has all fields prefilled" do it "has all fields prefilled" do
service = project.find_or_initialize_service('pushover') service = project.find_or_initialize_service('pushover')
expect(service.template).to eq(false) expect(service.instance).to eq(false)
expect(service.device).to eq('MyDevice') expect(service.device).to eq('MyDevice')
expect(service.sound).to eq('mic') expect(service.sound).to eq('mic')
expect(service.priority).to eq(4) expect(service.priority).to eq(4)
...@@ -391,14 +391,6 @@ describe Service do ...@@ -391,14 +391,6 @@ describe Service do
end end
end end
describe '.find_by_template' do
let!(:service) { create(:service, template: true) }
it 'returns service template' do
expect(described_class.find_by_template).to eq(service)
end
end
describe '#api_field_names' do describe '#api_field_names' do
let(:fake_service) do let(:fake_service) do
Class.new(Service) do Class.new(Service) do
......
...@@ -15,7 +15,7 @@ describe Projects::CreateService, '#execute' do ...@@ -15,7 +15,7 @@ describe Projects::CreateService, '#execute' do
} }
end end
it 'creates labels on Project creation if there are templates' do it 'creates labels on Project creation if there are instance level services' do
Label.create(title: "bug", template: true) Label.create(title: "bug", template: true)
project = create_project(user, opts) project = create_project(user, opts)
...@@ -90,7 +90,7 @@ describe Projects::CreateService, '#execute' do ...@@ -90,7 +90,7 @@ describe Projects::CreateService, '#execute' do
end end
it 'sets invalid service as inactive' do it 'sets invalid service as inactive' do
create(:service, type: 'JiraService', project: nil, template: true, active: true) create(:service, type: 'JiraService', project: nil, instance: true, active: true)
project = create_project(user, opts) project = create_project(user, opts)
service = project.services.first service = project.services.first
...@@ -336,22 +336,22 @@ describe Projects::CreateService, '#execute' do ...@@ -336,22 +336,22 @@ describe Projects::CreateService, '#execute' do
end end
end end
context 'when there is an active service template' do context 'when there is an active instance level service' do
before do before do
create(:service, project: nil, template: true, active: true) create(:service, project: nil, instance: true, active: true)
end end
it 'creates a service from this template' do it 'creates a service from instance level service' do
project = create_project(user, opts) project = create_project(user, opts)
expect(project.services.count).to eq 1 expect(project.services.count).to eq 1
end end
end end
context 'when a bad service template is created' do context 'when a bad instance level service is created' do
it 'sets service to be inactive' do it 'sets service to be inactive' do
opts[:import_url] = 'http://www.gitlab.com/gitlab-org/gitlab-foss' opts[:import_url] = 'http://www.gitlab.com/gitlab-org/gitlab-foss'
create(:service, type: 'DroneCiService', project: nil, template: true, active: true) create(:service, type: 'DroneCiService', project: nil, instance: true, active: true)
project = create_project(user, opts) project = create_project(user, opts)
service = project.services.first service = project.services.first
......
...@@ -2,11 +2,11 @@ ...@@ -2,11 +2,11 @@
require 'spec_helper' require 'spec_helper'
describe Projects::PropagateServiceTemplate do describe Projects::PropagateInstanceLevelService do
describe '.propagate' do describe '.propagate' do
let!(:service_template) do let!(:instance_level_integration) do
PushoverService.create( PushoverService.create(
template: true, instance: true,
active: true, active: true,
properties: { properties: {
device: 'MyDevice', device: 'MyDevice',
...@@ -22,14 +22,14 @@ describe Projects::PropagateServiceTemplate do ...@@ -22,14 +22,14 @@ describe Projects::PropagateServiceTemplate do
it 'creates services for projects' do it 'creates services for projects' do
expect(project.pushover_service).to be_nil expect(project.pushover_service).to be_nil
described_class.propagate(service_template) described_class.propagate(instance_level_integration)
expect(project.reload.pushover_service).to be_present expect(project.reload.pushover_service).to be_present
end end
it 'creates services for a project that has another service' do it 'creates services for a project that has another service' do
BambooService.create( BambooService.create(
template: true, instance: true,
active: true, active: true,
project: project, project: project,
properties: { properties: {
...@@ -42,14 +42,14 @@ describe Projects::PropagateServiceTemplate do ...@@ -42,14 +42,14 @@ describe Projects::PropagateServiceTemplate do
expect(project.pushover_service).to be_nil expect(project.pushover_service).to be_nil
described_class.propagate(service_template) described_class.propagate(instance_level_integration)
expect(project.reload.pushover_service).to be_present expect(project.reload.pushover_service).to be_present
end end
it 'does not create the service if it exists already' do it 'does not create the service if it exists already' do
other_service = BambooService.create( other_service = BambooService.create(
template: true, instance: true,
active: true, active: true,
properties: { properties: {
bamboo_url: 'http://gitlab.com', bamboo_url: 'http://gitlab.com',
...@@ -59,17 +59,17 @@ describe Projects::PropagateServiceTemplate do ...@@ -59,17 +59,17 @@ describe Projects::PropagateServiceTemplate do
} }
) )
Service.build_from_template(project.id, service_template).save! Service.build_from_instance(project.id, instance_level_integration).save!
Service.build_from_template(project.id, other_service).save! Service.build_from_instance(project.id, other_service).save!
expect { described_class.propagate(service_template) } expect { described_class.propagate(instance_level_integration) }
.not_to change { Service.count } .not_to change { Service.count }
end end
it 'creates the service containing the template attributes' do it 'creates the service containing the instance attributes' do
described_class.propagate(service_template) described_class.propagate(instance_level_integration)
expect(project.pushover_service.properties).to eq(service_template.properties) expect(project.pushover_service.properties).to eq(instance_level_integration.properties)
end end
describe 'bulk update', :use_sql_query_cache do describe 'bulk update', :use_sql_query_cache do
...@@ -80,7 +80,7 @@ describe Projects::PropagateServiceTemplate do ...@@ -80,7 +80,7 @@ describe Projects::PropagateServiceTemplate do
project_total.times { create(:project) } project_total.times { create(:project) }
described_class.propagate(service_template) described_class.propagate(instance_level_integration)
end end
it 'creates services for all projects' do it 'creates services for all projects' do
...@@ -90,18 +90,18 @@ describe Projects::PropagateServiceTemplate do ...@@ -90,18 +90,18 @@ describe Projects::PropagateServiceTemplate do
describe 'external tracker' do describe 'external tracker' do
it 'updates the project external tracker' do it 'updates the project external tracker' do
service_template.update!(category: 'issue_tracker', default: false) instance_level_integration.update!(category: 'issue_tracker', default: false)
expect { described_class.propagate(service_template) } expect { described_class.propagate(instance_level_integration) }
.to change { project.reload.has_external_issue_tracker }.to(true) .to change { project.reload.has_external_issue_tracker }.to(true)
end end
end end
describe 'external wiki' do describe 'external wiki' do
it 'updates the project external tracker' do it 'updates the project external tracker' do
service_template.update!(type: 'ExternalWikiService') instance_level_integration.update!(type: 'ExternalWikiService')
expect { described_class.propagate(service_template) } expect { described_class.propagate(instance_level_integration) }
.to change { project.reload.has_external_wiki }.to(true) .to change { project.reload.has_external_wiki }.to(true)
end end
end end
......
...@@ -2,13 +2,13 @@ ...@@ -2,13 +2,13 @@
require 'spec_helper' require 'spec_helper'
describe PropagateServiceTemplateWorker do describe PropagateInstanceLevelServiceWorker do
include ExclusiveLeaseHelpers include ExclusiveLeaseHelpers
describe '#perform' do describe '#perform' do
it 'calls the propagate service with the template' do it 'calls the propagate service with the instance level service' do
template = PushoverService.create( instance_level_service = PushoverService.create(
template: true, instance: true,
active: true, active: true,
properties: { properties: {
device: 'MyDevice', device: 'MyDevice',
...@@ -18,14 +18,14 @@ describe PropagateServiceTemplateWorker do ...@@ -18,14 +18,14 @@ describe PropagateServiceTemplateWorker do
api_key: '123456789' api_key: '123456789'
}) })
stub_exclusive_lease("propagate_service_template_worker:#{template.id}", stub_exclusive_lease("propagate_instance_level_service_worker:#{instance_level_service.id}",
timeout: PropagateServiceTemplateWorker::LEASE_TIMEOUT) timeout: PropagateInstanceLevelServiceWorker::LEASE_TIMEOUT)
expect(Projects::PropagateServiceTemplate) expect(Projects::PropagateInstanceLevelService)
.to receive(:propagate) .to receive(:propagate)
.with(template) .with(instance_level_service)
subject.perform(template.id) subject.perform(instance_level_service.id)
end end
end 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