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

sidekiq_cluster_spec.rb « sidekiq_cluster « spec - gitlab.com/gitlab-org/gitlab-foss.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
blob: 3df2aa70553d9c14ef6bcbcb5392954f7b68131a (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
# frozen_string_literal: true

require 'rspec-parameterized'

require_relative '../../sidekiq_cluster/sidekiq_cluster'

RSpec.describe Gitlab::SidekiqCluster do # rubocop:disable RSpec/FilePath
  describe '.start' do
    it 'starts Sidekiq with the given queues, environment and options' do
      expected_options = {
        env: :production,
        directory: 'foo/bar',
        max_concurrency: 20,
        min_concurrency: 10,
        timeout: 25,
        dryrun: true
      }

      expect(described_class).to receive(:start_sidekiq).ordered.with(%w(foo), expected_options.merge(worker_id: 0))
      expect(described_class).to receive(:start_sidekiq).ordered.with(%w(bar baz), expected_options.merge(worker_id: 1))

      described_class.start([%w(foo), %w(bar baz)], env: :production, directory: 'foo/bar', max_concurrency: 20, min_concurrency: 10, dryrun: true)
    end

    it 'starts Sidekiq with the given queues and sensible default options' do
      expected_options = {
        env: :development,
        directory: an_instance_of(String),
        max_concurrency: 50,
        min_concurrency: 0,
        worker_id: an_instance_of(Integer),
        timeout: 25,
        dryrun: false
      }

      expect(described_class).to receive(:start_sidekiq).ordered.with(%w(foo bar baz), expected_options)
      expect(described_class).to receive(:start_sidekiq).ordered.with(%w(solo), expected_options)

      described_class.start([%w(foo bar baz), %w(solo)])
    end
  end

  describe '.start_sidekiq' do
    let(:first_worker_id) { 0 }
    let(:options) do
      { env: :production, directory: 'foo/bar', max_concurrency: 20, min_concurrency: 0, worker_id: first_worker_id, timeout: 10, dryrun: false }
    end

    let(:env) { { "ENABLE_SIDEKIQ_CLUSTER" => "1", "SIDEKIQ_WORKER_ID" => first_worker_id.to_s } }
    let(:args) { ['bundle', 'exec', 'sidekiq', anything, '-eproduction', '-t10', *([anything] * 5)] }

    it 'starts a Sidekiq process' do
      allow(Process).to receive(:spawn).and_return(1)

      expect(Gitlab::ProcessManagement).to receive(:wait_async).with(1)
      expect(described_class.start_sidekiq(%w(foo), **options)).to eq(1)
    end

    it 'handles duplicate queue names' do
      allow(Process)
        .to receive(:spawn)
        .with(env, *args, anything)
        .and_return(1)

      expect(Gitlab::ProcessManagement).to receive(:wait_async).with(1)
      expect(described_class.start_sidekiq(%w(foo foo bar baz), **options)).to eq(1)
    end

    it 'runs the sidekiq process in a new process group' do
      expect(Process)
        .to receive(:spawn)
        .with(anything, *args, a_hash_including(pgroup: true))
        .and_return(1)

      allow(Gitlab::ProcessManagement).to receive(:wait_async)
      expect(described_class.start_sidekiq(%w(foo bar baz), **options)).to eq(1)
    end
  end

  describe '.count_by_queue' do
    it 'tallies the queue counts' do
      queues = [%w(foo), %w(bar baz), %w(foo)]

      expect(described_class.count_by_queue(queues)).to eq(%w(foo) => 2, %w(bar baz) => 1)
    end
  end

  describe '.concurrency' do
    using RSpec::Parameterized::TableSyntax

    where(:queue_count, :min, :max, :expected) do
      2 | 0 | 0 | 3 # No min or max specified
      2 | 0 | 9 | 3 # No min specified, value < max
      2 | 1 | 4 | 3 # Value between min and max
      2 | 4 | 5 | 4 # Value below range
      5 | 2 | 3 | 3 # Value above range
      2 | 1 | 1 | 1 # Value above explicit setting (min == max)
      0 | 3 | 3 | 3 # Value below explicit setting (min == max)
      1 | 4 | 3 | 3 # Min greater than max
    end

    with_them do
      let(:queues) { Array.new(queue_count) }

      it { expect(described_class.concurrency(queues, min, max)).to eq(expected) }
    end
  end
end