diff options
author | GitLab Bot <gitlab-bot@gitlab.com> | 2020-05-20 17:34:42 +0300 |
---|---|---|
committer | GitLab Bot <gitlab-bot@gitlab.com> | 2020-05-20 17:34:42 +0300 |
commit | 9f46488805e86b1bc341ea1620b866016c2ce5ed (patch) | |
tree | f9748c7e287041e37d6da49e0a29c9511dc34768 /spec/support/helpers | |
parent | dfc92d081ea0332d69c8aca2f0e745cb48ae5e6d (diff) |
Add latest changes from gitlab-org/gitlab@13-0-stable-ee
Diffstat (limited to 'spec/support/helpers')
20 files changed, 471 insertions, 89 deletions
diff --git a/spec/support/helpers/admin_mode_helpers.rb b/spec/support/helpers/admin_mode_helpers.rb index e995a7d4f5e..36ed262f8ae 100644 --- a/spec/support/helpers/admin_mode_helpers.rb +++ b/spec/support/helpers/admin_mode_helpers.rb @@ -7,6 +7,9 @@ module AdminModeHelper # mode for accessing any administrative functionality. This helper lets a user # be in admin mode without requiring a second authentication step (provided # the user is an admin) + # + # See also tag :enable_admin_mode in spec/spec_helper.rb for a spec-wide + # alternative def enable_admin_mode!(user) fake_user_mode = instance_double(Gitlab::Auth::CurrentUserMode) diff --git a/spec/support/helpers/concurrent_helpers.rb b/spec/support/helpers/concurrent_helpers.rb new file mode 100644 index 00000000000..4eecc2133e7 --- /dev/null +++ b/spec/support/helpers/concurrent_helpers.rb @@ -0,0 +1,40 @@ +# frozen_string_literal: true + +module ConcurrentHelpers + Cancelled = Class.new(StandardError) + + # To test for contention, we may need to run some actions in parallel. This + # helper takes an array of blocks and schedules them all on different threads + # in a fixed-size thread pool. + # + # @param [Array[Proc]] blocks + # @param [Integer] task_wait_time: time to wait for each task (upper bound on + # reasonable task execution time) + # @param [Integer] max_concurrency: maximum number of tasks to run at once + # + def run_parallel(blocks, task_wait_time: 20.seconds, max_concurrency: Concurrent.processor_count - 1) + thread_pool = Concurrent::FixedThreadPool.new( + [2, max_concurrency].max, { max_queue: blocks.size } + ) + opts = { executor: thread_pool } + + error = Concurrent::MVar.new + + blocks.map { |block| Concurrent::Future.execute(opts, &block) }.each do |future| + future.wait(task_wait_time) + + if future.complete? + error.put(future.reason) if future.reason && error.empty? + else + future.cancel + error.put(Cancelled.new) if error.empty? + end + end + + raise error.take if error.full? + ensure + thread_pool.shutdown + thread_pool.wait_for_termination(10) + thread_pool.kill if thread_pool.running? + end +end diff --git a/spec/support/helpers/design_management_test_helpers.rb b/spec/support/helpers/design_management_test_helpers.rb new file mode 100644 index 00000000000..bf41e2f5079 --- /dev/null +++ b/spec/support/helpers/design_management_test_helpers.rb @@ -0,0 +1,45 @@ +# frozen_string_literal: true + +module DesignManagementTestHelpers + def enable_design_management(enabled = true, ref_filter = true) + stub_lfs_setting(enabled: enabled) + stub_feature_flags(design_management_reference_filter_gfm_pipeline: ref_filter) + end + + def delete_designs(*designs) + act_on_designs(designs) { ::DesignManagement::Action.deletion } + end + + def restore_designs(*designs) + act_on_designs(designs) { ::DesignManagement::Action.creation } + end + + def modify_designs(*designs) + act_on_designs(designs) { ::DesignManagement::Action.modification } + end + + def path_for_design(design) + path_options = { vueroute: design.filename } + Gitlab::Routing.url_helpers.designs_project_issue_path(design.project, design.issue, path_options) + end + + def url_for_design(design) + path_options = { vueroute: design.filename } + Gitlab::Routing.url_helpers.designs_project_issue_url(design.project, design.issue, path_options) + end + + def url_for_designs(issue) + Gitlab::Routing.url_helpers.designs_project_issue_url(issue.project, issue) + end + + private + + def act_on_designs(designs, &block) + issue = designs.first.issue + version = build(:design_version, :empty, issue: issue).tap { |v| v.save(validate: false) } + designs.each do |d| + yield.create(design: d, version: version) + end + version + end +end diff --git a/spec/support/helpers/exclusive_lease_helpers.rb b/spec/support/helpers/exclusive_lease_helpers.rb index 77703e20602..95cfc56c273 100644 --- a/spec/support/helpers/exclusive_lease_helpers.rb +++ b/spec/support/helpers/exclusive_lease_helpers.rb @@ -9,7 +9,9 @@ module ExclusiveLeaseHelpers Gitlab::ExclusiveLease, try_obtain: uuid, exists?: true, - renew: renew + renew: renew, + cancel: nil, + ttl: timeout ) allow(Gitlab::ExclusiveLease) diff --git a/spec/support/helpers/fake_blob_helpers.rb b/spec/support/helpers/fake_blob_helpers.rb index a7eafb0fd23..6c8866deac4 100644 --- a/spec/support/helpers/fake_blob_helpers.rb +++ b/spec/support/helpers/fake_blob_helpers.rb @@ -22,7 +22,11 @@ module FakeBlobHelpers alias_method :name, :path def id - 0 + "00000000" + end + + def commit_id + "11111111" end def binary_in_repo? diff --git a/spec/support/helpers/graphql_helpers.rb b/spec/support/helpers/graphql_helpers.rb index fc543186b08..b3d7f7bcece 100644 --- a/spec/support/helpers/graphql_helpers.rb +++ b/spec/support/helpers/graphql_helpers.rb @@ -246,12 +246,19 @@ module GraphqlHelpers # Raises an error if no data is found def graphql_data + # Note that `json_response` is defined as `let(:json_response)` and + # therefore, in a spec with multiple queries, will only contain data + # from the _first_ query, not subsequent ones json_response['data'] || (raise NoData, graphql_errors) end def graphql_data_at(*path) + graphql_dig_at(graphql_data, *path) + end + + def graphql_dig_at(data, *path) keys = path.map { |segment| GraphqlHelpers.fieldnamerize(segment) } - graphql_data.dig(*keys) + data.dig(*keys) end def graphql_errors diff --git a/spec/support/helpers/jira_service_helper.rb b/spec/support/helpers/jira_service_helper.rb index c23a8d52c84..198bedfe3bc 100644 --- a/spec/support/helpers/jira_service_helper.rb +++ b/spec/support/helpers/jira_service_helper.rb @@ -78,6 +78,11 @@ module JiraServiceHelper JIRA_API + "/issue/#{issue_id}" end + def stub_jira_service_test + WebMock.stub_request(:get, 'https://jira.example.com/rest/api/2/serverInfo') + .to_return(body: { url: 'http://url' }.to_json) + end + def stub_jira_urls(issue_id) WebMock.stub_request(:get, jira_project_url) WebMock.stub_request(:get, jira_api_comment_url(issue_id)).to_return(body: jira_issue_comments) diff --git a/spec/support/helpers/kubernetes_helpers.rb b/spec/support/helpers/kubernetes_helpers.rb index ca910e47695..8882f31e2f4 100644 --- a/spec/support/helpers/kubernetes_helpers.rb +++ b/spec/support/helpers/kubernetes_helpers.rb @@ -3,6 +3,8 @@ module KubernetesHelpers include Gitlab::Kubernetes + NODE_NAME = "gke-cluster-applications-default-pool-49b7f225-v527" + def kube_response(body) { body: body.to_json } end @@ -11,6 +13,14 @@ module KubernetesHelpers kube_response(kube_pods_body) end + def nodes_response + kube_response(nodes_body) + end + + def nodes_metrics_response + kube_response(nodes_metrics_body) + end + def kube_pod_response kube_response(kube_pod) end @@ -34,6 +44,9 @@ module KubernetesHelpers WebMock .stub_request(:get, api_url + '/apis/rbac.authorization.k8s.io/v1') .to_return(kube_response(kube_v1_rbac_authorization_discovery_body)) + WebMock + .stub_request(:get, api_url + '/apis/metrics.k8s.io/v1beta1') + .to_return(kube_response(kube_metrics_v1beta1_discovery_body)) end def stub_kubeclient_discover_istio(api_url) @@ -76,6 +89,22 @@ module KubernetesHelpers WebMock.stub_request(:get, pods_url).to_return(response || kube_pods_response) end + def stub_kubeclient_nodes(api_url) + stub_kubeclient_discover_base(api_url) + + nodes_url = api_url + "/api/v1/nodes" + + WebMock.stub_request(:get, nodes_url).to_return(nodes_response) + end + + def stub_kubeclient_nodes_and_nodes_metrics(api_url) + stub_kubeclient_nodes(api_url) + + nodes_url = api_url + "/apis/metrics.k8s.io/v1beta1/nodes" + + WebMock.stub_request(:get, nodes_url).to_return(nodes_metrics_response) + end + def stub_kubeclient_pods(namespace, status: nil) stub_kubeclient_discover(service.api_url) pods_url = service.api_url + "/api/v1/namespaces/#{namespace}/pods" @@ -201,28 +230,8 @@ module KubernetesHelpers .to_return(kube_response({})) end - def stub_kubeclient_get_cluster_role_binding_error(api_url, name, status: 404) - WebMock.stub_request(:get, api_url + "/apis/rbac.authorization.k8s.io/v1/clusterrolebindings/#{name}") - .to_return(status: [status, "Internal Server Error"]) - end - - def stub_kubeclient_create_cluster_role_binding(api_url) - WebMock.stub_request(:post, api_url + '/apis/rbac.authorization.k8s.io/v1/clusterrolebindings') - .to_return(kube_response({})) - end - - def stub_kubeclient_get_role_binding(api_url, name, namespace: 'default') - WebMock.stub_request(:get, api_url + "/apis/rbac.authorization.k8s.io/v1/namespaces/#{namespace}/rolebindings/#{name}") - .to_return(kube_response({})) - end - - def stub_kubeclient_get_role_binding_error(api_url, name, namespace: 'default', status: 404) - WebMock.stub_request(:get, api_url + "/apis/rbac.authorization.k8s.io/v1/namespaces/#{namespace}/rolebindings/#{name}") - .to_return(status: [status, "Internal Server Error"]) - end - - def stub_kubeclient_create_role_binding(api_url, namespace: 'default') - WebMock.stub_request(:post, api_url + "/apis/rbac.authorization.k8s.io/v1/namespaces/#{namespace}/rolebindings") + def stub_kubeclient_put_cluster_role_binding(api_url, name) + WebMock.stub_request(:put, api_url + "/apis/rbac.authorization.k8s.io/v1/clusterrolebindings/#{name}") .to_return(kube_response({})) end @@ -274,6 +283,7 @@ module KubernetesHelpers { "kind" => "APIResourceList", "resources" => [ + { "name" => "nodes", "namespaced" => false, "kind" => "Node" }, { "name" => "pods", "namespaced" => true, "kind" => "Pod" }, { "name" => "deployments", "namespaced" => true, "kind" => "Deployment" }, { "name" => "secrets", "namespaced" => true, "kind" => "Secret" }, @@ -334,6 +344,16 @@ module KubernetesHelpers } end + def kube_metrics_v1beta1_discovery_body + { + "kind" => "APIResourceList", + "resources" => [ + { "name" => "nodes", "namespaced" => false, "kind" => "NodeMetrics" }, + { "name" => "pods", "namespaced" => true, "kind" => "PodMetrics" } + ] + } + end + def kube_istio_discovery_body { "kind" => "APIResourceList", @@ -462,6 +482,20 @@ module KubernetesHelpers } end + def nodes_body + { + "kind" => "NodeList", + "items" => [kube_node] + } + end + + def nodes_metrics_body + { + "kind" => "List", + "items" => [kube_node_metrics] + } + end + def kube_logs_body "2019-12-13T14:04:22.123456Z Log 1\n2019-12-13T14:04:23.123456Z Log 2\n2019-12-13T14:04:24.123456Z Log 3" end @@ -514,6 +548,40 @@ module KubernetesHelpers } end + # This is a partial response, it will have many more elements in reality but + # these are the ones we care about at the moment + def kube_node + { + "metadata" => { + "name" => NODE_NAME + }, + "status" => { + "capacity" => { + "cpu" => "2", + "memory" => "7657228Ki" + }, + "allocatable" => { + "cpu" => "1930m", + "memory" => "5777164Ki" + } + } + } + end + + # This is a partial response, it will have many more elements in reality but + # these are the ones we care about at the moment + def kube_node_metrics + { + "metadata" => { + "name" => NODE_NAME + }, + "usage" => { + "cpu" => "144208668n", + "memory" => "1789048Ki" + } + } + end + # Similar to a kube_pod, but should contain a running service def kube_knative_pod(name: "kube-pod", namespace: "default", status: "Running") { diff --git a/spec/support/helpers/login_helpers.rb b/spec/support/helpers/login_helpers.rb index 6a4dcfcdb1e..cb880939b1c 100644 --- a/spec/support/helpers/login_helpers.rb +++ b/spec/support/helpers/login_helpers.rb @@ -50,9 +50,7 @@ module LoginHelpers def gitlab_enable_admin_mode_sign_in(user) visit new_admin_session_path - fill_in 'user_password', with: user.password - click_button 'Enter Admin Mode' end diff --git a/spec/support/helpers/query_recorder.rb b/spec/support/helpers/query_recorder.rb index fd200a1abf3..61634813a1c 100644 --- a/spec/support/helpers/query_recorder.rb +++ b/spec/support/helpers/query_recorder.rb @@ -19,7 +19,9 @@ module ActiveRecord def show_backtrace(values) Rails.logger.debug("QueryRecorder SQL: #{values[:sql]}") - Gitlab::BacktraceCleaner.clean_backtrace(caller).each { |line| Rails.logger.debug(" --> #{line}") } + Gitlab::BacktraceCleaner.clean_backtrace(caller).each do |line| + Rails.logger.debug("QueryRecorder backtrace: --> #{line}") + end end def get_sql_source(sql) diff --git a/spec/support/helpers/reactive_caching_helpers.rb b/spec/support/helpers/reactive_caching_helpers.rb index aa9d3b3a199..0b0b0622696 100644 --- a/spec/support/helpers/reactive_caching_helpers.rb +++ b/spec/support/helpers/reactive_caching_helpers.rb @@ -10,8 +10,11 @@ module ReactiveCachingHelpers end def stub_reactive_cache(subject = nil, data = nil, *qualifiers) - allow(ReactiveCachingWorker).to receive(:perform_async) - allow(ReactiveCachingWorker).to receive(:perform_in) + ReactiveCaching::WORK_TYPE.values.each do |worker| + allow(worker).to receive(:perform_async) + allow(worker).to receive(:perform_in) + end + write_reactive_cache(subject, data, *qualifiers) unless subject.nil? end @@ -42,8 +45,8 @@ module ReactiveCachingHelpers Rails.cache.write(alive_reactive_cache_key(subject, *qualifiers), true) end - def expect_reactive_cache_update_queued(subject) - expect(ReactiveCachingWorker) + def expect_reactive_cache_update_queued(subject, worker_klass: ReactiveCachingWorker) + expect(worker_klass) .to receive(:perform_in) .with(subject.class.reactive_cache_refresh_interval, subject.class, subject.id) end diff --git a/spec/support/helpers/smime_helper.rb b/spec/support/helpers/smime_helper.rb index 96da3d81708..261aef9518e 100644 --- a/spec/support/helpers/smime_helper.rb +++ b/spec/support/helpers/smime_helper.rb @@ -5,20 +5,24 @@ module SmimeHelper SHORT_EXPIRY = 30.minutes def generate_root - issue(signed_by: nil, expires_in: INFINITE_EXPIRY, certificate_authority: true) + issue(cn: 'RootCA', signed_by: nil, expires_in: INFINITE_EXPIRY, certificate_authority: true) end - def generate_cert(root_ca:, expires_in: SHORT_EXPIRY) - issue(signed_by: root_ca, expires_in: expires_in, certificate_authority: false) + def generate_intermediate(signer_ca:) + issue(cn: 'IntermediateCA', signed_by: signer_ca, expires_in: INFINITE_EXPIRY, certificate_authority: true) + end + + def generate_cert(signer_ca:, expires_in: SHORT_EXPIRY) + issue(signed_by: signer_ca, expires_in: expires_in, certificate_authority: false) end # returns a hash { key:, cert: } containing a generated key, cert pair - def issue(email_address: 'test@example.com', signed_by:, expires_in:, certificate_authority:) + def issue(email_address: 'test@example.com', cn: nil, signed_by:, expires_in:, certificate_authority:) key = OpenSSL::PKey::RSA.new(4096) public_key = key.public_key subject = if certificate_authority - OpenSSL::X509::Name.parse("/CN=EU") + OpenSSL::X509::Name.parse("/CN=#{cn}") else OpenSSL::X509::Name.parse("/CN=#{email_address}") end diff --git a/spec/support/helpers/stub_feature_flags.rb b/spec/support/helpers/stub_feature_flags.rb index 6c3efff7262..5b8a85b206f 100644 --- a/spec/support/helpers/stub_feature_flags.rb +++ b/spec/support/helpers/stub_feature_flags.rb @@ -9,23 +9,27 @@ module StubFeatureFlags # Examples # - `stub_feature_flags(ci_live_trace: false)` ... Disable `ci_live_trace` # feature flag globally. - # - `stub_feature_flags(ci_live_trace: { enabled: false, thing: project })` ... - # Disable `ci_live_trace` feature flag on the specified project. + # - `stub_feature_flags(ci_live_trace: project)` ... + # - `stub_feature_flags(ci_live_trace: [project1, project2])` ... + # Enable `ci_live_trace` feature flag only on the specified projects. def stub_feature_flags(features) - features.each do |feature_name, option| - if option.is_a?(Hash) - enabled, thing = option.values_at(:enabled, :thing) - else - enabled = option - thing = nil - end + features.each do |feature_name, actors| + allow(Feature).to receive(:enabled?).with(feature_name, any_args).and_return(false) + allow(Feature).to receive(:enabled?).with(feature_name.to_s, any_args).and_return(false) + + Array(actors).each do |actor| + raise ArgumentError, "actor cannot be Hash" if actor.is_a?(Hash) - if thing - allow(Feature).to receive(:enabled?).with(feature_name, thing, any_args) { enabled } - allow(Feature).to receive(:enabled?).with(feature_name.to_s, thing, any_args) { enabled } - else - allow(Feature).to receive(:enabled?).with(feature_name, any_args) { enabled } - allow(Feature).to receive(:enabled?).with(feature_name.to_s, any_args) { enabled } + case actor + when false, true + allow(Feature).to receive(:enabled?).with(feature_name, any_args).and_return(actor) + allow(Feature).to receive(:enabled?).with(feature_name.to_s, any_args).and_return(actor) + when nil, ActiveRecord::Base, Symbol, RSpec::Mocks::Double + allow(Feature).to receive(:enabled?).with(feature_name, actor, any_args).and_return(true) + allow(Feature).to receive(:enabled?).with(feature_name.to_s, actor, any_args).and_return(true) + else + raise ArgumentError, "#stub_feature_flags accepts only `nil`, `true`, `false`, `ActiveRecord::Base` or `Symbol` as actors" + end end end end diff --git a/spec/support/helpers/stub_gitlab_calls.rb b/spec/support/helpers/stub_gitlab_calls.rb index 40f4151c0fb..120d432655b 100644 --- a/spec/support/helpers/stub_gitlab_calls.rb +++ b/spec/support/helpers/stub_gitlab_calls.rb @@ -86,7 +86,7 @@ module StubGitlabCalls def stub_container_registry_tag_manifest_content fixture_path = 'spec/fixtures/container_registry/tag_manifest.json' - JSON.parse(File.read(Rails.root + fixture_path)) + Gitlab::Json.parse(File.read(Rails.root + fixture_path)) end def stub_container_registry_blob_content @@ -113,12 +113,12 @@ module StubGitlabCalls def stub_project_8 data = File.read(Rails.root.join('spec/support/gitlab_stubs/project_8.json')) - allow_any_instance_of(Network).to receive(:project).and_return(JSON.parse(data)) + allow_any_instance_of(Network).to receive(:project).and_return(Gitlab::Json.parse(data)) end def stub_project_8_hooks data = File.read(Rails.root.join('spec/support/gitlab_stubs/project_8_hooks.json')) - allow_any_instance_of(Network).to receive(:project_hooks).and_return(JSON.parse(data)) + allow_any_instance_of(Network).to receive(:project_hooks).and_return(Gitlab::Json.parse(data)) end def stub_projects @@ -143,7 +143,7 @@ module StubGitlabCalls def project_hash_array f = File.read(Rails.root.join('spec/support/gitlab_stubs/projects.json')) - JSON.parse f + Gitlab::Json.parse(f) end end diff --git a/spec/support/helpers/stub_object_storage.rb b/spec/support/helpers/stub_object_storage.rb index d4ac286e959..b473cdaefc1 100644 --- a/spec/support/helpers/stub_object_storage.rb +++ b/spec/support/helpers/stub_object_storage.rb @@ -45,7 +45,7 @@ module StubObjectStorage def stub_external_diffs_object_storage(uploader = described_class, **params) stub_object_storage_uploader(config: Gitlab.config.external_diffs.object_store, uploader: uploader, - remote_directory: 'external_diffs', + remote_directory: 'external-diffs', **params) end diff --git a/spec/support/helpers/test_env.rb b/spec/support/helpers/test_env.rb index 47d69ca1f6a..130650b7e2e 100644 --- a/spec/support/helpers/test_env.rb +++ b/spec/support/helpers/test_env.rb @@ -1,7 +1,5 @@ # frozen_string_literal: true -require 'rspec/mocks' - module TestEnv extend ActiveSupport::Concern extend self @@ -61,7 +59,7 @@ module TestEnv 'merge-commit-analyze-side-branch' => '8a99451', 'merge-commit-analyze-after' => '646ece5', 'snippet/single-file' => '43e4080aaa14fc7d4b77ee1f5c9d067d5a7df10e', - 'snippet/multiple-files' => 'b80faa8c5b2b62f6489a0d84755580e927e1189b', + 'snippet/multiple-files' => '40232f7eb98b3f221886432def6e8bab2432add9', 'snippet/rename-and-edit-file' => '220a1e4b4dff37feea0625a7947a4c60fbe78365', 'snippet/edit-file' => 'c2f074f4f26929c92795a75775af79a6ed6d8430', 'snippet/no-files' => '671aaa842a4875e5f30082d1ab6feda345fdb94d', @@ -284,29 +282,33 @@ module TestEnv end def setup_factory_repo - setup_repo(factory_repo_path, factory_repo_path_bare, factory_repo_name, - BRANCH_SHA) + setup_repo(factory_repo_path, factory_repo_path_bare, factory_repo_name, BRANCH_SHA) end # This repo has a submodule commit that is not present in the main test # repository. def setup_forked_repo - setup_repo(forked_repo_path, forked_repo_path_bare, forked_repo_name, - FORKED_BRANCH_SHA) + setup_repo(forked_repo_path, forked_repo_path_bare, forked_repo_name, FORKED_BRANCH_SHA) end def setup_repo(repo_path, repo_path_bare, repo_name, refs) clone_url = "https://gitlab.com/gitlab-org/#{repo_name}.git" unless File.directory?(repo_path) - system(*%W(#{Gitlab.config.git.bin_path} clone -q #{clone_url} #{repo_path})) + puts "\n==> Setting up #{repo_name} repository in #{repo_path}..." + start = Time.now + system(*%W(#{Gitlab.config.git.bin_path} clone --quiet -- #{clone_url} #{repo_path})) + puts " #{repo_path} set up in #{Time.now - start} seconds...\n" end set_repo_refs(repo_path, refs) unless File.directory?(repo_path_bare) + puts "\n==> Setting up #{repo_name} bare repository in #{repo_path_bare}..." + start = Time.now # We must copy bare repositories because we will push to them. - system(git_env, *%W(#{Gitlab.config.git.bin_path} clone -q --bare #{repo_path} #{repo_path_bare})) + system(git_env, *%W(#{Gitlab.config.git.bin_path} clone --quiet --bare -- #{repo_path} #{repo_path_bare})) + puts " #{repo_path_bare} set up in #{Time.now - start} seconds...\n" end end diff --git a/spec/support/helpers/usage_data_helpers.rb b/spec/support/helpers/usage_data_helpers.rb index 1f1e686fb21..382e4f6a1a4 100644 --- a/spec/support/helpers/usage_data_helpers.rb +++ b/spec/support/helpers/usage_data_helpers.rb @@ -19,6 +19,9 @@ module UsageDataHelpers cycle_analytics_views productivity_analytics_views source_code_pushes + design_management_designs_create + design_management_designs_update + design_management_designs_delete ).freeze COUNTS_KEYS = %i( @@ -96,6 +99,24 @@ module UsageDataHelpers projects_with_error_tracking_enabled projects_with_alerts_service_enabled projects_with_prometheus_alerts + projects_with_expiration_policy_enabled + projects_with_expiration_policy_disabled + projects_with_expiration_policy_enabled_with_keep_n_unset + projects_with_expiration_policy_enabled_with_keep_n_set_to_1 + projects_with_expiration_policy_enabled_with_keep_n_set_to_5 + projects_with_expiration_policy_enabled_with_keep_n_set_to_10 + projects_with_expiration_policy_enabled_with_keep_n_set_to_25 + projects_with_expiration_policy_enabled_with_keep_n_set_to_50 + projects_with_expiration_policy_enabled_with_older_than_unset + projects_with_expiration_policy_enabled_with_older_than_set_to_7d + projects_with_expiration_policy_enabled_with_older_than_set_to_14d + projects_with_expiration_policy_enabled_with_older_than_set_to_30d + projects_with_expiration_policy_enabled_with_older_than_set_to_90d + projects_with_expiration_policy_enabled_with_cadence_set_to_1d + projects_with_expiration_policy_enabled_with_cadence_set_to_7d + projects_with_expiration_policy_enabled_with_cadence_set_to_14d + projects_with_expiration_policy_enabled_with_cadence_set_to_1month + projects_with_expiration_policy_enabled_with_cadence_set_to_3month pages_domains protected_branches releases @@ -130,28 +151,62 @@ module UsageDataHelpers gitaly database avg_cycle_analytics - influxdb_metrics_enabled prometheus_metrics_enabled web_ide_clientside_preview_enabled ingress_modsecurity_enabled - projects_with_expiration_policy_disabled - projects_with_expiration_policy_enabled - projects_with_expiration_policy_enabled_with_keep_n_unset - projects_with_expiration_policy_enabled_with_older_than_unset - projects_with_expiration_policy_enabled_with_keep_n_set_to_1 - projects_with_expiration_policy_enabled_with_keep_n_set_to_5 - projects_with_expiration_policy_enabled_with_keep_n_set_to_10 - projects_with_expiration_policy_enabled_with_keep_n_set_to_25 - projects_with_expiration_policy_enabled_with_keep_n_set_to_50 - projects_with_expiration_policy_enabled_with_keep_n_set_to_100 - projects_with_expiration_policy_enabled_with_cadence_set_to_1d - projects_with_expiration_policy_enabled_with_cadence_set_to_7d - projects_with_expiration_policy_enabled_with_cadence_set_to_14d - projects_with_expiration_policy_enabled_with_cadence_set_to_1month - projects_with_expiration_policy_enabled_with_cadence_set_to_3month - projects_with_expiration_policy_enabled_with_older_than_set_to_7d - projects_with_expiration_policy_enabled_with_older_than_set_to_14d - projects_with_expiration_policy_enabled_with_older_than_set_to_30d - projects_with_expiration_policy_enabled_with_older_than_set_to_90d + object_store ).freeze + + def stub_object_store_settings + allow(Settings).to receive(:[]).with('artifacts') + .and_return( + { 'enabled' => true, + 'object_store' => + { 'enabled' => true, + 'remote_directory' => 'artifacts', + 'direct_upload' => true, + 'connection' => + { 'provider' => 'AWS', 'aws_access_key_id' => 'minio', 'aws_secret_access_key' => 'gdk-minio', 'region' => 'gdk', 'endpoint' => 'http://127.0.0.1:9000', 'path_style' => true }, + 'background_upload' => false, + 'proxy_download' => false } } + ) + + allow(Settings).to receive(:[]).with('external_diffs').and_return({ 'enabled' => false }) + + allow(Settings).to receive(:[]).with('lfs') + .and_return( + { 'enabled' => true, + 'object_store' => + { 'enabled' => false, + 'remote_directory' => 'lfs-objects', + 'direct_upload' => true, + 'connection' => + { 'provider' => 'AWS', 'aws_access_key_id' => 'minio', 'aws_secret_access_key' => 'gdk-minio', 'region' => 'gdk', 'endpoint' => 'http://127.0.0.1:9000', 'path_style' => true }, + 'background_upload' => false, + 'proxy_download' => false } } + ) + allow(Settings).to receive(:[]).with('uploads') + .and_return( + { 'object_store' => + { 'enabled' => false, + 'remote_directory' => 'uploads', + 'direct_upload' => true, + 'connection' => + { 'provider' => 'AWS', 'aws_access_key_id' => 'minio', 'aws_secret_access_key' => 'gdk-minio', 'region' => 'gdk', 'endpoint' => 'http://127.0.0.1:9000', 'path_style' => true }, + 'background_upload' => false, + 'proxy_download' => false } } + ) + allow(Settings).to receive(:[]).with('packages') + .and_return( + { 'enabled' => true, + 'object_store' => + { 'enabled' => false, + 'remote_directory' => 'packages', + 'direct_upload' => false, + 'connection' => + { 'provider' => 'AWS', 'aws_access_key_id' => 'minio', 'aws_secret_access_key' => 'gdk-minio', 'region' => 'gdk', 'endpoint' => 'http://127.0.0.1:9000', 'path_style' => true }, + 'background_upload' => true, + 'proxy_download' => false } } + ) + end end diff --git a/spec/support/helpers/wiki_helpers.rb b/spec/support/helpers/wiki_helpers.rb index 86eb1793707..e6818ff8f0c 100644 --- a/spec/support/helpers/wiki_helpers.rb +++ b/spec/support/helpers/wiki_helpers.rb @@ -14,7 +14,10 @@ module WikiHelpers file_content: File.read(expand_fixture_path(file_name)) } - ::Wikis::CreateAttachmentService.new(project, user, opts) - .execute[:result][:file_path] + ::Wikis::CreateAttachmentService.new( + container: project, + current_user: user, + params: opts + ).execute[:result][:file_path] end end diff --git a/spec/support/helpers/workhorse_helpers.rb b/spec/support/helpers/workhorse_helpers.rb index 53b36b3dd45..f16b6c1e910 100644 --- a/spec/support/helpers/workhorse_helpers.rb +++ b/spec/support/helpers/workhorse_helpers.rb @@ -11,7 +11,7 @@ module WorkhorseHelpers header = split_header.join(':') [ type, - JSON.parse(Base64.urlsafe_decode64(header)) + Gitlab::Json.parse(Base64.urlsafe_decode64(header)) ] end end diff --git a/spec/support/helpers/x509_helpers.rb b/spec/support/helpers/x509_helpers.rb index 9ea997bf5f4..ce0fa268ace 100644 --- a/spec/support/helpers/x509_helpers.rb +++ b/spec/support/helpers/x509_helpers.rb @@ -173,22 +173,155 @@ module X509Helpers Time.at(1561027326) end + def signed_tag_signature + <<~SIGNATURE + -----BEGIN SIGNED MESSAGE----- + MIISfwYJKoZIhvcNAQcCoIIScDCCEmwCAQExDTALBglghkgBZQMEAgEwCwYJKoZI + hvcNAQcBoIIP8zCCB3QwggVcoAMCAQICBBXXLOIwDQYJKoZIhvcNAQELBQAwgbYx + CzAJBgNVBAYTAkRFMQ8wDQYDVQQIDAZCYXllcm4xETAPBgNVBAcMCE11ZW5jaGVu + MRAwDgYDVQQKDAdTaWVtZW5zMREwDwYDVQQFEwhaWlpaWlpBNjEdMBsGA1UECwwU + U2llbWVucyBUcnVzdCBDZW50ZXIxPzA9BgNVBAMMNlNpZW1lbnMgSXNzdWluZyBD + QSBNZWRpdW0gU3RyZW5ndGggQXV0aGVudGljYXRpb24gMjAxNjAeFw0xNzAyMDMw + NjU4MzNaFw0yMDAyMDMwNjU4MzNaMFsxETAPBgNVBAUTCFowMDBOV0RIMQ4wDAYD + VQQqDAVSb2dlcjEOMAwGA1UEBAwFTWVpZXIxEDAOBgNVBAoMB1NpZW1lbnMxFDAS + BgNVBAMMC01laWVyIFJvZ2VyMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKC + AQEAuBNea/68ZCnHYQjpm/k3ZBG0wBpEKSwG6lk9CEQlSxsqVLQHAoAKBIlJm1in + YVLcK/Sq1yhYJ/qWcY/M53DhK2rpPuhtrWJUdOUy8EBWO20F4bd4Fw9pO7jt8bme + u33TSrK772vKjuppzB6SeG13Cs08H+BIeD106G27h7ufsO00pvsxoSDL+uc4slnr + pBL+2TAL7nSFnB9QHWmRIK27SPqJE+lESdb0pse11x1wjvqKy2Q7EjL9fpqJdHzX + NLKHXd2r024TOORTa05DFTNR+kQEKKV96XfpYdtSBomXNQ44cisiPBJjFtYvfnFE + wgrHa8fogn/b0C+A+HAoICN12wIDAQABo4IC4jCCAt4wHQYDVR0OBBYEFCF+gkUp + XQ6xGc0kRWXuDFxzA14zMEMGA1UdEQQ8MDqgIwYKKwYBBAGCNxQCA6AVDBNyLm1l + aWVyQHNpZW1lbnMuY29tgRNyLm1laWVyQHNpZW1lbnMuY29tMA4GA1UdDwEB/wQE + AwIHgDAdBgNVHSUEFjAUBggrBgEFBQcDAgYIKwYBBQUHAwQwgcoGA1UdHwSBwjCB + vzCBvKCBuaCBtoYmaHR0cDovL2NoLnNpZW1lbnMuY29tL3BraT9aWlpaWlpBNi5j + cmyGQWxkYXA6Ly9jbC5zaWVtZW5zLm5ldC9DTj1aWlpaWlpBNixMPVBLST9jZXJ0 + aWZpY2F0ZVJldm9jYXRpb25MaXN0hklsZGFwOi8vY2wuc2llbWVucy5jb20vQ049 + WlpaWlpaQTYsbz1UcnVzdGNlbnRlcj9jZXJ0aWZpY2F0ZVJldm9jYXRpb25MaXN0 + MEUGA1UdIAQ+MDwwOgYNKwYBBAGhaQcCAgMBAzApMCcGCCsGAQUFBwIBFhtodHRw + Oi8vd3d3LnNpZW1lbnMuY29tL3BraS8wDAYDVR0TAQH/BAIwADAfBgNVHSMEGDAW + gBT4FV1HDGx3e3LEAheRaKK292oJRDCCAQQGCCsGAQUFBwEBBIH3MIH0MDIGCCsG + AQUFBzAChiZodHRwOi8vYWguc2llbWVucy5jb20vcGtpP1paWlpaWkE2LmNydDBB + BggrBgEFBQcwAoY1bGRhcDovL2FsLnNpZW1lbnMubmV0L0NOPVpaWlpaWkE2LEw9 + UEtJP2NBQ2VydGlmaWNhdGUwSQYIKwYBBQUHMAKGPWxkYXA6Ly9hbC5zaWVtZW5z + LmNvbS9DTj1aWlpaWlpBNixvPVRydXN0Y2VudGVyP2NBQ2VydGlmaWNhdGUwMAYI + KwYBBQUHMAGGJGh0dHA6Ly9vY3NwLnBraS1zZXJ2aWNlcy5zaWVtZW5zLmNvbTAN + BgkqhkiG9w0BAQsFAAOCAgEAXPVcX6vaEcszJqg5IemF9aFTlwTrX5ITNIpzcqG+ + kD5haOf2mZYLjl+MKtLC1XfmIsGCUZNb8bjP6QHQEI+2d6x/ZOqPq7Kd7PwVu6x6 + xZrkDjUyhUbUntT5+RBy++l3Wf6Cq6Kx+K8ambHBP/bu90/p2U8KfFAG3Kr2gI2q + fZrnNMOxmJfZ3/sXxssgLkhbZ7hRa+MpLfQ6uFsSiat3vlawBBvTyHnoZ/7oRc8y + qi6QzWcd76CPpMElYWibl+hJzKbBZUWvc71AzHR6i1QeZ6wubYz7vr+FF5Y7tnxB + Vz6omPC9XAg0F+Dla6Zlz3Awj5imCzVXa+9SjtnsidmJdLcKzTAKyDewewoxYOOJ + j3cJU7VSjJPl+2fVmDBaQwcNcUcu/TPAKApkegqO7tRF9IPhjhW8QkRnkqMetO3D + OXmAFVIsEI0Hvb2cdb7B6jSpjGUuhaFm9TCKhQtCk2p8JCDTuaENLm1x34rrJKbT + 2vzyYN0CZtSkUdgD4yQxK9VWXGEzexRisWb4AnZjD2NAquLPpXmw8N0UwFD7MSpC + dpaX7FktdvZmMXsnGiAdtLSbBgLVWOD1gmJFDjrhNbI8NOaOaNk4jrfGqNh5lhGU + 4DnBT2U6Cie1anLmFH/oZooAEXR2o3Nu+1mNDJChnJp0ovs08aa3zZvBdcloOvfU + qdowggh3MIIGX6ADAgECAgQtyi/nMA0GCSqGSIb3DQEBCwUAMIGZMQswCQYDVQQG + EwJERTEPMA0GA1UECAwGQmF5ZXJuMREwDwYDVQQHDAhNdWVuY2hlbjEQMA4GA1UE + CgwHU2llbWVuczERMA8GA1UEBRMIWlpaWlpaQTExHTAbBgNVBAsMFFNpZW1lbnMg + VHJ1c3QgQ2VudGVyMSIwIAYDVQQDDBlTaWVtZW5zIFJvb3QgQ0EgVjMuMCAyMDE2 + MB4XDTE2MDcyMDEzNDYxMFoXDTIyMDcyMDEzNDYxMFowgbYxCzAJBgNVBAYTAkRF + MQ8wDQYDVQQIDAZCYXllcm4xETAPBgNVBAcMCE11ZW5jaGVuMRAwDgYDVQQKDAdT + aWVtZW5zMREwDwYDVQQFEwhaWlpaWlpBNjEdMBsGA1UECwwUU2llbWVucyBUcnVz + dCBDZW50ZXIxPzA9BgNVBAMMNlNpZW1lbnMgSXNzdWluZyBDQSBNZWRpdW0gU3Ry + ZW5ndGggQXV0aGVudGljYXRpb24gMjAxNjCCAiIwDQYJKoZIhvcNAQEBBQADggIP + ADCCAgoCggIBAL9UfK+JAZEqVMVvECdYF9IK4KSw34AqyNl3rYP5x03dtmKaNu+2 + 0fQqNESA1NGzw3s6LmrKLh1cR991nB2cvKOXu7AvEGpSuxzIcOROd4NpvRx+Ej1p + JIPeqf+ScmVK7lMSO8QL/QzjHOpGV3is9sG+ZIxOW9U1ESooy4Hal6ZNs4DNItsz + piCKqm6G3et4r2WqCy2RRuSqvnmMza7Y8BZsLy0ZVo5teObQ37E/FxqSrbDI8nxn + B7nVUve5ZjrqoIGSkEOtyo11003dVO1vmWB9A0WQGDqE/q3w178hGhKfxzRaqzyi + SoADUYS2sD/CglGTUxVq6u0pGLLsCFjItcCWqW+T9fPYfJ2CEd5b3hvqdCn+pXjZ + /gdX1XAcdUF5lRnGWifaYpT9n4s4adzX8q6oHSJxTppuAwLRKH6eXALbGQ1I9lGQ + DSOipD/09xkEsPw6HOepmf2U3YxZK1VU2sHqugFJboeLcHMzp6E1n2ctlNG1GKE9 + FDHmdyFzDi0Nnxtf/GgVjnHF68hByEE1MYdJ4nJLuxoT9hyjYdRW9MpeNNxxZnmz + W3zh7QxIqP0ZfIz6XVhzrI9uZiqwwojDiM5tEOUkQ7XyW6grNXe75yt6mTj89LlB + H5fOW2RNmCy/jzBXDjgyskgK7kuCvUYTuRv8ITXbBY5axFA+CpxZqokpAgMBAAGj + ggKmMIICojCCAQUGCCsGAQUFBwEBBIH4MIH1MEEGCCsGAQUFBzAChjVsZGFwOi8v + YWwuc2llbWVucy5uZXQvQ049WlpaWlpaQTEsTD1QS0k/Y0FDZXJ0aWZpY2F0ZTAy + BggrBgEFBQcwAoYmaHR0cDovL2FoLnNpZW1lbnMuY29tL3BraT9aWlpaWlpBMS5j + cnQwSgYIKwYBBQUHMAKGPmxkYXA6Ly9hbC5zaWVtZW5zLmNvbS91aWQ9WlpaWlpa + QTEsbz1UcnVzdGNlbnRlcj9jQUNlcnRpZmljYXRlMDAGCCsGAQUFBzABhiRodHRw + Oi8vb2NzcC5wa2ktc2VydmljZXMuc2llbWVucy5jb20wHwYDVR0jBBgwFoAUcG2g + UOyp0CxnnRkV/v0EczXD4tQwEgYDVR0TAQH/BAgwBgEB/wIBADBABgNVHSAEOTA3 + MDUGCCsGAQQBoWkHMCkwJwYIKwYBBQUHAgEWG2h0dHA6Ly93d3cuc2llbWVucy5j + b20vcGtpLzCBxwYDVR0fBIG/MIG8MIG5oIG2oIGzhj9sZGFwOi8vY2wuc2llbWVu + cy5uZXQvQ049WlpaWlpaQTEsTD1QS0k/YXV0aG9yaXR5UmV2b2NhdGlvbkxpc3SG + Jmh0dHA6Ly9jaC5zaWVtZW5zLmNvbS9wa2k/WlpaWlpaQTEuY3JshkhsZGFwOi8v + Y2wuc2llbWVucy5jb20vdWlkPVpaWlpaWkExLG89VHJ1c3RjZW50ZXI/YXV0aG9y + aXR5UmV2b2NhdGlvbkxpc3QwJwYDVR0lBCAwHgYIKwYBBQUHAwIGCCsGAQUFBwME + BggrBgEFBQcDCTAOBgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYEFPgVXUcMbHd7csQC + F5Foorb3aglEMA0GCSqGSIb3DQEBCwUAA4ICAQBw+sqMp3SS7DVKcILEmXbdRAg3 + lLO1r457KY+YgCT9uX4VG5EdRKcGfWXK6VHGCi4Dos5eXFV34Mq/p8nu1sqMuoGP + YjHn604eWDprhGy6GrTYdxzcE/GGHkpkuE3Ir/45UcmZlOU41SJ9SNjuIVrSHMOf + ccSY42BCspR/Q1Z/ykmIqQecdT3/Kkx02GzzSN2+HlW6cEO4GBW5RMqsvd2n0h2d + fe2zcqOgkLtx7u2JCR/U77zfyxG3qXtcymoz0wgSHcsKIl+GUjITLkHfS9Op8V7C + Gr/dX437sIg5pVHmEAWadjkIzqdHux+EF94Z6kaHywohc1xG0KvPYPX7iSNjkvhz + 4NY53DHmxl4YEMLffZnaS/dqyhe1GTpcpyN8WiR4KuPfxrkVDOsuzWFtMSvNdlOV + gdI0MXcLMP+EOeANZWX6lGgJ3vWyemo58nzgshKd24MY3w3i6masUkxJH2KvI7UH + /1Db3SC8oOUjInvSRej6M3ZhYWgugm6gbpUgFoDw/o9Cg6Qm71hY0JtcaPC13rzm + N8a2Br0+Fa5e2VhwLmAxyfe1JKzqPwuHT0S5u05SQghL5VdzqfA8FCL/j4XC9yI6 + csZTAQi73xFQYVjZt3+aoSz84lOlTmVo/jgvGMY/JzH9I4mETGgAJRNj34Z/0meh + M+pKWCojNH/dgyJSwDGCAlIwggJOAgEBMIG/MIG2MQswCQYDVQQGEwJERTEPMA0G + A1UECAwGQmF5ZXJuMREwDwYDVQQHDAhNdWVuY2hlbjEQMA4GA1UECgwHU2llbWVu + czERMA8GA1UEBRMIWlpaWlpaQTYxHTAbBgNVBAsMFFNpZW1lbnMgVHJ1c3QgQ2Vu + dGVyMT8wPQYDVQQDDDZTaWVtZW5zIElzc3VpbmcgQ0EgTWVkaXVtIFN0cmVuZ3Ro + IEF1dGhlbnRpY2F0aW9uIDIwMTYCBBXXLOIwCwYJYIZIAWUDBAIBoGkwHAYJKoZI + hvcNAQkFMQ8XDTE5MTEyMDE0NTYyMFowLwYJKoZIhvcNAQkEMSIEIJDnZUpcVLzC + OdtpkH8gtxwLPIDE0NmAmFC9uM8q2z+OMBgGCSqGSIb3DQEJAzELBgkqhkiG9w0B + BwEwCwYJKoZIhvcNAQEBBIIBAH/Pqv2xp3a0jSPkwU1K3eGA/1lfoNJMUny4d/PS + LVWlkgrmedXdLmuBzAGEaaZOJS0lEpNd01pR/reHs7xxZ+RZ0olTs2ufM0CijQSx + OL9HDl2O3OoD77NWx4tl3Wy1yJCeV3XH/cEI7AkKHCmKY9QMoMYWh16ORBtr+YcS + YK+gONOjpjgcgTJgZ3HSFgQ50xiD4WT1kFBHsuYsLqaOSbTfTN6Ayyg4edjrPQqa + VcVf1OQcIrfWA3yMQrnEZfOYfN/D4EPjTfxBV+VCi/F2bdZmMbJ7jNk1FbewSwWO + SDH1i0K32NyFbnh0BSos7njq7ELqKlYBsoB/sZfaH2vKy5U= + -----END SIGNED MESSAGE----- + SIGNATURE + end + + def signed_tag_base_data + <<~SIGNEDDATA + object 189a6c924013fc3fe40d6f1ec1dc20214183bc97 + type commit + tag v1.1.1 + tagger Roger Meier <r.meier@siemens.com> 1574261780 +0100 + + x509 signed tag + SIGNEDDATA + end + def certificate_crl 'http://ch.siemens.com/pki?ZZZZZZA2.crl' end + def tag_certificate_crl + 'http://ch.siemens.com/pki?ZZZZZZA6.crl' + end + def certificate_serial 1810356222 end + def tag_certificate_serial + 3664232660 + end + def certificate_subject_key_identifier 'EC:00:B5:28:02:5C:D3:A5:A1:AB:C2:A1:34:81:84:AA:BF:9B:CF:F8' end + def tag_certificate_subject_key_identifier + '21:7E:82:45:29:5D:0E:B1:19:CD:24:45:65:EE:0C:5C:73:03:5E:33' + end + def issuer_subject_key_identifier 'BD:BD:2A:43:22:3D:48:4A:57:7E:98:31:17:A9:70:9D:EE:9F:A8:99' end + def tag_issuer_subject_key_identifier + 'F8:15:5D:47:0C:6C:77:7B:72:C4:02:17:91:68:A2:B6:F7:6A:09:44' + end + def certificate_email 'r.meier@siemens.com' end @@ -197,6 +330,10 @@ module X509Helpers 'CN=Siemens Issuing CA EE Auth 2016,OU=Siemens Trust Center,serialNumber=ZZZZZZA2,O=Siemens,L=Muenchen,ST=Bayern,C=DE' end + def tag_certificate_issuer + 'CN=Siemens Issuing CA Medium Strength Authentication 2016,OU=Siemens Trust Center,serialNumber=ZZZZZZA6,O=Siemens,L=Muenchen,ST=Bayern,C=DE' + end + def certificate_subject 'CN=Meier Roger,O=Siemens,SN=Meier,GN=Roger,serialNumber=Z000NWDH' end |