Commit 232f4f1d authored by Shinya Maeda's avatar Shinya Maeda

Squashed commit of the following:

commit 7277b3b3
Author: Shinya Maeda <shinya@gitlab.com>
Date:   Tue Nov 28 03:06:38 2017 +0900

    Fix feature spec

commit b4c4e1bd
Author: Shinya Maeda <shinya@gitlab.com>
Date:   Tue Nov 28 02:01:41 2017 +0900

    Fix integraetion tests

commit 54c70a77
Author: Shinya Maeda <shinya@gitlab.com>
Date:   Tue Nov 28 01:26:14 2017 +0900

    Fix static analysys

commit f6d9dcf8
Author: Shinya Maeda <shinya@gitlab.com>
Date:   Mon Nov 27 23:55:25 2017 +0900

    Fix unit tests

commit c36d7842
Author: Shinya Maeda <shinya@gitlab.com>
Date:   Mon Nov 27 23:19:16 2017 +0900

    Aling shared_exmaples to "same behavior between KubernetesService and Platform::Kubernetes"

commit 53da3d97
Author: Shinya Maeda <shinya@gitlab.com>
Date:   Mon Nov 27 22:35:16 2017 +0900

    Replce kubernetes_service and deployment_service to deployment_platform

commit 1d7e3ef1
Author: Shinya Maeda <shinya@gitlab.com>
Date:   Mon Nov 27 21:48:54 2017 +0900

    Duplicate spec for Platform::Kubernetes with kubernetes_project

commit 5324383d
Author: Shinya Maeda <shinya@gitlab.com>
Date:   Wed Nov 22 23:21:02 2017 +0900

    Add test for checking interchangeability between KubernetesService and Clusters::Platform::Kubernetes

commit 45f2d0af
Author: Shinya Maeda <shinya@gitlab.com>
Date:   Wed Nov 22 18:31:07 2017 +0900

    Add test suit for platform::kubernetes

commit a8e2094c
Author: Shinya Maeda <shinya@gitlab.com>
Date:   Tue Nov 21 23:29:33 2017 +0900

    Remove logic which glues with KubernetesService, from Platforms::Kubernetes

commit 3cf53cc6
Author: Shinya Maeda <shinya@gitlab.com>
Date:   Tue Nov 21 22:53:36 2017 +0900

    Fix comments

commit cff5eadd
Author: Shinya Maeda <shinya@gitlab.com>
Date:   Tue Nov 21 22:52:05 2017 +0900

    Add deployment platform selector

commit cff4a50e
Author: Shinya Maeda <shinya@gitlab.com>
Date:   Tue Nov 21 22:33:25 2017 +0900

    Fix tests for Clusters::Platforms::Kubernetes

commit 0d95ce51
Author: Shinya Maeda <shinya@gitlab.com>
Date:   Tue Nov 21 22:03:07 2017 +0900

    Check diff between KubernetesService and Platforms::Kubernetes. Synchronize again.

commit 8a55d2c5
Author: Shinya Maeda <shinya@gitlab.com>
Date:   Tue Nov 21 21:09:55 2017 +0900

    Revert KubernetesService logic in Platforms::Kubernetes
