Commit 9a84bd33 authored by Alex Kalderimis's avatar Alex Kalderimis

Merge branch 'use-caller-feature-category-for-unowned-sidekiq-jobs' into 'master'

Use surrounding context's feature category for unowned workers

See merge request gitlab-org/gitlab!67355
parents acf4a364 cf9a27f0
...@@ -1890,7 +1890,7 @@ ...@@ -1890,7 +1890,7 @@
:tags: [] :tags: []
- :name: default - :name: default
:worker_name: :worker_name:
:feature_category: :feature_category: :not_owned
:has_external_dependencies: :has_external_dependencies:
:urgency: :urgency:
:resource_boundary: :resource_boundary:
...@@ -2215,7 +2215,7 @@ ...@@ -2215,7 +2215,7 @@
:tags: [] :tags: []
- :name: mailers - :name: mailers
:worker_name: ActionMailer::MailDeliveryJob :worker_name: ActionMailer::MailDeliveryJob
:feature_category: :issue_tracking :feature_category: :not_owned
:has_external_dependencies: :has_external_dependencies:
:urgency: low :urgency: low
:resource_boundary: :resource_boundary:
......
...@@ -46,8 +46,14 @@ module WorkerAttributes ...@@ -46,8 +46,14 @@ module WorkerAttributes
set_class_attribute(:feature_category, :not_owned) set_class_attribute(:feature_category, :not_owned)
end end
# Special case: if a worker is not owned, get the feature category
# (if present) from the calling context.
def get_feature_category def get_feature_category
get_class_attribute(:feature_category) feature_category = get_class_attribute(:feature_category)
return feature_category unless feature_category == :not_owned
Gitlab::ApplicationContext.current_context_attribute('meta.feature_category') || feature_category
end end
def feature_category_not_owned? def feature_category_not_owned?
......
...@@ -72,6 +72,11 @@ class SomeCrossCuttingConcernWorker ...@@ -72,6 +72,11 @@ class SomeCrossCuttingConcernWorker
end end
``` ```
Workers marked as not owned workers will, when possible, use the
category of their caller (worker or HTTP endpoint) in metrics and logs.
For instance, `ReactiveCachingWorker` can have multiple feature
categories in metrics and logs.
## Rails controllers ## Rails controllers
Specifying feature categories on controller actions can be done using Specifying feature categories on controller actions can be done using
......
...@@ -27,6 +27,10 @@ RSpec.describe Elastic::IndexingControlService, :clean_gitlab_redis_shared_state ...@@ -27,6 +27,10 @@ RSpec.describe Elastic::IndexingControlService, :clean_gitlab_redis_shared_state
subject { described_class.new(worker_class) } subject { described_class.new(worker_class) }
before do
stub_const(worker_class.name, worker_class)
end
describe '.initialize' do describe '.initialize' do
it 'raises an exception when passed wrong worker' do it 'raises an exception when passed wrong worker' do
expect { described_class.new(Class.new) }.to raise_error(ArgumentError) expect { described_class.new(Class.new) }.to raise_error(ArgumentError)
...@@ -154,6 +158,10 @@ RSpec.describe Elastic::IndexingControlService, :clean_gitlab_redis_shared_state ...@@ -154,6 +158,10 @@ RSpec.describe Elastic::IndexingControlService, :clean_gitlab_redis_shared_state
let(:other_subject) { described_class.new(second_worker_class) } let(:other_subject) { described_class.new(second_worker_class) }
before do
stub_const(second_worker_class.name, second_worker_class)
end
it 'allows to use queues independently of each other' do it 'allows to use queues independently of each other' do
expect { subject.add_to_waiting_queue!(worker_args, worker_context) }.to change { subject.queue_size }.from(0).to(1) expect { subject.add_to_waiting_queue!(worker_args, worker_context) }.to change { subject.queue_size }.from(0).to(1)
......
...@@ -23,12 +23,12 @@ module Gitlab ...@@ -23,12 +23,12 @@ module Gitlab
DEFAULT_WORKERS = { DEFAULT_WORKERS = {
'_' => DummyWorker.new( '_' => DummyWorker.new(
queue: 'default', queue: 'default',
weight: 1, tags: [] weight: 1,
tags: []
), ),
'ActionMailer::MailDeliveryJob' => DummyWorker.new( 'ActionMailer::MailDeliveryJob' => DummyWorker.new(
name: 'ActionMailer::MailDeliveryJob', name: 'ActionMailer::MailDeliveryJob',
queue: 'mailers', queue: 'mailers',
feature_category: :issue_tracking,
urgency: 'low', urgency: 'low',
weight: 2, weight: 2,
tags: [] tags: []
......
...@@ -6,7 +6,6 @@ module Gitlab ...@@ -6,7 +6,6 @@ module Gitlab
class DummyWorker class DummyWorker
ATTRIBUTE_METHODS = { ATTRIBUTE_METHODS = {
name: :name, name: :name,
feature_category: :get_feature_category,
has_external_dependencies: :worker_has_external_dependencies?, has_external_dependencies: :worker_has_external_dependencies?,
urgency: :get_urgency, urgency: :get_urgency,
resource_boundary: :get_worker_resource_boundary, resource_boundary: :get_worker_resource_boundary,
...@@ -27,6 +26,20 @@ module Gitlab ...@@ -27,6 +26,20 @@ module Gitlab
nil nil
end end
# All dummy workers are unowned; get the feature category from the
# context if available.
def get_feature_category
Gitlab::ApplicationContext.current_context_attribute('meta.feature_category') || :not_owned
end
def get_worker_context
nil
end
def context_for_arguments(*)
nil
end
ATTRIBUTE_METHODS.each do |attribute, meth| ATTRIBUTE_METHODS.each do |attribute, meth|
define_method meth do define_method meth do
@attributes[attribute] @attributes[attribute]
......
...@@ -13,6 +13,13 @@ module Gitlab ...@@ -13,6 +13,13 @@ module Gitlab
chain.add ::Gitlab::SidekiqMiddleware::SizeLimiter::Server chain.add ::Gitlab::SidekiqMiddleware::SizeLimiter::Server
chain.add ::Gitlab::SidekiqMiddleware::Monitor chain.add ::Gitlab::SidekiqMiddleware::Monitor
# Labkit wraps the job in the `Labkit::Context` resurrected from
# the job-hash. We need properties from the context for
# recording metrics, so this needs to be before
# `::Gitlab::SidekiqMiddleware::ServerMetrics` (if we're using
# that).
chain.add ::Labkit::Middleware::Sidekiq::Server
if metrics if metrics
chain.add ::Gitlab::SidekiqMiddleware::ServerMetrics chain.add ::Gitlab::SidekiqMiddleware::ServerMetrics
...@@ -24,7 +31,6 @@ module Gitlab ...@@ -24,7 +31,6 @@ module Gitlab
chain.add ::Gitlab::SidekiqMiddleware::RequestStoreMiddleware chain.add ::Gitlab::SidekiqMiddleware::RequestStoreMiddleware
chain.add ::Gitlab::SidekiqMiddleware::ExtraDoneLogMetadata chain.add ::Gitlab::SidekiqMiddleware::ExtraDoneLogMetadata
chain.add ::Gitlab::SidekiqMiddleware::BatchLoader chain.add ::Gitlab::SidekiqMiddleware::BatchLoader
chain.add ::Labkit::Middleware::Sidekiq::Server
chain.add ::Gitlab::SidekiqMiddleware::InstrumentationLogger chain.add ::Gitlab::SidekiqMiddleware::InstrumentationLogger
chain.add ::Gitlab::SidekiqMiddleware::AdminMode::Server chain.add ::Gitlab::SidekiqMiddleware::AdminMode::Server
chain.add ::Gitlab::SidekiqVersioning::Middleware chain.add ::Gitlab::SidekiqVersioning::Middleware
......
...@@ -14,6 +14,7 @@ module Gitlab ...@@ -14,6 +14,7 @@ module Gitlab
def call(worker_class, job, queue, _redis_pool) def call(worker_class, job, queue, _redis_pool)
# worker_class can either be the string or class of the worker being enqueued. # worker_class can either be the string or class of the worker being enqueued.
worker_class = worker_class.safe_constantize if worker_class.respond_to?(:safe_constantize) worker_class = worker_class.safe_constantize if worker_class.respond_to?(:safe_constantize)
labels = create_labels(worker_class, queue, job) labels = create_labels(worker_class, queue, job)
labels[:scheduling] = job.key?('at') ? 'delayed' : 'immediate' labels[:scheduling] = job.key?('at') ? 'delayed' : 'immediate'
......
...@@ -3,14 +3,21 @@ ...@@ -3,14 +3,21 @@
module Gitlab module Gitlab
module SidekiqMiddleware module SidekiqMiddleware
module MetricsHelper module MetricsHelper
include ::Gitlab::SidekiqMiddleware::WorkerContext
TRUE_LABEL = "yes" TRUE_LABEL = "yes"
FALSE_LABEL = "no" FALSE_LABEL = "no"
private private
def create_labels(worker_class, queue, job) def create_labels(worker_class, queue, job)
worker_name = (job['wrapped'].presence || worker_class).to_s worker = find_worker(worker_class, job)
worker = find_worker(worker_name, worker_class)
# This should never happen: we should always be able to find a
# worker class for a given Sidekiq job. But if we can't, we
# shouldn't blow up here, because we want to record this in our
# metrics.
worker_name = worker.try(:name) || worker.class.name
labels = { queue: queue.to_s, labels = { queue: queue.to_s,
worker: worker_name, worker: worker_name,
...@@ -23,9 +30,7 @@ module Gitlab ...@@ -23,9 +30,7 @@ module Gitlab
labels[:urgency] = worker.get_urgency.to_s labels[:urgency] = worker.get_urgency.to_s
labels[:external_dependencies] = bool_as_label(worker.worker_has_external_dependencies?) labels[:external_dependencies] = bool_as_label(worker.worker_has_external_dependencies?)
labels[:feature_category] = worker.get_feature_category.to_s
feature_category = worker.get_feature_category
labels[:feature_category] = feature_category.to_s
resource_boundary = worker.get_worker_resource_boundary resource_boundary = worker.get_worker_resource_boundary
labels[:boundary] = resource_boundary == :unknown ? "" : resource_boundary.to_s labels[:boundary] = resource_boundary == :unknown ? "" : resource_boundary.to_s
...@@ -36,10 +41,6 @@ module Gitlab ...@@ -36,10 +41,6 @@ module Gitlab
def bool_as_label(value) def bool_as_label(value)
value ? TRUE_LABEL : FALSE_LABEL value ? TRUE_LABEL : FALSE_LABEL
end end
def find_worker(worker_name, worker_class)
Gitlab::SidekiqConfig::DEFAULT_WORKERS.fetch(worker_name, worker_class)
end
end end
end end
end end
...@@ -10,6 +10,12 @@ module Gitlab ...@@ -10,6 +10,12 @@ module Gitlab
context_or_nil.use(&block) context_or_nil.use(&block)
end end
def find_worker(worker_class, job)
worker_name = (job['wrapped'].presence || worker_class).to_s
Gitlab::SidekiqConfig::DEFAULT_WORKERS[worker_name]&.klass || worker_class
end
end end
end end
end end
...@@ -7,20 +7,15 @@ module Gitlab ...@@ -7,20 +7,15 @@ module Gitlab
include Gitlab::SidekiqMiddleware::WorkerContext include Gitlab::SidekiqMiddleware::WorkerContext
def call(worker_class_or_name, job, _queue, _redis_pool, &block) def call(worker_class_or_name, job, _queue, _redis_pool, &block)
worker_class = worker_class_or_name.to_s.safe_constantize worker_class = find_worker(worker_class_or_name.to_s.safe_constantize, job)
# Mailers can't be constantized like this # This is not a worker we know about, perhaps from a gem
return yield unless worker_class return yield unless worker_class
return yield unless worker_class.include?(::ApplicationWorker) return yield unless worker_class.respond_to?(:context_for_arguments)
context_for_args = worker_class.context_for_arguments(job['args']) context_for_args = worker_class.context_for_arguments(job['args'])
wrap_in_optional_context(context_for_args) do wrap_in_optional_context(context_for_args, &block)
# This should be inside the context for the arguments so
# that we don't override the feature category on the worker
# with the one from the caller.
Gitlab::ApplicationContext.with_context(feature_category: worker_class.get_feature_category.to_s, &block)
end
end end
end end
end end
......
...@@ -7,7 +7,7 @@ module Gitlab ...@@ -7,7 +7,7 @@ module Gitlab
include Gitlab::SidekiqMiddleware::WorkerContext include Gitlab::SidekiqMiddleware::WorkerContext
def call(worker, job, _queue, &block) def call(worker, job, _queue, &block)
worker_class = worker.class worker_class = find_worker(worker.class, job)
# This is not a worker we know about, perhaps from a gem # This is not a worker we know about, perhaps from a gem
return yield unless worker_class.respond_to?(:get_worker_context) return yield unless worker_class.respond_to?(:get_worker_context)
......
...@@ -1631,10 +1631,19 @@ RSpec.describe Gitlab::Database::MigrationHelpers do ...@@ -1631,10 +1631,19 @@ RSpec.describe Gitlab::Database::MigrationHelpers do
let(:worker) do let(:worker) do
Class.new do Class.new do
include Sidekiq::Worker include Sidekiq::Worker
sidekiq_options queue: 'test' sidekiq_options queue: 'test'
def self.name
'WorkerClass'
end
end end
end end
before do
stub_const(worker.name, worker)
end
describe '#sidekiq_queue_length' do describe '#sidekiq_queue_length' do
context 'when queue is empty' do context 'when queue is empty' do
it 'returns zero' do it 'returns zero' do
......
...@@ -63,5 +63,18 @@ RSpec.describe Gitlab::SidekiqMiddleware::ClientMetrics do ...@@ -63,5 +63,18 @@ RSpec.describe Gitlab::SidekiqMiddleware::ClientMetrics do
Sidekiq::Testing.inline! { TestWorker.perform_in(1.second) } Sidekiq::Testing.inline! { TestWorker.perform_in(1.second) }
end end
end end
context 'when the worker class cannot be found' do
it 'increments enqueued jobs metric with the worker labels set to NilClass' do
test_anonymous_worker = Class.new(TestWorker)
expect(enqueued_jobs_metric).to receive(:increment).with(a_hash_including(worker: 'NilClass'), 1)
# Sidekiq won't be able to create an instance of this class
expect do
Sidekiq::Testing.inline! { test_anonymous_worker.perform_async }
end.to raise_error(NameError)
end
end
end end
end end
...@@ -211,6 +211,9 @@ RSpec.describe Gitlab::SidekiqMiddleware::ServerMetrics do ...@@ -211,6 +211,9 @@ RSpec.describe Gitlab::SidekiqMiddleware::ServerMetrics do
end end
end end
include_context 'server metrics with mocked prometheus'
include_context 'server metrics call'
before do before do
stub_const('TestWorker', Class.new) stub_const('TestWorker', Class.new)
TestWorker.class_eval do TestWorker.class_eval do
...@@ -234,9 +237,6 @@ RSpec.describe Gitlab::SidekiqMiddleware::ServerMetrics do ...@@ -234,9 +237,6 @@ RSpec.describe Gitlab::SidekiqMiddleware::ServerMetrics do
end end
end end
include_context 'server metrics with mocked prometheus'
include_context 'server metrics call'
shared_context 'worker declaring data consistency' do shared_context 'worker declaring data consistency' do
let(:worker_class) { LBTestWorker } let(:worker_class) { LBTestWorker }
...@@ -308,5 +308,67 @@ RSpec.describe Gitlab::SidekiqMiddleware::ServerMetrics do ...@@ -308,5 +308,67 @@ RSpec.describe Gitlab::SidekiqMiddleware::ServerMetrics do
end end
end end
end end
context 'feature attribution' do
let(:test_worker) do
category = worker_category
Class.new do
include Sidekiq::Worker
include WorkerAttributes
if category
feature_category category
else
feature_category_not_owned!
end
def perform
end
end
end
let(:context_category) { 'continuous_integration' }
let(:job) { { 'meta.feature_category' => 'continuous_integration' } }
before do
stub_const('TestWorker', test_worker)
end
around do |example|
with_sidekiq_server_middleware do |chain|
Gitlab::SidekiqMiddleware.server_configurator(
metrics: true,
arguments_logger: false,
memory_killer: false
).call(chain)
Sidekiq::Testing.inline! { example.run }
end
end
include_context 'server metrics with mocked prometheus'
include_context 'server metrics call'
context 'when a worker has a feature category' do
let(:worker_category) { 'authentication_and_authorization' }
it 'uses that category for metrics' do
expect(completion_seconds_metric).to receive(:observe).with(a_hash_including(feature_category: worker_category), anything)
TestWorker.process_job(job)
end
end
context 'when a worker does not have a feature category' do
let(:worker_category) { nil }
it 'uses the category from the context for metrics' do
expect(completion_seconds_metric).to receive(:observe).with(a_hash_including(feature_category: context_category), anything)
TestWorker.process_job(job)
end
end
end
end end
# rubocop: enable RSpec/MultipleMemoizedHelpers # rubocop: enable RSpec/MultipleMemoizedHelpers
...@@ -11,8 +11,6 @@ RSpec.describe Gitlab::SidekiqMiddleware::WorkerContext::Client do ...@@ -11,8 +11,6 @@ RSpec.describe Gitlab::SidekiqMiddleware::WorkerContext::Client do
include ApplicationWorker include ApplicationWorker
feature_category :issue_tracking
def self.job_for_args(args) def self.job_for_args(args)
jobs.find { |job| job['args'] == args } jobs.find { |job| job['args'] == args }
end end
...@@ -23,7 +21,7 @@ RSpec.describe Gitlab::SidekiqMiddleware::WorkerContext::Client do ...@@ -23,7 +21,7 @@ RSpec.describe Gitlab::SidekiqMiddleware::WorkerContext::Client do
end end
before do before do
stub_const('TestWithContextWorker', worker_class) stub_const(worker_class.name, worker_class)
end end
describe "#call" do describe "#call" do
...@@ -43,39 +41,5 @@ RSpec.describe Gitlab::SidekiqMiddleware::WorkerContext::Client do ...@@ -43,39 +41,5 @@ RSpec.describe Gitlab::SidekiqMiddleware::WorkerContext::Client do
expect(job1['meta.user']).to eq(user_per_job['job1'].username) expect(job1['meta.user']).to eq(user_per_job['job1'].username)
expect(job2['meta.user']).to eq(user_per_job['job2'].username) expect(job2['meta.user']).to eq(user_per_job['job2'].username)
end end
context 'when the feature category is set in the context_proc' do
it 'takes the feature category from the worker, not the caller' do
TestWithContextWorker.bulk_perform_async_with_contexts(
%w(job1 job2),
arguments_proc: -> (name) { [name, 1, 2, 3] },
context_proc: -> (_) { { feature_category: 'code_review' } }
)
job1 = TestWithContextWorker.job_for_args(['job1', 1, 2, 3])
job2 = TestWithContextWorker.job_for_args(['job2', 1, 2, 3])
expect(job1['meta.feature_category']).to eq('issue_tracking')
expect(job2['meta.feature_category']).to eq('issue_tracking')
end
end
context 'when the feature category is already set in the surrounding block' do
it 'takes the feature category from the worker, not the caller' do
Gitlab::ApplicationContext.with_context(feature_category: 'authentication_and_authorization') do
TestWithContextWorker.bulk_perform_async_with_contexts(
%w(job1 job2),
arguments_proc: -> (name) { [name, 1, 2, 3] },
context_proc: -> (_) { {} }
)
end
job1 = TestWithContextWorker.job_for_args(['job1', 1, 2, 3])
job2 = TestWithContextWorker.job_for_args(['job2', 1, 2, 3])
expect(job1['meta.feature_category']).to eq('issue_tracking')
expect(job2['meta.feature_category']).to eq('issue_tracking')
end
end
end end
end end
...@@ -3,7 +3,7 @@ ...@@ -3,7 +3,7 @@
require 'spec_helper' require 'spec_helper'
RSpec.describe Gitlab::SidekiqMiddleware::WorkerContext::Server do RSpec.describe Gitlab::SidekiqMiddleware::WorkerContext::Server do
let(:worker_class) do let(:test_worker) do
Class.new do Class.new do
def self.name def self.name
"TestWorker" "TestWorker"
...@@ -23,6 +23,16 @@ RSpec.describe Gitlab::SidekiqMiddleware::WorkerContext::Server do ...@@ -23,6 +23,16 @@ RSpec.describe Gitlab::SidekiqMiddleware::WorkerContext::Server do
end end
end end
let(:not_owned_worker) do
Class.new(test_worker) do
def self.name
"NotOwnedWorker"
end
feature_category_not_owned!
end
end
let(:other_worker) do let(:other_worker) do
Class.new do Class.new do
def self.name def self.name
...@@ -37,7 +47,8 @@ RSpec.describe Gitlab::SidekiqMiddleware::WorkerContext::Server do ...@@ -37,7 +47,8 @@ RSpec.describe Gitlab::SidekiqMiddleware::WorkerContext::Server do
end end
before do before do
stub_const("TestWorker", worker_class) stub_const("TestWorker", test_worker)
stub_const("NotOwnedWorker", not_owned_worker)
stub_const("OtherWorker", other_worker) stub_const("OtherWorker", other_worker)
end end
...@@ -57,12 +68,26 @@ RSpec.describe Gitlab::SidekiqMiddleware::WorkerContext::Server do ...@@ -57,12 +68,26 @@ RSpec.describe Gitlab::SidekiqMiddleware::WorkerContext::Server do
expect(TestWorker.contexts['identifier'].keys).not_to include('meta.user') expect(TestWorker.contexts['identifier'].keys).not_to include('meta.user')
end end
context 'feature category' do
it 'takes the feature category from the worker' do it 'takes the feature category from the worker' do
Gitlab::ApplicationContext.with_context(feature_category: 'authentication_and_authorization') do
TestWorker.perform_async('identifier', 1) TestWorker.perform_async('identifier', 1)
end
expect(TestWorker.contexts['identifier']).to include('meta.feature_category' => 'foo') expect(TestWorker.contexts['identifier']).to include('meta.feature_category' => 'foo')
end end
context 'when the worker is not owned' do
it 'takes the feature category from the surrounding context' do
Gitlab::ApplicationContext.with_context(feature_category: 'authentication_and_authorization') do
NotOwnedWorker.perform_async('identifier', 1)
end
expect(NotOwnedWorker.contexts['identifier']).to include('meta.feature_category' => 'authentication_and_authorization')
end
end
end
it "doesn't fail for unknown workers" do it "doesn't fail for unknown workers" do
expect { OtherWorker.perform_async }.not_to raise_error expect { OtherWorker.perform_async }.not_to raise_error
end end
......
...@@ -58,13 +58,13 @@ RSpec.describe Gitlab::SidekiqMiddleware do ...@@ -58,13 +58,13 @@ RSpec.describe Gitlab::SidekiqMiddleware do
let(:all_sidekiq_middlewares) do let(:all_sidekiq_middlewares) do
[ [
::Gitlab::SidekiqMiddleware::Monitor, ::Gitlab::SidekiqMiddleware::Monitor,
::Labkit::Middleware::Sidekiq::Server,
::Gitlab::SidekiqMiddleware::ServerMetrics, ::Gitlab::SidekiqMiddleware::ServerMetrics,
::Gitlab::SidekiqMiddleware::ArgumentsLogger, ::Gitlab::SidekiqMiddleware::ArgumentsLogger,
::Gitlab::SidekiqMiddleware::MemoryKiller, ::Gitlab::SidekiqMiddleware::MemoryKiller,
::Gitlab::SidekiqMiddleware::RequestStoreMiddleware, ::Gitlab::SidekiqMiddleware::RequestStoreMiddleware,
::Gitlab::SidekiqMiddleware::ExtraDoneLogMetadata, ::Gitlab::SidekiqMiddleware::ExtraDoneLogMetadata,
::Gitlab::SidekiqMiddleware::BatchLoader, ::Gitlab::SidekiqMiddleware::BatchLoader,
::Labkit::Middleware::Sidekiq::Server,
::Gitlab::SidekiqMiddleware::InstrumentationLogger, ::Gitlab::SidekiqMiddleware::InstrumentationLogger,
::Gitlab::SidekiqMiddleware::AdminMode::Server, ::Gitlab::SidekiqMiddleware::AdminMode::Server,
::Gitlab::SidekiqVersioning::Middleware, ::Gitlab::SidekiqVersioning::Middleware,
......
...@@ -17,6 +17,9 @@ RSpec.shared_context 'server metrics with mocked prometheus' do ...@@ -17,6 +17,9 @@ RSpec.shared_context 'server metrics with mocked prometheus' do
let(:elasticsearch_requests_total) { double('elasticsearch calls total metric') } let(:elasticsearch_requests_total) { double('elasticsearch calls total metric') }
before do before do
allow(Gitlab::Metrics).to receive(:histogram).and_call_original
allow(Gitlab::Metrics).to receive(:counter).and_call_original
allow(Gitlab::Metrics).to receive(:histogram).with(:sidekiq_jobs_queue_duration_seconds, anything, anything, anything).and_return(queue_duration_seconds) allow(Gitlab::Metrics).to receive(:histogram).with(:sidekiq_jobs_queue_duration_seconds, anything, anything, anything).and_return(queue_duration_seconds)
allow(Gitlab::Metrics).to receive(:histogram).with(:sidekiq_jobs_completion_seconds, anything, anything, anything).and_return(completion_seconds_metric) allow(Gitlab::Metrics).to receive(:histogram).with(:sidekiq_jobs_completion_seconds, anything, anything, anything).and_return(completion_seconds_metric)
allow(Gitlab::Metrics).to receive(:histogram).with(:sidekiq_jobs_cpu_seconds, anything, anything, anything).and_return(user_execution_seconds_metric) allow(Gitlab::Metrics).to receive(:histogram).with(:sidekiq_jobs_cpu_seconds, anything, anything, anything).and_return(user_execution_seconds_metric)
......
...@@ -248,6 +248,10 @@ RSpec.describe ApplicationWorker do ...@@ -248,6 +248,10 @@ RSpec.describe ApplicationWorker do
end end
describe '.perform_async' do describe '.perform_async' do
before do
stub_const(worker.name, worker)
end
shared_examples_for 'worker utilizes load balancing capabilities' do |data_consistency| shared_examples_for 'worker utilizes load balancing capabilities' do |data_consistency|
before do before do
worker.data_consistency(data_consistency) worker.data_consistency(data_consistency)
...@@ -282,6 +286,10 @@ RSpec.describe ApplicationWorker do ...@@ -282,6 +286,10 @@ RSpec.describe ApplicationWorker do
end end
describe '.bulk_perform_async' do describe '.bulk_perform_async' do
before do
stub_const(worker.name, worker)
end
it 'enqueues jobs in bulk' do it 'enqueues jobs in bulk' do
Sidekiq::Testing.fake! do Sidekiq::Testing.fake! do
worker.bulk_perform_async([['Foo', [1]], ['Foo', [2]]]) worker.bulk_perform_async([['Foo', [1]], ['Foo', [2]]])
...@@ -293,6 +301,10 @@ RSpec.describe ApplicationWorker do ...@@ -293,6 +301,10 @@ RSpec.describe ApplicationWorker do
end end
describe '.bulk_perform_in' do describe '.bulk_perform_in' do
before do
stub_const(worker.name, worker)
end
context 'when delay is valid' do context 'when delay is valid' do
it 'correctly schedules jobs' do it 'correctly schedules jobs' do
Sidekiq::Testing.fake! do Sidekiq::Testing.fake! do
......
...@@ -13,6 +13,10 @@ RSpec.describe WorkerContext do ...@@ -13,6 +13,10 @@ RSpec.describe WorkerContext do
end end
end end
before do
stub_const(worker.name, worker)
end
describe '.worker_context' do describe '.worker_context' do
it 'allows modifying the context for the entire worker' do it 'allows modifying the context for the entire worker' do
worker.worker_context(user: build_stubbed(:user)) worker.worker_context(user: build_stubbed(:user))
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment