diff options
author | GitLab Bot <gitlab-bot@gitlab.com> | 2022-02-18 09:45:46 +0000 |
---|---|---|
committer | GitLab Bot <gitlab-bot@gitlab.com> | 2022-02-18 09:45:46 +0000 |
commit | a7b3560714b4d9cc4ab32dffcd1f74a284b93580 (patch) | |
tree | 7452bd5c3545c2fa67a28aa013835fb4fa071baf /spec/services/google_cloud | |
parent | ee9173579ae56a3dbfe5afe9f9410c65bb327ca7 (diff) | |
download | gitlab-ce-a7b3560714b4d9cc4ab32dffcd1f74a284b93580.tar.gz |
Add latest changes from gitlab-org/gitlab@14-8-stable-eev14.8.0-rc42
Diffstat (limited to 'spec/services/google_cloud')
3 files changed, 281 insertions, 6 deletions
diff --git a/spec/services/google_cloud/create_service_accounts_service_spec.rb b/spec/services/google_cloud/create_service_accounts_service_spec.rb index 190e1a8098c..53d21df713a 100644 --- a/spec/services/google_cloud/create_service_accounts_service_spec.rb +++ b/spec/services/google_cloud/create_service_accounts_service_spec.rb @@ -2,22 +2,26 @@ require 'spec_helper' -# Mock Types -MockGoogleOAuth2Credentials = Struct.new(:app_id, :app_secret) -MockServiceAccount = Struct.new(:project_id, :unique_id) - RSpec.describe GoogleCloud::CreateServiceAccountsService do describe '#execute' do before do + mock_google_oauth2_creds = Struct.new(:app_id, :app_secret) + .new('mock-app-id', 'mock-app-secret') allow(Gitlab::Auth::OAuth::Provider).to receive(:config_for) .with('google_oauth2') - .and_return(MockGoogleOAuth2Credentials.new('mock-app-id', 'mock-app-secret')) + .and_return(mock_google_oauth2_creds) allow_next_instance_of(GoogleApi::CloudPlatform::Client) do |client| + mock_service_account = Struct.new(:project_id, :unique_id, :email) + .new('mock-project-id', 'mock-unique-id', 'mock-email') allow(client).to receive(:create_service_account) - .and_return(MockServiceAccount.new('mock-project-id', 'mock-unique-id')) + .and_return(mock_service_account) + allow(client).to receive(:create_service_account_key) .and_return('mock-key') + + allow(client) + .to receive(:grant_service_account_roles) end end diff --git a/spec/services/google_cloud/enable_cloud_run_service_spec.rb b/spec/services/google_cloud/enable_cloud_run_service_spec.rb new file mode 100644 index 00000000000..6d2b1f5cfd5 --- /dev/null +++ b/spec/services/google_cloud/enable_cloud_run_service_spec.rb @@ -0,0 +1,41 @@ +# frozen_string_literal: true + +require 'spec_helper' + +RSpec.describe GoogleCloud::EnableCloudRunService do + describe 'when a project does not have any gcp projects' do + let_it_be(:project) { create(:project) } + + it 'returns error' do + result = described_class.new(project).execute + + expect(result[:status]).to eq(:error) + expect(result[:message]).to eq('No GCP projects found. Configure a service account or GCP_PROJECT_ID ci variable.') + end + end + + describe 'when a project has 3 gcp projects' do + let_it_be(:project) { create(:project) } + + before do + project.variables.build(environment_scope: 'production', key: 'GCP_PROJECT_ID', value: 'prj-prod') + project.variables.build(environment_scope: 'staging', key: 'GCP_PROJECT_ID', value: 'prj-staging') + project.save! + end + + it 'enables cloud run, artifacts registry and cloud build', :aggregate_failures do + expect_next_instance_of(GoogleApi::CloudPlatform::Client) do |instance| + expect(instance).to receive(:enable_cloud_run).with('prj-prod') + expect(instance).to receive(:enable_artifacts_registry).with('prj-prod') + expect(instance).to receive(:enable_cloud_build).with('prj-prod') + expect(instance).to receive(:enable_cloud_run).with('prj-staging') + expect(instance).to receive(:enable_artifacts_registry).with('prj-staging') + expect(instance).to receive(:enable_cloud_build).with('prj-staging') + end + + result = described_class.new(project).execute + + expect(result[:status]).to eq(:success) + end + end +end diff --git a/spec/services/google_cloud/generate_pipeline_service_spec.rb b/spec/services/google_cloud/generate_pipeline_service_spec.rb new file mode 100644 index 00000000000..75494f229b5 --- /dev/null +++ b/spec/services/google_cloud/generate_pipeline_service_spec.rb @@ -0,0 +1,230 @@ +# frozen_string_literal: true + +require 'spec_helper' + +RSpec.describe GoogleCloud::GeneratePipelineService do + describe 'for cloud-run' do + describe 'when there is no existing pipeline' do + let_it_be(:project) { create(:project, :repository) } + let_it_be(:maintainer) { create(:user) } + let_it_be(:service_params) { { action: described_class::ACTION_DEPLOY_TO_CLOUD_RUN } } + let_it_be(:service) { described_class.new(project, maintainer, service_params) } + + before do + project.add_maintainer(maintainer) + end + + it 'creates a new branch with commit for cloud-run deployment' do + response = service.execute + + branch_name = response[:branch_name] + commit = response[:commit] + local_branches = project.repository.local_branches + created_branch = local_branches.find { |branch| branch.name == branch_name } + + expect(response[:status]).to eq(:success) + expect(branch_name).to start_with('deploy-to-cloud-run-') + expect(created_branch).to be_present + expect(created_branch.target).to eq(commit[:result]) + end + + it 'generated pipeline includes cloud-run deployment' do + response = service.execute + + ref = response[:commit][:result] + gitlab_ci_yml = project.repository.gitlab_ci_yml_for(ref) + + expect(response[:status]).to eq(:success) + expect(gitlab_ci_yml).to include('https://gitlab.com/gitlab-org/incubation-engineering/five-minute-production/library/-/raw/main/gcp/cloud-run.gitlab-ci.yml') + end + + context 'simulate errors' do + it 'fails to create branch' do + allow_next_instance_of(Branches::CreateService) do |create_service| + allow(create_service).to receive(:execute) + .and_return({ status: :error }) + end + + response = service.execute + expect(response[:status]).to eq(:error) + end + + it 'fails to commit changes' do + allow_next_instance_of(Files::CreateService) do |create_service| + allow(create_service).to receive(:execute) + .and_return({ status: :error }) + end + + response = service.execute + expect(response[:status]).to eq(:error) + end + end + end + + describe 'when there is an existing pipeline without `deploy` stage' do + let_it_be(:project) { create(:project, :repository) } + let_it_be(:maintainer) { create(:user) } + let_it_be(:service_params) { { action: GoogleCloud::GeneratePipelineService::ACTION_DEPLOY_TO_CLOUD_RUN } } + let_it_be(:service) { described_class.new(project, maintainer, service_params) } + + before do + project.add_maintainer(maintainer) + + file_name = '.gitlab-ci.yml' + file_content = <<EOF +stages: + - build + - test + +build-java: + stage: build + script: mvn clean install + +test-java: + stage: test + script: mvn clean test +EOF + project.repository.create_file(maintainer, + file_name, + file_content, + message: 'Pipeline with three stages and two jobs', + branch_name: project.default_branch) + end + + it 'introduces a `deploy` stage and includes the deploy-to-cloud-run job' do + response = service.execute + + branch_name = response[:branch_name] + gitlab_ci_yml = project.repository.gitlab_ci_yml_for(branch_name) + pipeline = Gitlab::Config::Loader::Yaml.new(gitlab_ci_yml).load! + + expect(response[:status]).to eq(:success) + expect(pipeline[:stages]).to eq(%w[build test deploy]) + expect(pipeline[:include]).to be_present + expect(gitlab_ci_yml).to include('https://gitlab.com/gitlab-org/incubation-engineering/five-minute-production/library/-/raw/main/gcp/cloud-run.gitlab-ci.yml') + end + end + + describe 'when there is an existing pipeline with `deploy` stage' do + let_it_be(:project) { create(:project, :repository) } + let_it_be(:maintainer) { create(:user) } + let_it_be(:service_params) { { action: GoogleCloud::GeneratePipelineService::ACTION_DEPLOY_TO_CLOUD_RUN } } + let_it_be(:service) { described_class.new(project, maintainer, service_params) } + + before do + project.add_maintainer(maintainer) + + file_name = '.gitlab-ci.yml' + file_content = <<EOF +stages: + - build + - test + - deploy + +build-java: + stage: build + script: mvn clean install + +test-java: + stage: test + script: mvn clean test +EOF + project.repository.create_file(maintainer, + file_name, + file_content, + message: 'Pipeline with three stages and two jobs', + branch_name: project.default_branch) + end + + it 'includes the deploy-to-cloud-run job' do + response = service.execute + + branch_name = response[:branch_name] + gitlab_ci_yml = project.repository.gitlab_ci_yml_for(branch_name) + pipeline = Gitlab::Config::Loader::Yaml.new(gitlab_ci_yml).load! + + expect(response[:status]).to eq(:success) + expect(pipeline[:stages]).to eq(%w[build test deploy]) + expect(pipeline[:include]).to be_present + expect(gitlab_ci_yml).to include('https://gitlab.com/gitlab-org/incubation-engineering/five-minute-production/library/-/raw/main/gcp/cloud-run.gitlab-ci.yml') + end + end + + describe 'when there is an existing pipeline with `includes`' do + let_it_be(:project) { create(:project, :repository) } + let_it_be(:maintainer) { create(:user) } + let_it_be(:service_params) { { action: GoogleCloud::GeneratePipelineService::ACTION_DEPLOY_TO_CLOUD_RUN } } + let_it_be(:service) { described_class.new(project, maintainer, service_params) } + + before do + project.add_maintainer(maintainer) + + file_name = '.gitlab-ci.yml' + file_content = <<EOF +stages: + - build + - test + - deploy + +include: + local: 'some-pipeline.yml' +EOF + project.repository.create_file(maintainer, + file_name, + file_content, + message: 'Pipeline with three stages and two jobs', + branch_name: project.default_branch) + end + + it 'includes the deploy-to-cloud-run job' do + response = service.execute + + branch_name = response[:branch_name] + gitlab_ci_yml = project.repository.gitlab_ci_yml_for(branch_name) + pipeline = Gitlab::Config::Loader::Yaml.new(gitlab_ci_yml).load! + + expect(response[:status]).to eq(:success) + expect(pipeline[:stages]).to eq(%w[build test deploy]) + expect(pipeline[:include]).to be_present + expect(gitlab_ci_yml).to include('https://gitlab.com/gitlab-org/incubation-engineering/five-minute-production/library/-/raw/main/gcp/cloud-run.gitlab-ci.yml') + end + end + end + + describe 'for cloud-storage' do + describe 'when there is no existing pipeline' do + let_it_be(:project) { create(:project, :repository) } + let_it_be(:maintainer) { create(:user) } + let_it_be(:service_params) { { action: GoogleCloud::GeneratePipelineService::ACTION_DEPLOY_TO_CLOUD_STORAGE } } + let_it_be(:service) { described_class.new(project, maintainer, service_params) } + + before do + project.add_maintainer(maintainer) + end + + it 'creates a new branch with commit for cloud-storage deployment' do + response = service.execute + + branch_name = response[:branch_name] + commit = response[:commit] + local_branches = project.repository.local_branches + search_for_created_branch = local_branches.find { |branch| branch.name == branch_name } + + expect(response[:status]).to eq(:success) + expect(branch_name).to start_with('deploy-to-cloud-storage-') + expect(search_for_created_branch).to be_present + expect(search_for_created_branch.target).to eq(commit[:result]) + end + + it 'generated pipeline includes cloud-storage deployment' do + response = service.execute + + ref = response[:commit][:result] + gitlab_ci_yml = project.repository.gitlab_ci_yml_for(ref) + + expect(response[:status]).to eq(:success) + expect(gitlab_ci_yml).to include('https://gitlab.com/gitlab-org/incubation-engineering/five-minute-production/library/-/raw/main/gcp/cloud-storage.gitlab-ci.yml') + end + end + end +end |