diff options
Diffstat (limited to 'spec/services/clusters/parse_cluster_applications_artifact_service_spec.rb')
-rw-r--r-- | spec/services/clusters/parse_cluster_applications_artifact_service_spec.rb | 200 |
1 files changed, 200 insertions, 0 deletions
diff --git a/spec/services/clusters/parse_cluster_applications_artifact_service_spec.rb b/spec/services/clusters/parse_cluster_applications_artifact_service_spec.rb new file mode 100644 index 00000000000..f14c929554a --- /dev/null +++ b/spec/services/clusters/parse_cluster_applications_artifact_service_spec.rb @@ -0,0 +1,200 @@ +# frozen_string_literal: true + +require 'spec_helper' + +describe Clusters::ParseClusterApplicationsArtifactService do + let_it_be(:project) { create(:project) } + let_it_be(:user) { create(:user) } + + before do + project.add_maintainer(user) + end + + describe 'RELEASE_NAMES' do + it 'is included in Cluster application names', :aggregate_failures do + described_class::RELEASE_NAMES.each do |release_name| + expect(Clusters::Cluster::APPLICATIONS).to include(release_name) + end + end + end + + describe '.new' do + let(:job) { build(:ci_build) } + + it 'sets the project and current user', :aggregate_failures do + service = described_class.new(job, user) + + expect(service.project).to eq(job.project) + expect(service.current_user).to eq(user) + end + end + + describe '#execute' do + let_it_be(:cluster, reload: true) { create(:cluster, projects: [project]) } + let_it_be(:deployment, reload: true) { create(:deployment, cluster: cluster) } + + let(:job) { deployment.deployable } + let(:artifact) { create(:ci_job_artifact, :cluster_applications, job: job) } + + context 'when cluster_applications_artifact feature flag is disabled' do + before do + stub_feature_flags(cluster_applications_artifact: false) + end + + it 'does not call Gitlab::Kubernetes::Helm::Parsers::ListV2 and returns success immediately' do + expect(Gitlab::Kubernetes::Helm::Parsers::ListV2).not_to receive(:new) + + result = described_class.new(job, user).execute(artifact) + + expect(result[:status]).to eq(:success) + end + end + + context 'when cluster_applications_artifact feature flag is enabled for project' do + before do + stub_feature_flags(cluster_applications_artifact: job.project) + end + + it 'calls Gitlab::Kubernetes::Helm::Parsers::ListV2' do + expect(Gitlab::Kubernetes::Helm::Parsers::ListV2).to receive(:new).and_call_original + + result = described_class.new(job, user).execute(artifact) + + expect(result[:status]).to eq(:success) + end + + context 'artifact is not of cluster_applications type' do + let(:artifact) { create(:ci_job_artifact, :archive) } + let(:job) { artifact.job } + + it 'raise ArgumentError' do + expect do + described_class.new(job, user).execute(artifact) + end.to raise_error(ArgumentError, 'Artifact is not cluster_applications file type') + end + end + + context 'artifact exceeds acceptable size' do + it 'returns an error' do + stub_const("#{described_class}::MAX_ACCEPTABLE_ARTIFACT_SIZE", 1.byte) + + result = described_class.new(job, user).execute(artifact) + + expect(result[:status]).to eq(:error) + expect(result[:message]).to eq('Cluster_applications artifact too big. Maximum allowable size: 1 Byte') + end + end + + context 'job has no deployment cluster' do + let(:job) { build(:ci_build) } + + it 'returns an error' do + result = described_class.new(job, user).execute(artifact) + + expect(result[:status]).to eq(:error) + expect(result[:message]).to eq('No deployment cluster found for this job') + end + end + + context 'job has deployment cluster' do + context 'current user does not have access to deployment cluster' do + let(:other_user) { create(:user) } + + it 'returns an error' do + result = described_class.new(job, other_user).execute(artifact) + + expect(result[:status]).to eq(:error) + expect(result[:message]).to eq('No deployment cluster found for this job') + end + end + + context 'release is missing' do + let(:fixture) { 'spec/fixtures/helm/helm_list_v2_prometheus_missing.json.gz' } + let(:file) { fixture_file_upload(Rails.root.join(fixture)) } + let(:artifact) { create(:ci_job_artifact, :cluster_applications, job: job, file: file) } + + context 'application does not exist' do + it 'does not create or destroy an application' do + expect do + described_class.new(job, user).execute(artifact) + end.not_to change(Clusters::Applications::Prometheus, :count) + end + end + + context 'application exists' do + before do + create(:clusters_applications_prometheus, :installed, cluster: cluster) + end + + it 'marks the application as uninstalled' do + described_class.new(job, user).execute(artifact) + + cluster.application_prometheus.reload + expect(cluster.application_prometheus).to be_uninstalled + end + end + end + + context 'release is deployed' do + let(:fixture) { 'spec/fixtures/helm/helm_list_v2_prometheus_deployed.json.gz' } + let(:file) { fixture_file_upload(Rails.root.join(fixture)) } + let(:artifact) { create(:ci_job_artifact, :cluster_applications, job: job, file: file) } + + context 'application does not exist' do + it 'creates an application and marks it as installed' do + expect do + described_class.new(job, user).execute(artifact) + end.to change(Clusters::Applications::Prometheus, :count) + + expect(cluster.application_prometheus).to be_persisted + expect(cluster.application_prometheus).to be_installed + end + end + + context 'application exists' do + before do + create(:clusters_applications_prometheus, :errored, cluster: cluster) + end + + it 'marks the application as installed' do + described_class.new(job, user).execute(artifact) + + expect(cluster.application_prometheus).to be_installed + end + end + end + + context 'release is failed' do + let(:fixture) { 'spec/fixtures/helm/helm_list_v2_prometheus_failed.json.gz' } + let(:file) { fixture_file_upload(Rails.root.join(fixture)) } + let(:artifact) { create(:ci_job_artifact, :cluster_applications, job: job, file: file) } + + context 'application does not exist' do + it 'creates an application and marks it as errored' do + expect do + described_class.new(job, user).execute(artifact) + end.to change(Clusters::Applications::Prometheus, :count) + + expect(cluster.application_prometheus).to be_persisted + expect(cluster.application_prometheus).to be_errored + expect(cluster.application_prometheus.status_reason).to eq('Helm release failed to install') + end + end + + context 'application exists' do + before do + create(:clusters_applications_prometheus, :installed, cluster: cluster) + end + + it 'marks the application as errored' do + described_class.new(job, user).execute(artifact) + + expect(cluster.application_prometheus).to be_errored + expect(cluster.application_prometheus.status_reason).to eq('Helm release failed to install') + end + end + end + end + end + end +end |