File: command_spec.rb

package info (click to toggle)
ruby-delayed-job 4.1.13-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 372 kB
  • sloc: ruby: 2,650; makefile: 8
file content (179 lines) | stat: -rw-r--r-- 5,675 bytes parent folder | download | duplicates (4)
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
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
require 'helper'
require 'delayed/command'

describe Delayed::Command do
  let(:options) { [] }
  let(:logger) { double('Logger') }

  subject { Delayed::Command.new options }

  before do
    allow(Delayed::Worker).to receive(:after_fork)
    allow(Dir).to receive(:chdir)
    allow(Logger).to receive(:new).and_return(logger)
    allow_any_instance_of(Delayed::Worker).to receive(:start)
    allow(Delayed::Worker).to receive(:logger=)
    allow(Delayed::Worker).to receive(:logger).and_return(nil, logger)
  end

  shared_examples_for 'uses --log-dir option' do
    context 'when --log-dir is specified' do
      let(:options) { ['--log-dir=/custom/log/dir'] }

      it 'creates the delayed_job.log in the specified directory' do
        expect(Logger).to receive(:new).with('/custom/log/dir/delayed_job.log')
        subject.run
      end
    end
  end

  describe 'run' do
    it 'sets the Delayed::Worker logger' do
      expect(Delayed::Worker).to receive(:logger=).with(logger)
      subject.run
    end

    context 'when Rails root is defined' do
      let(:rails_root) { Pathname.new '/rails/root' }
      let(:rails) { double('Rails', :root => rails_root) }

      before do
        stub_const('Rails', rails)
      end

      it 'runs the Delayed::Worker process in Rails.root' do
        expect(Dir).to receive(:chdir).with(rails_root)
        subject.run
      end

      context 'when --log-dir is not specified' do
        it 'creates the delayed_job.log in Rails.root/log' do
          expect(Logger).to receive(:new).with('/rails/root/log/delayed_job.log')
          subject.run
        end
      end

      include_examples 'uses --log-dir option'
    end

    context 'when Rails root is not defined' do
      let(:rails_without_root) { double('Rails') }

      before do
        stub_const('Rails', rails_without_root)
      end

      it 'runs the Delayed::Worker process in $PWD' do
        expect(Dir).to receive(:chdir).with(Delayed::Command::DIR_PWD)
        subject.run
      end

      context 'when --log-dir is not specified' do
        it 'creates the delayed_job.log in $PWD/log' do
          expect(Logger).to receive(:new).with("#{Delayed::Command::DIR_PWD}/log/delayed_job.log")
          subject.run
        end
      end

      include_examples 'uses --log-dir option'
    end

    context 'when an error is raised' do
      let(:test_error) { Class.new(StandardError) }

      before do
        allow(Delayed::Worker).to receive(:new).and_raise(test_error.new('An error'))
        allow(subject).to receive(:exit_with_error_status)
        allow(STDERR).to receive(:puts)
      end

      it 'prints the error message to STDERR' do
        expect(STDERR).to receive(:puts).with('An error')
        subject.run
      end

      it 'exits with an error status' do
        expect(subject).to receive(:exit_with_error_status)
        subject.run
      end

      context 'when Rails logger is not defined' do
        let(:rails) { double('Rails') }

        before do
          stub_const('Rails', rails)
        end

        it 'does not attempt to use the Rails logger' do
          subject.run
        end
      end

      context 'when Rails logger is defined' do
        let(:rails_logger) { double('Rails logger') }
        let(:rails) { double('Rails', :logger => rails_logger) }

        before do
          stub_const('Rails', rails)
        end

        it 'logs the error to the Rails logger' do
          expect(rails_logger).to receive(:fatal).with(test_error)
          subject.run
        end
      end
    end
  end

  describe 'parsing --pool argument' do
    it 'should parse --pool correctly' do
      command = Delayed::Command.new(['--pool=*:1', '--pool=test_queue:4', '--pool=mailers,misc:2'])

      expect(command.worker_pools).to eq [
        [[], 1],
        [['test_queue'], 4],
        [%w[mailers misc], 2]
      ]
    end

    it 'should allow * or blank to specify any pools' do
      command = Delayed::Command.new(['--pool=*:4'])
      expect(command.worker_pools).to eq [
        [[], 4],
      ]

      command = Delayed::Command.new(['--pool=:4'])
      expect(command.worker_pools).to eq [
        [[], 4],
      ]
    end

    it 'should default to one worker if not specified' do
      command = Delayed::Command.new(['--pool=mailers'])
      expect(command.worker_pools).to eq [
        [['mailers'], 1],
      ]
    end
  end

  describe 'running worker pools defined by multiple --pool arguments' do
    it 'should run the correct worker processes' do
      command = Delayed::Command.new(['--pool=*:1', '--pool=test_queue:4', '--pool=mailers,misc:2'])
      expect(FileUtils).to receive(:mkdir_p).with('./tmp/pids').once

      [
        ['delayed_job.0', {:quiet => true, :pid_dir => './tmp/pids', :log_dir => './log', :queues => []}],
        ['delayed_job.1', {:quiet => true, :pid_dir => './tmp/pids', :log_dir => './log', :queues => ['test_queue']}],
        ['delayed_job.2', {:quiet => true, :pid_dir => './tmp/pids', :log_dir => './log', :queues => ['test_queue']}],
        ['delayed_job.3', {:quiet => true, :pid_dir => './tmp/pids', :log_dir => './log', :queues => ['test_queue']}],
        ['delayed_job.4', {:quiet => true, :pid_dir => './tmp/pids', :log_dir => './log', :queues => ['test_queue']}],
        ['delayed_job.5', {:quiet => true, :pid_dir => './tmp/pids', :log_dir => './log', :queues => %w[mailers misc]}],
        ['delayed_job.6', {:quiet => true, :pid_dir => './tmp/pids', :log_dir => './log', :queues => %w[mailers misc]}]
      ].each do |args|
        expect(command).to receive(:run_process).with(*args).once
      end

      command.daemonize
    end
  end
end