From c207122fd2b4439ff8303a1860c35de658d6bdfb Mon Sep 17 00:00:00 2001 From: Matt Coleman Date: Thu, 21 Sep 2017 16:05:44 -0400 Subject: Add Packagist project service --- .../project_services/packagist_service_spec.rb | 46 ++++++++++++++++++++++ spec/models/project_spec.rb | 1 + 2 files changed, 47 insertions(+) create mode 100644 spec/models/project_services/packagist_service_spec.rb (limited to 'spec/models') diff --git a/spec/models/project_services/packagist_service_spec.rb b/spec/models/project_services/packagist_service_spec.rb new file mode 100644 index 00000000000..6acee311700 --- /dev/null +++ b/spec/models/project_services/packagist_service_spec.rb @@ -0,0 +1,46 @@ +require 'spec_helper' + +describe PackagistService do + describe "Associations" do + it { is_expected.to belong_to :project } + it { is_expected.to have_one :service_hook } + end + + let(:project) { create(:project) } + + let(:packagist_server) { 'https://packagist.example.com' } + let(:packagist_username) { 'theUser' } + let(:packagist_token) { 'verySecret' } + let(:packagist_hook_url) do + "#{packagist_server}/api/update-package?username=#{packagist_username}&apiToken=#{packagist_token}" + end + + let(:packagist_params) do + { + active: true, + project: project, + properties: { + username: packagist_username, + token: packagist_token, + server: packagist_server + } + } + end + + describe '#execute' do + let(:user) { create(:user) } + let(:project) { create(:project, :repository) } + let(:push_sample_data) { Gitlab::DataBuilder::Push.build_sample(project, user) } + let(:packagist_service) { described_class.create(packagist_params) } + + before do + stub_request(:post, packagist_hook_url) + end + + it 'calls Packagist API' do + packagist_service.execute(push_sample_data) + + expect(a_request(:post, packagist_hook_url)).to have_been_made.once + end + end +end diff --git a/spec/models/project_spec.rb b/spec/models/project_spec.rb index cf26dbfea49..fe572ec922e 100644 --- a/spec/models/project_spec.rb +++ b/spec/models/project_spec.rb @@ -24,6 +24,7 @@ describe Project do it { is_expected.to have_one(:slack_service) } it { is_expected.to have_one(:microsoft_teams_service) } it { is_expected.to have_one(:mattermost_service) } + it { is_expected.to have_one(:packagist_service) } it { is_expected.to have_one(:pushover_service) } it { is_expected.to have_one(:asana_service) } it { is_expected.to have_many(:boards) } -- cgit v1.2.1 From 6798bab12a0faabf43f61eb65561b9f058824e4d Mon Sep 17 00:00:00 2001 From: Alessio Caiazza Date: Thu, 26 Oct 2017 16:04:28 +0200 Subject: Remove duped tests Likely caused by EE conflicts resolution --- .../project_services/kubernetes_service_spec.rb | 28 ---------------------- 1 file changed, 28 deletions(-) (limited to 'spec/models') diff --git a/spec/models/project_services/kubernetes_service_spec.rb b/spec/models/project_services/kubernetes_service_spec.rb index 537cdadd528..69da4375245 100644 --- a/spec/models/project_services/kubernetes_service_spec.rb +++ b/spec/models/project_services/kubernetes_service_spec.rb @@ -124,34 +124,6 @@ describe KubernetesService, :use_clean_rails_memory_store_caching do end end - describe '#actual_namespace' do - subject { service.actual_namespace } - - it "returns the default namespace" do - is_expected.to eq(service.send(:default_namespace)) - end - - context 'when namespace is specified' do - before do - service.namespace = 'my-namespace' - end - - it "returns the user-namespace" do - is_expected.to eq('my-namespace') - end - end - - context 'when service is not assigned to project' do - before do - service.project = nil - end - - it "does not return namespace" do - is_expected.to be_nil - end - end - end - describe '#test' do let(:discovery_url) { 'https://kubernetes.example.com/api/v1' } -- cgit v1.2.1 From 3aafcc16fbdde08bf333eab97c5b1b3c4249a5cf Mon Sep 17 00:00:00 2001 From: Alessio Caiazza Date: Thu, 26 Oct 2017 16:38:10 +0200 Subject: Add KubernetesService#default_namespace tests --- .../project_services/kubernetes_service_spec.rb | 27 ++++++++++++++++++---- 1 file changed, 22 insertions(+), 5 deletions(-) (limited to 'spec/models') diff --git a/spec/models/project_services/kubernetes_service_spec.rb b/spec/models/project_services/kubernetes_service_spec.rb index 69da4375245..fa478a22cf4 100644 --- a/spec/models/project_services/kubernetes_service_spec.rb +++ b/spec/models/project_services/kubernetes_service_spec.rb @@ -99,8 +99,25 @@ describe KubernetesService, :use_clean_rails_memory_store_caching do describe '#actual_namespace' do subject { service.actual_namespace } - it "returns the default namespace" do - is_expected.to eq(service.send(:default_namespace)) + shared_examples 'a correctly formatted namespace' do + it 'returns a valid Kubernetes namespace name' do + expect(subject).to match(Gitlab::Regex.kubernetes_namespace_regex) + expect(subject).to eq(expected_namespace) + end + end + + it_behaves_like 'a correctly formatted namespace' do + let(:expected_namespace) { service.send(:default_namespace) } + end + + context 'when the project path contains forbidden characters' do + before do + project.path = '-a_Strange.Path--forSure' + end + + it_behaves_like 'a correctly formatted namespace' do + let(:expected_namespace) { "a-strange-path--forsure-#{project.id}" } + end end context 'when namespace is specified' do @@ -108,8 +125,8 @@ describe KubernetesService, :use_clean_rails_memory_store_caching do service.namespace = 'my-namespace' end - it "returns the user-namespace" do - is_expected.to eq('my-namespace') + it_behaves_like 'a correctly formatted namespace' do + let(:expected_namespace) { 'my-namespace' } end end @@ -118,7 +135,7 @@ describe KubernetesService, :use_clean_rails_memory_store_caching do service.project = nil end - it "does not return namespace" do + it 'does not return namespace' do is_expected.to be_nil end end -- cgit v1.2.1 From 3411fef1df22295cc68b1d39576917dd533da580 Mon Sep 17 00:00:00 2001 From: Zeger-Jan van de Weg Date: Fri, 13 Oct 2017 10:37:31 +0200 Subject: Cache commits on the repository model Now, when requesting a commit from the Repository model, the results are not cached. This means we're fetching the same commit by oid multiple times during the same request. To prevent us from doing this, we now cache results. Caching is done only based on object id (aka SHA). Given we cache on the Repository model, results are scoped to the associated project, eventhough the change of two repositories having the same oids for different commits is small. --- spec/models/merge_request_spec.rb | 4 ++-- spec/models/repository_spec.rb | 20 ++++++++++++++++++++ 2 files changed, 22 insertions(+), 2 deletions(-) (limited to 'spec/models') diff --git a/spec/models/merge_request_spec.rb b/spec/models/merge_request_spec.rb index 73e038b61ed..2b8aa7cf9c3 100644 --- a/spec/models/merge_request_spec.rb +++ b/spec/models/merge_request_spec.rb @@ -86,7 +86,7 @@ describe MergeRequest do context 'when the target branch does not exist' do before do - project.repository.raw_repository.delete_branch(subject.target_branch) + project.repository.rm_branch(subject.author, subject.target_branch) end it 'returns nil' do @@ -1388,7 +1388,7 @@ describe MergeRequest do context 'when the target branch does not exist' do before do - subject.project.repository.raw_repository.delete_branch(subject.target_branch) + subject.project.repository.rm_branch(subject.author, subject.target_branch) end it 'returns nil' do diff --git a/spec/models/repository_spec.rb b/spec/models/repository_spec.rb index 39d188f18af..aa376d46a67 100644 --- a/spec/models/repository_spec.rb +++ b/spec/models/repository_spec.rb @@ -2238,4 +2238,24 @@ describe Repository do end end end + + describe 'commit cache' do + set(:project) { create(:project, :repository) } + + it 'caches based on SHA' do + # Gets the commit oid, and warms the cache + oid = project.commit.id + + expect(Gitlab::Git::Commit).not_to receive(:find).once + + project.commit_by(oid: oid) + end + + it 'caches nil values' do + expect(Gitlab::Git::Commit).to receive(:find).once + + project.commit_by(oid: '1' * 40) + project.commit_by(oid: '1' * 40) + end + end end -- cgit v1.2.1 From a2894b7ad2b26ff65d36b9c87b79c60ff4ddda59 Mon Sep 17 00:00:00 2001 From: Brett Walker Date: Fri, 27 Oct 2017 16:32:48 +0200 Subject: use a delegate for `username` to be more future friendly --- spec/models/email_spec.rb | 8 ++++++++ 1 file changed, 8 insertions(+) (limited to 'spec/models') diff --git a/spec/models/email_spec.rb b/spec/models/email_spec.rb index b32dd31ae6d..4676612ad52 100644 --- a/spec/models/email_spec.rb +++ b/spec/models/email_spec.rb @@ -40,4 +40,12 @@ describe Email do expect(user.emails.confirmed.count).to eq 1 end end + + describe 'delegation' do + let(:user) { create(:user) } + + it 'delegates to :user' do + expect(build(:email, user: user).username).to eq user.username + end + end end -- cgit v1.2.1 From 34254e1d58991dadb461fea2b62d3d93b17fbb73 Mon Sep 17 00:00:00 2001 From: Brett Walker Date: Fri, 27 Oct 2017 17:35:40 +0200 Subject: remove extra whitespace --- spec/models/email_spec.rb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'spec/models') diff --git a/spec/models/email_spec.rb b/spec/models/email_spec.rb index 4676612ad52..47eb0717c0c 100644 --- a/spec/models/email_spec.rb +++ b/spec/models/email_spec.rb @@ -40,10 +40,10 @@ describe Email do expect(user.emails.confirmed.count).to eq 1 end end - + describe 'delegation' do let(:user) { create(:user) } - + it 'delegates to :user' do expect(build(:email, user: user).username).to eq user.username end -- cgit v1.2.1 From 57d7ed05d96928f7e33135e7397bdd6b3b0d25e0 Mon Sep 17 00:00:00 2001 From: "Lin Jen-Shin (godfat)" Date: Fri, 27 Oct 2017 15:55:08 +0000 Subject: Fetch the merged branches at once --- spec/models/repository_spec.rb | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) (limited to 'spec/models') diff --git a/spec/models/repository_spec.rb b/spec/models/repository_spec.rb index 455d5e8a656..d7c07676911 100644 --- a/spec/models/repository_spec.rb +++ b/spec/models/repository_spec.rb @@ -299,6 +299,24 @@ describe Repository do it { is_expected.to be_falsey } end + + context 'when pre-loaded merged branches are provided' do + using RSpec::Parameterized::TableSyntax + + where(:branch, :pre_loaded, :expected) do + 'not-merged-branch' | ['branch-merged'] | false + 'branch-merged' | ['not-merged-branch'] | false + 'branch-merged' | ['branch-merged'] | true + 'not-merged-branch' | ['not-merged-branch'] | false + 'master' | ['master'] | false + end + + with_them do + subject { repository.merged_to_root_ref?(branch, pre_loaded) } + + it { is_expected.to eq(expected) } + end + end end describe '#can_be_merged?' do -- cgit v1.2.1 From b19076948de9d637ab5a74ea59249cdb680c8495 Mon Sep 17 00:00:00 2001 From: Gabriel Mazetto Date: Fri, 27 Oct 2017 21:27:17 +0200 Subject: Moved renaming operations to storage layer abstraction When project storage_version is `2` means attachments are using hashed storage. --- spec/models/project_spec.rb | 55 +++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 51 insertions(+), 4 deletions(-) (limited to 'spec/models') diff --git a/spec/models/project_spec.rb b/spec/models/project_spec.rb index 74eba7e33f6..d80af378140 100644 --- a/spec/models/project_spec.rb +++ b/spec/models/project_spec.rb @@ -2452,6 +2452,7 @@ describe Project do context 'legacy storage' do let(:project) { create(:project, :repository) } let(:gitlab_shell) { Gitlab::Shell.new } + let(:project_storage) { project.send(:storage) } before do allow(project).to receive(:gitlab_shell).and_return(gitlab_shell) @@ -2546,6 +2547,30 @@ describe Project do it { expect { subject }.to raise_error(StandardError) } end + + context 'gitlab pages' do + before do + expect(project_storage).to receive(:rename_repo) { true } + end + + it 'moves pages folder to new location' do + expect_any_instance_of(Gitlab::PagesTransfer).to receive(:rename_project) + + project.rename_repo + end + end + + context 'attachments' do + before do + expect(project_storage).to receive(:rename_repo) { true } + end + + it 'moves uploads folder to new location' do + expect_any_instance_of(Gitlab::UploadsTransfer).to receive(:rename_project) + + project.rename_repo + end + end end describe '#pages_path' do @@ -2649,10 +2674,6 @@ describe Project do .to receive(:execute_hooks_for) .with(project, :rename) - expect_any_instance_of(Gitlab::UploadsTransfer) - .to receive(:rename_project) - .with('foo', project.path, project.namespace.full_path) - expect(project).to receive(:expire_caches_before_rename) expect(project).to receive(:expires_full_path_cache) @@ -2673,6 +2694,32 @@ describe Project do it { expect { subject }.to raise_error(StandardError) } end + + context 'gitlab pages' do + it 'moves pages folder to new location' do + expect_any_instance_of(Gitlab::PagesTransfer).to receive(:rename_project) + + project.rename_repo + end + end + + context 'attachments' do + it 'keeps uploads folder location unchanged' do + expect_any_instance_of(Gitlab::UploadsTransfer).not_to receive(:rename_project) + + project.rename_repo + end + + context 'when not rolled out' do + let(:project) { create(:project, :repository, storage_version: 1) } + + it 'moves pages folder to new location' do + expect_any_instance_of(Gitlab::UploadsTransfer).to receive(:rename_project) + + project.rename_repo + end + end + end end describe '#pages_path' do -- cgit v1.2.1 From a6c52c4e593850eb270e5bfbd021cdfb56e6eed6 Mon Sep 17 00:00:00 2001 From: Oswaldo Ferreira Date: Fri, 27 Oct 2017 22:11:21 +0200 Subject: Make merge_jid handling less stateful in MergeService --- spec/models/merge_request_spec.rb | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'spec/models') diff --git a/spec/models/merge_request_spec.rb b/spec/models/merge_request_spec.rb index 2b8aa7cf9c3..476a2697605 100644 --- a/spec/models/merge_request_spec.rb +++ b/spec/models/merge_request_spec.rb @@ -1460,6 +1460,12 @@ describe MergeRequest do end describe '#merge_ongoing?' do + it 'returns true when the merge request is locked' do + merge_request = build_stubbed(:merge_request, state: :locked) + + expect(merge_request.merge_ongoing?).to be(true) + end + it 'returns true when merge_id, MR is not merged and it has no running job' do merge_request = build_stubbed(:merge_request, state: :open, merge_jid: 'foo') allow(Gitlab::SidekiqStatus).to receive(:running?).with('foo') { true } -- cgit v1.2.1 From 478e59fe8d82b99800a2613aa4d153bf692fbd6b Mon Sep 17 00:00:00 2001 From: Shinya Maeda Date: Mon, 30 Oct 2017 03:48:45 +0900 Subject: specs for models. Improved details. --- spec/models/clusters/cluster_spec.rb | 180 +++++++++++++ spec/models/clusters/platforms/kubernetes_spec.rb | 304 ++++++++++++++++++++++ spec/models/clusters/project_spec.rb | 6 + spec/models/clusters/providers/gcp_spec.rb | 183 +++++++++++++ spec/models/gcp/cluster_spec.rb | 264 ------------------- 5 files changed, 673 insertions(+), 264 deletions(-) create mode 100644 spec/models/clusters/cluster_spec.rb create mode 100644 spec/models/clusters/platforms/kubernetes_spec.rb create mode 100644 spec/models/clusters/project_spec.rb create mode 100644 spec/models/clusters/providers/gcp_spec.rb delete mode 100644 spec/models/gcp/cluster_spec.rb (limited to 'spec/models') diff --git a/spec/models/clusters/cluster_spec.rb b/spec/models/clusters/cluster_spec.rb new file mode 100644 index 00000000000..e53ce8497f5 --- /dev/null +++ b/spec/models/clusters/cluster_spec.rb @@ -0,0 +1,180 @@ +require 'spec_helper' + +describe Clusters::Cluster do + it { is_expected.to belong_to(:user) } + it { is_expected.to have_many(:projects) } + it { is_expected.to have_one(:provider_gcp) } + it { is_expected.to have_one(:platform_kubernetes) } + it { is_expected.to delegate_method(:status).to(:provider) } + 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 respond_to :project } + + describe '.enabled' do + subject { described_class.enabled } + + let!(:cluster) { create(:cluster, enabled: true) } + + before do + create(:cluster, enabled: false) + end + + it { is_expected.to contain_exactly(cluster) } + end + + describe '.disabled' do + subject { described_class.disabled } + + let!(:cluster) { create(:cluster, enabled: false) } + + before do + create(:cluster, enabled: true) + end + + it { is_expected.to contain_exactly(cluster) } + end + + describe 'validation' do + subject { cluster.valid? } + + context 'when validates name' do + context 'when provided by user' do + let!(:cluster) { build(:cluster, :provided_by_user, name: name) } + + context 'when name is empty' do + let(:name) { '' } + + it { is_expected.to be_falsey } + end + + context 'when name is nil' do + let(:name) { nil } + + it { is_expected.to be_falsey } + end + + context 'when name is present' do + let(:name) { 'cluster-name-1' } + + it { is_expected.to be_truthy } + end + end + + context 'when provided by gcp' do + let!(:cluster) { build(:cluster, :provided_by_gcp, name: name) } + + context 'when name is shorter than 1' do + let(:name) { '' } + + it { is_expected.to be_falsey } + end + + context 'when name is longer than 63' do + let(:name) { 'a' * 64 } + + it { is_expected.to be_falsey } + end + + context 'when name includes invalid character' do + let(:name) { '!!!!!!' } + + it { is_expected.to be_falsey } + end + + context 'when name is present' do + let(:name) { 'cluster-name-1' } + + it { is_expected.to be_truthy } + end + + context 'when record is persisted' do + let(:name) { 'cluster-name-1' } + + before do + cluster.save! + end + + context 'when name is changed' do + before do + cluster.name = 'new-cluster-name' + end + + it { is_expected.to be_falsey } + end + + context 'when name is same' do + before do + cluster.name = name + end + + it { is_expected.to be_truthy } + end + end + end + end + + context 'when validates restrict_modification' do + context 'when creation is on going' do + let!(:cluster) { create(:cluster, :providing_by_gcp) } + + it { expect(cluster.update(enabled: false)).to be_falsey } + end + + context 'when creation is done' do + let!(:cluster) { create(:cluster, :provided_by_gcp) } + + it { expect(cluster.update(enabled: false)).to be_truthy } + end + end + end + + describe '#provider' do + subject { cluster.provider } + + context 'when provider is gcp' do + let(:cluster) { create(:cluster, :provided_by_gcp) } + + it 'returns a provider' do + is_expected.to eq(cluster.provider_gcp) + expect(subject.class.name.deconstantize).to eq(Clusters::Providers.to_s) + end + end + + context 'when provider is user' do + let(:cluster) { create(:cluster, :provided_by_user) } + + it { is_expected.to be_nil } + end + end + + describe '#platform' do + subject { cluster.platform } + + context 'when platform is kubernetes' do + let(:cluster) { create(:cluster, :provided_by_user) } + + it 'returns a platform' do + is_expected.to eq(cluster.platform_kubernetes) + expect(subject.class.name.deconstantize).to eq(Clusters::Platforms.to_s) + end + end + end + + describe '#first_project' do + subject { cluster.first_project } + + context 'when cluster belongs to a project' do + let(:cluster) { create(:cluster, :project) } + let(:project) { Clusters::Project.find_by_cluster_id(cluster.id).project } + + it { is_expected.to eq(project) } + end + + context 'when cluster does not belong to projects' do + let(:cluster) { create(:cluster) } + + it { is_expected.to be_nil } + end + end +end diff --git a/spec/models/clusters/platforms/kubernetes_spec.rb b/spec/models/clusters/platforms/kubernetes_spec.rb new file mode 100644 index 00000000000..ec6ecee6ff2 --- /dev/null +++ b/spec/models/clusters/platforms/kubernetes_spec.rb @@ -0,0 +1,304 @@ +require 'spec_helper' + +describe Clusters::Platforms::Kubernetes, :use_clean_rails_memory_store_caching do + include KubernetesHelpers + include ReactiveCachingHelpers + + it { is_expected.to belong_to(:cluster) } + it { is_expected.to be_kind_of(Gitlab::Kubernetes) } + it { is_expected.to be_kind_of(ReactiveCaching) } + it { is_expected.to respond_to :ca_pem } + + describe 'before_validation' do + context 'when namespace includes upper case' do + let(:kubernetes) { create(:platform_kubernetes, namespace: namespace) } + let(:namespace) { 'ABC' } + + it 'converts to lower case' do + expect(kubernetes.namespace).to eq('abc') + end + end + end + + describe 'validation' do + subject { kubernetes.valid? } + + context 'when validates namespace' do + let(:kubernetes) { build(:platform_kubernetes, namespace: namespace) } + + context 'when namespace is blank' do + let(:namespace) { '' } + + it { is_expected.to be_truthy } + end + + context 'when namespace is longer than 63' do + let(:namespace) { 'a' * 64 } + + it { is_expected.to be_falsey } + end + + context 'when namespace includes invalid character' do + let(:namespace) { '!!!!!!' } + + it { is_expected.to be_falsey } + end + + context 'when namespace is vaild' do + let(:namespace) { 'namespace-123' } + + it { is_expected.to be_truthy } + end + end + + context 'when validates api_url' do + context 'when updates a record' do + let(:kubernetes) { create(:platform_kubernetes) } + + before do + kubernetes.api_url = api_url + end + + context 'when api_url is invalid url' do + let(:api_url) { '!!!!!!' } + + it { expect(kubernetes.save).to be_falsey } + end + + context 'when api_url is nil' do + let(:api_url) { nil } + + it { expect(kubernetes.save).to be_falsey } + end + + context 'when api_url is valid url' do + let(:api_url) { 'https://111.111.111.111' } + + it { expect(kubernetes.save).to be_truthy } + end + end + + context 'when creates a record' do + let(:kubernetes) { build(:platform_kubernetes) } + + before do + kubernetes.api_url = api_url + end + + context 'when api_url is nil' do + let(:api_url) { nil } + + it { expect(kubernetes.save).to be_truthy } + end + end + end + + context 'when validates token' do + context 'when updates a record' do + let(:kubernetes) { create(:platform_kubernetes) } + + before do + kubernetes.token = token + end + + context 'when token is nil' do + let(:token) { nil } + + it { expect(kubernetes.save).to be_falsey } + end + end + + context 'when creates a record' do + let(:kubernetes) { build(:platform_kubernetes) } + + before do + kubernetes.token = token + end + + context 'when token is nil' do + let(:token) { nil } + + it { expect(kubernetes.save).to be_truthy } + end + end + end + end + + describe '#actual_namespace' do + subject { kubernetes.actual_namespace } + + let!(:cluster) { create(:cluster, :project, platform_kubernetes: kubernetes) } + let(:kubernetes) { create(:platform_kubernetes, namespace: namespace) } + + context 'when namespace is present' do + let(:namespace) { 'namespace-123' } + + it { is_expected.to eq(namespace) } + end + + context 'when namespace is not present' do + let(:namespace) { nil } + + it { is_expected.to eq("#{cluster.project.path}-#{cluster.project.id}") } + end + end + + describe '.namespace_for_project' do + subject { described_class.namespace_for_project(project) } + + let(:project) { create(:project) } + + it { is_expected.to eq("#{project.path}-#{project.id}") } + end + + describe '#default_namespace' do + subject { kubernetes.default_namespace } + + let(:kubernetes) { create(:platform_kubernetes) } + + context 'when cluster belongs to a project' do + let!(:cluster) { create(:cluster, :project, platform_kubernetes: kubernetes) } + + it { is_expected.to eq("#{cluster.project.path}-#{cluster.project.id}") } + end + + context 'when cluster belongs to nothing' do + let!(:cluster) { create(:cluster, platform_kubernetes: kubernetes) } + + it { is_expected.to be_nil } + end + end + + describe '#predefined_variables' do + let!(:cluster) { create(:cluster, :project, platform_kubernetes: kubernetes) } + let(:kubernetes) { create(:platform_kubernetes, api_url: api_url, ca_cert: ca_pem, token: token) } + let(:api_url) { 'https://kube.domain.com' } + let(:ca_pem) { 'CA PEM DATA' } + let(:token) { 'token' } + + let(:kubeconfig) do + config_file = expand_fixture_path('config/kubeconfig.yml') + config = YAML.load(File.read(config_file)) + config.dig('users', 0, 'user')['token'] = token + config.dig('contexts', 0, 'context')['namespace'] = namespace + config.dig('clusters', 0, 'cluster')['certificate-authority-data'] = + Base64.strict_encode64(ca_pem) + + YAML.dump(config) + end + + shared_examples 'setting variables' do + it 'sets the variables' do + expect(kubernetes.predefined_variables).to include( + { key: 'KUBE_URL', value: api_url, public: true }, + { key: 'KUBE_TOKEN', value: token, public: false }, + { key: 'KUBE_NAMESPACE', value: namespace, public: true }, + { key: 'KUBECONFIG', value: kubeconfig, public: false, file: true }, + { key: 'KUBE_CA_PEM', value: ca_pem, public: true }, + { key: 'KUBE_CA_PEM_FILE', value: ca_pem, public: true, file: true } + ) + end + end + + context 'namespace is provided' do + let(:namespace) { 'my-project' } + + before do + kubernetes.namespace = namespace + end + + it_behaves_like 'setting variables' + end + + context 'no namespace provided' do + let(:namespace) { kubernetes.actual_namespace } + + it_behaves_like 'setting variables' + + it 'sets the KUBE_NAMESPACE' do + kube_namespace = kubernetes.predefined_variables.find { |h| h[:key] == 'KUBE_NAMESPACE' } + + expect(kube_namespace).not_to be_nil + expect(kube_namespace[:value]).to match(/\A#{Gitlab::PathRegex::PATH_REGEX_STR}-\d+\z/) + end + end + end + + describe '#terminals' do + subject { service.terminals(environment) } + + let!(:cluster) { create(:cluster, :project, platform_kubernetes: service) } + let(:project) { cluster.project } + let(:service) { create(:platform_kubernetes) } + let(:environment) { build(:environment, project: project, name: "env", slug: "env-000000") } + + context 'with invalid pods' do + it 'returns no terminals' do + stub_reactive_cache(service, pods: [{ "bad" => "pod" }]) + + is_expected.to be_empty + end + end + + context 'with valid pods' do + let(:pod) { kube_pod(app: environment.slug) } + let(:terminals) { kube_terminals(service, pod) } + + before do + stub_reactive_cache( + service, + pods: [pod, pod, kube_pod(app: "should-be-filtered-out")] + ) + end + + it 'returns terminals' do + is_expected.to eq(terminals + terminals) + end + + it 'uses max session time from settings' do + stub_application_setting(terminal_max_session_time: 600) + + times = subject.map { |terminal| terminal[:max_session_time] } + expect(times).to eq [600, 600, 600, 600] + end + end + end + + describe '#calculate_reactive_cache' do + subject { service.calculate_reactive_cache } + + let!(:cluster) { create(:cluster, :project, enabled: enabled, platform_kubernetes: service) } + let(:service) { create(:platform_kubernetes, :ca_cert) } + let(:enabled) { true } + + context 'when cluster is disabled' do + let(:enabled) { false } + + it { is_expected.to be_nil } + end + + context 'when kubernetes responds with valid pods' do + before do + stub_kubeclient_pods + end + + it { is_expected.to eq(pods: [kube_pod]) } + end + + context 'when kubernetes responds with 500s' do + before do + stub_kubeclient_pods(status: 500) + end + + it { expect { subject }.to raise_error(KubeException) } + end + + context 'when kubernetes responds with 404s' do + before do + stub_kubeclient_pods(status: 404) + end + + it { is_expected.to eq(pods: []) } + end + end +end diff --git a/spec/models/clusters/project_spec.rb b/spec/models/clusters/project_spec.rb new file mode 100644 index 00000000000..7d75d6ab345 --- /dev/null +++ b/spec/models/clusters/project_spec.rb @@ -0,0 +1,6 @@ +require 'spec_helper' + +describe Clusters::Project do + it { is_expected.to belong_to(:cluster) } + it { is_expected.to belong_to(:project) } +end diff --git a/spec/models/clusters/providers/gcp_spec.rb b/spec/models/clusters/providers/gcp_spec.rb new file mode 100644 index 00000000000..99eb8c46e9a --- /dev/null +++ b/spec/models/clusters/providers/gcp_spec.rb @@ -0,0 +1,183 @@ +require 'spec_helper' + +describe Clusters::Providers::Gcp do + it { is_expected.to belong_to(:cluster) } + it { is_expected.to validate_presence_of(:zone) } + + describe 'default_value_for' do + let(:gcp) { build(:provider_gcp) } + + it "has default value" do + expect(gcp.zone).to eq('us-central1-a') + expect(gcp.num_nodes).to eq(3) + expect(gcp.machine_type).to eq('n1-standard-4') + end + end + + describe 'validation' do + subject { gcp.valid? } + + context 'when validates gcp_project_id' do + let(:gcp) { build(:provider_gcp, gcp_project_id: gcp_project_id) } + + context 'when gcp_project_id is shorter than 1' do + let(:gcp_project_id) { '' } + + it { is_expected.to be_falsey } + end + + context 'when gcp_project_id is longer than 63' do + let(:gcp_project_id) { 'a' * 64 } + + it { is_expected.to be_falsey } + end + + context 'when gcp_project_id includes invalid character' do + let(:gcp_project_id) { '!!!!!!' } + + it { is_expected.to be_falsey } + end + + context 'when gcp_project_id is valid' do + let(:gcp_project_id) { 'gcp-project-1' } + + it { is_expected.to be_truthy } + end + end + + context 'when validates num_nodes' do + let(:gcp) { build(:provider_gcp, num_nodes: num_nodes) } + + context 'when num_nodes is string' do + let(:num_nodes) { 'A3' } + + it { is_expected.to be_falsey } + end + + context 'when num_nodes is nil' do + let(:num_nodes) { nil } + + it { is_expected.to be_falsey } + end + + context 'when num_nodes is smaller than 1' do + let(:num_nodes) { 0 } + + it { is_expected.to be_falsey } + end + + context 'when num_nodes is valid' do + let(:num_nodes) { 3 } + + it { is_expected.to be_truthy } + end + end + end + + describe '#state_machine' do + context 'when any => [:created]' do + let(:gcp) { build(:provider_gcp, :creating) } + + before do + gcp.make_created + end + + it 'nullify access_token and operation_id' do + expect(gcp.access_token).to be_nil + expect(gcp.operation_id).to be_nil + expect(gcp).to be_created + end + end + + context 'when any => [:creating]' do + let(:gcp) { build(:provider_gcp) } + + context 'when operation_id is present' do + let(:operation_id) { 'operation-xxx' } + + before do + gcp.make_creating(operation_id) + end + + it 'sets operation_id' do + expect(gcp.operation_id).to eq(operation_id) + expect(gcp).to be_creating + end + end + + context 'when operation_id is nil' do + let(:operation_id) { nil } + + it 'raises an error' do + expect { gcp.make_creating(operation_id) } + .to raise_error('operation_id is required') + end + end + end + + context 'when any => [:errored]' do + let(:gcp) { build(:provider_gcp, :creating) } + let(:status_reason) { 'err msg' } + + it 'nullify access_token and operation_id' do + gcp.make_errored(status_reason) + + expect(gcp.access_token).to be_nil + expect(gcp.operation_id).to be_nil + expect(gcp.status_reason).to eq(status_reason) + expect(gcp).to be_errored + end + + context 'when status_reason is nil' do + let(:gcp) { build(:provider_gcp, :errored) } + + it 'does not set status_reason' do + gcp.make_errored(nil) + + expect(gcp.status_reason).not_to be_nil + end + end + end + end + + describe '#on_creation?' do + subject { gcp.on_creation? } + + context 'when status is creating' do + let(:gcp) { create(:provider_gcp, :creating) } + + it { is_expected.to be_truthy } + end + + context 'when status is created' do + let(:gcp) { create(:provider_gcp, :created) } + + it { is_expected.to be_falsey } + end + end + + describe '#api_client' do + subject { gcp.api_client } + + context 'when status is creating' do + let(:gcp) { build(:provider_gcp, :creating) } + + it 'returns Cloud Platform API clinet' do + expect(subject).to be_an_instance_of(GoogleApi::CloudPlatform::Client) + expect(subject.access_token).to eq(gcp.access_token) + end + end + + context 'when status is created' do + let(:gcp) { build(:provider_gcp, :created) } + + it { is_expected.to be_nil } + end + + context 'when status is errored' do + let(:gcp) { build(:provider_gcp, :errored) } + + it { is_expected.to be_nil } + end + end +end diff --git a/spec/models/gcp/cluster_spec.rb b/spec/models/gcp/cluster_spec.rb deleted file mode 100644 index 8f39fff6394..00000000000 --- a/spec/models/gcp/cluster_spec.rb +++ /dev/null @@ -1,264 +0,0 @@ -require 'spec_helper' - -describe Gcp::Cluster do - it { is_expected.to belong_to(:project) } - it { is_expected.to belong_to(:user) } - it { is_expected.to belong_to(:service) } - - it { is_expected.to validate_presence_of(:gcp_cluster_zone) } - - describe '.enabled' do - subject { described_class.enabled } - - let!(:cluster) { create(:gcp_cluster, enabled: true) } - - before do - create(:gcp_cluster, enabled: false) - end - - it { is_expected.to contain_exactly(cluster) } - end - - describe '.disabled' do - subject { described_class.disabled } - - let!(:cluster) { create(:gcp_cluster, enabled: false) } - - before do - create(:gcp_cluster, enabled: true) - end - - it { is_expected.to contain_exactly(cluster) } - end - - describe '#default_value_for' do - let(:cluster) { described_class.new } - - it { expect(cluster.gcp_cluster_zone).to eq('us-central1-a') } - it { expect(cluster.gcp_cluster_size).to eq(3) } - it { expect(cluster.gcp_machine_type).to eq('n1-standard-4') } - end - - describe '#validates' do - subject { cluster.valid? } - - context 'when validates gcp_project_id' do - let(:cluster) { build(:gcp_cluster, gcp_project_id: gcp_project_id) } - - context 'when valid' do - let(:gcp_project_id) { 'gcp-project-12345' } - - it { is_expected.to be_truthy } - end - - context 'when empty' do - let(:gcp_project_id) { '' } - - it { is_expected.to be_falsey } - end - - context 'when too long' do - let(:gcp_project_id) { 'A' * 64 } - - it { is_expected.to be_falsey } - end - - context 'when includes abnormal character' do - let(:gcp_project_id) { '!!!!!!' } - - it { is_expected.to be_falsey } - end - end - - context 'when validates gcp_cluster_name' do - let(:cluster) { build(:gcp_cluster, gcp_cluster_name: gcp_cluster_name) } - - context 'when valid' do - let(:gcp_cluster_name) { 'test-cluster' } - - it { is_expected.to be_truthy } - end - - context 'when empty' do - let(:gcp_cluster_name) { '' } - - it { is_expected.to be_falsey } - end - - context 'when too long' do - let(:gcp_cluster_name) { 'A' * 64 } - - it { is_expected.to be_falsey } - end - - context 'when includes abnormal character' do - let(:gcp_cluster_name) { '!!!!!!' } - - it { is_expected.to be_falsey } - end - end - - context 'when validates gcp_cluster_size' do - let(:cluster) { build(:gcp_cluster, gcp_cluster_size: gcp_cluster_size) } - - context 'when valid' do - let(:gcp_cluster_size) { 1 } - - it { is_expected.to be_truthy } - end - - context 'when zero' do - let(:gcp_cluster_size) { 0 } - - it { is_expected.to be_falsey } - end - end - - context 'when validates project_namespace' do - let(:cluster) { build(:gcp_cluster, project_namespace: project_namespace) } - - context 'when valid' do - let(:project_namespace) { 'default-namespace' } - - it { is_expected.to be_truthy } - end - - context 'when empty' do - let(:project_namespace) { '' } - - it { is_expected.to be_truthy } - end - - context 'when too long' do - let(:project_namespace) { 'A' * 64 } - - it { is_expected.to be_falsey } - end - - context 'when includes abnormal character' do - let(:project_namespace) { '!!!!!!' } - - it { is_expected.to be_falsey } - end - end - - context 'when validates restrict_modification' do - let(:cluster) { create(:gcp_cluster) } - - before do - cluster.make_creating! - end - - context 'when created' do - before do - cluster.make_created! - end - - it { is_expected.to be_truthy } - end - - context 'when creating' do - it { is_expected.to be_falsey } - end - end - end - - describe '#state_machine' do - let(:cluster) { build(:gcp_cluster) } - - context 'when transits to created state' do - before do - cluster.gcp_token = 'tmp' - cluster.gcp_operation_id = 'tmp' - cluster.make_created! - end - - it 'nullify gcp_token and gcp_operation_id' do - expect(cluster.gcp_token).to be_nil - expect(cluster.gcp_operation_id).to be_nil - expect(cluster).to be_created - end - end - - context 'when transits to errored state' do - let(:reason) { 'something wrong' } - - before do - cluster.make_errored!(reason) - end - - it 'sets status_reason' do - expect(cluster.status_reason).to eq(reason) - expect(cluster).to be_errored - end - end - end - - describe '#project_namespace_placeholder' do - subject { cluster.project_namespace_placeholder } - - let(:cluster) { create(:gcp_cluster) } - - it 'returns a placeholder' do - is_expected.to eq("#{cluster.project.path}-#{cluster.project.id}") - end - end - - describe '#on_creation?' do - subject { cluster.on_creation? } - - let(:cluster) { create(:gcp_cluster) } - - context 'when status is creating' do - before do - cluster.make_creating! - end - - it { is_expected.to be_truthy } - end - - context 'when status is created' do - before do - cluster.make_created! - end - - it { is_expected.to be_falsey } - end - end - - describe '#api_url' do - subject { cluster.api_url } - - let(:cluster) { create(:gcp_cluster, :created_on_gke) } - let(:api_url) { 'https://' + cluster.endpoint } - - it { is_expected.to eq(api_url) } - end - - describe '#restrict_modification' do - subject { cluster.restrict_modification } - - let(:cluster) { create(:gcp_cluster) } - - context 'when status is created' do - before do - cluster.make_created! - end - - it { is_expected.to be_truthy } - end - - context 'when status is creating' do - before do - cluster.make_creating! - end - - it { is_expected.to be_falsey } - - it 'sets error' do - is_expected.to be_falsey - expect(cluster.errors).not_to be_empty - end - end - end -end -- cgit v1.2.1 From 1796936abc8873c1fcc38061fe3d8b44acda3ffe Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alejandro=20Rodr=C3=ADguez?= Date: Mon, 30 Oct 2017 20:21:56 -0300 Subject: Handle large values on `MergeRequestDiffCommit` dates --- spec/models/merge_request_diff_commit_spec.rb | 83 ++++++++++++++++++++++++++- 1 file changed, 81 insertions(+), 2 deletions(-) (limited to 'spec/models') diff --git a/spec/models/merge_request_diff_commit_spec.rb b/spec/models/merge_request_diff_commit_spec.rb index 9d4a0ecf8c0..7709cf43200 100644 --- a/spec/models/merge_request_diff_commit_spec.rb +++ b/spec/models/merge_request_diff_commit_spec.rb @@ -2,14 +2,93 @@ require 'rails_helper' describe MergeRequestDiffCommit do let(:merge_request) { create(:merge_request) } - subject { merge_request.commits.first } + let(:project) { merge_request.project } describe '#to_hash' do + subject { merge_request.commits.first } + it 'returns the same results as Commit#to_hash, except for parent_ids' do - commit_from_repo = merge_request.project.repository.commit(subject.sha) + commit_from_repo = project.repository.commit(subject.sha) commit_from_repo_hash = commit_from_repo.to_hash.merge(parent_ids: []) expect(subject.to_hash).to eq(commit_from_repo_hash) end end + + describe '.create_bulk' do + let(:sha_attribute) { Gitlab::Database::ShaAttribute.new } + let(:merge_request_diff_id) { merge_request.merge_request_diff.id } + let(:commits) do + [ + project.commit('5937ac0a7beb003549fc5fd26fc247adbce4a52e'), + project.commit('570e7b2abdd848b95f2f578043fc23bd6f6fd24d') + ] + end + let(:rows) do + [ + { + "message": "Add submodule from gitlab.com\n\nSigned-off-by: Dmitriy Zaporozhets \u003cdmitriy.zaporozhets@gmail.com\u003e\n", + "authored_date": "2014-02-27T10:01:38.000+01:00".to_time, + "author_name": "Dmitriy Zaporozhets", + "author_email": "dmitriy.zaporozhets@gmail.com", + "committed_date": "2014-02-27T10:01:38.000+01:00".to_time, + "committer_name": "Dmitriy Zaporozhets", + "committer_email": "dmitriy.zaporozhets@gmail.com", + "merge_request_diff_id": merge_request_diff_id, + "relative_order": 0, + "sha": sha_attribute.type_cast_for_database('5937ac0a7beb003549fc5fd26fc247adbce4a52e') + }, + { + "message": "Change some files\n\nSigned-off-by: Dmitriy Zaporozhets \u003cdmitriy.zaporozhets@gmail.com\u003e\n", + "authored_date": "2014-02-27T09:57:31.000+01:00".to_time, + "author_name": "Dmitriy Zaporozhets", + "author_email": "dmitriy.zaporozhets@gmail.com", + "committed_date": "2014-02-27T09:57:31.000+01:00".to_time, + "committer_name": "Dmitriy Zaporozhets", + "committer_email": "dmitriy.zaporozhets@gmail.com", + "merge_request_diff_id": merge_request_diff_id, + "relative_order": 1, + "sha": sha_attribute.type_cast_for_database('570e7b2abdd848b95f2f578043fc23bd6f6fd24d') + } + ] + end + + subject { described_class.create_bulk(merge_request_diff_id, commits) } + + it 'inserts the commits into the database en masse' do + expect(Gitlab::Database).to receive(:bulk_insert) + .with(described_class.table_name, rows) + + subject + end + + context 'with dates larger than the DB limit' do + let(:commits) do + # This commit's date is "Sun Aug 17 07:12:55 292278994 +0000" + [project.commit('ba3343bc4fa403a8dfbfcab7fc1a8c29ee34bd69')] + end + let(:timestamp) { Time.at((1 << 31) - 1) } + let(:rows) do + [{ + "message": "Weird commit date\n", + "authored_date": timestamp, + "author_name": "Alejandro Rodríguez", + "author_email": "alejorro70@gmail.com", + "committed_date": timestamp, + "committer_name": "Alejandro Rodríguez", + "committer_email": "alejorro70@gmail.com", + "merge_request_diff_id": merge_request_diff_id, + "relative_order": 0, + "sha": sha_attribute.type_cast_for_database('ba3343bc4fa403a8dfbfcab7fc1a8c29ee34bd69') + }] + end + + it 'uses a sanitized date' do + expect(Gitlab::Database).to receive(:bulk_insert) + .with(described_class.table_name, rows) + + subject + end + end + end end -- cgit v1.2.1 From 6a4534b62fad51e5e9da0d132ed64626ffdc2d10 Mon Sep 17 00:00:00 2001 From: Gabriel Mazetto Date: Tue, 31 Oct 2017 02:00:40 +0100 Subject: Code Style changes and `hashed_storage?` now receives optional feature --- spec/models/project_spec.rb | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) (limited to 'spec/models') diff --git a/spec/models/project_spec.rb b/spec/models/project_spec.rb index d80af378140..fb5d0f9db9c 100644 --- a/spec/models/project_spec.rb +++ b/spec/models/project_spec.rb @@ -2630,8 +2630,22 @@ describe Project do end describe '#hashed_storage?' do - it 'returns true' do - expect(project.hashed_storage?).to be_truthy + context 'without specifying feature' do + it 'returns true' do + expect(project.hashed_storage?).to be_truthy + end + end + + context 'specifying feature' do + it 'returns true if rolled out' do + expect(project.hashed_storage?(:attachments)).to be_truthy + end + + it 'returns false when not rolled out yet' do + project.storage_version = 1 + + expect(project.hashed_storage?(:attachments)).to be_falsey + end end end -- cgit v1.2.1 From 6a65e2f5f94781a69f3f7fb329483ead6bc81fd9 Mon Sep 17 00:00:00 2001 From: Shinya Maeda Date: Tue, 31 Oct 2017 17:47:48 +0900 Subject: specs for controller. Improved validation --- spec/models/clusters/cluster_spec.rb | 2 + spec/models/clusters/platforms/kubernetes_spec.rb | 90 ++++++++--------------- 2 files changed, 32 insertions(+), 60 deletions(-) (limited to 'spec/models') diff --git a/spec/models/clusters/cluster_spec.rb b/spec/models/clusters/cluster_spec.rb index e53ce8497f5..997ed865545 100644 --- a/spec/models/clusters/cluster_spec.rb +++ b/spec/models/clusters/cluster_spec.rb @@ -10,6 +10,8 @@ describe Clusters::Cluster do it { is_expected.to delegate_method(:status_name).to(:provider) } it { is_expected.to delegate_method(:on_creation?).to(:provider) } it { is_expected.to respond_to :project } + it { is_expected.to validate_presence_of(:provider_type) } + it { is_expected.to validate_presence_of(:platform_type) } describe '.enabled' do subject { described_class.enabled } diff --git a/spec/models/clusters/platforms/kubernetes_spec.rb b/spec/models/clusters/platforms/kubernetes_spec.rb index ec6ecee6ff2..d11ce690601 100644 --- a/spec/models/clusters/platforms/kubernetes_spec.rb +++ b/spec/models/clusters/platforms/kubernetes_spec.rb @@ -11,7 +11,7 @@ describe Clusters::Platforms::Kubernetes, :use_clean_rails_memory_store_caching describe 'before_validation' do context 'when namespace includes upper case' do - let(:kubernetes) { create(:platform_kubernetes, namespace: namespace) } + let(:kubernetes) { create(:platform_kubernetes, :configured, namespace: namespace) } let(:namespace) { 'ABC' } it 'converts to lower case' do @@ -24,7 +24,7 @@ describe Clusters::Platforms::Kubernetes, :use_clean_rails_memory_store_caching subject { kubernetes.valid? } context 'when validates namespace' do - let(:kubernetes) { build(:platform_kubernetes, namespace: namespace) } + let(:kubernetes) { build(:platform_kubernetes, :configured, namespace: namespace) } context 'when namespace is blank' do let(:namespace) { '' } @@ -52,74 +52,42 @@ describe Clusters::Platforms::Kubernetes, :use_clean_rails_memory_store_caching end context 'when validates api_url' do - context 'when updates a record' do - let(:kubernetes) { create(:platform_kubernetes) } + let(:kubernetes) { build(:platform_kubernetes, :configured) } - before do - kubernetes.api_url = api_url - end - - context 'when api_url is invalid url' do - let(:api_url) { '!!!!!!' } - - it { expect(kubernetes.save).to be_falsey } - end - - context 'when api_url is nil' do - let(:api_url) { nil } - - it { expect(kubernetes.save).to be_falsey } - end + before do + kubernetes.api_url = api_url + end - context 'when api_url is valid url' do - let(:api_url) { 'https://111.111.111.111' } + context 'when api_url is invalid url' do + let(:api_url) { '!!!!!!' } - it { expect(kubernetes.save).to be_truthy } - end + it { expect(kubernetes.save).to be_falsey } end - context 'when creates a record' do - let(:kubernetes) { build(:platform_kubernetes) } + context 'when api_url is nil' do + let(:api_url) { nil } - before do - kubernetes.api_url = api_url - end + it { expect(kubernetes.save).to be_falsey } + end - context 'when api_url is nil' do - let(:api_url) { nil } + context 'when api_url is valid url' do + let(:api_url) { 'https://111.111.111.111' } - it { expect(kubernetes.save).to be_truthy } - end + it { expect(kubernetes.save).to be_truthy } end end context 'when validates token' do - context 'when updates a record' do - let(:kubernetes) { create(:platform_kubernetes) } + let(:kubernetes) { build(:platform_kubernetes, :configured) } - before do - kubernetes.token = token - end - - context 'when token is nil' do - let(:token) { nil } - - it { expect(kubernetes.save).to be_falsey } - end + before do + kubernetes.token = token end - context 'when creates a record' do - let(:kubernetes) { build(:platform_kubernetes) } + context 'when token is nil' do + let(:token) { nil } - before do - kubernetes.token = token - end - - context 'when token is nil' do - let(:token) { nil } - - it { expect(kubernetes.save).to be_truthy } - end + it { expect(kubernetes.save).to be_falsey } end end end @@ -128,7 +96,8 @@ describe Clusters::Platforms::Kubernetes, :use_clean_rails_memory_store_caching subject { kubernetes.actual_namespace } let!(:cluster) { create(:cluster, :project, platform_kubernetes: kubernetes) } - let(:kubernetes) { create(:platform_kubernetes, namespace: namespace) } + let(:project) { cluster.project } + let(:kubernetes) { create(:platform_kubernetes, :configured, namespace: namespace) } context 'when namespace is present' do let(:namespace) { 'namespace-123' } @@ -139,7 +108,7 @@ describe Clusters::Platforms::Kubernetes, :use_clean_rails_memory_store_caching context 'when namespace is not present' do let(:namespace) { nil } - it { is_expected.to eq("#{cluster.project.path}-#{cluster.project.id}") } + it { is_expected.to eq("#{project.path}-#{project.id}") } end end @@ -154,12 +123,13 @@ describe Clusters::Platforms::Kubernetes, :use_clean_rails_memory_store_caching describe '#default_namespace' do subject { kubernetes.default_namespace } - let(:kubernetes) { create(:platform_kubernetes) } + let(:kubernetes) { create(:platform_kubernetes, :configured) } context 'when cluster belongs to a project' do let!(:cluster) { create(:cluster, :project, platform_kubernetes: kubernetes) } + let(:project) { cluster.project } - it { is_expected.to eq("#{cluster.project.path}-#{cluster.project.id}") } + it { is_expected.to eq("#{project.path}-#{project.id}") } end context 'when cluster belongs to nothing' do @@ -229,7 +199,7 @@ describe Clusters::Platforms::Kubernetes, :use_clean_rails_memory_store_caching let!(:cluster) { create(:cluster, :project, platform_kubernetes: service) } let(:project) { cluster.project } - let(:service) { create(:platform_kubernetes) } + let(:service) { create(:platform_kubernetes, :configured) } let(:environment) { build(:environment, project: project, name: "env", slug: "env-000000") } context 'with invalid pods' do @@ -268,7 +238,7 @@ describe Clusters::Platforms::Kubernetes, :use_clean_rails_memory_store_caching subject { service.calculate_reactive_cache } let!(:cluster) { create(:cluster, :project, enabled: enabled, platform_kubernetes: service) } - let(:service) { create(:platform_kubernetes, :ca_cert) } + let(:service) { create(:platform_kubernetes, :configured) } let(:enabled) { true } context 'when cluster is disabled' do -- cgit v1.2.1 From 9c41c7ac1ea2e9085424e3eb1fe9924243affb7c Mon Sep 17 00:00:00 2001 From: Gabriel Mazetto Date: Tue, 31 Oct 2017 11:31:57 +0100 Subject: Make `#hashed_storage?` require feature argument --- spec/models/project_spec.rb | 20 ++++++-------------- 1 file changed, 6 insertions(+), 14 deletions(-) (limited to 'spec/models') diff --git a/spec/models/project_spec.rb b/spec/models/project_spec.rb index fb5d0f9db9c..5eaff405c0e 100644 --- a/spec/models/project_spec.rb +++ b/spec/models/project_spec.rb @@ -2494,7 +2494,7 @@ describe Project do describe '#hashed_storage?' do it 'returns false' do - expect(project.hashed_storage?).to be_falsey + expect(project.hashed_storage?(:repository)).to be_falsey end end @@ -2630,22 +2630,14 @@ describe Project do end describe '#hashed_storage?' do - context 'without specifying feature' do - it 'returns true' do - expect(project.hashed_storage?).to be_truthy - end + it 'returns true if rolled out' do + expect(project.hashed_storage?(:attachments)).to be_truthy end - context 'specifying feature' do - it 'returns true if rolled out' do - expect(project.hashed_storage?(:attachments)).to be_truthy - end - - it 'returns false when not rolled out yet' do - project.storage_version = 1 + it 'returns false when not rolled out yet' do + project.storage_version = 1 - expect(project.hashed_storage?(:attachments)).to be_falsey - end + expect(project.hashed_storage?(:attachments)).to be_falsey end end -- cgit v1.2.1 From b3a0166203e4b187de8956a14b40957f7d967e32 Mon Sep 17 00:00:00 2001 From: Ahmad Sherif Date: Tue, 31 Oct 2017 12:38:15 +0200 Subject: Migrate Gitlab::Git::Wiki#delete_page to Gitaly Closes gitaly#673 --- spec/models/project_wiki_spec.rb | 38 ++++++++++++++++++++++++-------------- spec/models/wiki_page_spec.rb | 2 +- 2 files changed, 25 insertions(+), 15 deletions(-) (limited to 'spec/models') diff --git a/spec/models/project_wiki_spec.rb b/spec/models/project_wiki_spec.rb index f10d9383ae2..95d58b96f33 100644 --- a/spec/models/project_wiki_spec.rb +++ b/spec/models/project_wiki_spec.rb @@ -265,23 +265,33 @@ describe ProjectWiki do end describe "#delete_page" do - before do - create_page("index", "some content") - @page = subject.wiki.page(title: "index") - end + shared_examples 'deleting a wiki page' do + before do + create_page("index", "some content") + @page = subject.wiki.page(title: "index") + end - it "deletes the page" do - subject.delete_page(@page) - expect(subject.pages.count).to eq(0) - end + it "deletes the page" do + subject.delete_page(@page) + expect(subject.pages.count).to eq(0) + end - it 'updates project activity' do - subject.delete_page(@page) + it 'updates project activity' do + subject.delete_page(@page) - project.reload + project.reload - expect(project.last_activity_at).to be_within(1.minute).of(Time.now) - expect(project.last_repository_updated_at).to be_within(1.minute).of(Time.now) + expect(project.last_activity_at).to be_within(1.minute).of(Time.now) + expect(project.last_repository_updated_at).to be_within(1.minute).of(Time.now) + end + end + + context 'when Gitaly wiki_delete_page is enabled' do + it_behaves_like 'deleting a wiki page' + end + + context 'when Gitaly wiki_delete_page is disabled', :skip_gitaly_mock do + it_behaves_like 'deleting a wiki page' end end @@ -343,6 +353,6 @@ describe ProjectWiki do end def destroy_page(page) - subject.delete_page(page, commit_details) + subject.delete_page(page, "test commit") end end diff --git a/spec/models/wiki_page_spec.rb b/spec/models/wiki_page_spec.rb index 1f14d06997e..a7227b38850 100644 --- a/spec/models/wiki_page_spec.rb +++ b/spec/models/wiki_page_spec.rb @@ -402,7 +402,7 @@ describe WikiPage do def destroy_page(title) page = wiki.wiki.page(title: title) - wiki.delete_page(page, commit_details) + wiki.delete_page(page, "test commit") end def get_slugs(page_or_dir) -- cgit v1.2.1 From 8399de0c961be75d0cd90e59a7e89fabc11025b8 Mon Sep 17 00:00:00 2001 From: Douwe Maan Date: Tue, 31 Oct 2017 10:52:44 +0100 Subject: Normalize LDAP DN when looking up identity --- spec/models/identity_spec.rb | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) (limited to 'spec/models') diff --git a/spec/models/identity_spec.rb b/spec/models/identity_spec.rb index 4ca6556d0f4..3ed048744de 100644 --- a/spec/models/identity_spec.rb +++ b/spec/models/identity_spec.rb @@ -1,6 +1,6 @@ require 'spec_helper' -RSpec.describe Identity do +describe Identity do describe 'relations' do it { is_expected.to belong_to(:user) } end @@ -22,4 +22,16 @@ RSpec.describe Identity do expect(other_identity.ldap?).to be_falsey end end + + describe '.with_extern_uid' do + context 'LDAP identity' do + let!(:ldap_identity) { create(:identity, provider: 'ldapmain', extern_uid: 'uid=john smith,ou=people,dc=example,dc=com') } + + it 'finds the identity when the DN is formatted differently' do + identity = described_class.with_extern_uid('ldapmain', 'uid=John Smith, ou=People, dc=example, dc=com').first + + expect(identity).to eq(ldap_identity) + end + end + end end -- cgit v1.2.1 From 6dc9028fbb3856c8c7814446ed176880f7d5213f Mon Sep 17 00:00:00 2001 From: Eric Eastwood Date: Tue, 31 Oct 2017 16:15:03 +0000 Subject: Load participants async --- spec/models/concerns/subscribable_spec.rb | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'spec/models') diff --git a/spec/models/concerns/subscribable_spec.rb b/spec/models/concerns/subscribable_spec.rb index 28ff8158e0e..45dfb136aea 100644 --- a/spec/models/concerns/subscribable_spec.rb +++ b/spec/models/concerns/subscribable_spec.rb @@ -6,6 +6,12 @@ describe Subscribable, 'Subscribable' do let(:user_1) { create(:user) } describe '#subscribed?' do + context 'without user' do + it 'returns false' do + expect(resource.subscribed?(nil, project)).to be_falsey + end + end + context 'without project' do it 'returns false when no subscription exists' do expect(resource.subscribed?(user_1)).to be_falsey -- cgit v1.2.1 From 964cbb67da78dc89dbe32c113c5bee8f805d2784 Mon Sep 17 00:00:00 2001 From: Ahmad Sherif Date: Thu, 19 Oct 2017 16:18:26 +0200 Subject: Migrate Gitlab::Git::Wiki#page to Gitaly Closes gitaly#677 --- spec/models/project_wiki_spec.rb | 46 ++++++++++++++++++++++++---------------- 1 file changed, 28 insertions(+), 18 deletions(-) (limited to 'spec/models') diff --git a/spec/models/project_wiki_spec.rb b/spec/models/project_wiki_spec.rb index 95d58b96f33..52a2b4b2850 100644 --- a/spec/models/project_wiki_spec.rb +++ b/spec/models/project_wiki_spec.rb @@ -117,31 +117,41 @@ describe ProjectWiki do end describe "#find_page" do - before do - create_page("index page", "This is an awesome Gollum Wiki") - end + shared_examples 'finding a wiki page' do + before do + create_page("index page", "This is an awesome Gollum Wiki") + end - after do - destroy_page(subject.pages.first.page) - end + after do + destroy_page(subject.pages.first.page) + end - it "returns the latest version of the page if it exists" do - page = subject.find_page("index page") - expect(page.title).to eq("index page") - end + it "returns the latest version of the page if it exists" do + page = subject.find_page("index page") + expect(page.title).to eq("index page") + end + + it "returns nil if the page does not exist" do + expect(subject.find_page("non-existant")).to eq(nil) + end + + it "can find a page by slug" do + page = subject.find_page("index-page") + expect(page.title).to eq("index page") + end - it "returns nil if the page does not exist" do - expect(subject.find_page("non-existant")).to eq(nil) + it "returns a WikiPage instance" do + page = subject.find_page("index page") + expect(page).to be_a WikiPage + end end - it "can find a page by slug" do - page = subject.find_page("index-page") - expect(page.title).to eq("index page") + context 'when Gitaly wiki_find_page is enabled' do + it_behaves_like 'finding a wiki page' end - it "returns a WikiPage instance" do - page = subject.find_page("index page") - expect(page).to be_a WikiPage + context 'when Gitaly wiki_find_page is disabled', :skip_gitaly_mock do + it_behaves_like 'finding a wiki page' end end -- cgit v1.2.1 From 56e53556c538236a040dcd0e499cc198d66e7cf6 Mon Sep 17 00:00:00 2001 From: Ahmad Sherif Date: Mon, 23 Oct 2017 22:12:11 +0200 Subject: Migrate Gitlab::Git::Wiki#file to Gitaly Closes gitaly#689 --- spec/models/project_wiki_spec.rb | 47 ++++++++++++++++++++-------------------- 1 file changed, 23 insertions(+), 24 deletions(-) (limited to 'spec/models') diff --git a/spec/models/project_wiki_spec.rb b/spec/models/project_wiki_spec.rb index 52a2b4b2850..3d46434fc27 100644 --- a/spec/models/project_wiki_spec.rb +++ b/spec/models/project_wiki_spec.rb @@ -156,36 +156,35 @@ describe ProjectWiki do end describe '#find_file' do - before do - file = Gollum::File.new(subject.wiki) - allow_any_instance_of(Gollum::Wiki) - .to receive(:file).with('image.jpg', 'master') - .and_return(file) - allow_any_instance_of(Gollum::File) - .to receive(:mime_type) - .and_return('image/jpeg') - allow_any_instance_of(Gollum::Wiki) - .to receive(:file).with('non-existant', 'master') - .and_return(nil) - end + shared_examples 'finding a wiki file' do + before do + file = File.open(Rails.root.join('spec', 'fixtures', 'dk.png')) + subject.wiki # Make sure the wiki repo exists - after do - allow_any_instance_of(Gollum::Wiki).to receive(:file).and_call_original - allow_any_instance_of(Gollum::File).to receive(:mime_type).and_call_original - end + BareRepoOperations.new(subject.repository.path_to_repo).commit_file(file, 'image.png') + end - it 'returns the latest version of the file if it exists' do - file = subject.find_file('image.jpg') - expect(file.mime_type).to eq('image/jpeg') + it 'returns the latest version of the file if it exists' do + file = subject.find_file('image.png') + expect(file.mime_type).to eq('image/png') + end + + it 'returns nil if the page does not exist' do + expect(subject.find_file('non-existant')).to eq(nil) + end + + it 'returns a Gitlab::Git::WikiFile instance' do + file = subject.find_file('image.png') + expect(file).to be_a Gitlab::Git::WikiFile + end end - it 'returns nil if the page does not exist' do - expect(subject.find_file('non-existant')).to eq(nil) + context 'when Gitaly wiki_find_file is enabled' do + it_behaves_like 'finding a wiki file' end - it 'returns a Gitlab::Git::WikiFile instance' do - file = subject.find_file('image.jpg') - expect(file).to be_a Gitlab::Git::WikiFile + context 'when Gitaly wiki_find_file is disabled', :skip_gitaly_mock do + it_behaves_like 'finding a wiki file' end end -- cgit v1.2.1 From 253bf69dda460869741bc6c9d864c789055b8013 Mon Sep 17 00:00:00 2001 From: Shinya Maeda Date: Wed, 1 Nov 2017 03:59:40 +0900 Subject: specs for feature --- spec/models/clusters/platforms/kubernetes_spec.rb | 56 +++++++++++----------- .../project_services/kubernetes_service_spec.rb | 4 +- 2 files changed, 30 insertions(+), 30 deletions(-) (limited to 'spec/models') diff --git a/spec/models/clusters/platforms/kubernetes_spec.rb b/spec/models/clusters/platforms/kubernetes_spec.rb index d11ce690601..df68720ffd8 100644 --- a/spec/models/clusters/platforms/kubernetes_spec.rb +++ b/spec/models/clusters/platforms/kubernetes_spec.rb @@ -51,45 +51,45 @@ describe Clusters::Platforms::Kubernetes, :use_clean_rails_memory_store_caching end end - context 'when validates api_url' do - let(:kubernetes) { build(:platform_kubernetes, :configured) } + # context 'when validates api_url' do + # let(:kubernetes) { build(:platform_kubernetes, :configured) } - before do - kubernetes.api_url = api_url - end + # before do + # kubernetes.api_url = api_url + # end - context 'when api_url is invalid url' do - let(:api_url) { '!!!!!!' } + # context 'when api_url is invalid url' do + # let(:api_url) { '!!!!!!' } - it { expect(kubernetes.save).to be_falsey } - end + # it { expect(kubernetes.save).to be_falsey } + # end - context 'when api_url is nil' do - let(:api_url) { nil } + # context 'when api_url is nil' do + # let(:api_url) { nil } - it { expect(kubernetes.save).to be_falsey } - end + # it { expect(kubernetes.save).to be_falsey } + # end - context 'when api_url is valid url' do - let(:api_url) { 'https://111.111.111.111' } + # context 'when api_url is valid url' do + # let(:api_url) { 'https://111.111.111.111' } - it { expect(kubernetes.save).to be_truthy } - end - end + # it { expect(kubernetes.save).to be_truthy } + # end + # end - context 'when validates token' do - let(:kubernetes) { build(:platform_kubernetes, :configured) } + # context 'when validates token' do + # let(:kubernetes) { build(:platform_kubernetes, :configured) } - before do - kubernetes.token = token - end + # before do + # kubernetes.token = token + # end - context 'when token is nil' do - let(:token) { nil } + # context 'when token is nil' do + # let(:token) { nil } - it { expect(kubernetes.save).to be_falsey } - end - end + # it { expect(kubernetes.save).to be_falsey } + # end + # end end describe '#actual_namespace' do diff --git a/spec/models/project_services/kubernetes_service_spec.rb b/spec/models/project_services/kubernetes_service_spec.rb index 2298dcab55f..0840a867aed 100644 --- a/spec/models/project_services/kubernetes_service_spec.rb +++ b/spec/models/project_services/kubernetes_service_spec.rb @@ -156,7 +156,7 @@ describe KubernetesService, :use_clean_rails_memory_store_caching do let(:discovery_url) { 'https://kubernetes.example.com/api/v1' } before do - stub_kubeclient_discover + stub_kubeclient_discover(service.api_url) end context 'with path prefix in api_url' do @@ -164,7 +164,7 @@ describe KubernetesService, :use_clean_rails_memory_store_caching do it 'tests with the prefix' do service.api_url = 'https://kubernetes.example.com/prefix' - stub_kubeclient_discover + stub_kubeclient_discover(service.api_url) expect(service.test[:success]).to be_truthy expect(WebMock).to have_requested(:get, discovery_url).once -- cgit v1.2.1 From 6571efb6c3afd568c019e7bb46aba84328a4e821 Mon Sep 17 00:00:00 2001 From: Shinya Maeda Date: Wed, 1 Nov 2017 16:12:44 +0900 Subject: Fix spec. Fix usage ping. Fix warnings by adding new models and attributes. --- spec/models/clusters/platforms/kubernetes_spec.rb | 56 +++++++++++------------ 1 file changed, 28 insertions(+), 28 deletions(-) (limited to 'spec/models') diff --git a/spec/models/clusters/platforms/kubernetes_spec.rb b/spec/models/clusters/platforms/kubernetes_spec.rb index df68720ffd8..d11ce690601 100644 --- a/spec/models/clusters/platforms/kubernetes_spec.rb +++ b/spec/models/clusters/platforms/kubernetes_spec.rb @@ -51,45 +51,45 @@ describe Clusters::Platforms::Kubernetes, :use_clean_rails_memory_store_caching end end - # context 'when validates api_url' do - # let(:kubernetes) { build(:platform_kubernetes, :configured) } + context 'when validates api_url' do + let(:kubernetes) { build(:platform_kubernetes, :configured) } - # before do - # kubernetes.api_url = api_url - # end + before do + kubernetes.api_url = api_url + end - # context 'when api_url is invalid url' do - # let(:api_url) { '!!!!!!' } + context 'when api_url is invalid url' do + let(:api_url) { '!!!!!!' } - # it { expect(kubernetes.save).to be_falsey } - # end + it { expect(kubernetes.save).to be_falsey } + end - # context 'when api_url is nil' do - # let(:api_url) { nil } + context 'when api_url is nil' do + let(:api_url) { nil } - # it { expect(kubernetes.save).to be_falsey } - # end + it { expect(kubernetes.save).to be_falsey } + end - # context 'when api_url is valid url' do - # let(:api_url) { 'https://111.111.111.111' } + context 'when api_url is valid url' do + let(:api_url) { 'https://111.111.111.111' } - # it { expect(kubernetes.save).to be_truthy } - # end - # end + it { expect(kubernetes.save).to be_truthy } + end + end - # context 'when validates token' do - # let(:kubernetes) { build(:platform_kubernetes, :configured) } + context 'when validates token' do + let(:kubernetes) { build(:platform_kubernetes, :configured) } - # before do - # kubernetes.token = token - # end + before do + kubernetes.token = token + end - # context 'when token is nil' do - # let(:token) { nil } + context 'when token is nil' do + let(:token) { nil } - # it { expect(kubernetes.save).to be_falsey } - # end - # end + it { expect(kubernetes.save).to be_falsey } + end + end end describe '#actual_namespace' do -- cgit v1.2.1 From 294fa6fcdcfa7d76bc97b754d2930f3686f54997 Mon Sep 17 00:00:00 2001 From: Douwe Maan Date: Thu, 12 Oct 2017 11:01:12 +0200 Subject: Remove authentication using user.private_token --- spec/models/concerns/token_authenticatable_spec.rb | 2 +- spec/models/user_spec.rb | 9 --------- 2 files changed, 1 insertion(+), 10 deletions(-) (limited to 'spec/models') diff --git a/spec/models/concerns/token_authenticatable_spec.rb b/spec/models/concerns/token_authenticatable_spec.rb index 882afeccfc6..dfb83578fce 100644 --- a/spec/models/concerns/token_authenticatable_spec.rb +++ b/spec/models/concerns/token_authenticatable_spec.rb @@ -12,7 +12,7 @@ shared_examples 'TokenAuthenticatable' do end describe User, 'TokenAuthenticatable' do - let(:token_field) { :authentication_token } + let(:token_field) { :rss_token } it_behaves_like 'TokenAuthenticatable' describe 'ensures authentication token' do diff --git a/spec/models/user_spec.rb b/spec/models/user_spec.rb index 1c3c9068f12..fb03e320734 100644 --- a/spec/models/user_spec.rb +++ b/spec/models/user_spec.rb @@ -346,7 +346,6 @@ describe User do describe "Respond to" do it { is_expected.to respond_to(:admin?) } it { is_expected.to respond_to(:name) } - it { is_expected.to respond_to(:private_token) } it { is_expected.to respond_to(:external?) } end @@ -526,14 +525,6 @@ describe User do end end - describe 'authentication token' do - it "has authentication token" do - user = create(:user) - - expect(user.authentication_token).not_to be_blank - end - end - describe 'ensure incoming email token' do it 'has incoming email token' do user = create(:user) -- cgit v1.2.1 From 3602c0b9874c6b93e6cf55e1cb0238951784604d Mon Sep 17 00:00:00 2001 From: Shinya Maeda Date: Fri, 3 Nov 2017 03:37:32 +0900 Subject: Fix some tests --- spec/models/clusters/cluster_spec.rb | 3 +- spec/models/clusters/platforms/kubernetes_spec.rb | 185 ++++++---------------- 2 files changed, 51 insertions(+), 137 deletions(-) (limited to 'spec/models') diff --git a/spec/models/clusters/cluster_spec.rb b/spec/models/clusters/cluster_spec.rb index 997ed865545..12123a3d753 100644 --- a/spec/models/clusters/cluster_spec.rb +++ b/spec/models/clusters/cluster_spec.rb @@ -9,9 +9,8 @@ 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 } - it { is_expected.to validate_presence_of(:provider_type) } - it { is_expected.to validate_presence_of(:platform_type) } describe '.enabled' do subject { described_class.enabled } diff --git a/spec/models/clusters/platforms/kubernetes_spec.rb b/spec/models/clusters/platforms/kubernetes_spec.rb index d11ce690601..71d06a4ae66 100644 --- a/spec/models/clusters/platforms/kubernetes_spec.rb +++ b/spec/models/clusters/platforms/kubernetes_spec.rb @@ -5,8 +5,6 @@ describe Clusters::Platforms::Kubernetes, :use_clean_rails_memory_store_caching include ReactiveCachingHelpers it { is_expected.to belong_to(:cluster) } - it { is_expected.to be_kind_of(Gitlab::Kubernetes) } - it { is_expected.to be_kind_of(ReactiveCaching) } it { is_expected.to respond_to :ca_pem } describe 'before_validation' do @@ -92,6 +90,56 @@ 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(:platform_kubernetes, :configured) } + let(:provider) { build(: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 + # TODO: This doesn't work as intended because `enabled?` in Clusters::Platforms::Kubernetes is still true without `reload` + 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(:platform_kubernetes, :configured, api_url: 'https://111.111.111.111') } + let(:provider) { build(: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 } @@ -138,137 +186,4 @@ describe Clusters::Platforms::Kubernetes, :use_clean_rails_memory_store_caching it { is_expected.to be_nil } end end - - describe '#predefined_variables' do - let!(:cluster) { create(:cluster, :project, platform_kubernetes: kubernetes) } - let(:kubernetes) { create(:platform_kubernetes, api_url: api_url, ca_cert: ca_pem, token: token) } - let(:api_url) { 'https://kube.domain.com' } - let(:ca_pem) { 'CA PEM DATA' } - let(:token) { 'token' } - - let(:kubeconfig) do - config_file = expand_fixture_path('config/kubeconfig.yml') - config = YAML.load(File.read(config_file)) - config.dig('users', 0, 'user')['token'] = token - config.dig('contexts', 0, 'context')['namespace'] = namespace - config.dig('clusters', 0, 'cluster')['certificate-authority-data'] = - Base64.strict_encode64(ca_pem) - - YAML.dump(config) - end - - shared_examples 'setting variables' do - it 'sets the variables' do - expect(kubernetes.predefined_variables).to include( - { key: 'KUBE_URL', value: api_url, public: true }, - { key: 'KUBE_TOKEN', value: token, public: false }, - { key: 'KUBE_NAMESPACE', value: namespace, public: true }, - { key: 'KUBECONFIG', value: kubeconfig, public: false, file: true }, - { key: 'KUBE_CA_PEM', value: ca_pem, public: true }, - { key: 'KUBE_CA_PEM_FILE', value: ca_pem, public: true, file: true } - ) - end - end - - context 'namespace is provided' do - let(:namespace) { 'my-project' } - - before do - kubernetes.namespace = namespace - end - - it_behaves_like 'setting variables' - end - - context 'no namespace provided' do - let(:namespace) { kubernetes.actual_namespace } - - it_behaves_like 'setting variables' - - it 'sets the KUBE_NAMESPACE' do - kube_namespace = kubernetes.predefined_variables.find { |h| h[:key] == 'KUBE_NAMESPACE' } - - expect(kube_namespace).not_to be_nil - expect(kube_namespace[:value]).to match(/\A#{Gitlab::PathRegex::PATH_REGEX_STR}-\d+\z/) - end - end - end - - describe '#terminals' do - subject { service.terminals(environment) } - - let!(:cluster) { create(:cluster, :project, platform_kubernetes: service) } - let(:project) { cluster.project } - let(:service) { create(:platform_kubernetes, :configured) } - let(:environment) { build(:environment, project: project, name: "env", slug: "env-000000") } - - context 'with invalid pods' do - it 'returns no terminals' do - stub_reactive_cache(service, pods: [{ "bad" => "pod" }]) - - is_expected.to be_empty - end - end - - context 'with valid pods' do - let(:pod) { kube_pod(app: environment.slug) } - let(:terminals) { kube_terminals(service, pod) } - - before do - stub_reactive_cache( - service, - pods: [pod, pod, kube_pod(app: "should-be-filtered-out")] - ) - end - - it 'returns terminals' do - is_expected.to eq(terminals + terminals) - end - - it 'uses max session time from settings' do - stub_application_setting(terminal_max_session_time: 600) - - times = subject.map { |terminal| terminal[:max_session_time] } - expect(times).to eq [600, 600, 600, 600] - end - end - end - - describe '#calculate_reactive_cache' do - subject { service.calculate_reactive_cache } - - let!(:cluster) { create(:cluster, :project, enabled: enabled, platform_kubernetes: service) } - let(:service) { create(:platform_kubernetes, :configured) } - let(:enabled) { true } - - context 'when cluster is disabled' do - let(:enabled) { false } - - it { is_expected.to be_nil } - end - - context 'when kubernetes responds with valid pods' do - before do - stub_kubeclient_pods - end - - it { is_expected.to eq(pods: [kube_pod]) } - end - - context 'when kubernetes responds with 500s' do - before do - stub_kubeclient_pods(status: 500) - end - - it { expect { subject }.to raise_error(KubeException) } - end - - context 'when kubernetes responds with 404s' do - before do - stub_kubeclient_pods(status: 404) - end - - it { is_expected.to eq(pods: []) } - end - end end -- cgit v1.2.1 From 0b18023c89864b7e38e4dc43cff9f8ad4017c044 Mon Sep 17 00:00:00 2001 From: Stan Hu Date: Thu, 2 Nov 2017 15:32:22 -0700 Subject: Avoid regenerating the ref path for the environment Closes #39752 --- spec/models/environment_spec.rb | 15 +++++++++++++++ 1 file changed, 15 insertions(+) (limited to 'spec/models') diff --git a/spec/models/environment_spec.rb b/spec/models/environment_spec.rb index e1be23541e8..f75de0a0d88 100644 --- a/spec/models/environment_spec.rb +++ b/spec/models/environment_spec.rb @@ -547,6 +547,15 @@ describe Environment do expect(environment.slug).to eq(original_slug) end + + it "regenerates the slug if nil" do + environment = build(:environment, slug: nil) + + new_slug = environment.slug + + expect(new_slug).not_to be_nil + expect(environment.slug).to eq(new_slug) + end end describe '#generate_slug' do @@ -583,6 +592,12 @@ describe Environment do it 'returns a path that uses the slug and does not have spaces' do expect(environment.ref_path).to start_with('refs/environments/staging-review-1-') end + + it "doesn't change when the slug is nil initially" do + environment.slug = nil + + expect(environment.ref_path).to eq(environment.ref_path) + end end describe '#external_url_for' do -- cgit v1.2.1 From 600d5f4fba4f73ef438db651d20da92080e5b3b0 Mon Sep 17 00:00:00 2001 From: Shinya Maeda Date: Fri, 3 Nov 2017 17:22:49 +0900 Subject: Fix tests. Remove NOT NULL constraint from cluster.user. --- spec/models/clusters/platforms/kubernetes_spec.rb | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'spec/models') diff --git a/spec/models/clusters/platforms/kubernetes_spec.rb b/spec/models/clusters/platforms/kubernetes_spec.rb index 71d06a4ae66..e6ebe079ceb 100644 --- a/spec/models/clusters/platforms/kubernetes_spec.rb +++ b/spec/models/clusters/platforms/kubernetes_spec.rb @@ -117,7 +117,6 @@ describe Clusters::Platforms::Kubernetes, :use_clean_rails_memory_store_caching let(:kubernetes_service) { project.kubernetes_service } it 'updates KubernetesService' do - # TODO: This doesn't work as intended because `enabled?` in Clusters::Platforms::Kubernetes is still true without `reload` cluster.update(enabled: enabled) expect(kubernetes_service.active).to eq(enabled) @@ -135,7 +134,7 @@ describe Clusters::Platforms::Kubernetes, :use_clean_rails_memory_store_caching end it 'raises an error' do - expect{ cluster.save! }.to raise_error('Kubernetes service already configured') + expect { cluster.save! }.to raise_error('Kubernetes service already configured') end end end -- cgit v1.2.1 From 39d00bddc494c7f13527887e005b53431642d24c Mon Sep 17 00:00:00 2001 From: Bob Van Landuyt Date: Fri, 3 Nov 2017 11:08:36 +0100 Subject: Make sure the settings page renders when root of a fork is deleted --- spec/models/project_spec.rb | 14 ++++++++++++++ 1 file changed, 14 insertions(+) (limited to 'spec/models') diff --git a/spec/models/project_spec.rb b/spec/models/project_spec.rb index ed6e42d476e..e8588975118 100644 --- a/spec/models/project_spec.rb +++ b/spec/models/project_spec.rb @@ -1923,6 +1923,20 @@ describe Project do expect(forked_project.in_fork_network_of?(other_project)).to be_falsy end end + + describe '#fork_source' do + let!(:second_fork) { fork_project(forked_project) } + + it 'returns the direct source if it exists' do + expect(second_fork.fork_source).to eq(forked_project) + end + + it 'returns the root of the fork network when the directs source was deleted' do + forked_project.destroy + + expect(second_fork.fork_source).to eq(project) + end + end end describe '#pushes_since_gc' do -- cgit v1.2.1 From 7582bc8b4eacfe70ecc575f724285de471d6c743 Mon Sep 17 00:00:00 2001 From: Bob Van Landuyt Date: Fri, 3 Nov 2017 11:31:29 +0100 Subject: Unlink a project from a fork network when it's source was deleted. We need to close all merge requests coming from the project within the entire fork network. --- spec/models/fork_network_spec.rb | 10 ++++++++++ 1 file changed, 10 insertions(+) (limited to 'spec/models') diff --git a/spec/models/fork_network_spec.rb b/spec/models/fork_network_spec.rb index 605ccd6db06..a43baf1820a 100644 --- a/spec/models/fork_network_spec.rb +++ b/spec/models/fork_network_spec.rb @@ -24,6 +24,16 @@ describe ForkNetwork do end end + describe '#merge_requests' do + it 'finds merge requests within the fork network' do + project = create(:project) + forked_project = fork_project(project) + merge_request = create(:merge_request, source_project: forked_project, target_project: project) + + expect(project.fork_network.merge_requests).to include(merge_request) + end + end + context 'for a deleted project' do it 'keeps the fork network' do project = create(:project, :public) -- cgit v1.2.1 From 6f1a4ba457afd92a12913a9eddd7af483f5cfff1 Mon Sep 17 00:00:00 2001 From: Winnie Hellmann Date: Fri, 3 Nov 2017 11:26:52 +0000 Subject: Add system hooks user_rename and group_rename --- spec/models/concerns/routable_spec.rb | 1 + spec/models/group_spec.rb | 41 +++++++++++++++++++++++++++++++++++ spec/models/user_spec.rb | 36 ++++++++++++++++++++++++++++++ 3 files changed, 78 insertions(+) (limited to 'spec/models') diff --git a/spec/models/concerns/routable_spec.rb b/spec/models/concerns/routable_spec.rb index ab8773b7ede..3106207811a 100644 --- a/spec/models/concerns/routable_spec.rb +++ b/spec/models/concerns/routable_spec.rb @@ -134,6 +134,7 @@ describe Group, 'Routable' do context 'with RequestStore active', :request_store do it 'does not load the route table more than once' do + group.expires_full_path_cache expect(group).to receive(:uncached_full_path).once.and_call_original 3.times { group.full_path } diff --git a/spec/models/group_spec.rb b/spec/models/group_spec.rb index f36d6eeb327..0e1a7fdce0b 100644 --- a/spec/models/group_spec.rb +++ b/spec/models/group_spec.rb @@ -488,6 +488,47 @@ describe Group do end end + describe '#path_changed_hook' do + let(:system_hook_service) { SystemHooksService.new } + + context 'for a new group' do + let(:group) { build(:group) } + + before do + expect(group).to receive(:system_hook_service).and_return(system_hook_service) + end + + it 'does not trigger system hook' do + expect(system_hook_service).to receive(:execute_hooks_for).with(group, :create) + + group.save! + end + end + + context 'for an existing group' do + let(:group) { create(:group, path: 'old-path') } + + context 'when the path is changed' do + let(:new_path) { 'very-new-path' } + + it 'triggers the rename system hook' do + expect(group).to receive(:system_hook_service).and_return(system_hook_service) + expect(system_hook_service).to receive(:execute_hooks_for).with(group, :rename) + + group.update_attributes!(path: new_path) + end + end + + context 'when the path is not changed' do + it 'does not trigger system hook' do + expect(group).not_to receive(:system_hook_service) + + group.update_attributes!(name: 'new name') + end + end + end + end + describe '#secret_variables_for' do let(:project) { create(:project, group: group) } diff --git a/spec/models/user_spec.rb b/spec/models/user_spec.rb index fb03e320734..e0896d64c8f 100644 --- a/spec/models/user_spec.rb +++ b/spec/models/user_spec.rb @@ -2217,6 +2217,42 @@ describe User do end end + describe '#username_changed_hook' do + context 'for a new user' do + let(:user) { build(:user) } + + it 'does not trigger system hook' do + expect(user).not_to receive(:system_hook_service) + + user.save! + end + end + + context 'for an existing user' do + let(:user) { create(:user, username: 'old-username') } + + context 'when the username is changed' do + let(:new_username) { 'very-new-name' } + + it 'triggers the rename system hook' do + system_hook_service = SystemHooksService.new + expect(system_hook_service).to receive(:execute_hooks_for).with(user, :rename) + expect(user).to receive(:system_hook_service).and_return(system_hook_service) + + user.update_attributes!(username: new_username) + end + end + + context 'when the username is not changed' do + it 'does not trigger system hook' do + expect(user).not_to receive(:system_hook_service) + + user.update_attributes!(email: 'asdf@asdf.com') + end + end + end + end + describe '#sync_attribute?' do let(:user) { described_class.new } -- cgit v1.2.1 From 3f0233e5b531b44b2c276c8e8f536af6d2c15db3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alejandro=20Rodr=C3=ADguez?= Date: Thu, 19 Oct 2017 13:27:03 -0300 Subject: Create a Wiki Repository's raw_repository properly --- spec/models/repository_spec.rb | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) (limited to 'spec/models') diff --git a/spec/models/repository_spec.rb b/spec/models/repository_spec.rb index d7c07676911..8a6aa767ce6 100644 --- a/spec/models/repository_spec.rb +++ b/spec/models/repository_spec.rb @@ -2298,4 +2298,24 @@ describe Repository do project.commit_by(oid: '1' * 40) end end + + describe '#raw_repository' do + subject { repository.raw_repository } + + it 'returns a Gitlab::Git::Repository representation of the repository' do + expect(subject).to be_a(Gitlab::Git::Repository) + expect(subject.relative_path).to eq(project.disk_path + '.git') + expect(subject.gl_repository).to eq("project-#{project.id}") + end + + context 'with a wiki repository' do + let(:repository) { project.wiki.repository } + + it 'creates a Gitlab::Git::Repository with the proper attributes' do + expect(subject).to be_a(Gitlab::Git::Repository) + expect(subject.relative_path).to eq(project.disk_path + '.wiki.git') + expect(subject.gl_repository).to eq("wiki-#{project.id}") + end + end + end end -- cgit v1.2.1 From 576f0a5a6d3819149590fad00986dee8c719db32 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matija=20=C4=8Cupi=C4=87?= Date: Sat, 4 Nov 2017 02:42:16 +0100 Subject: Expose project visibility as CI variable --- spec/models/ci/build_spec.rb | 1 + 1 file changed, 1 insertion(+) (limited to 'spec/models') diff --git a/spec/models/ci/build_spec.rb b/spec/models/ci/build_spec.rb index 41ecdb604f1..f804b422794 100644 --- a/spec/models/ci/build_spec.rb +++ b/spec/models/ci/build_spec.rb @@ -1271,6 +1271,7 @@ describe Ci::Build do { key: 'CI_PROJECT_PATH_SLUG', value: project.full_path_slug, public: true }, { key: 'CI_PROJECT_NAMESPACE', value: project.namespace.full_path, public: true }, { key: 'CI_PROJECT_URL', value: project.web_url, public: true }, + { key: 'CI_PROJECT_VISIBILITY', value: Gitlab::VisibilityLevel.string_level(project.visibility_level), public: true }, { key: 'CI_PIPELINE_ID', value: pipeline.id.to_s, public: true }, { key: 'CI_CONFIG_PATH', value: pipeline.ci_yaml_file_path, public: true }, { key: 'CI_REGISTRY_USER', value: 'gitlab-ci-token', public: true }, -- cgit v1.2.1 From 5423e5464943e30c4eadf874f86fa86cd2d557ad Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matija=20=C4=8Cupi=C4=87?= Date: Sat, 4 Nov 2017 20:20:59 +0100 Subject: Harcode project visibility --- spec/models/ci/build_spec.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'spec/models') diff --git a/spec/models/ci/build_spec.rb b/spec/models/ci/build_spec.rb index f804b422794..5ed2e1ca99a 100644 --- a/spec/models/ci/build_spec.rb +++ b/spec/models/ci/build_spec.rb @@ -1271,7 +1271,7 @@ describe Ci::Build do { key: 'CI_PROJECT_PATH_SLUG', value: project.full_path_slug, public: true }, { key: 'CI_PROJECT_NAMESPACE', value: project.namespace.full_path, public: true }, { key: 'CI_PROJECT_URL', value: project.web_url, public: true }, - { key: 'CI_PROJECT_VISIBILITY', value: Gitlab::VisibilityLevel.string_level(project.visibility_level), public: true }, + { key: 'CI_PROJECT_VISIBILITY', value: 'private', public: true }, { key: 'CI_PIPELINE_ID', value: pipeline.id.to_s, public: true }, { key: 'CI_CONFIG_PATH', value: pipeline.ci_yaml_file_path, public: true }, { key: 'CI_REGISTRY_USER', value: 'gitlab-ci-token', public: true }, -- cgit v1.2.1 From c1f064cbe39d6008206a0fe31e10f4a5e0c9ad28 Mon Sep 17 00:00:00 2001 From: Shinya Maeda Date: Mon, 6 Nov 2017 16:00:39 +0900 Subject: Remove unique validation from external_url in Environment --- spec/models/environment_spec.rb | 1 - 1 file changed, 1 deletion(-) (limited to 'spec/models') diff --git a/spec/models/environment_spec.rb b/spec/models/environment_spec.rb index f75de0a0d88..1ce1d595c60 100644 --- a/spec/models/environment_spec.rb +++ b/spec/models/environment_spec.rb @@ -18,7 +18,6 @@ describe Environment do it { is_expected.to validate_length_of(:slug).is_at_most(24) } it { is_expected.to validate_length_of(:external_url).is_at_most(255) } - it { is_expected.to validate_uniqueness_of(:external_url).scoped_to(:project_id) } describe '.order_by_last_deployed_at' do let(:project) { create(:project, :repository) } -- cgit v1.2.1