diff options
author | GitLab Bot <gitlab-bot@gitlab.com> | 2022-11-23 12:08:15 +0300 |
---|---|---|
committer | GitLab Bot <gitlab-bot@gitlab.com> | 2022-11-23 12:08:15 +0300 |
commit | abbb493d78e42f044d732c7ad46917300cca1516 (patch) | |
tree | ae786d6bc1ba548421c20d1667f528d4ff90e113 | |
parent | 9d15ef5c5caf584ae16398940c16f2bdafd6f3e2 (diff) |
Add latest changes from gitlab-org/gitlab@master
-rw-r--r-- | app/finders/clusters/agent_tokens_finder.rb | 2 | ||||
-rw-r--r-- | app/models/clusters/agent_token.rb | 4 | ||||
-rw-r--r-- | app/models/environment.rb | 15 | ||||
-rw-r--r-- | lib/api/clusters/agent_tokens.rb | 3 | ||||
-rw-r--r-- | qa/qa.rb | 3 | ||||
-rw-r--r-- | qa/qa/git/location.rb | 5 | ||||
-rw-r--r-- | qa/qa/page/base.rb | 39 | ||||
-rw-r--r-- | qa/qa/resource/ssh_key.rb | 4 | ||||
-rw-r--r-- | qa/qa/runtime/logger.rb | 26 | ||||
-rw-r--r-- | qa/qa/support/formatters/test_metrics_formatter.rb | 23 | ||||
-rw-r--r-- | qa/qa/support/influxdb_tools.rb | 2 | ||||
-rw-r--r-- | qa/qa/support/knapsack_report.rb | 6 | ||||
-rw-r--r-- | qa/qa/tools/long_running_spec_reporter.rb | 6 | ||||
-rw-r--r-- | spec/models/clusters/agent_token_spec.rb | 8 | ||||
-rw-r--r-- | spec/models/environment_spec.rb | 28 | ||||
-rw-r--r-- | spec/requests/api/clusters/agent_tokens_spec.rb | 21 |
16 files changed, 128 insertions, 67 deletions
diff --git a/app/finders/clusters/agent_tokens_finder.rb b/app/finders/clusters/agent_tokens_finder.rb index 60609fa6c6d..c0d1f911d92 100644 --- a/app/finders/clusters/agent_tokens_finder.rb +++ b/app/finders/clusters/agent_tokens_finder.rb @@ -2,6 +2,8 @@ module Clusters class AgentTokensFinder + include FinderMethods + def initialize(agent, current_user) @agent = agent @current_user = current_user diff --git a/app/models/clusters/agent_token.rb b/app/models/clusters/agent_token.rb index 1607d0b6d19..e2dcff13a69 100644 --- a/app/models/clusters/agent_token.rb +++ b/app/models/clusters/agent_token.rb @@ -25,5 +25,9 @@ module Clusters active: 0, revoked: 1 } + + def to_ability_name + :cluster + end end end diff --git a/app/models/environment.rb b/app/models/environment.rb index 4e2791c96c2..b4586bfbca8 100644 --- a/app/models/environment.rb +++ b/app/models/environment.rb @@ -28,21 +28,23 @@ class Environment < ApplicationRecord has_many :self_managed_prometheus_alert_events, inverse_of: :environment has_many :alert_management_alerts, class_name: 'AlertManagement::Alert', inverse_of: :environment - # NOTE: If you preload multiple last deployments of environments, use Preloaders::Environments::DeploymentPreloader. - has_one :last_deployment, -> { success.ordered }, class_name: 'Deployment', inverse_of: :environment - has_one :last_visible_deployment, -> { visible.order(id: :desc) }, inverse_of: :environment, class_name: 'Deployment' + # NOTE: + # 1) no-op arguments is to prevent accidental legacy preloading. See: https://gitlab.com/gitlab-org/gitlab/-/issues/369240 + # 2) If you preload multiple last deployments of environments, use Preloaders::Environments::DeploymentPreloader. + has_one :last_deployment, -> (_env) { success.ordered }, class_name: 'Deployment', inverse_of: :environment + has_one :last_visible_deployment, -> (_env) { visible.order(id: :desc) }, inverse_of: :environment, class_name: 'Deployment' + has_one :upcoming_deployment, -> (_env) { upcoming.order(id: :desc) }, class_name: 'Deployment', inverse_of: :environment Deployment::FINISHED_STATUSES.each do |status| - has_one :"last_#{status}_deployment", -> { where(status: status).ordered }, + has_one :"last_#{status}_deployment", -> (_env) { where(status: status).ordered }, class_name: 'Deployment', inverse_of: :environment end Deployment::UPCOMING_STATUSES.each do |status| - has_one :"last_#{status}_deployment", -> { where(status: status).ordered_as_upcoming }, + has_one :"last_#{status}_deployment", -> (_env) { where(status: status).ordered_as_upcoming }, class_name: 'Deployment', inverse_of: :environment end - has_one :upcoming_deployment, -> { upcoming.order(id: :desc) }, class_name: 'Deployment', inverse_of: :environment has_one :latest_opened_most_severe_alert, -> { order_severity_with_open_prometheus_alert }, class_name: 'AlertManagement::Alert', inverse_of: :environment before_validation :generate_slug, if: ->(env) { env.slug.blank? } @@ -88,7 +90,6 @@ class Environment < ApplicationRecord scope :in_review_folder, -> { where(environment_type: "review") } scope :for_name, -> (name) { where(name: name) } - scope :preload_cluster, -> { preload(last_deployment: :cluster) } scope :preload_project, -> { preload(:project) } scope :auto_stoppable, -> (limit) { available.where('auto_stop_at < ?', Time.zone.now).limit(limit) } scope :auto_deletable, -> (limit) { stopped.where('auto_delete_at < ?', Time.zone.now).limit(limit) } diff --git a/lib/api/clusters/agent_tokens.rb b/lib/api/clusters/agent_tokens.rb index d2088557019..04e9d421228 100644 --- a/lib/api/clusters/agent_tokens.rb +++ b/lib/api/clusters/agent_tokens.rb @@ -43,8 +43,7 @@ module API end get ':token_id' do agent = ::Clusters::AgentsFinder.new(user_project, current_user).find(params[:agent_id]) - - token = agent.agent_tokens.find(params[:token_id]) + token = ::Clusters::AgentTokensFinder.new(agent, current_user).find(params[:token_id]) present token, with: Entities::Clusters::AgentToken end @@ -13,9 +13,10 @@ Bundler.require(:default) require 'securerandom' require 'pathname' +require 'rainbow/refinement' require 'active_support/core_ext/hash' require 'active_support/core_ext/object/blank' -require 'rainbow/refinement' +require 'active_support/core_ext/module/delegation' module QA root = "#{__dir__}/qa" diff --git a/qa/qa/git/location.rb b/qa/qa/git/location.rb index c3733572e70..9ac97a66e53 100644 --- a/qa/qa/git/location.rb +++ b/qa/qa/git/location.rb @@ -1,16 +1,13 @@ # frozen_string_literal: true require 'uri' -require 'forwardable' module QA module Git class Location - extend Forwardable - attr_reader :git_uri, :uri - def_delegators :@uri, :user, :host, :path + delegate :user, :host, :path, to: :@uri # See: config/initializers/1_settings.rb # Settings#build_gitlab_shell_ssh_path_prefix diff --git a/qa/qa/page/base.rb b/qa/qa/page/base.rb index f59b06b4e75..ab83da7dacf 100644 --- a/qa/qa/page/base.rb +++ b/qa/qa/page/base.rb @@ -13,7 +13,6 @@ module QA include Support::WaitForRequests extend Validatable - extend SingleForwardable ElementNotFound = Class.new(RuntimeError) @@ -31,8 +30,6 @@ module QA end end - def_delegators :evaluator, :view, :views - def initialize @retry_later_backoff = QA::Support::Repeater::DEFAULT_MAX_WAIT_TIME end @@ -276,7 +273,7 @@ module QA visible = kwargs.delete(:visible) visible = visible.nil? && true - try_find_element = lambda do |wait| + try_find_element = ->(wait) do if disabled.nil? has_css?(element_selector_css(name, kwargs), text: text, wait: wait, class: klass, visible: visible) else @@ -422,26 +419,30 @@ module QA URI(page.current_url).host end - def self.path - raise NotImplementedError - end + class << self + def path + raise NotImplementedError + end - def self.evaluator - @evaluator ||= Page::Base::DSL.new - end + def evaluator + @evaluator ||= Page::Base::DSL.new + end - def self.errors - return ["Page class does not have views / elements defined!"] if views.empty? + def errors + return ["Page class does not have views / elements defined!"] if views.empty? - views.flat_map(&:errors) - end + views.flat_map(&:errors) + end - def self.elements - views.flat_map(&:elements) - end + def elements + views.flat_map(&:elements) + end + + def required_elements + elements.select(&:required?) + end - def self.required_elements - elements.select(&:required?) + delegate :view, :views, to: :evaluator end def send_keys_to_element(name, keys) diff --git a/qa/qa/resource/ssh_key.rb b/qa/qa/resource/ssh_key.rb index dd475d7fa66..1c142058908 100644 --- a/qa/qa/resource/ssh_key.rb +++ b/qa/qa/resource/ssh_key.rb @@ -3,14 +3,12 @@ module QA module Resource class SSHKey < Base - extend Forwardable - attr_reader :title attr_accessor :expires_at attribute :id - def_delegators :key, :private_key, :public_key, :md5_fingerprint, :sha256_fingerprint + delegate :private_key, :public_key, :md5_fingerprint, :sha256_fingerprint, to: :key def initialize self.title = Time.now.to_f diff --git a/qa/qa/runtime/logger.rb b/qa/qa/runtime/logger.rb index e0e7385d6d4..7e78ba470d8 100644 --- a/qa/qa/runtime/logger.rb +++ b/qa/qa/runtime/logger.rb @@ -1,23 +1,21 @@ # frozen_string_literal: true -require 'forwardable' - module QA module Runtime class Logger - extend SingleForwardable - - def_delegators :logger, :debug, :info, :warn, :error, :fatal, :unknown + class << self + # Global logger instance + # + # @return [ActiveSupport::Logger] + def logger + @logger ||= Gitlab::QA::TestLogger.logger( + level: Gitlab::QA::Runtime::Env.log_level, + source: 'QA Tests', + path: File.expand_path('../../tmp', __dir__) + ) + end - # Global logger instance - # - # @return [ActiveSupport::Logger] - def self.logger - @logger ||= Gitlab::QA::TestLogger.logger( - level: Gitlab::QA::Runtime::Env.log_level, - source: 'QA Tests', - path: File.expand_path('../../tmp', __dir__) - ) + delegate :debug, :info, :warn, :error, :fatal, :unknown, to: :logger end end end diff --git a/qa/qa/support/formatters/test_metrics_formatter.rb b/qa/qa/support/formatters/test_metrics_formatter.rb index e84373a487d..1d60e4060d9 100644 --- a/qa/qa/support/formatters/test_metrics_formatter.rb +++ b/qa/qa/support/formatters/test_metrics_formatter.rb @@ -19,16 +19,15 @@ module QA parse_execution_data(notification.examples) - if Runtime::Env.export_metrics? - push_test_metrics - push_fabrication_metrics - end - - save_test_metrics if Runtime::Env.save_metrics_json? + push_test_metrics + push_fabrication_metrics + save_test_metrics end private + delegate :export_metrics?, :save_metrics_json?, :ci_job_url, :ci_job_name, to: "QA::Runtime::Env" + # Save execution data for the run # # @param [Array<RSpec::Core::Example>] examples @@ -42,6 +41,8 @@ module QA # # @return [void] def push_test_metrics + return log(:debug, "Metrics export not enabled, skipping test metrics export") unless export_metrics? + write_api.write(data: execution_data) log(:debug, "Pushed #{execution_data.length} test execution entries to influxdb") rescue StandardError => e @@ -52,6 +53,8 @@ module QA # # @return [void] def push_fabrication_metrics + return log(:debug, "Metrics export not enabled, skipping fabrication metrics export") unless export_metrics? + data = Tools::TestResourceDataProcessor.resources.flat_map do |resource, values| values.map { |v| fabrication_stats(resource: resource, **v) } end @@ -67,6 +70,8 @@ module QA # # @return [void] def save_test_metrics + return log(:debug, "Saving test metrics json not enabled, skipping") unless save_metrics_json? + File.write("tmp/test-metrics-#{env('CI_JOB_NAME_SLUG') || 'local'}.json", execution_data.to_json) rescue StandardError => e log(:error, "Failed to save test execution metrics, error: #{e}") @@ -110,7 +115,7 @@ module QA ui_fabrication: ui_fabrication, total_fabrication: api_fabrication + ui_fabrication, retry_attempts: retry_attempts(example.metadata), - job_url: QA::Runtime::Env.ci_job_url, + job_url: ci_job_url, pipeline_url: env('CI_PIPELINE_URL'), pipeline_id: env('CI_PIPELINE_ID'), job_id: env('CI_JOB_ID'), @@ -145,7 +150,7 @@ module QA fields: { fabrication_time: fabrication_time, info: info, - job_url: QA::Runtime::Env.ci_job_url, + job_url: ci_job_url, timestamp: timestamp } } @@ -155,7 +160,7 @@ module QA # # @return [String] def job_name - @job_name ||= QA::Runtime::Env.ci_job_name&.gsub(%r{ \d{1,2}/\d{1,2}}, '') + @job_name ||= ci_job_name&.gsub(%r{ \d{1,2}/\d{1,2}}, '') end # Single common timestamp for all exported example metrics to keep data points consistently grouped diff --git a/qa/qa/support/influxdb_tools.rb b/qa/qa/support/influxdb_tools.rb index e817b096864..efdbe1cd129 100644 --- a/qa/qa/support/influxdb_tools.rb +++ b/qa/qa/support/influxdb_tools.rb @@ -1,7 +1,5 @@ # frozen_string_literal: true -require "active_support/core_ext/module/delegation" - module QA module Support # Common tools for use with influxdb metrics setup diff --git a/qa/qa/support/knapsack_report.rb b/qa/qa/support/knapsack_report.rb index 659b8f10e0a..27d8b144f3b 100644 --- a/qa/qa/support/knapsack_report.rb +++ b/qa/qa/support/knapsack_report.rb @@ -5,13 +5,13 @@ require "fog/google" module QA module Support class KnapsackReport - extend SingleForwardable - PROJECT = "gitlab-qa-resources" BUCKET = "knapsack-reports" FALLBACK_REPORT = "knapsack/master_report.json" - def_delegators :new, :configure!, :move_regenerated_report, :download_report, :upload_report + class << self + delegate :configure!, :move_regenerated_report, :download_report, :upload_report, to: :new + end def initialize(report_name = nil) @report_name = report_name diff --git a/qa/qa/tools/long_running_spec_reporter.rb b/qa/qa/tools/long_running_spec_reporter.rb index ce035248baa..865b16f1d41 100644 --- a/qa/qa/tools/long_running_spec_reporter.rb +++ b/qa/qa/tools/long_running_spec_reporter.rb @@ -6,15 +6,15 @@ require "slack-notifier" module QA module Tools class LongRunningSpecReporter - extend SingleForwardable - SLACK_CHANNEL = "#quality-reports" PROJECT = "gitlab-qa-resources" BUCKET = "knapsack-reports" REPORT_NAME = "ee-instance-parallel.json" RUNTIME_THRESHOLD = 300 - def_delegator :new, :execute + class << self + delegate :execute, to: :new + end # Find and report specs exceeding runtime threshold # diff --git a/spec/models/clusters/agent_token_spec.rb b/spec/models/clusters/agent_token_spec.rb index efa2a3eb09b..74723e3abd8 100644 --- a/spec/models/clusters/agent_token_spec.rb +++ b/spec/models/clusters/agent_token_spec.rb @@ -49,4 +49,12 @@ RSpec.describe Clusters::AgentToken do expect(agent_token.token.length).to be >= 50 end end + + describe '#to_ability_name' do + it 'is :cluster' do + agent_token = build(:cluster_agent_token) + + expect(agent_token.to_ability_name).to eq :cluster + end + end end diff --git a/spec/models/environment_spec.rb b/spec/models/environment_spec.rb index d4694109b12..8fef895901d 100644 --- a/spec/models/environment_spec.rb +++ b/spec/models/environment_spec.rb @@ -64,6 +64,34 @@ RSpec.describe Environment, :use_clean_rails_memory_store_caching do end end + describe 'preloading deployment associations' do + let!(:environment) { create(:environment, project: project) } + + associations = [:last_deployment, :last_visible_deployment, :upcoming_deployment] + associations.concat Deployment::FINISHED_STATUSES.map { |status| "last_#{status}_deployment".to_sym } + associations.concat Deployment::UPCOMING_STATUSES.map { |status| "last_#{status}_deployment".to_sym } + + context 'raises error for legacy approach' do + let!(:error_pattern) { /Preloading instance dependent scopes is not supported/ } + + subject { described_class.preload(association_name).find_by(id: environment) } + + shared_examples 'raises error' do + it do + expect { subject }.to raise_error(error_pattern) + end + end + + associations.each do |association| + context association.to_s do + let!(:association_name) { association } + + include_examples "raises error" + end + end + end + end + describe 'validate and sanitize external url' do let_it_be_with_refind(:environment) { create(:environment) } diff --git a/spec/requests/api/clusters/agent_tokens_spec.rb b/spec/requests/api/clusters/agent_tokens_spec.rb index a33bef53b14..7b9aed80e9d 100644 --- a/spec/requests/api/clusters/agent_tokens_spec.rb +++ b/spec/requests/api/clusters/agent_tokens_spec.rb @@ -80,6 +80,27 @@ RSpec.describe API::Clusters::AgentTokens do end end + it 'returns an agent token that is revoked' do + get api("/projects/#{project.id}/cluster_agents/#{agent.id}/tokens/#{revoked_agent_token.id}", user) + + aggregate_failures "testing response" do + expect(response).to have_gitlab_http_status(:ok) + expect(response).to match_response_schema('public_api/v4/agent_token') + expect(json_response['id']).to eq(revoked_agent_token.id) + expect(json_response['name']).to eq(revoked_agent_token.name) + expect(json_response['agent_id']).to eq(agent.id) + expect(json_response['status']).to eq('revoked') + end + end + + it 'returns a 404 if agent does not exist' do + path = "/projects/#{project.id}/cluster_agents/#{non_existing_record_id}/tokens/#{non_existing_record_id}" + + get api(path, user) + + expect(response).to have_gitlab_http_status(:not_found) + end + it 'returns a 404 error if agent token id is not available' do get api("/projects/#{project.id}/cluster_agents/#{agent.id}/tokens/#{non_existing_record_id}", user) |