diff options
author | Shinya Maeda <shinya@gitlab.com> | 2017-10-30 21:55:18 +0900 |
---|---|---|
committer | Shinya Maeda <shinya@gitlab.com> | 2017-10-30 21:55:18 +0900 |
commit | d6744d98384192799c9b3a97ad0eaf69cb4d25ee (patch) | |
tree | 68cb8a8002448165c350c6556175ba57befabe3a /spec/services | |
parent | 478e59fe8d82b99800a2613aa4d153bf692fbd6b (diff) | |
download | gitlab-ce-d6744d98384192799c9b3a97ad0eaf69cb4d25ee.tar.gz |
specs for services. Improved details.
Diffstat (limited to 'spec/services')
13 files changed, 450 insertions, 372 deletions
diff --git a/spec/services/ci/create_cluster_service_spec.rb b/spec/services/ci/create_cluster_service_spec.rb deleted file mode 100644 index 6e7398fbffa..00000000000 --- a/spec/services/ci/create_cluster_service_spec.rb +++ /dev/null @@ -1,47 +0,0 @@ -require 'spec_helper' - -describe Ci::CreateClusterService do - describe '#execute' do - let(:access_token) { 'xxx' } - let(:project) { create(:project) } - let(:user) { create(:user) } - let(:result) { described_class.new(project, user, params).execute(access_token) } - - context 'when correct params' do - let(:params) do - { - gcp_project_id: 'gcp-project', - gcp_cluster_name: 'test-cluster', - gcp_cluster_zone: 'us-central1-a', - gcp_cluster_size: 1 - } - end - - it 'creates a cluster object' do - expect(ClusterProvisionWorker).to receive(:perform_async) - expect { result }.to change { Gcp::Cluster.count }.by(1) - expect(result.gcp_project_id).to eq('gcp-project') - expect(result.gcp_cluster_name).to eq('test-cluster') - expect(result.gcp_cluster_zone).to eq('us-central1-a') - expect(result.gcp_cluster_size).to eq(1) - expect(result.gcp_token).to eq(access_token) - end - end - - context 'when invalid params' do - let(:params) do - { - gcp_project_id: 'gcp-project', - gcp_cluster_name: 'test-cluster', - gcp_cluster_zone: 'us-central1-a', - gcp_cluster_size: 'ABC' - } - end - - it 'returns an error' do - expect(ClusterProvisionWorker).not_to receive(:perform_async) - expect { result }.to change { Gcp::Cluster.count }.by(0) - end - end - end -end diff --git a/spec/services/ci/fetch_gcp_operation_service_spec.rb b/spec/services/ci/fetch_gcp_operation_service_spec.rb deleted file mode 100644 index 7792979c5cb..00000000000 --- a/spec/services/ci/fetch_gcp_operation_service_spec.rb +++ /dev/null @@ -1,36 +0,0 @@ -require 'spec_helper' -require 'google/apis' - -describe Ci::FetchGcpOperationService do - describe '#execute' do - let(:cluster) { create(:gcp_cluster) } - let(:operation) { double } - - context 'when suceeded' do - before do - allow_any_instance_of(GoogleApi::CloudPlatform::Client) - .to receive(:projects_zones_operations).and_return(operation) - end - - it 'fetch the gcp operaion' do - expect { |b| described_class.new.execute(cluster, &b) } - .to yield_with_args(operation) - end - end - - context 'when raises an error' do - let(:error) { Google::Apis::ServerError.new('a') } - - before do - allow_any_instance_of(GoogleApi::CloudPlatform::Client) - .to receive(:projects_zones_operations).and_raise(error) - end - - it 'sets an error to cluster object' do - expect { |b| described_class.new.execute(cluster, &b) } - .not_to yield_with_args - expect(cluster.reload).to be_errored - end - end - end -end diff --git a/spec/services/ci/fetch_kubernetes_token_service_spec.rb b/spec/services/ci/fetch_kubernetes_token_service_spec.rb deleted file mode 100644 index 1d05c9671a9..00000000000 --- a/spec/services/ci/fetch_kubernetes_token_service_spec.rb +++ /dev/null @@ -1,64 +0,0 @@ -require 'spec_helper' - -describe Ci::FetchKubernetesTokenService do - describe '#execute' do - subject { described_class.new(api_url, ca_pem, username, password).execute } - - let(:api_url) { 'http://111.111.111.111' } - let(:ca_pem) { '' } - let(:username) { 'admin' } - let(:password) { 'xxx' } - - context 'when params correct' do - let(:token) { 'xxx.token.xxx' } - - let(:secrets_json) do - [ - { - 'metadata': { - name: metadata_name - }, - 'data': { - 'token': Base64.encode64(token) - } - } - ] - end - - before do - allow_any_instance_of(Kubeclient::Client) - .to receive(:get_secrets).and_return(secrets_json) - end - - context 'when default-token exists' do - let(:metadata_name) { 'default-token-123' } - - it { is_expected.to eq(token) } - end - - context 'when default-token does not exist' do - let(:metadata_name) { 'another-token-123' } - - it { is_expected.to be_nil } - end - end - - context 'when api_url is nil' do - let(:api_url) { nil } - - it { expect { subject }.to raise_error("Incomplete settings") } - end - - context 'when username is nil' do - let(:username) { nil } - - it { expect { subject }.to raise_error("Incomplete settings") } - end - - context 'when password is nil' do - let(:password) { nil } - - it { expect { subject }.to raise_error("Incomplete settings") } - end - end -end diff --git a/spec/services/ci/finalize_cluster_creation_service_spec.rb b/spec/services/ci/finalize_cluster_creation_service_spec.rb deleted file mode 100644 index def3709fdb4..00000000000 --- a/spec/services/ci/finalize_cluster_creation_service_spec.rb +++ /dev/null @@ -1,61 +0,0 @@ -require 'spec_helper' - -describe Ci::FinalizeClusterCreationService do - describe '#execute' do - let(:cluster) { create(:gcp_cluster) } - let(:result) { described_class.new.execute(cluster) } - - context 'when suceeded to get cluster from api' do - let(:gke_cluster) { double } - - before do - allow(gke_cluster).to receive(:endpoint).and_return('111.111.111.111') - allow(gke_cluster).to receive(:master_auth).and_return(spy) - allow_any_instance_of(GoogleApi::CloudPlatform::Client) - .to receive(:projects_zones_clusters_get).and_return(gke_cluster) - end - - context 'when suceeded to get kubernetes token' do - let(:kubernetes_token) { 'abc' } - - before do - allow_any_instance_of(Ci::FetchKubernetesTokenService) - .to receive(:execute).and_return(kubernetes_token) - end - - it 'executes integration cluster' do - expect_any_instance_of(Ci::IntegrateClusterService).to receive(:execute) - described_class.new.execute(cluster) - end - end - - context 'when failed to get kubernetes token' do - before do - allow_any_instance_of(Ci::FetchKubernetesTokenService) - .to receive(:execute).and_return(nil) - end - - it 'sets an error to cluster object' do - described_class.new.execute(cluster) - - expect(cluster.reload).to be_errored - end - end - end - - context 'when failed to get cluster from api' do - let(:error) { Google::Apis::ServerError.new('a') } - - before do - allow_any_instance_of(GoogleApi::CloudPlatform::Client) - .to receive(:projects_zones_clusters_get).and_raise(error) - end - - it 'sets an error to cluster object' do - described_class.new.execute(cluster) - - expect(cluster.reload).to be_errored - end - end - end -end diff --git a/spec/services/ci/integrate_cluster_service_spec.rb b/spec/services/ci/integrate_cluster_service_spec.rb deleted file mode 100644 index 3a79c205bd1..00000000000 --- a/spec/services/ci/integrate_cluster_service_spec.rb +++ /dev/null @@ -1,42 +0,0 @@ -require 'spec_helper' - -describe Ci::IntegrateClusterService do - describe '#execute' do - let(:cluster) { create(:gcp_cluster, :custom_project_namespace) } - let(:endpoint) { '123.123.123.123' } - let(:ca_cert) { 'ca_cert_xxx' } - let(:token) { 'token_xxx' } - let(:username) { 'username_xxx' } - let(:password) { 'password_xxx' } - - before do - described_class - .new.execute(cluster, endpoint, ca_cert, token, username, password) - - cluster.reload - end - - context 'when correct params' do - it 'creates a cluster object' do - expect(cluster.endpoint).to eq(endpoint) - expect(cluster.ca_cert).to eq(ca_cert) - expect(cluster.kubernetes_token).to eq(token) - expect(cluster.username).to eq(username) - expect(cluster.password).to eq(password) - expect(cluster.service.active).to be_truthy - expect(cluster.service.api_url).to eq(cluster.api_url) - expect(cluster.service.ca_pem).to eq(ca_cert) - expect(cluster.service.namespace).to eq(cluster.project_namespace) - expect(cluster.service.token).to eq(token) - end - end - - context 'when invalid params' do - let(:endpoint) { nil } - - it 'sets an error to cluster object' do - expect(cluster).to be_errored - end - end - end -end diff --git a/spec/services/ci/provision_cluster_service_spec.rb b/spec/services/ci/provision_cluster_service_spec.rb deleted file mode 100644 index 5ce5c788314..00000000000 --- a/spec/services/ci/provision_cluster_service_spec.rb +++ /dev/null @@ -1,85 +0,0 @@ -require 'spec_helper' - -describe Ci::ProvisionClusterService do - describe '#execute' do - let(:cluster) { create(:gcp_cluster) } - let(:operation) { spy } - - shared_examples 'error' do - it 'sets an error to cluster object' do - described_class.new.execute(cluster) - - expect(cluster.reload).to be_errored - end - end - - context 'when suceeded to request provision' do - before do - allow_any_instance_of(GoogleApi::CloudPlatform::Client) - .to receive(:projects_zones_clusters_create).and_return(operation) - end - - context 'when operation status is RUNNING' do - before do - allow(operation).to receive(:status).and_return('RUNNING') - end - - context 'when suceeded to parse gcp operation id' do - before do - allow_any_instance_of(GoogleApi::CloudPlatform::Client) - .to receive(:parse_operation_id).and_return('operation-123') - end - - context 'when cluster status is scheduled' do - before do - allow_any_instance_of(GoogleApi::CloudPlatform::Client) - .to receive(:parse_operation_id).and_return('operation-123') - end - - it 'schedules a worker for status minitoring' do - expect(WaitForClusterCreationWorker).to receive(:perform_in) - - described_class.new.execute(cluster) - end - end - - context 'when cluster status is creating' do - before do - cluster.make_creating! - end - - it_behaves_like 'error' - end - end - - context 'when failed to parse gcp operation id' do - before do - allow_any_instance_of(GoogleApi::CloudPlatform::Client) - .to receive(:parse_operation_id).and_return(nil) - end - - it_behaves_like 'error' - end - end - - context 'when operation status is others' do - before do - allow(operation).to receive(:status).and_return('others') - end - - it_behaves_like 'error' - end - end - - context 'when failed to request provision' do - let(:error) { Google::Apis::ServerError.new('a') } - - before do - allow_any_instance_of(GoogleApi::CloudPlatform::Client) - .to receive(:projects_zones_clusters_create).and_raise(error) - end - - it_behaves_like 'error' - end - end -end diff --git a/spec/services/ci/update_cluster_service_spec.rb b/spec/services/ci/update_cluster_service_spec.rb deleted file mode 100644 index a289385b88f..00000000000 --- a/spec/services/ci/update_cluster_service_spec.rb +++ /dev/null @@ -1,37 +0,0 @@ -require 'spec_helper' - -describe Ci::UpdateClusterService do - describe '#execute' do - let(:cluster) { create(:gcp_cluster, :created_on_gke, :with_kubernetes_service) } - - before do - described_class.new(cluster.project, cluster.user, params).execute(cluster) - - cluster.reload - end - - context 'when correct params' do - context 'when enabled is true' do - let(:params) { { 'enabled' => 'true' } } - - it 'enables cluster and overwrite kubernetes service' do - expect(cluster.enabled).to be_truthy - expect(cluster.service.active).to be_truthy - expect(cluster.service.api_url).to eq(cluster.api_url) - expect(cluster.service.ca_pem).to eq(cluster.ca_cert) - expect(cluster.service.namespace).to eq(cluster.project_namespace) - expect(cluster.service.token).to eq(cluster.kubernetes_token) - end - end - - context 'when enabled is false' do - let(:params) { { 'enabled' => 'false' } } - - it 'disables cluster and kubernetes service' do - expect(cluster.enabled).to be_falsy - expect(cluster.service.active).to be_falsy - end - end - end - end -end diff --git a/spec/services/clusters/create_service_spec.rb b/spec/services/clusters/create_service_spec.rb new file mode 100644 index 00000000000..14f88d3f0f5 --- /dev/null +++ b/spec/services/clusters/create_service_spec.rb @@ -0,0 +1,62 @@ +require 'spec_helper' + +describe Clusters::CreateService do + let(:access_token) { 'xxx' } + let(:project) { create(:project) } + let(:user) { create(:user) } + let(:result) { described_class.new(project, user, params).execute(access_token) } + + context 'when correct params' do + let(:params) do + { + name: 'test-cluster', + platform_type: :kubernetes, + provider_type: :gcp, + platform_kubernetes_attributes: { + namespace: 'custom-namespace' + }, + provider_gcp_attributes: { + gcp_project_id: 'gcp-project', + zone: 'us-central1-a', + num_nodes: 1, + machine_type: 'machine_type-a' + } + } + end + + it 'creates a cluster object and performs a worker' do + expect(ClusterProvisionWorker).to receive(:perform_async) + expect { result }.to change { Clusters::Cluster.count }.by(1) + expect(result.name).to eq('test-cluster') + expect(result.user).to eq(user) + expect(result.project).to eq(project) + expect(result.provider.gcp_project_id).to eq('gcp-project') + expect(result.provider.zone).to eq('us-central1-a') + expect(result.provider.num_nodes).to eq(1) + expect(result.provider.machine_type).to eq('machine_type-a') + expect(result.provider.access_token).to eq(access_token) + expect(result.platform.namespace).to eq('custom-namespace') + end + end + + context 'when invalid params' do + let(:params) do + { + name: 'test-cluster', + platform_type: :kubernetes, + provider_type: :user, + provider_gcp_attributes: { + gcp_project_id: 'gcp-project', + zone: 'us-central1-a', + num_nodes: 'ABC' + } + } + end + + it 'returns an error' do + expect(ClusterProvisionWorker).not_to receive(:perform_async) + expect { result }.to change { Clusters::Cluster.count }.by(0) + expect(result.errors[:"provider_gcp.num_nodes"]).to be_present + end + end +end diff --git a/spec/services/clusters/gcp/fetch_operation_service_spec.rb b/spec/services/clusters/gcp/fetch_operation_service_spec.rb new file mode 100644 index 00000000000..20d46608033 --- /dev/null +++ b/spec/services/clusters/gcp/fetch_operation_service_spec.rb @@ -0,0 +1,43 @@ +require 'spec_helper' + +describe Clusters::Gcp::FetchOperationService do + include GoogleApi::CloudPlatformHelpers + + describe '#execute' do + let(:provider) { create(:provider_gcp, :creating) } + let(:gcp_project_id) { provider.gcp_project_id } + let(:zone) { provider.zone } + let(:operation_id) { provider.operation_id } + + shared_examples 'success' do + it 'yields' do + expect { |b| described_class.new.execute(provider, &b) } + .to yield_with_args + end + end + + shared_examples 'error' do + it 'sets an error to provider object' do + expect { |b| described_class.new.execute(provider, &b) } + .not_to yield_with_args + expect(provider.reload).to be_errored + end + end + + context 'when suceeded to fetch operation' do + before do + stub_cloud_platform_get_zone_operation(gcp_project_id, zone, operation_id) + end + + it_behaves_like 'success' + end + + context 'when Internal Server Error happened' do + before do + stub_cloud_platform_get_zone_operation_error(gcp_project_id, zone, operation_id) + end + + it_behaves_like 'error' + end + end +end diff --git a/spec/services/clusters/gcp/finalize_creation_service_spec.rb b/spec/services/clusters/gcp/finalize_creation_service_spec.rb new file mode 100644 index 00000000000..70ea1cbca46 --- /dev/null +++ b/spec/services/clusters/gcp/finalize_creation_service_spec.rb @@ -0,0 +1,110 @@ +require 'spec_helper' + +describe Clusters::Gcp::FinalizeCreationService do + include GoogleApi::CloudPlatformHelpers + include KubernetesHelpers + + describe '#execute' do + let(:cluster) { create(:cluster, :project, :providing_by_gcp) } + let(:provider) { cluster.provider } + let(:platform) { cluster.platform } + let(:gcp_project_id) { provider.gcp_project_id } + let(:zone) { provider.zone } + let(:cluster_name) { cluster.name } + + shared_examples 'success' do + it 'configures provider and kubernetes' do + described_class.new.execute(provider) + + expect(provider).to be_created + end + end + + shared_examples 'error' do + it 'sets an error to provider object' do + described_class.new.execute(provider) + + expect(provider.reload).to be_errored + end + end + + context 'when suceeded to fetch gke cluster info' do + let(:endpoint) { '111.111.111.111' } + let(:api_url) { 'https://' + endpoint } + let(:username) { 'sample-username' } + let(:password) { 'sample-password' } + + before do + stub_cloud_platform_get_zone_cluster( + gcp_project_id, zone, cluster_name, + { + endpoint: endpoint, + username: username, + password: password, + } + ) + + stub_kubeclient_discover(api_url) + end + + context 'when suceeded to fetch kuberenetes token' do + let(:token) { 'sample-token' } + + before do + stub_kubeclient_get_secrets( + api_url, + { + token: Base64.encode64(token) + } ) + end + + it_behaves_like 'success' + + it 'has corresponded data' do + described_class.new.execute(provider) + provider.reload + platform.reload + + expect(provider.endpoint).to eq(endpoint) + expect(platform.api_url).to eq(api_url) + expect(platform.ca_cert).to eq(Base64.decode64(load_sample_cert)) + expect(platform.username).to eq(username) + expect(platform.password).to eq(password) + expect(platform.token).to eq(token) + end + end + + context 'when default-token is not found' do + before do + stub_kubeclient_get_secrets(api_url, metadata_name: 'aaaa') + end + + it_behaves_like 'error' + end + + context 'when token is empty' do + before do + stub_kubeclient_get_secrets(api_url, token: '') + end + + it_behaves_like 'error' + end + + context 'when failed to fetch kuberenetes token' do + before do + stub_kubeclient_get_secrets_error(api_url) + end + + it_behaves_like 'error' + end + end + + context 'when failed to fetch gke cluster info' do + before do + stub_cloud_platform_get_zone_cluster_error(gcp_project_id, zone, cluster_name) + end + + it_behaves_like 'error' + end + end +end diff --git a/spec/services/clusters/gcp/provision_service_spec.rb b/spec/services/clusters/gcp/provision_service_spec.rb new file mode 100644 index 00000000000..f5f9d4800fd --- /dev/null +++ b/spec/services/clusters/gcp/provision_service_spec.rb @@ -0,0 +1,69 @@ +require 'spec_helper' + +describe Clusters::Gcp::ProvisionService do + include GoogleApi::CloudPlatformHelpers + + describe '#execute' do + let(:provider) { create(:provider_gcp, :scheduled) } + let(:gcp_project_id) { provider.gcp_project_id } + let(:zone) { provider.zone } + + shared_examples 'success' do + it 'schedules a worker for status minitoring' do + expect(WaitForClusterCreationWorker).to receive(:perform_in) + + described_class.new.execute(provider) + + expect(provider.reload).to be_creating + end + end + + shared_examples 'error' do + it 'sets an error to provider object' do + described_class.new.execute(provider) + + expect(provider.reload).to be_errored + end + end + + context 'when suceeded to request provision' do + before do + stub_cloud_platform_create_cluster(gcp_project_id, zone) + end + + it_behaves_like 'success' + end + + context 'when operation status is unexpected' do + before do + stub_cloud_platform_create_cluster( + gcp_project_id, zone, + { + "status": 'unexpected' + } ) + end + + it_behaves_like 'error' + end + + context 'when selfLink is unexpected' do + before do + stub_cloud_platform_create_cluster( + gcp_project_id, zone, + { + "selfLink": 'unexpected' + }) + end + + it_behaves_like 'error' + end + + context 'when Internal Server Error happened' do + before do + stub_cloud_platform_create_cluster_error(gcp_project_id, zone) + end + + it_behaves_like 'error' + end + end +end diff --git a/spec/services/clusters/gcp/verify_provision_status_service_spec.rb b/spec/services/clusters/gcp/verify_provision_status_service_spec.rb new file mode 100644 index 00000000000..666fcf13cac --- /dev/null +++ b/spec/services/clusters/gcp/verify_provision_status_service_spec.rb @@ -0,0 +1,107 @@ +require 'spec_helper' + +describe Clusters::Gcp::VerifyProvisionStatusService do + include GoogleApi::CloudPlatformHelpers + + describe '#execute' do + let(:provider) { create(:provider_gcp, :creating) } + let(:gcp_project_id) { provider.gcp_project_id } + let(:zone) { provider.zone } + let(:operation_id) { provider.operation_id } + + shared_examples 'continue_creation' do + it 'schedules a worker for status minitoring' do + expect(WaitForClusterCreationWorker).to receive(:perform_in) + + described_class.new.execute(provider) + end + end + + shared_examples 'finalize_creation' do + it 'schedules a worker for status minitoring' do + expect_any_instance_of(Clusters::Gcp::FinalizeCreationService).to receive(:execute) + + described_class.new.execute(provider) + end + end + + shared_examples 'error' do + it 'sets an error to provider object' do + described_class.new.execute(provider) + + expect(provider.reload).to be_errored + end + end + + context 'when operation status is RUNNING' do + before do + stub_cloud_platform_get_zone_operation( + gcp_project_id, zone, operation_id, + { + "status": 'RUNNING', + "startTime": 1.minute.ago.strftime("%FT%TZ") + } ) + end + + it_behaves_like 'continue_creation' + + context 'when cluster creation time exceeds timeout' do + before do + stub_cloud_platform_get_zone_operation( + gcp_project_id, zone, operation_id, + { + "status": 'RUNNING', + "startTime": 30.minutes.ago.strftime("%FT%TZ") + } ) + end + + it_behaves_like 'error' + end + end + + context 'when operation status is PENDING' do + before do + stub_cloud_platform_get_zone_operation( + gcp_project_id, zone, operation_id, + { + "status": 'PENDING', + "startTime": 1.minute.ago.strftime("%FT%TZ") + } ) + end + + it_behaves_like 'continue_creation' + end + + context 'when operation status is DONE' do + before do + stub_cloud_platform_get_zone_operation( + gcp_project_id, zone, operation_id, + { + "status": 'DONE' + } ) + end + + it_behaves_like 'finalize_creation' + end + + context 'when operation status is unexpected' do + before do + stub_cloud_platform_get_zone_operation( + gcp_project_id, zone, operation_id, + { + "status": 'unexpected' + } ) + end + + it_behaves_like 'error' + end + + context 'when failed to get operation status' do + before do + stub_cloud_platform_get_zone_operation_error(gcp_project_id, zone, operation_id) + end + + it_behaves_like 'error' + end + end +end diff --git a/spec/services/clusters/update_service_spec.rb b/spec/services/clusters/update_service_spec.rb new file mode 100644 index 00000000000..2d91a21035d --- /dev/null +++ b/spec/services/clusters/update_service_spec.rb @@ -0,0 +1,59 @@ +require 'spec_helper' + +describe Clusters::UpdateService do + describe '#execute' do + subject { described_class.new(cluster.project, cluster.user, params).execute(cluster) } + + let(:cluster) { create(:cluster, :project, :provided_by_user) } + + context 'when correct params' do + context 'when enabled is true' do + let(:params) { { enabled: true } } + + it 'enables cluster' do + is_expected.to eq(true) + expect(cluster.enabled).to be_truthy + end + end + + context 'when enabled is false' do + let(:params) { { enabled: false } } + + it 'disables cluster' do + is_expected.to eq(true) + expect(cluster.enabled).to be_falsy + end + end + + context 'when namespace is specified' do + let(:params) do + { + platform_kubernetes_attributes: { + namespace: 'custom-namespace' + } + } + end + + it 'updates namespace' do + is_expected.to eq(true) + expect(cluster.platform.namespace).to eq('custom-namespace') + end + end + end + + context 'when invalid params' do + let(:params) do + { + platform_kubernetes_attributes: { + namespace: '!!!' + } + } + end + + it 'returns false' do + is_expected.to eq(false) + expect(cluster.errors[:"platform_kubernetes.namespace"]).to be_present + end + end + end +end |