parent d9b64cc6
......@@ -41,7 +41,7 @@ class Projects::BranchesController < Projects::ApplicationController
branch_name = sanitize(strip_tags(params[:branch_name]))
branch_name = Addressable::URI.unescape(branch_name)
redirect_to_autodeploy = project.empty_repo? && project.deployment_services.present?
redirect_to_autodeploy = project.empty_repo? && project.deployment_platform.present?
result = CreateBranchService.new(project, current_user)
.execute(branch_name, ref)
......
......@@ -26,7 +26,7 @@ module AutoDevopsHelper
def auto_devops_warning_message(project)
missing_domain = !project.auto_devops&.has_domain?
missing_service = !project.kubernetes_service&.active?
missing_service = !project.deployment_platform&.active?
if missing_service
params = {
......
......@@ -378,7 +378,7 @@ module Ci
end
def has_kubernetes_active?
project.kubernetes_service&.active?
project.deployment_platform&.active?
end
def has_stage_seeds?
......
......@@ -6,7 +6,7 @@ module Clusters
include ReactiveCaching
self.table_name = 'cluster_platforms_kubernetes'
self.reactive_cache_key = ->(kubernetes) { [kubernetes.class.model_name.singular, kubernetes.cluster_id] }
self.reactive_cache_key = ->(kubernetes) { [kubernetes.class.model_name.singular, kubernetes.id] }
belongs_to :cluster, inverse_of: :platform_kubernetes, class_name: 'Clusters::Cluster'
......@@ -41,6 +41,8 @@ module Clusters
delegate :project, to: :cluster, allow_nil: true
delegate :enabled?, to: :cluster, allow_nil: true
alias_method :active?, :enabled?
def actual_namespace
if namespace.present?
namespace
......@@ -132,6 +134,7 @@ module Clusters
kubeclient.get_pods(namespace: actual_namespace).as_json
rescue KubeException => err
raise err unless err.error_code == 404
[]
end
......
......@@ -137,16 +137,12 @@ class Environment < ActiveRecord::Base
end
end
def deployment_service_ready?
project.deployment_service.present? && available? && last_deployment.present?
def has_terminals?
project.deployment_platform.present? && available? && last_deployment.present?
end
def terminals
project.deployment_service.terminals(self) if deployment_service_ready?
end
def rollout_status
project.deployment_service.rollout_status(self) if deployment_service_ready?
project.deployment_platform.terminals(self) if has_terminals?
end
def has_metrics?
......
......@@ -20,9 +20,6 @@ class Project < ActiveRecord::Base
include GroupDescendant
include Gitlab::SQL::Pattern
# EE specific modules
prepend EE::Project
extend Gitlab::ConfigHelper
extend Gitlab::CurrentSettings
......@@ -103,7 +100,6 @@ class Project < ActiveRecord::Base
# Project services
has_one :campfire_service
has_one :drone_ci_service
has_one :gitlab_slack_application_service
has_one :emails_on_push_service
has_one :pipelines_email_service
has_one :irker_service
......@@ -127,7 +123,7 @@ class Project < ActiveRecord::Base
has_one :bugzilla_service
has_one :gitlab_issue_tracker_service, inverse_of: :project
has_one :external_wiki_service
# has_one :kubernetes_service, inverse_of: :project
has_one :kubernetes_service, inverse_of: :project
has_one :prometheus_service, inverse_of: :project
has_one :mock_ci_service
has_one :mock_deployment_service
......@@ -293,6 +289,7 @@ class Project < ActiveRecord::Base
scope :non_archived, -> { where(archived: false) }
scope :for_milestones, ->(ids) { joins(:milestones).where('milestones.id' => ids).distinct }
scope :with_push, -> { joins(:events).where('events.action = ?', Event::PUSHED) }
scope :with_project_feature, -> { joins('LEFT JOIN project_features ON projects.id = project_features.project_id') }
scope :with_statistics, -> { includes(:statistics) }
scope :with_shared_runners, -> { where(shared_runners_enabled: true) }
......@@ -393,6 +390,10 @@ class Project < ActiveRecord::Base
transition [:scheduled, :started] => :failed
end
event :import_retry do
transition failed: :started
end
state :scheduled
state :started
state :finished
......@@ -481,14 +482,6 @@ class Project < ActiveRecord::Base
.base_and_ancestors(upto: top)
end
def root_namespace
if namespace.has_parent?
namespace.root_ancestor
else
namespace
end
end
def lfs_enabled?
return namespace.lfs_enabled? if self[:lfs_enabled].nil?
......@@ -624,8 +617,6 @@ class Project < ActiveRecord::Base
else
super
end
rescue
super
end
def valid_import_url?
......@@ -906,16 +897,10 @@ class Project < ActiveRecord::Base
@ci_service ||= ci_services.reorder(nil).find_by(active: true)
end
def deployment_services
services.where(category: :deployment)
end
def deployment_service
deployment_platform
end
def kubernetes_service
deployment_platform
# TODO: This will be extended for multiple enviroment clusters
def deployment_platform
@deployment_platform ||= clusters.find_by(enabled: true)&.platform_kubernetes
@deployment_platform ||= services.where(category: :deployment).reorder(nil).find_by(active: true)
end
def monitoring_services
......@@ -1055,7 +1040,6 @@ class Project < ActiveRecord::Base
# Expires various caches before a project is renamed.
def expire_caches_before_rename(old_path)
# TODO: if we start using UUIDs for cache, we don't need to do this HACK anymore
repo = Repository.new(old_path, self)
wiki = Repository.new("#{old_path}.wiki", self)
......@@ -1561,9 +1545,9 @@ class Project < ActiveRecord::Base
end
def deployment_variables
return [] unless deployment_service
return [] unless deployment_platform
deployment_service.predefined_variables
deployment_platform.predefined_variables
end
def auto_devops_variables
......@@ -1635,6 +1619,10 @@ class Project < ActiveRecord::Base
feature_available?(:multiple_issue_boards, user)
end
def issue_board_milestone_available?(user = nil)
feature_available?(:issue_board_milestone, user)
end
def full_path_was
File.join(namespace.full_path, previous_changes['path'].first)
end
......@@ -1852,11 +1840,4 @@ class Project < ActiveRecord::Base
raise ex
end
# TODO: This will be extended for multiple enviroment clusters
# TODO: Add super nice tests to check this interchangeability
def deployment_platform
@deployment_platform ||= clusters.where(enabled: true).first&.platform_kubernetes
@deployment_platform ||= deployment_services.reorder(nil).find_by(active: true)
end
end
......@@ -5,7 +5,7 @@
.col-sm-4
= render 'sidebar'
.col-sm-8
- if @project.kubernetes_service&.active?
- if @project.deployment_platform&.active?
%h4.prepend-top-0= s_('ClusterIntegration|Cluster management')
%p= s_('ClusterIntegration|A cluster has been set up on this project through the Kubernetes integration page')
......
......@@ -159,7 +159,7 @@
%ul
%li Be careful. Renaming a project's repository can have unintended side effects.
%li You will need to update your local repositories to point to the new location.
- if @project.deployment_services.any?
- if @project.deployment_platform.present?
%li Your deployment services will be broken, you will need to manually fix the services after renaming.
= f.submit 'Rename project', class: "btn btn-warning"
- if can?(current_user, :change_namespace, @project)
......
......@@ -67,7 +67,7 @@
- if koding_enabled? && @repository.koding_yml.blank?
%li.missing
= link_to _('Set up Koding'), add_koding_stack_path(@project)
- if @repository.gitlab_ci_yml.blank? && @project.deployment_service.present?
- if @repository.gitlab_ci_yml.blank? && @project.deployment_platform.present?
%li.missing
= link_to add_special_file_path(@project, file_name: '.gitlab-ci.yml', commit_message: 'Set up auto deploy', branch_name: 'auto-deploy', context: 'autodeploy') do
#{ _('Set up auto deploy') }
......
......@@ -76,7 +76,7 @@ module Gitlab
timeframe_start: timeframe_start,
timeframe_end: timeframe_end,
ci_environment_slug: environment.slug,
kube_namespace: environment.project.kubernetes_service&.actual_namespace || '',
kube_namespace: environment.project.deployment_platform&.actual_namespace || '',
environment_filter: %{container_name!="POD",environment="#{environment.slug}"}
}
end
......
......@@ -113,22 +113,38 @@ describe Projects::BranchesController do
expect(response).to redirect_to project_tree_path(project, branch)
end
it 'redirects to autodeploy setup page' do
result = { status: :success, branch: double(name: branch) }
shared_examples 'same behavior between KubernetesService and Platform::Kubernetes' do
it 'redirects to autodeploy setup page' do
result = { status: :success, branch: double(name: branch) }
expect_any_instance_of(CreateBranchService).to receive(:execute).and_return(result)
expect(SystemNoteService).to receive(:new_issue_branch).and_return(true)
post :create,
namespace_id: project.namespace.to_param,
project_id: project.to_param,
branch_name: branch,
issue_iid: issue.iid
expect(response.location).to include(project_new_blob_path(project, branch))
expect(response).to have_gitlab_http_status(302)
end
end
project.services << build(:kubernetes_service)
context 'when user configured kubernetes from Integration > Kubernetes' do
before do
project.services << build(:kubernetes_service)
end
expect_any_instance_of(CreateBranchService).to receive(:execute).and_return(result)
expect(SystemNoteService).to receive(:new_issue_branch).and_return(true)
it_behaves_like 'same behavior between KubernetesService and Platform::Kubernetes'
end
post :create,
namespace_id: project.namespace.to_param,
project_id: project.to_param,
branch_name: branch,
issue_iid: issue.iid
context 'when user configured kubernetes from CI/CD > Clusters' do
before do
create(:cluster, :provided_by_gcp, projects: [project])
end
expect(response.location).to include(project_new_blob_path(project, branch))
expect(response).to have_gitlab_http_status(302)
it_behaves_like 'same behavior between KubernetesService and Platform::Kubernetes'
end
it 'redirects to autodeploy setup page' do
......
......@@ -4,16 +4,10 @@ describe 'Auto deploy' do
let(:user) { create(:user) }
let(:project) { create(:project, :repository) }
context 'when user configured kubernetes from Integration > Kubernetes' do
before do
create :kubernetes_service, project: project
project.team << [user, :master]
sign_in user
end
shared_examples 'same behavior between KubernetesService and Platform::Kubernetes' do
context 'when no deployment service is active' do
before do
project.kubernetes_service.update!(active: false)
trun_off
end
it 'does not show a button to set up auto deploy' do
......@@ -24,7 +18,7 @@ describe 'Auto deploy' do
context 'when a deployment service is active' do
before do
project.kubernetes_service.update!(active: true)
trun_on
visit project_path(project)
end
......@@ -55,54 +49,29 @@ describe 'Auto deploy' do
end
end
context 'when user configured kubernetes from CI/CD > Clusters' do
context 'when user configured kubernetes from Integration > Kubernetes' do
before do
create(:cluster, :provided_by_gcp, projects: [project])
create :kubernetes_service, project: project
project.team << [user, :master]
sign_in user
end
context 'when no deployment service is active' do
before do
project.kubernetes_service.update!(active: false)
end
it 'does not show a button to set up auto deploy' do
visit project_path(project)
expect(page).to have_no_content('Set up auto deploy')
end
end
context 'when a deployment service is active' do
before do
project.kubernetes_service.update!(active: true)
visit project_path(project)
end
it 'shows a button to set up auto deploy' do
expect(page).to have_link('Set up auto deploy')
end
let(:trun_on) { project.deployment_platform.update!(active: true) }
let(:trun_off) { project.deployment_platform.update!(active: false) }
it 'includes OpenShift as an available template', :js do
click_link 'Set up auto deploy'
click_button 'Apply a GitLab CI Yaml template'
it_behaves_like 'same behavior between KubernetesService and Platform::Kubernetes'
end
within '.gitlab-ci-yml-selector' do
expect(page).to have_content('OpenShift')
end
end
context 'when user configured kubernetes from CI/CD > Clusters' do
before do
create(:cluster, :provided_by_gcp, projects: [project])
project.team << [user, :master]
sign_in user
end
it 'creates a merge request using "auto-deploy" branch', :js do
click_link 'Set up auto deploy'
click_button 'Apply a GitLab CI Yaml template'
within '.gitlab-ci-yml-selector' do
click_on 'OpenShift'
end
wait_for_requests
click_button 'Commit changes'
let(:trun_on) { project.deployment_platform.cluster.update!(enabled: true) }
let(:trun_off) { project.deployment_platform.cluster.update!(enabled: false) }
expect(page).to have_content('New Merge Request From auto-deploy into master')
end
end
it_behaves_like 'same behavior between KubernetesService and Platform::Kubernetes'
end
end
require 'spec_helper'
feature 'Interchangeability between KubernetesService and Platform::Kubernetes' do
let!(:project) { create(:project, :repository) }
EXCEPT_METHODS = %i[test title description help fields initialize_properties namespace namespace= api_url api_url=]
EXCEPT_METHODS_GREP_V = %w[_touched? _changed? _was]
EXCEPT_METHODS = %i[test title description help fields initialize_properties namespace namespace= api_url api_url=].freeze
EXCEPT_METHODS_GREP_V = %w[_touched? _changed? _was].freeze
it 'Clusters::Platform::Kubernetes covers core interfaces in KubernetesService' do
expected_interfaces = KubernetesService.instance_methods(false)
......@@ -12,34 +10,7 @@ feature 'Interchangeability between KubernetesService and Platform::Kubernetes'
EXCEPT_METHODS_GREP_V.each do |g|
expected_interfaces = expected_interfaces.grep_v(/#{Regexp.escape(g)}\z/)
end
expect(expected_interfaces - Clusters::Platforms::Kubernetes.instance_methods).to be_empty
end
shared_examples 'selects kubernetes instance' do
context 'when user configured kubernetes from Integration > Kubernetes' do
let!(:kubernetes_service) { create(:kubernetes_service, project: project) }
it { is_expected.to eq(kubernetes_service) }
end
context 'when user configured kubernetes from CI/CD > Clusters' do
let!(:cluster) { create(:cluster, :provided_by_gcp, projects: [project]) }
let(:platform_kubernetes) { cluster.platform_kubernetes }
it { is_expected.to eq(platform_kubernetes) }
end
end
describe 'Project#deployment_service' do
subject { project.deployment_service }
it_behaves_like 'selects kubernetes instance'
end
describe 'Project#kubernetes_service' do
subject { project.kubernetes_service }
it_behaves_like 'selects kubernetes instance'
expect(expected_interfaces - Clusters::Platforms::Kubernetes.instance_methods).to be_empty
end
end
......@@ -101,7 +101,7 @@ feature 'Environment' do
end
context 'with terminal' do
shared_examples 'correct behavior with terminal' do
shared_examples 'same behavior between KubernetesService and Platform::Kubernetes' do
context 'for project master' do
let(:role) { :master }
......@@ -135,14 +135,14 @@ feature 'Environment' do
context 'when user configured kubernetes from Integration > Kubernetes' do
let(:project) { create(:kubernetes_project, :test_repo) }
it_behaves_like 'correct behavior with terminal'
it_behaves_like 'same behavior between KubernetesService and Platform::Kubernetes'
end
context 'when user configured kubernetes from CI/CD > Clusters' do
let!(:cluster) { create(:cluster, :project, :provided_by_gcp) }
let(:project) { cluster.project }
it_behaves_like 'correct behavior with terminal'
it_behaves_like 'same behavior between KubernetesService and Platform::Kubernetes'
end
end
......
......@@ -208,7 +208,7 @@ feature 'Environments page', :js do
end
context 'when kubernetes terminal is available' do
shared_examples 'correct behavior with terminal' do
shared_examples 'same behavior between KubernetesService and Platform::Kubernetes' do
context 'for project master' do
let(:role) { :master }
......@@ -225,18 +225,18 @@ feature 'Environments page', :js do
end
end
end
context 'when user configured kubernetes from Integration > Kubernetes' do
let(:project) { create(:kubernetes_project, :test_repo) }
it_behaves_like 'correct behavior with terminal'
it_behaves_like 'same behavior between KubernetesService and Platform::Kubernetes'
end
context 'when user configured kubernetes from CI/CD > Clusters' do
let!(:cluster) { create(:cluster, :project, :provided_by_gcp) }
let(:cluster) { create(:cluster, :provided_by_gcp, projects: [create(:project, :repository)]) }
let(:project) { cluster.project }
it_behaves_like 'correct behavior with terminal'
it_behaves_like 'same behavior between KubernetesService and Platform::Kubernetes'
end
end
end
......
......@@ -4,7 +4,7 @@ describe Gitlab::Ci::Build::Policy::Kubernetes do
let(:pipeline) { create(:ci_pipeline, project: project) }
context 'when kubernetes service is active' do
shared_examples 'correct behavior for satisfied_by?' do
shared_examples 'same behavior between KubernetesService and Platform::Kubernetes' do
it 'is satisfied by a kubernetes pipeline' do
expect(described_class.new('active'))
.to be_satisfied_by(pipeline)
......@@ -14,14 +14,14 @@ describe Gitlab::Ci::Build::Policy::Kubernetes do
context 'when user configured kubernetes from Integration > Kubernetes' do
let(:project) { create(:kubernetes_project) }
it_behaves_like 'correct behavior for satisfied_by?'
it_behaves_like 'same behavior between KubernetesService and Platform::Kubernetes'
end
context 'when user configured kubernetes from CI/CD > Clusters' do
let!(:cluster) { create(:cluster, :project, :provided_by_gcp) }
let(:project) { cluster.project }
it_behaves_like 'correct behavior for satisfied_by?'
it_behaves_like 'same behavior between KubernetesService and Platform::Kubernetes'
end
end
......
......@@ -178,15 +178,29 @@ module Gitlab
end
context 'when kubernetes is active' do
let(:project) { create(:kubernetes_project) }
let(:pipeline) { create(:ci_empty_pipeline, project: project) }
shared_examples 'same behavior between KubernetesService and Platform::Kubernetes' do
it 'returns seeds for kubernetes dependent job' do
seeds = subject.stage_seeds(pipeline)
it 'returns seeds for kubernetes dependent job' do
seeds = subject.stage_seeds(pipeline)
expect(seeds.size).to eq 2
expect(seeds.first.builds.dig(0, :name)).to eq 'spinach'
expect(seeds.second.builds.dig(0, :name)).to eq 'production'
end
end
expect(seeds.size).to eq 2
expect(seeds.first.builds.dig(0, :name)).to eq 'spinach'
expect(seeds.second.builds.dig(0, :name)).to eq 'production'
context 'when user configured kubernetes from Integration > Kubernetes' do
let(:project) { create(:kubernetes_project) }
let(:pipeline) { create(:ci_empty_pipeline, project: project) }
it_behaves_like 'same behavior between KubernetesService and Platform::Kubernetes'
end
context 'when user configured kubernetes from CI/CD > Clusters' do
let!(:cluster) { create(:cluster, :project, :provided_by_gcp) }
let(:project) { cluster.project }
let(:pipeline) { create(:ci_empty_pipeline, project: project) }
it_behaves_like 'same behavior between KubernetesService and Platform::Kubernetes'
end
end
......
......@@ -561,10 +561,23 @@ describe Ci::Pipeline, :mailer do
describe '#has_kubernetes_active?' do
context 'when kubernetes is active' do
let(:project) { create(:kubernetes_project) }
shared_examples 'same behavior between KubernetesService and Platform::Kubernetes' do
it 'returns true' do
expect(pipeline).to have_kubernetes_active
end
end
it 'returns true' do
expect(pipeline).to have_kubernetes_active
context 'when user configured kubernetes from Integration > Kubernetes' do
let(:project) { create(:kubernetes_project) }
it_behaves_like 'same behavior between KubernetesService and Platform::Kubernetes'
end
context 'when user configured kubernetes from CI/CD > Clusters' do
let!(:cluster) { create(:cluster, :project, :provided_by_gcp) }
let(:project) { cluster.project }
it_behaves_like 'same behavior between KubernetesService and Platform::Kubernetes'
end
end
......
......@@ -9,7 +9,6 @@ describe Clusters::Cluster do
it { is_expected.to delegate_method(:status_reason).to(:provider) }
it { is_expected.to delegate_method(:status_name).to(:provider) }
it { is_expected.to delegate_method(:on_creation?).to(:provider) }
it { is_expected.to delegate_method(:update_kubernetes_integration!).to(:platform) }
it { is_expected.to respond_to :project }
describe '.enabled' do
......
......@@ -92,55 +92,6 @@ describe Clusters::Platforms::Kubernetes, :use_clean_rails_memory_store_caching
end
end
describe 'after_save from Clusters::Cluster' do
context 'when platform_kubernetes is being cerated' do
let(:enabled) { true }
let(:project) { create(:project) }
let(:cluster) { build(:cluster, provider_type: :gcp, platform_type: :kubernetes, platform_kubernetes: platform, provider_gcp: provider, enabled: enabled, projects: [project]) }
let(:platform) { build(:cluster_platform_kubernetes, :configured) }
let(:provider) { build(:cluster_provider_gcp) }
let(:kubernetes_service) { project.kubernetes_service }
it 'updates KubernetesService' do
cluster.save!
expect(kubernetes_service.active).to eq(enabled)
expect(kubernetes_service.api_url).to eq(platform.api_url)
expect(kubernetes_service.namespace).to eq(platform.namespace)
expect(kubernetes_service.ca_pem).to eq(platform.ca_cert)
end
end
context 'when platform_kubernetes has been created' do
let(:enabled) { false }
let!(:project) { create(:project) }
let!(:cluster) { create(:cluster, :provided_by_gcp, projects: [project]) }
let(:platform) { cluster.platform }
let(:kubernetes_service) { project.kubernetes_service }
it 'updates KubernetesService' do
cluster.update(enabled: enabled)
expect(kubernetes_service.active).to eq(enabled)
end
end
context 'when kubernetes_service has been configured without cluster integration' do
let!(:project) { create(:project) }
let(:cluster) { build(:cluster, provider_type: :gcp, platform_type: :kubernetes, platform_kubernetes: platform, provider_gcp: provider, projects: [project]) }
let(:platform) { build(:cluster_platform_kubernetes, :configured, api_url: 'https://111.111.111.111') }
let(:provider) { build(:cluster_provider_gcp) }
before do
create(:kubernetes_service, project: project)
end
it 'raises an error' do
expect { cluster.save! }.to raise_error('Kubernetes service already configured')
end
end
end
describe '#actual_namespace' do
subject { kubernetes.actual_namespace }
......
......@@ -327,15 +327,28 @@ describe Environment do
context 'when the enviroment is available' do
context 'with a deployment service' do
let(:project) { create(:kubernetes_project) }
shared_examples 'same behavior between KubernetesService and Platform::Kubernetes' do
context 'and a deployment' do
let!(:deployment) { create(:deployment, environment: environment) }
it { is_expected.to be_truthy }
end
context 'and a deployment' do
let!(:deployment) { create(:deployment, environment: environment) }
it { is_expected.to be_truthy }
context 'but no deployments' do
it { is_expected.to be_falsy }
end
end
context 'but no deployments' do
it { is_expected.to be_falsy }
context 'when user configured kubernetes from Integration > Kubernetes' do
let(:project) { create(:kubernetes_project) }
it_behaves_like 'same behavior between KubernetesService and Platform::Kubernetes'
end
context 'when user configured kubernetes from CI/CD > Clusters' do
let!(:cluster) { create(:cluster, :project, :provided_by_gcp) }
let(:project) { cluster.project }
it_behaves_like 'same behavior between KubernetesService and Platform::Kubernetes'
end
end
......@@ -356,7 +369,6 @@ describe Environment do
end
describe '#terminals' do
let(:project) { create(:kubernetes_project) }
subject { environment.terminals }
context 'when the environment has terminals' do
......@@ -364,12 +376,27 @@ describe Environment do
allow(environment).to receive(:deployment_service_ready?).and_return(true)
end
it 'returns the terminals from the deployment service' do
expect(project.deployment_service)
.to receive(:terminals).with(environment)
.and_return(:fake_terminals)
shared_examples 'same behavior between KubernetesService and Platform::Kubernetes' do
it 'returns the terminals from the deployment service' do
expect(project.deployment_platform)
.to receive(:terminals).with(environment)
.and_return(:fake_terminals)
is_expected.to eq(:fake_terminals)
end
end
context 'when user configured kubernetes from Integration > Kubernetes' do
let(:project) { create(:kubernetes_project) }
it_behaves_like 'same behavior between KubernetesService and Platform::Kubernetes'
end
context 'when user configured kubernetes from CI/CD > Clusters' do
let!(:cluster) { create(:cluster, :project, :provided_by_gcp) }
let(:project) { cluster.project }
is_expected.to eq(:fake_terminals)
it_behaves_like 'same behavior between KubernetesService and Platform::Kubernetes'
end
end
......
......@@ -4,8 +4,8 @@ describe KubernetesService, :use_clean_rails_memory_store_caching do
include KubernetesHelpers
include ReactiveCachingHelpers
let(:project) { build_stubbed(:kubernetes_project) }
let(:service) { project.kubernetes_service }
let(:project) { create(:kubernetes_project) }
let(:service) { project.deployment_platform }
describe 'Associations' do
it { is_expected.to belong_to :project }
......
......@@ -75,7 +75,6 @@ describe Project do
it { is_expected.to have_many(:project_group_links) }
it { is_expected.to have_many(:notification_settings).dependent(:delete_all) }
it { is_expected.to have_many(:forks).through(:forked_project_links) }
it { is_expected.to have_many(:approver_groups).dependent(:destroy) }
it { is_expected.to have_many(:uploads).dependent(:destroy) }
it { is_expected.to have_many(:pipeline_schedules) }
it { is_expected.to have_many(:members_and_requesters) }
......@@ -101,6 +100,15 @@ describe Project do
let(:namespace) { project }
end
end
describe '#boards' do
it 'raises an error when attempting to add more than one board to the project' do
subject.boards.build
expect { subject.boards.build }.to raise_error(Project::BoardLimitExceeded, 'Number of permitted boards exceeded')
expect(subject.boards.size).to eq 1
end
end
end
describe 'modules' do
......@@ -114,18 +122,6 @@ describe Project do
it { is_expected.to include_module(Sortable) }
end
describe 'scopes' do
context '#with_wiki_enabled' do
it 'returns a project' do
project = create(:project_empty_repo, wiki_access_level: ProjectFeature::ENABLED)
project1 = create(:project, wiki_access_level: ProjectFeature::DISABLED)
expect(described_class.with_wiki_enabled).to include(project)
expect(described_class.with_wiki_enabled).not_to include(project1)
end
end
end
describe 'validation' do
let!(:project) { create(:project) }
......@@ -191,28 +187,6 @@ describe Project do
end
end
context '#mark_stuck_remote_mirrors_as_failed!' do
it 'fails stuck remote mirrors' do
project = create(:project, :repository, :remote_mirror)
project.remote_mirrors.first.update_attributes(
update_status: :started,
last_update_at: 2.days.ago
)
expect do
project.mark_stuck_remote_mirrors_as_failed!
end.to change { project.remote_mirrors.stuck.count }.from(1).to(0)
end
end
context 'mirror' do
subject { build(:project, mirror: true) }
it { is_expected.to validate_presence_of(:import_url) }
it { is_expected.to validate_presence_of(:mirror_user) }
end
it 'does not allow an invalid URI as import_url' do
project2 = build(:project, import_url: 'invalid://')
......@@ -257,18 +231,6 @@ describe Project do
expect(project2.errors[:import_url]).to include('imports are not allowed from that URL')
end
it 'creates mirror data when enabled' do
project2 = create(:project, :mirror, mirror: false)
expect { project2.update_attributes(mirror: true) }.to change { ProjectMirrorData.count }.from(0).to(1)
end
it 'destroys mirror data when disabled' do
project2 = create(:project, :mirror)
expect { project2.update_attributes(mirror: false) }.to change { ProjectMirrorData.count }.from(1).to(0)
end
describe 'project pending deletion' do
let!(:project_pending_deletion) do
create(:project,
......@@ -489,14 +451,6 @@ describe Project do
end
end
describe "#kerberos_url_to_repo" do
let(:project) { create(:project, path: "somewhere") }
it 'returns valid kerberos url for this repo' do
expect(project.kerberos_url_to_repo).to eq("#{Gitlab.config.build_gitlab_kerberos_url}/#{project.namespace.path}/somewhere.git")
end
end
describe "#new_issue_address" do
let(:project) { create(:project, path: "somewhere") }
let(:user) { create(:user) }
......@@ -677,92 +631,6 @@ describe Project do
end
end
describe 'repository size restrictions' do
let(:project) { build(:project) }
before do
allow_any_instance_of(ApplicationSetting).to receive(:repository_size_limit).and_return(50)
end
describe '#changes_will_exceed_size_limit?' do
before do
allow(project).to receive(:repository_and_lfs_size).and_return(49)
end
it 'returns true when changes go over' do
expect(project.changes_will_exceed_size_limit?(5)).to be_truthy
end
end
describe '#actual_size_limit' do
it 'returns the limit set in the application settings' do
expect(project.actual_size_limit).to eq(50)
end
it 'returns the value set in the group' do
group = create(:group, repository_size_limit: 100)
project.update_attribute(:namespace_id, group.id)
expect(project.actual_size_limit).to eq(100)
end
it 'returns the value set locally' do
project.update_attribute(:repository_size_limit, 75)
expect(project.actual_size_limit).to eq(75)
end
end
describe '#size_limit_enabled?' do
it 'returns false when disabled' do
project.update_attribute(:repository_size_limit, 0)
expect(project.size_limit_enabled?).to be_falsey
end
it 'returns true when a limit is set' do
project.update_attribute(:repository_size_limit, 75)
expect(project.size_limit_enabled?).to be_truthy
end
end
describe '#above_size_limit?' do
let(:project) do
create(:project,
statistics: build(:project_statistics))
end
it 'returns true when above the limit' do
allow(project).to receive(:repository_and_lfs_size).and_return(100)
expect(project.above_size_limit?).to be_truthy
end
it 'returns false when not over the limit' do
expect(project.above_size_limit?).to be_falsey
end
end
describe '#size_to_remove' do
it 'returns the correct value' do
allow(project).to receive(:repository_and_lfs_size).and_return(100)
expect(project.size_to_remove).to eq(50)
end
end
end
describe '#repository_size_limit column' do
it 'support values up to 8 exabytes' do
project = create(:project)
project.update_column(:repository_size_limit, 8.exabytes - 1)
project.reload
expect(project.repository_size_limit).to eql(8.exabytes - 1)
end
end
describe '#default_issues_tracker?' do
it "is true if used internal tracker" do
project = build(:project)
......@@ -1020,18 +888,6 @@ describe Project do
expect(project.avatar_url).to eq(project.avatar.url)
expect(project.avatar_url(only_path: false)).to eq([Gitlab.config.gitlab.url, project.avatar.url].join)
end
context 'When in a geo secondary node' do
let(:geo_url) { 'http://geo.example.com' }
let(:avatar_path) { project.avatar_path(only_path: true) }
before do
allow(Gitlab::Geo).to receive(:secondary?) { true }
allow(Gitlab::Geo).to receive_message_chain(:primary_node, :url) { geo_url }
end
it { is_expected.to eq "#{geo_url}#{avatar_path}" }
end
end
context 'when avatar file in git' do
......@@ -1547,28 +1403,6 @@ describe Project do
end
end
describe 'handling import URL' do
context 'when project is a mirror' do
it 'returns the full URL' do
project = create(:project, :mirror, import_url: 'http://user:pass@test.com')
project.import_finish
expect(project.reload.import_url).to eq('http://user:pass@test.com')
end
end
context 'when project is not a mirror' do
it 'returns the sanitized URL' do
project = create(:project, import_status: 'started', import_url: 'http://user:pass@test.com')
project.import_finish
expect(project.reload.import_url).to eq('http://test.com')
end
end
end
describe '#user_can_push_to_empty_repo?' do
let(:project) { create(:project) }
let(:user) { create(:user) }
......@@ -1739,18 +1573,6 @@ describe Project do
expect { project.import_schedule }.to change { project.import_jid }
expect(project.reload.import_status).to eq('finished')
end
context 'with a mirrored project' do
let(:project) { create(:project, :mirror) }
it 'calls RepositoryImportWorker and inserts in front of the mirror scheduler queue' do
allow_any_instance_of(described_class).to receive(:repository_exists?).and_return(false, true)
expect_any_instance_of(EE::Project).to receive(:force_import_job!)
expect_any_instance_of(RepositoryImportWorker).to receive(:perform).with(project.id).and_call_original
expect { project.import_schedule }.to change { project.import_jid }
end
end
end
describe 'project import state transitions' do
......@@ -1800,46 +1622,6 @@ describe Project do
expect(housekeeping_service).not_to have_received(:execute)
end
context 'elasticsearch indexing disabled' do
before do
stub_application_setting(elasticsearch_indexing: false)
end
it 'does not index the repository' do
project = create(:project, :import_started, import_type: :github)
expect(ElasticCommitIndexerWorker).not_to receive(:perform_async)
project.import_finish
end
end
context 'elasticsearch indexing enabled' do
let(:project) { create(:project, :import_started, import_type: :github) }
before do
stub_application_setting(elasticsearch_indexing: true)
end
context 'no index status' do
it 'schedules a full index of the repository' do
expect(ElasticCommitIndexerWorker).to receive(:perform_async).with(project.id, nil)
project.import_finish
end
end
context 'with index status' do
let!(:index_status) { project.create_index_status!(indexed_at: Time.now, last_commit: 'foo') }
it 'schedules a progressive index of the repository' do
expect(ElasticCommitIndexerWorker).to receive(:perform_async).with(project.id, index_status.last_commit)
project.import_finish
end
end
end
end
end
......@@ -1939,32 +1721,6 @@ describe Project do
expect(project.add_import_job).to eq(import_jid)
end
context 'without mirror' do
it 'returns nil' do
project = create(:project)
expect(project.add_import_job).to be nil
end
end
context 'without repository' do
it 'schedules RepositoryImportWorker' do
project = create(:project, import_url: generate(:url))
expect(RepositoryImportWorker).to receive(:perform_async).with(project.id).and_return(import_jid)
expect(project.add_import_job).to eq(import_jid)
end
end
context 'with mirror' do
it 'schedules RepositoryUpdateMirrorWorker' do
project = create(:project, :mirror, :repository)
expect(RepositoryUpdateMirrorWorker).to receive(:perform_async).with(project.id).and_return(import_jid)
expect(project.add_import_job).to eq(import_jid)
end
end
end
context 'not forked' do
......@@ -2066,96 +1822,6 @@ describe Project do
end
end
describe '.where_full_path_in' do
context 'without any paths' do
it 'returns an empty relation' do
expect(described_class.where_full_path_in([])).to eq([])
end
end
context 'without any valid paths' do
it 'returns an empty relation' do
expect(described_class.where_full_path_in(%w[foo])).to eq([])
end
end
context 'with valid paths' do
let!(:project1) { create(:project) }
let!(:project2) { create(:project) }
it 'returns the projects matching the paths' do
projects = described_class.where_full_path_in([project1.full_path,
project2.full_path])
expect(projects).to contain_exactly(project1, project2)
end
it 'returns projects regardless of the casing of paths' do
projects = described_class.where_full_path_in([project1.full_path.upcase,
project2.full_path.upcase])
expect(projects).to contain_exactly(project1, project2)
end
end
end
describe '#find_path_lock' do
let(:project) { create :project }
let(:path_lock) { create :path_lock, project: project }
let(:path) { path_lock.path }
it 'returns path_lock' do
expect(project.find_path_lock(path)).to eq(path_lock)
end
it 'returns nil' do
expect(project.find_path_lock('app/controllers')).to be_falsey
end
end
describe '#change_repository_storage' do
let(:project) { create(:project, :repository) }
let(:read_only_project) { create(:project, :repository, repository_read_only: true) }
before do
FileUtils.mkdir('tmp/tests/extra_storage')
stub_storage_settings('extra' => { 'path' => 'tmp/tests/extra_storage' })
end
after do
FileUtils.rm_rf('tmp/tests/extra_storage')
end
it 'schedule the transfer of the repository to the new storage and locks the project' do
expect(ProjectUpdateRepositoryStorageWorker).to receive(:perform_async).with(project.id, 'extra')
project.change_repository_storage('extra')
project.save
expect(project).to be_repository_read_only
end
it "doesn't schedule the transfer if the repository is already read-only" do
expect(ProjectUpdateRepositoryStorageWorker).not_to receive(:perform_async)
read_only_project.change_repository_storage('extra')
read_only_project.save
end
it "doesn't lock or schedule the transfer if the storage hasn't changed" do
expect(ProjectUpdateRepositoryStorageWorker).not_to receive(:perform_async)
project.change_repository_storage(project.repository_storage)
project.save
expect(project).not_to be_repository_read_only
end
it 'throws an error if an invalid repository storage is provided' do
expect { project.change_repository_storage('unknown') }.to raise_error(ArgumentError)
end
end
describe '#change_head' do
let(:project) { create(:project, :repository) }
......@@ -2310,35 +1976,6 @@ describe Project do
end
end
describe '#repository_and_lfs_size' do
let(:project) { create(:project, :repository) }
let(:size) { 50 }
before do
allow(project.statistics).to receive(:total_repository_size).and_return(size)
end
it 'returns the total repository and lfs size' do
expect(project.repository_and_lfs_size).to eq(size)
end
end
describe '#approver_group_ids=' do
let(:project) { create(:project) }
it 'create approver_groups' do
group = create :group
group1 = create :group
project = create :project
project.approver_group_ids = "#{group.id}, #{group1.id}"
project.save!
expect(project.approver_groups.map(&:group)).to match_array([group, group1])
end
end
describe '#reset_pushes_since_gc' do
let(:project) { create(:project) }
......@@ -2365,10 +2002,10 @@ describe Project do
end
context 'when project has a deployment service' do
shared_examples 'correct behavior with variables' do
shared_examples 'same behavior between KubernetesService and Platform::Kubernetes' do
it 'returns variables from this service' do
expect(project.deployment_variables).to include(
{ key: 'KUBE_TOKEN', value: project.kubernetes_service.token, public: false }
{ key: 'KUBE_TOKEN', value: project.deployment_platform.token, public: false }
)
end
end
......@@ -2376,14 +2013,14 @@ describe Project do
context 'when user configured kubernetes from Integration > Kubernetes' do
let(:project) { create(:kubernetes_project) }
it_behaves_like 'correct behavior with variables'
it_behaves_like 'same behavior between KubernetesService and Platform::Kubernetes'
end
context 'when user configured kubernetes from CI/CD > Clusters' do
let!(:cluster) { create(:cluster, :project, :provided_by_gcp) }
let(:project) { cluster.project }
it_behaves_like 'correct behavior with variables'
it_behaves_like 'same behavior between KubernetesService and Platform::Kubernetes'
end
end
end
......@@ -2492,16 +2129,6 @@ describe Project do
end
end
describe '#create_mirror_data' do
it 'it is called after save' do
project = create(:project)
expect(project).to receive(:create_mirror_data)
project.update(mirror: true, mirror_user: project.owner, import_url: 'http://foo.com')
end
end
describe 'inside_path' do
let!(:project1) { create(:project, namespace: create(:namespace, path: 'name_pace')) }
let!(:project2) { create(:project) }
......@@ -3470,26 +3097,22 @@ describe Project do
end
end
describe '#root_namespace' do
let(:project) { build(:project, namespace: parent) }
describe '#deployment_platform' do
subject { project.deployment_platform }
subject { project.root_namespace }
let(:project) { create(:project) }
context 'when namespace has parent group' do
let(:root_ancestor) { create(:group) }
let(:parent) { build(:group, parent: root_ancestor) }
context 'when user configured kubernetes from Integration > Kubernetes' do
let!(:kubernetes_service) { create(:kubernetes_service, project: project) }
it 'returns root ancestor' do
is_expected.to eq(root_ancestor)
end
it { is_expected.to eq(kubernetes_service) }
end
context 'when namespace is root ancestor' do
let(:parent) { build(:group) }
context 'when user configured kubernetes from CI/CD > Clusters' do
let!(:cluster) { create(:cluster, :provided_by_gcp, projects: [project]) }
let(:platform_kubernetes) { cluster.platform_kubernetes }
it 'returns current namespace' do
is_expected.to eq(parent)
end
it { is_expected.to eq(platform_kubernetes) }
end
end
end
......@@ -41,9 +41,9 @@ RSpec.shared_examples 'additional metrics query' do
end
describe 'project has Kubernetes service' do
shared_examples 'correct behavior with metrics' do
shared_examples 'same behavior between KubernetesService and Platform::Kubernetes' do
let(:environment) { create(:environment, slug: 'environment-slug', project: project) }
let(:kube_namespace) { project.kubernetes_service.actual_namespace }
let(:kube_namespace) { project.deployment_platform.actual_namespace }
it_behaves_like 'query context containing environment slug and filter'
......@@ -57,14 +57,14 @@ RSpec.shared_examples 'additional metrics query' do
context 'when user configured kubernetes from Integration > Kubernetes' do
let(:project) { create(:kubernetes_project) }
it_behaves_like 'correct behavior with metrics'
it_behaves_like 'same behavior between KubernetesService and Platform::Kubernetes'
end
context 'when user configured kubernetes from CI/CD > Clusters' do
let!(:cluster) { create(:cluster, :project, :provided_by_gcp) }
let(:project) { cluster.project }
it_behaves_like 'correct behavior with metrics'
it_behaves_like 'same behavior between KubernetesService and Platform::Kubernetes'
end
end
......
......@@ -35,7 +35,7 @@ describe 'projects/pipelines_settings/_show' do
context 'when kubernetes is active' do
before do
project.build_kubernetes_service(active: true)
create(:kubernetes_service, project: project)
end
context 'when auto devops domain is not defined' do
......
require 'spec_helper'
describe ReactiveCachingWorker do
let(:project) { create(:kubernetes_project) }
let(:service) { project.deployment_service }
subject { described_class.new.perform("KubernetesService", service.id) }
let(:service) { project.deployment_platform }
describe '#perform' do
it 'calls #exclusively_update_reactive_cache!' do
expect_any_instance_of(KubernetesService).to receive(:exclusively_update_reactive_cache!)
context 'when user configured kubernetes from Integration > Kubernetes' do
let(:project) { create(:kubernetes_project) }
subject
it 'calls #exclusively_update_reactive_cache!' do
expect_any_instance_of(KubernetesService).to receive(:exclusively_update_reactive_cache!)
described_class.new.perform("KubernetesService", service.id)
end
end
context 'when user configured kubernetes from CI/CD > Clusters' do
let!(:cluster) { create(:cluster, :project, :provided_by_gcp) }
let(:project) { cluster.project }
it 'calls #exclusively_update_reactive_cache!' do
expect_any_instance_of(Clusters::Platforms::Kubernetes).to receive(:exclusively_update_reactive_cache!)
described_class.new.perform("Clusters::Platforms::Kubernetes", service.id)
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