Welcome to mirror list, hosted at ThFree Co, Russian Federation.

gitlab.com/gitlab-org/gitlab-foss.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'spec/tooling')
-rw-r--r--spec/tooling/danger/config_files_spec.rb30
-rw-r--r--spec/tooling/danger/feature_flag_spec.rb70
-rw-r--r--spec/tooling/danger/product_intelligence_spec.rb47
-rw-r--r--spec/tooling/danger/project_helper_spec.rb10
-rw-r--r--spec/tooling/danger/specs_spec.rb71
-rw-r--r--spec/tooling/danger/stable_branch_spec.rb137
-rw-r--r--spec/tooling/lib/tooling/helm3_client_spec.rb48
-rw-r--r--spec/tooling/lib/tooling/kubernetes_client_spec.rb20
-rw-r--r--spec/tooling/lib/tooling/mappings/base_spec.rb44
-rw-r--r--spec/tooling/lib/tooling/mappings/js_to_system_specs_mappings_spec.rb169
-rw-r--r--spec/tooling/lib/tooling/mappings/view_to_js_mappings_spec.rb (renamed from spec/tooling/lib/tooling/view_to_js_mappings_spec.rb)49
11 files changed, 518 insertions, 177 deletions
diff --git a/spec/tooling/danger/config_files_spec.rb b/spec/tooling/danger/config_files_spec.rb
index 88b327df63f..65edcabb817 100644
--- a/spec/tooling/danger/config_files_spec.rb
+++ b/spec/tooling/danger/config_files_spec.rb
@@ -13,7 +13,6 @@ RSpec.describe Tooling::Danger::ConfigFiles do
let(:fake_danger) { DangerSpecHelper.fake_danger.include(described_class) }
let(:fake_project_helper) { instance_double(Tooling::Danger::ProjectHelper) }
- let(:matching_line) { "+ introduced_by_url:" }
subject(:config_file) { fake_danger.new(helper: fake_helper) }
@@ -22,29 +21,42 @@ RSpec.describe Tooling::Danger::ConfigFiles do
end
describe '#add_suggestion_for_missing_introduced_by_url' do
- let(:file_lines) do
+ let(:file_diff) do
[
- "---",
- "name: about_some_new_flow",
- "introduced_by_url: #{url}",
- "rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/355909",
- "milestone: '14.10'"
+ "+---",
+ "+name: about_some_new_flow",
+ "+introduced_by_url: #{url}",
+ "+rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/355909",
+ "+milestone: '14.10'"
]
end
+ let(:file_lines) do
+ file_diff.map { |line| line.delete_prefix('+') }
+ end
+
let(:filename) { 'config/feature_flags/new_ff.yml' }
+ let(:mr_url) { 'https://gitlab.com/gitlab-org/gitlab/-/merge_requests/1' }
before do
allow(config_file.project_helper).to receive(:file_lines).and_return(file_lines)
allow(config_file.helper).to receive(:added_files).and_return([filename])
- allow(config_file.helper).to receive(:mr_web_url).and_return(url)
+ allow(config_file.helper).to receive(:changed_lines).with(filename).and_return(file_diff)
+ allow(config_file.helper).to receive(:mr_web_url).and_return(mr_url)
end
context 'when config file has an empty introduced_by_url line' do
let(:url) { '' }
it 'adds suggestions at the correct line' do
- expected_format = format(described_class::SUGGEST_INTRODUCED_BY_COMMENT, url: url)
+ template = <<~SUGGEST_COMMENT
+ ```suggestion
+ introduced_by_url: %<mr_url>s
+ ```
+ SUGGEST_COMMENT
+
+ expected_format = format(template, mr_url: mr_url)
+
expect(config_file).to receive(:markdown).with(expected_format, file: filename, line: 3)
config_file.add_suggestion_for_missing_introduced_by_url
diff --git a/spec/tooling/danger/feature_flag_spec.rb b/spec/tooling/danger/feature_flag_spec.rb
index 0e9eda54510..4575d8ca981 100644
--- a/spec/tooling/danger/feature_flag_spec.rb
+++ b/spec/tooling/danger/feature_flag_spec.rb
@@ -86,14 +86,20 @@ RSpec.describe Tooling::Danger::FeatureFlag do
describe described_class::Found do
let(:feature_flag_path) { 'config/feature_flags/development/entry.yml' }
let(:group) { 'group::source code' }
- let(:raw_yaml) do
- YAML.dump(
+ let(:yaml) do
+ {
'group' => group,
'default_enabled' => true,
- 'rollout_issue_url' => 'https://gitlab.com/gitlab-org/gitlab/-/issues/1'
- )
+ 'rollout_issue_url' => 'https://gitlab.com/gitlab-org/gitlab/-/issues/1',
+ 'introduced_by_url' => 'https://gitlab.com/gitlab-org/gitlab/-/issues/2',
+ 'milestone' => '15.9',
+ 'type' => 'development',
+ 'name' => 'entry'
+ }
end
+ let(:raw_yaml) { YAML.dump(yaml) }
+
subject(:found) { described_class.new(feature_flag_path) }
before do
@@ -101,58 +107,34 @@ RSpec.describe Tooling::Danger::FeatureFlag do
expect(File).to receive(:read).with(feature_flag_path).and_return(raw_yaml)
end
- describe '#raw' do
- it 'returns the raw YAML' do
- expect(found.raw).to eq(raw_yaml)
- end
- end
-
- describe '#group' do
- it 'returns the group found in the YAML' do
- expect(found.group).to eq(group)
- end
- end
-
- describe '#default_enabled' do
- it 'returns the default_enabled found in the YAML' do
- expect(found.default_enabled).to eq(true)
+ described_class::ATTRIBUTES.each do |attribute|
+ describe "##{attribute}" do
+ it 'returns value from the YAML' do
+ expect(found.public_send(attribute)).to eq(yaml[attribute])
+ end
end
end
- describe '#rollout_issue_url' do
- it 'returns the rollout_issue_url found in the YAML' do
- expect(found.rollout_issue_url).to eq('https://gitlab.com/gitlab-org/gitlab/-/issues/1')
+ describe '#raw' do
+ it 'returns the raw YAML' do
+ expect(found.raw).to eq(raw_yaml)
end
end
describe '#group_match_mr_label?' do
- subject(:result) { found.group_match_mr_label?(mr_group_label) }
-
- context 'when MR labels match FF group' do
- let(:mr_group_label) { 'group::source code' }
-
- specify { expect(result).to eq(true) }
- end
-
- context 'when MR labels does not match FF group' do
- let(:mr_group_label) { 'group::authentication and authorization' }
-
- specify { expect(result).to eq(false) }
- end
-
context 'when group is nil' do
let(:group) { nil }
- context 'and MR has no group label' do
- let(:mr_group_label) { nil }
-
- specify { expect(result).to eq(true) }
+ it 'is true only if MR has no group label' do
+ expect(found.group_match_mr_label?(nil)).to eq true
+ expect(found.group_match_mr_label?('group::source code')).to eq false
end
+ end
- context 'and MR has a group label' do
- let(:mr_group_label) { 'group::source code' }
-
- specify { expect(result).to eq(false) }
+ context 'when group is not nil' do
+ it 'is true only if MR has the same group label' do
+ expect(found.group_match_mr_label?(group)).to eq true
+ expect(found.group_match_mr_label?('group::authentication and authorization')).to eq false
end
end
end
diff --git a/spec/tooling/danger/product_intelligence_spec.rb b/spec/tooling/danger/product_intelligence_spec.rb
index fab8b0c61fa..c4cd0e5bfb6 100644
--- a/spec/tooling/danger/product_intelligence_spec.rb
+++ b/spec/tooling/danger/product_intelligence_spec.rb
@@ -18,7 +18,7 @@ RSpec.describe Tooling::Danger::ProductIntelligence do
let(:has_product_intelligence_label) { true }
before do
- allow(fake_helper).to receive(:changed_lines).and_return(changed_lines)
+ allow(fake_helper).to receive(:changed_lines).and_return(changed_lines) if defined?(changed_lines)
allow(fake_helper).to receive(:labels_to_add).and_return(labels_to_add)
allow(fake_helper).to receive(:ci?).and_return(ci_env)
allow(fake_helper).to receive(:mr_has_labels?).with('product intelligence').and_return(has_product_intelligence_label)
@@ -175,4 +175,49 @@ RSpec.describe Tooling::Danger::ProductIntelligence do
end
end
end
+
+ describe '#check_usage_data_insertions!' do
+ context 'when usage_data.rb is modified' do
+ let(:modified_files) { ['lib/gitlab/usage_data.rb'] }
+
+ before do
+ allow(fake_helper).to receive(:changed_lines).with("lib/gitlab/usage_data.rb").and_return(changed_lines)
+ end
+
+ context 'and has insertions' do
+ let(:changed_lines) { ['+ ci_runners: count(::Ci::CiRunner),'] }
+
+ it 'produces warning' do
+ expect(product_intelligence).to receive(:warn).with(/usage_data\.rb has been deprecated/)
+
+ product_intelligence.check_usage_data_insertions!
+ end
+ end
+
+ context 'and changes are not insertions' do
+ let(:changed_lines) { ['- ci_runners: count(::Ci::CiRunner),'] }
+
+ it 'doesnt do anything' do
+ expect(product_intelligence).not_to receive(:warn)
+
+ product_intelligence.check_usage_data_insertions!
+ end
+ end
+ end
+
+ context 'when usage_data.rb is not modified' do
+ context 'and another file has insertions' do
+ let(:modified_files) { ['tooling/danger/product_intelligence.rb'] }
+
+ it 'doesnt do anything' do
+ expect(fake_helper).to receive(:changed_lines).with("lib/gitlab/usage_data.rb").and_return([])
+ allow(fake_helper).to receive(:changed_lines).with("tooling/danger/product_intelligence.rb").and_return(["+ Inserting"])
+
+ expect(product_intelligence).not_to receive(:warn)
+
+ product_intelligence.check_usage_data_insertions!
+ end
+ end
+ end
+ end
end
diff --git a/spec/tooling/danger/project_helper_spec.rb b/spec/tooling/danger/project_helper_spec.rb
index 669867ffb4f..48050649f54 100644
--- a/spec/tooling/danger/project_helper_spec.rb
+++ b/spec/tooling/danger/project_helper_spec.rb
@@ -48,8 +48,8 @@ RSpec.describe Tooling::Danger::ProjectHelper do
'PROCESS.md' | [:docs]
'README.md' | [:docs]
- 'ee/doc/foo' | [:unknown]
- 'ee/README' | [:unknown]
+ 'ee/doc/foo' | [:none]
+ 'ee/README' | [:none]
'app/assets/foo' | [:frontend]
'app/views/foo' | [:frontend, :backend]
@@ -139,7 +139,7 @@ RSpec.describe Tooling::Danger::ProjectHelper do
'lib/gitlab/ci/templates/Security/SAST.gitlab-ci.yml' | [:ci_template]
'lib/gitlab/ci/templates/dotNET-Core.yml' | [:ci_template]
- 'ee/FOO_VERSION' | [:unknown]
+ 'ee/FOO_VERSION' | [:none]
'db/schema.rb' | [:database]
'db/structure.sql' | [:database]
@@ -170,8 +170,8 @@ RSpec.describe Tooling::Danger::ProjectHelper do
'locale/gitlab.pot' | [:none]
- 'FOO' | [:unknown]
- 'foo' | [:unknown]
+ 'FOO' | [:none]
+ 'foo' | [:none]
'foo/bar.rb' | [:backend]
'foo/bar.js' | [:frontend]
diff --git a/spec/tooling/danger/specs_spec.rb b/spec/tooling/danger/specs_spec.rb
index 422923827a8..cdac5954f92 100644
--- a/spec/tooling/danger/specs_spec.rb
+++ b/spec/tooling/danger/specs_spec.rb
@@ -19,14 +19,16 @@ RSpec.describe Tooling::Danger::Specs, feature_category: :tooling do
let(:file_lines) do
[
" describe 'foo' do",
- " expect(foo).to match(['bar'])",
+ " expect(foo).to match(['bar', 'baz'])",
" end",
- " expect(foo).to match(['bar'])", # same line as line 1 above, we expect two different suggestions
+ " expect(foo).to match(['bar', 'baz'])", # same line as line 1 above, we expect two different suggestions
" ",
- " expect(foo).to match ['bar']",
- " expect(foo).to eq(['bar'])",
- " expect(foo).to eq ['bar']",
- " expect(foo).to(match(['bar']))",
+ " expect(foo).to match ['bar', 'baz']",
+ " expect(foo).to eq(['bar', 'baz'])",
+ " expect(foo).to eq ['bar', 'baz']",
+ " expect(foo).to(match(['bar', 'baz']))",
+ " expect(foo).to(eq(['bar', 'baz']))",
+ " expect(foo).to(eq([bar, baz]))",
" expect(foo).to(eq(['bar']))",
" foo.eq(['bar'])"
]
@@ -35,28 +37,30 @@ RSpec.describe Tooling::Danger::Specs, feature_category: :tooling do
let(:matching_lines) do
[
"+ expect(foo).to match(['should not error'])",
- "+ expect(foo).to match(['bar'])",
- "+ expect(foo).to match(['bar'])",
- "+ expect(foo).to match ['bar']",
- "+ expect(foo).to eq(['bar'])",
- "+ expect(foo).to eq ['bar']",
- "+ expect(foo).to(match(['bar']))",
- "+ expect(foo).to(eq(['bar']))"
+ "+ expect(foo).to match(['bar', 'baz'])",
+ "+ expect(foo).to match(['bar', 'baz'])",
+ "+ expect(foo).to match ['bar', 'baz']",
+ "+ expect(foo).to eq(['bar', 'baz'])",
+ "+ expect(foo).to eq ['bar', 'baz']",
+ "+ expect(foo).to(match(['bar', 'baz']))",
+ "+ expect(foo).to(eq(['bar', 'baz']))",
+ "+ expect(foo).to(eq([bar, baz]))"
]
end
let(:changed_lines) do
[
- " expect(foo).to match(['bar'])",
- " expect(foo).to match(['bar'])",
- " expect(foo).to match ['bar']",
- " expect(foo).to eq(['bar'])",
- " expect(foo).to eq ['bar']",
- "- expect(foo).to match(['bar'])",
- "- expect(foo).to match(['bar'])",
- "- expect(foo).to match ['bar']",
- "- expect(foo).to eq(['bar'])",
- "- expect(foo).to eq ['bar']",
+ " expect(foo).to match(['bar', 'baz'])",
+ " expect(foo).to match(['bar', 'baz'])",
+ " expect(foo).to match ['bar', 'baz']",
+ " expect(foo).to eq(['bar', 'baz'])",
+ " expect(foo).to eq ['bar', 'baz']",
+ "- expect(foo).to match(['bar', 'baz'])",
+ "- expect(foo).to match(['bar', 'baz'])",
+ "- expect(foo).to match ['bar', 'baz']",
+ "- expect(foo).to eq(['bar', 'baz'])",
+ "- expect(foo).to eq ['bar', 'baz']",
+ "- expect(foo).to eq [bar, foo]",
"+ expect(foo).to eq([])"
] + matching_lines
end
@@ -107,7 +111,7 @@ RSpec.describe Tooling::Danger::Specs, feature_category: :tooling do
describe '#add_suggestions_for_match_with_array' do
let(:template) do
- <<~MARKDOWN
+ <<~MARKDOWN.chomp
```suggestion
%<suggested_line>s
```
@@ -118,13 +122,14 @@ RSpec.describe Tooling::Danger::Specs, feature_category: :tooling do
it 'adds suggestions at the correct lines' do
[
- { suggested_line: " expect(foo).to match_array(['bar'])", number: 2 },
- { suggested_line: " expect(foo).to match_array(['bar'])", number: 4 },
- { suggested_line: " expect(foo).to match_array ['bar']", number: 6 },
- { suggested_line: " expect(foo).to match_array(['bar'])", number: 7 },
- { suggested_line: " expect(foo).to match_array ['bar']", number: 8 },
- { suggested_line: " expect(foo).to(match_array(['bar']))", number: 9 },
- { suggested_line: " expect(foo).to(match_array(['bar']))", number: 10 }
+ { suggested_line: " expect(foo).to match_array(['bar', 'baz'])", number: 2 },
+ { suggested_line: " expect(foo).to match_array(['bar', 'baz'])", number: 4 },
+ { suggested_line: " expect(foo).to match_array ['bar', 'baz']", number: 6 },
+ { suggested_line: " expect(foo).to match_array(['bar', 'baz'])", number: 7 },
+ { suggested_line: " expect(foo).to match_array ['bar', 'baz']", number: 8 },
+ { suggested_line: " expect(foo).to(match_array(['bar', 'baz']))", number: 9 },
+ { suggested_line: " expect(foo).to(match_array(['bar', 'baz']))", number: 10 },
+ { suggested_line: " expect(foo).to(match_array([bar, baz]))", number: 11 }
].each do |test_case|
comment = format(template, suggested_line: test_case[:suggested_line])
expect(specs).to receive(:markdown).with(comment, file: filename, line: test_case[:number])
@@ -136,7 +141,7 @@ RSpec.describe Tooling::Danger::Specs, feature_category: :tooling do
describe '#add_suggestions_for_project_factory_usage' do
let(:template) do
- <<~MARKDOWN
+ <<~MARKDOWN.chomp
```suggestion
%<suggested_line>s
```
@@ -220,7 +225,7 @@ RSpec.describe Tooling::Danger::Specs, feature_category: :tooling do
describe '#add_suggestions_for_feature_category' do
let(:template) do
- <<~SUGGESTION_MARKDOWN
+ <<~SUGGESTION_MARKDOWN.chomp
```suggestion
%<suggested_line>s
```
diff --git a/spec/tooling/danger/stable_branch_spec.rb b/spec/tooling/danger/stable_branch_spec.rb
index 08fd25b30e0..9eee077d493 100644
--- a/spec/tooling/danger/stable_branch_spec.rb
+++ b/spec/tooling/danger/stable_branch_spec.rb
@@ -12,6 +12,8 @@ RSpec.describe Tooling::Danger::StableBranch, feature_category: :delivery do
include_context 'with dangerfile'
let(:fake_danger) { DangerSpecHelper.fake_danger.include(described_class) }
+ let(:fake_api) { double('Api') } # rubocop:disable RSpec/VerifiedDoubles
+ let(:gitlab_gem_client) { double('gitlab') } # rubocop:disable RSpec/VerifiedDoubles
let(:stable_branch) { fake_danger.new(helper: fake_helper) }
@@ -34,6 +36,28 @@ RSpec.describe Tooling::Danger::StableBranch, feature_category: :delivery do
end
end
+ shared_examples 'with a warning' do |warning_message|
+ it 'warns' do
+ expect(stable_branch).to receive(:warn).with(warning_message)
+
+ subject
+ end
+ end
+
+ shared_examples 'bypassing when flaky test or docs only' do
+ context 'when failure::flaky-test label is present' do
+ let(:flaky_test_label_present) { true }
+
+ it_behaves_like 'without a failure'
+ end
+
+ context 'with only docs changes' do
+ let(:changes_by_category_response) { { docs: ['foo.md'] } }
+
+ it_behaves_like 'without a failure'
+ end
+ end
+
context 'when not applicable' do
where(:stable_branch?, :security_mr?) do
true | true
@@ -47,15 +71,32 @@ RSpec.describe Tooling::Danger::StableBranch, feature_category: :delivery do
allow(fake_helper).to receive(:security_mr?).and_return(security_mr?)
end
- it_behaves_like "without a failure"
+ it_behaves_like 'without a failure'
end
end
context 'when applicable' do
let(:target_branch) { '15-1-stable-ee' }
+ let(:source_branch) { 'my_bug_branch' }
let(:feature_label_present) { false }
let(:bug_label_present) { true }
+ let(:pipeline_expedite_label_present) { false }
+ let(:flaky_test_label_present) { false }
let(:response_success) { true }
+
+ let(:changes_by_category_response) do
+ {
+ graphql: ['bar.rb']
+ }
+ end
+
+ let(:pipeline_bridges_response) do
+ [
+ { 'name' => 'e2e:package-and-test',
+ 'status' => 'success' }
+ ]
+ end
+
let(:parsed_response) do
[
{ 'version' => '15.1.1' },
@@ -79,14 +120,27 @@ RSpec.describe Tooling::Danger::StableBranch, feature_category: :delivery do
before do
allow(fake_helper).to receive(:mr_target_branch).and_return(target_branch)
+ allow(fake_helper).to receive(:mr_source_branch).and_return(source_branch)
allow(fake_helper).to receive(:security_mr?).and_return(false)
+ allow(fake_helper).to receive(:mr_target_project_id).and_return(1)
allow(fake_helper).to receive(:mr_has_labels?).with('type::feature').and_return(feature_label_present)
allow(fake_helper).to receive(:mr_has_labels?).with('type::bug').and_return(bug_label_present)
+ allow(fake_helper).to receive(:mr_has_labels?).with('pipeline:expedite')
+ .and_return(pipeline_expedite_label_present)
+ allow(fake_helper).to receive(:mr_has_labels?).with('failure::flaky-test')
+ .and_return(flaky_test_label_present)
+ allow(fake_helper).to receive(:changes_by_category).and_return(changes_by_category_response)
allow(HTTParty).to receive(:get).with(/page=1/).and_return(version_response)
+ allow(fake_helper).to receive(:api).and_return(fake_api)
+ allow(stable_branch).to receive(:gitlab).and_return(gitlab_gem_client)
+ allow(gitlab_gem_client).to receive(:mr_json).and_return({ 'head_pipeline' => { 'id' => '1' } })
+ allow(gitlab_gem_client).to receive(:api).and_return(fake_api)
+ allow(fake_api).to receive(:pipeline_bridges).with(1, '1')
+ .and_return(pipeline_bridges_response)
end
# the stubbed behavior above is the success path
- it_behaves_like "without a failure"
+ it_behaves_like 'without a failure'
context 'with a feature label' do
let(:feature_label_present) { true }
@@ -100,20 +154,65 @@ RSpec.describe Tooling::Danger::StableBranch, feature_category: :delivery do
it_behaves_like 'with a failure', described_class::BUG_ERROR_MESSAGE
end
+ context 'with a pipeline:expedite label' do
+ let(:pipeline_expedite_label_present) { true }
+
+ it_behaves_like 'with a failure', described_class::PIPELINE_EXPEDITE_ERROR_MESSAGE
+ it_behaves_like 'bypassing when flaky test or docs only'
+ end
+
+ context 'when no package-and-test job is found' do
+ let(:pipeline_bridges_response) { nil }
+
+ it_behaves_like 'with a failure', described_class::NEEDS_PACKAGE_AND_TEST_MESSAGE
+ it_behaves_like 'bypassing when flaky test or docs only'
+ end
+
+ context 'when package-and-test job is in manual state' do
+ described_class::FAILING_PACKAGE_AND_TEST_STATUSES.each do |status|
+ let(:pipeline_bridges_response) do
+ [
+ { 'name' => 'e2e:package-and-test',
+ 'status' => status }
+ ]
+ end
+
+ it_behaves_like 'with a failure', described_class::NEEDS_PACKAGE_AND_TEST_MESSAGE
+ it_behaves_like 'bypassing when flaky test or docs only'
+ end
+ end
+
+ context 'when package-and-test job is in a non-successful state' do
+ let(:pipeline_bridges_response) do
+ [
+ { 'name' => 'e2e:package-and-test',
+ 'status' => 'running' }
+ ]
+ end
+
+ it_behaves_like 'with a warning', described_class::WARN_PACKAGE_AND_TEST_MESSAGE
+ it_behaves_like 'bypassing when flaky test or docs only'
+ end
+
+ context 'when no pipeline is found' do
+ before do
+ allow(gitlab_gem_client).to receive(:mr_json).and_return({})
+ end
+
+ it_behaves_like 'with a failure', described_class::NEEDS_PACKAGE_AND_TEST_MESSAGE
+ it_behaves_like 'bypassing when flaky test or docs only'
+ end
+
context 'when not an applicable version' do
let(:target_branch) { '14-9-stable-ee' }
- it_behaves_like 'with a failure', described_class::VERSION_ERROR_MESSAGE
+ it_behaves_like 'with a warning', described_class::VERSION_WARNING_MESSAGE
end
context 'when the version API request fails' do
let(:response_success) { false }
- it 'adds a warning' do
- expect(stable_branch).to receive(:warn).with(described_class::FAILED_VERSION_REQUEST_MESSAGE)
-
- subject
- end
+ it_behaves_like 'with a warning', described_class::FAILED_VERSION_REQUEST_MESSAGE
end
context 'when more than one page of versions is needed' do
@@ -151,7 +250,7 @@ RSpec.describe Tooling::Danger::StableBranch, feature_category: :delivery do
allow(HTTParty).to receive(:get).with(/page=2/).and_return(second_version_response)
end
- it_behaves_like "without a failure"
+ it_behaves_like 'without a failure'
end
context 'when too many version API requests are made' do
@@ -166,4 +265,24 @@ RSpec.describe Tooling::Danger::StableBranch, feature_category: :delivery do
end
end
end
+
+ describe '#non_security_stable_branch?' do
+ subject { stable_branch.non_security_stable_branch? }
+
+ where(:stable_branch?, :security_mr?, :expected_result) do
+ true | true | false
+ false | true | false
+ true | false | true
+ false | false | false
+ end
+
+ with_them do
+ before do
+ allow(fake_helper).to receive(:mr_target_branch).and_return(stable_branch? ? '15-1-stable-ee' : 'main')
+ allow(fake_helper).to receive(:security_mr?).and_return(security_mr?)
+ end
+
+ it { is_expected.to eq(expected_result) }
+ end
+ end
end
diff --git a/spec/tooling/lib/tooling/helm3_client_spec.rb b/spec/tooling/lib/tooling/helm3_client_spec.rb
index 52d1b5a1567..5a015ddfa7c 100644
--- a/spec/tooling/lib/tooling/helm3_client_spec.rb
+++ b/spec/tooling/lib/tooling/helm3_client_spec.rb
@@ -3,15 +3,14 @@
require_relative '../../../../tooling/lib/tooling/helm3_client'
RSpec.describe Tooling::Helm3Client do
- let(:namespace) { 'review-apps' }
let(:release_name) { 'my-release' }
let(:raw_helm_list_page1) do
<<~OUTPUT
[
- {"name":"review-qa-60-reor-1mugd1","namespace":"#{namespace}","revision":1,"updated":"2020-04-03 17:27:10.245952 +0800 +08","status":"failed","chart":"gitlab-1.1.3","app_version":"12.9.2"},
- {"name":"review-7846-fix-s-261vd6","namespace":"#{namespace}","revision":2,"updated":"2020-04-02 17:27:12.245952 +0800 +08","status":"deployed","chart":"gitlab-1.1.3","app_version":"12.9.2"},
- {"name":"review-7867-snowp-lzo3iy","namespace":"#{namespace}","revision":1,"updated":"2020-04-02 15:27:12.245952 +0800 +08","status":"deployed","chart":"gitlab-1.1.3","app_version":"12.9.1"},
- {"name":"review-6709-group-2pzeec","namespace":"#{namespace}","revision":2,"updated":"2020-04-01 21:27:12.245952 +0800 +08","status":"failed","chart":"gitlab-1.1.3","app_version":"12.9.1"}
+ {"name":"review-qa-60-reor-1mugd1","namespace":"review-qa-60-reor-1mugd1","revision":1,"updated":"2020-04-03 17:27:10.245952 +0800 +08","status":"failed","chart":"gitlab-1.1.3","app_version":"12.9.2"},
+ {"name":"review-7846-fix-s-261vd6","namespace":"review-7846-fix-s-261vd6","revision":2,"updated":"2020-04-02 17:27:12.245952 +0800 +08","status":"deployed","chart":"gitlab-1.1.3","app_version":"12.9.2"},
+ {"name":"review-7867-snowp-lzo3iy","namespace":"review-7867-snowp-lzo3iy","revision":1,"updated":"2020-04-02 15:27:12.245952 +0800 +08","status":"deployed","chart":"gitlab-1.1.3","app_version":"12.9.1"},
+ {"name":"review-6709-group-2pzeec","namespace":"review-6709-group-2pzeec","revision":2,"updated":"2020-04-01 21:27:12.245952 +0800 +08","status":"failed","chart":"gitlab-1.1.3","app_version":"12.9.1"}
]
OUTPUT
end
@@ -19,7 +18,7 @@ RSpec.describe Tooling::Helm3Client do
let(:raw_helm_list_page2) do
<<~OUTPUT
[
- {"name":"review-6709-group-t40qbv","namespace":"#{namespace}","revision":2,"updated":"2020-04-01 11:27:12.245952 +0800 +08","status":"deployed","chart":"gitlab-1.1.3","app_version":"12.9.1"}
+ {"name":"review-6709-group-t40qbv","namespace":"review-6709-group-t40qbv","revision":2,"updated":"2020-04-01 11:27:12.245952 +0800 +08","status":"deployed","chart":"gitlab-1.1.3","app_version":"12.9.1"}
]
OUTPUT
end
@@ -30,7 +29,7 @@ RSpec.describe Tooling::Helm3Client do
OUTPUT
end
- subject { described_class.new(namespace: namespace) }
+ subject { described_class.new }
describe '#releases' do
it 'raises an error if the Helm command fails' do
@@ -74,7 +73,7 @@ RSpec.describe Tooling::Helm3Client do
status: 'deployed',
chart: 'gitlab-1.1.3',
app_version: '12.9.1',
- namespace: namespace
+ namespace: 'review-6709-group-t40qbv'
)
end
@@ -98,18 +97,19 @@ RSpec.describe Tooling::Helm3Client do
describe '#delete' do
it 'raises an error if the Helm command fails' do
expect(Gitlab::Popen).to receive(:popen_with_detail)
- .with([%(helm uninstall #{release_name})])
+ .with([%(helm uninstall --namespace #{release_name} #{release_name})])
.and_return(Gitlab::Popen::Result.new([], '', '', double(success?: false)))
- expect { subject.delete(release_name: release_name) }.to raise_error(described_class::CommandFailedError)
+ expect { subject.delete(release_name: release_name, namespace: release_name) }
+ .to raise_error(described_class::CommandFailedError)
end
it 'calls helm uninstall with default arguments' do
expect(Gitlab::Popen).to receive(:popen_with_detail)
- .with([%(helm uninstall #{release_name})])
+ .with([%(helm uninstall --namespace #{release_name} #{release_name})])
.and_return(Gitlab::Popen::Result.new([], '', '', double(success?: true)))
- expect(subject.delete(release_name: release_name)).to eq('')
+ subject.delete(release_name: release_name, namespace: release_name)
end
context 'with multiple release names' do
@@ -117,18 +117,30 @@ RSpec.describe Tooling::Helm3Client do
it 'raises an error if the Helm command fails' do
expect(Gitlab::Popen).to receive(:popen_with_detail)
- .with([%(helm uninstall #{release_name.join(' ')})])
+ .with([%(helm uninstall --namespace #{release_name[0]} #{release_name[0]})])
.and_return(Gitlab::Popen::Result.new([], '', '', double(success?: false)))
expect { subject.delete(release_name: release_name) }.to raise_error(described_class::CommandFailedError)
end
- it 'calls helm uninstall with multiple release names' do
- expect(Gitlab::Popen).to receive(:popen_with_detail)
- .with([%(helm uninstall #{release_name.join(' ')})])
- .and_return(Gitlab::Popen::Result.new([], '', '', double(success?: true)))
+ it 'calls helm uninstall with multiple release names and a namespace' do
+ release_name.each do |release|
+ expect(Gitlab::Popen).to receive(:popen_with_detail)
+ .with([%(helm uninstall --namespace namespace #{release})])
+ .and_return(Gitlab::Popen::Result.new([], '', '', double(success?: true)))
+ end
+
+ subject.delete(release_name: release_name, namespace: 'namespace')
+ end
+
+ it 'calls helm uninstall with multiple release names and no namespace' do
+ release_name.each do |release|
+ expect(Gitlab::Popen).to receive(:popen_with_detail)
+ .with([%(helm uninstall --namespace #{release} #{release})])
+ .and_return(Gitlab::Popen::Result.new([], '', '', double(success?: true)))
+ end
- expect(subject.delete(release_name: release_name)).to eq('')
+ subject.delete(release_name: release_name)
end
end
end
diff --git a/spec/tooling/lib/tooling/kubernetes_client_spec.rb b/spec/tooling/lib/tooling/kubernetes_client_spec.rb
index a7f50b0bb50..50d33182a42 100644
--- a/spec/tooling/lib/tooling/kubernetes_client_spec.rb
+++ b/spec/tooling/lib/tooling/kubernetes_client_spec.rb
@@ -250,7 +250,7 @@ RSpec.describe Tooling::KubernetesClient do
describe '#review_app_namespaces_created_before' do
let(:three_days_ago) { Time.now - 3600 * 24 * 3 }
let(:two_days_ago) { Time.now - 3600 * 24 * 2 }
- let(:namespace_created_three_days_ago) { 'namespace-created-three-days-ago' }
+ let(:namespace_created_three_days_ago) { 'review-ns-created-three-days-ago' }
let(:resource_type) { 'namespace' }
let(:raw_resources) do
{
@@ -260,10 +260,7 @@ RSpec.describe Tooling::KubernetesClient do
kind: "Namespace",
metadata: {
creationTimestamp: three_days_ago,
- name: namespace_created_three_days_ago,
- labels: {
- tls: 'review-apps-tls'
- }
+ name: namespace_created_three_days_ago
}
},
{
@@ -271,10 +268,7 @@ RSpec.describe Tooling::KubernetesClient do
kind: "Namespace",
metadata: {
creationTimestamp: Time.now,
- name: 'another-pvc',
- labels: {
- tls: 'review-apps-tls'
- }
+ name: 'another-namespace'
}
}
]
@@ -283,12 +277,10 @@ RSpec.describe Tooling::KubernetesClient do
specify do
expect(Gitlab::Popen).to receive(:popen_with_detail)
- .with(["kubectl get namespace " \
- "-l tls=review-apps-tls " \
- "--sort-by='{.metadata.creationTimestamp}' -o json"])
- .and_return(Gitlab::Popen::Result.new([], raw_resources, '', double(success?: true)))
+ .with(["kubectl get namespace --sort-by='{.metadata.creationTimestamp}' -o json"])
+ .and_return(Gitlab::Popen::Result.new([], raw_resources, '', double(success?: true)))
- expect(subject.__send__(:review_app_namespaces_created_before, created_before: two_days_ago)).to contain_exactly(namespace_created_three_days_ago)
+ expect(subject.__send__(:review_app_namespaces_created_before, created_before: two_days_ago)).to eq([namespace_created_three_days_ago])
end
end
end
diff --git a/spec/tooling/lib/tooling/mappings/base_spec.rb b/spec/tooling/lib/tooling/mappings/base_spec.rb
new file mode 100644
index 00000000000..935f833fa8b
--- /dev/null
+++ b/spec/tooling/lib/tooling/mappings/base_spec.rb
@@ -0,0 +1,44 @@
+# frozen_string_literal: true
+
+require_relative '../../../../../tooling/lib/tooling/mappings/view_to_js_mappings'
+
+RSpec.describe Tooling::Mappings::Base, feature_category: :tooling do
+ describe '#folders_for_available_editions' do
+ let(:base_folder_path) { 'app/views' }
+
+ subject { described_class.new.folders_for_available_editions(base_folder_path) }
+
+ context 'when FOSS' do
+ before do
+ allow(GitlabEdition).to receive(:ee?).and_return(false)
+ allow(GitlabEdition).to receive(:jh?).and_return(false)
+ end
+
+ it 'returns the correct paths' do
+ expect(subject).to match_array([base_folder_path])
+ end
+ end
+
+ context 'when EE' do
+ before do
+ allow(GitlabEdition).to receive(:ee?).and_return(true)
+ allow(GitlabEdition).to receive(:jh?).and_return(false)
+ end
+
+ it 'returns the correct paths' do
+ expect(subject).to match_array([base_folder_path, "ee/#{base_folder_path}"])
+ end
+ end
+
+ context 'when JiHu' do
+ before do
+ allow(GitlabEdition).to receive(:ee?).and_return(true)
+ allow(GitlabEdition).to receive(:jh?).and_return(true)
+ end
+
+ it 'returns the correct paths' do
+ expect(subject).to match_array([base_folder_path, "ee/#{base_folder_path}", "jh/#{base_folder_path}"])
+ end
+ end
+ end
+end
diff --git a/spec/tooling/lib/tooling/mappings/js_to_system_specs_mappings_spec.rb b/spec/tooling/lib/tooling/mappings/js_to_system_specs_mappings_spec.rb
new file mode 100644
index 00000000000..72e02547938
--- /dev/null
+++ b/spec/tooling/lib/tooling/mappings/js_to_system_specs_mappings_spec.rb
@@ -0,0 +1,169 @@
+# frozen_string_literal: true
+
+require 'tempfile'
+require_relative '../../../../../tooling/lib/tooling/mappings/js_to_system_specs_mappings'
+
+RSpec.describe Tooling::Mappings::JsToSystemSpecsMappings, feature_category: :tooling do
+ # We set temporary folders, and those readers give access to those folder paths
+ attr_accessor :js_base_folder, :system_specs_base_folder
+
+ around do |example|
+ Dir.mktmpdir do |tmp_js_base_folder|
+ Dir.mktmpdir do |tmp_system_specs_base_folder|
+ self.system_specs_base_folder = tmp_system_specs_base_folder
+ self.js_base_folder = tmp_js_base_folder
+
+ example.run
+ end
+ end
+ end
+
+ describe '#execute' do
+ let(:instance) do
+ described_class.new(
+ system_specs_base_folder: system_specs_base_folder,
+ js_base_folder: js_base_folder
+ )
+ end
+
+ subject { instance.execute(changed_files) }
+
+ context 'when no JS files were changed' do
+ let(:changed_files) { [] }
+
+ it 'returns nothing' do
+ expect(subject).to match_array([])
+ end
+ end
+
+ context 'when some JS files were changed' do
+ let(:changed_files) { ["#{js_base_folder}/issues/secret_values.js"] }
+
+ context 'when the JS files are not present on disk' do
+ it 'returns nothing' do
+ expect(subject).to match_array([])
+ end
+ end
+
+ context 'when the JS files are present on disk' do
+ before do
+ FileUtils.mkdir_p("#{js_base_folder}/issues")
+ File.write("#{js_base_folder}/issues/secret_values.js", "hello")
+ end
+
+ context 'when no system specs match the JS keyword' do
+ it 'returns nothing' do
+ expect(subject).to match_array([])
+ end
+ end
+
+ context 'when a system spec matches the JS keyword' do
+ before do
+ FileUtils.mkdir_p("#{system_specs_base_folder}/confidential_issues")
+ File.write("#{system_specs_base_folder}/confidential_issues/issues_spec.rb", "a test")
+ end
+
+ it 'returns something' do
+ expect(subject).to match_array(["#{system_specs_base_folder}/confidential_issues/issues_spec.rb"])
+ end
+ end
+ end
+ end
+ end
+
+ describe '#filter_files' do
+ subject { described_class.new(js_base_folder: js_base_folder).filter_files(changed_files) }
+
+ before do
+ File.write("#{js_base_folder}/index.js", "index.js")
+ File.write("#{js_base_folder}/index-with-ee-in-it.js", "index-with-ee-in-it.js")
+ File.write("#{js_base_folder}/index-with-jh-in-it.js", "index-with-jh-in-it.js")
+ end
+
+ context 'when no files were changed' do
+ let(:changed_files) { [] }
+
+ it 'returns an empty array' do
+ expect(subject).to match_array([])
+ end
+ end
+
+ context 'when JS files were changed' do
+ let(:changed_files) do
+ [
+ "#{js_base_folder}/index.js",
+ "#{js_base_folder}/index-with-ee-in-it.js",
+ "#{js_base_folder}/index-with-jh-in-it.js"
+ ]
+ end
+
+ it 'returns the path to the JS files' do
+ # "nil" group represents FOSS JS files in app/assets/javascripts
+ expect(subject).to match(nil => [
+ "#{js_base_folder}/index.js",
+ "#{js_base_folder}/index-with-ee-in-it.js",
+ "#{js_base_folder}/index-with-jh-in-it.js"
+ ])
+ end
+ end
+
+ context 'when JS files are deleted' do
+ let(:changed_files) { ["#{system_specs_base_folder}/deleted.html"] }
+
+ it 'returns an empty array' do
+ expect(subject).to match_array([])
+ end
+ end
+ end
+
+ describe '#construct_js_keywords' do
+ subject { described_class.new.construct_js_keywords(js_files) }
+
+ let(:js_files) do
+ %w[
+ app/assets/javascripts/boards/issue_board_filters.js
+ ee/app/assets/javascripts/queries/epic_due_date.query.graphql
+ ]
+ end
+
+ it 'returns a singularized keyword based on the first folder the file is in' do
+ expect(subject).to eq(%w[board query])
+ end
+ end
+
+ describe '#system_specs_for_edition' do
+ subject do
+ described_class.new(system_specs_base_folder: system_specs_base_folder).system_specs_for_edition(edition)
+ end
+
+ context 'when FOSS' do
+ let(:edition) { nil }
+
+ it 'checks the correct folder' do
+ expect(Dir).to receive(:[]).with("#{system_specs_base_folder}/**/*").and_call_original
+
+ subject
+ end
+ end
+
+ context 'when EE' do
+ let(:edition) { 'ee' }
+
+ it 'checks the correct folder' do
+ expect(Dir).to receive(:[]).with("ee#{system_specs_base_folder}/**/*").and_call_original
+
+ subject
+ end
+ end
+
+ context 'when JiHu' do
+ let(:edition) { 'jh' }
+
+ it 'checks the correct folder' do
+ expect(Dir).to receive(:[]).with("jh#{system_specs_base_folder}/**/*").and_call_original
+
+ subject
+ end
+ end
+ end
+end
diff --git a/spec/tooling/lib/tooling/view_to_js_mappings_spec.rb b/spec/tooling/lib/tooling/mappings/view_to_js_mappings_spec.rb
index b09df2a9200..eaa0124370d 100644
--- a/spec/tooling/lib/tooling/view_to_js_mappings_spec.rb
+++ b/spec/tooling/lib/tooling/mappings/view_to_js_mappings_spec.rb
@@ -1,9 +1,9 @@
# frozen_string_literal: true
require 'tempfile'
-require_relative '../../../../tooling/lib/tooling/view_to_js_mappings'
+require_relative '../../../../../tooling/lib/tooling/mappings/view_to_js_mappings'
-RSpec.describe Tooling::ViewToJsMappings, feature_category: :tooling do
+RSpec.describe Tooling::Mappings::ViewToJsMappings, feature_category: :tooling do
# We set temporary folders, and those readers give access to those folder paths
attr_accessor :view_base_folder, :js_base_folder
@@ -32,7 +32,7 @@ RSpec.describe Tooling::ViewToJsMappings, feature_category: :tooling do
context 'when no view files have been changed' do
before do
- allow(instance).to receive(:view_files).and_return([])
+ allow(instance).to receive(:filter_files).and_return([])
end
it 'returns nothing' do
@@ -140,8 +140,8 @@ RSpec.describe Tooling::ViewToJsMappings, feature_category: :tooling do
end
end
- describe '#view_files' do
- subject { described_class.new(view_base_folder: view_base_folder).view_files(changed_files) }
+ describe '#filter_files' do
+ subject { described_class.new(view_base_folder: view_base_folder).filter_files(changed_files) }
before do
File.write("#{js_base_folder}/index.js", "index.js")
@@ -181,45 +181,6 @@ RSpec.describe Tooling::ViewToJsMappings, feature_category: :tooling do
end
end
- describe '#folders_for_available_editions' do
- let(:base_folder_path) { 'app/views' }
-
- subject { described_class.new.folders_for_available_editions(base_folder_path) }
-
- context 'when FOSS' do
- before do
- allow(GitlabEdition).to receive(:ee?).and_return(false)
- allow(GitlabEdition).to receive(:jh?).and_return(false)
- end
-
- it 'returns the correct paths' do
- expect(subject).to match_array([base_folder_path])
- end
- end
-
- context 'when EE' do
- before do
- allow(GitlabEdition).to receive(:ee?).and_return(true)
- allow(GitlabEdition).to receive(:jh?).and_return(false)
- end
-
- it 'returns the correct paths' do
- expect(subject).to eq([base_folder_path, "ee/#{base_folder_path}"])
- end
- end
-
- context 'when JiHu' do
- before do
- allow(GitlabEdition).to receive(:ee?).and_return(true)
- allow(GitlabEdition).to receive(:jh?).and_return(true)
- end
-
- it 'returns the correct paths' do
- expect(subject).to eq([base_folder_path, "ee/#{base_folder_path}", "jh/#{base_folder_path}"])
- end
- end
- end
-
describe '#find_partials' do
subject { described_class.new(view_base_folder: view_base_folder).find_partials(file_path) }