resque-cluster 0.1.1.1 → 0.2.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +5 -5
- data/Gemfile +3 -1
- data/Gemfile.lock +47 -44
- data/lib/resque/cluster.rb +1 -0
- data/lib/resque/cluster/config.rb +169 -0
- data/lib/resque/cluster/config/file.rb +40 -0
- data/lib/resque/cluster/config/verifier.rb +27 -0
- data/lib/resque/cluster/member.rb +17 -27
- data/lib/resque/cluster/version.rb +1 -1
- data/lib/resque/pool/patches.rb +5 -0
- data/resque-cluster.gemspec +1 -1
- data/spec/integration/cluster_spec.rb +41 -11
- data/spec/integration/config/bad_global_config.yml +3 -0
- data/spec/integration/config/global_rebalance_config3.yml +5 -0
- data/spec/integration/config/rebalance_config.yml +4 -0
- data/spec/integration/spec_helper.rb +3 -0
- data/spec/integration/test_member_manager.rb +50 -19
- data/spec/unit/config/verifier_spec.rb +86 -0
- data/spec/unit/config_spec.rb +194 -0
- data/spec/unit/member_spec.rb +5 -32
- data/spec/unit/resque_pool_patches_spec.rb +3 -3
- data/spec/unit/spec_helper.rb +5 -1
- data/spec/unit/support/broken_yaml_config.yml +1 -0
- data/spec/unit/support/empty_config.yml +1 -0
- data/spec/unit/support/missing_global_maximum.yml +3 -0
- data/spec/unit/support/missing_local_maximum.yml +3 -0
- data/spec/unit/support/non_hash_config.yml +0 -0
- data/spec/unit/support/separate_missing_global.yml +2 -0
- data/spec/unit/support/separate_missing_local.yml +2 -0
- data/spec/unit/support/single_old_missing_global.yml +9 -0
- data/spec/unit/support/single_old_missing_local.yml +9 -0
- data/spec/unit/support/valid_config.yml +13 -0
- data/spec/unit/support/valid_global_config.yml +1 -0
- data/spec/unit/support/valid_local_config.yml +1 -0
- data/spec/unit/support/valid_single_new_config.yml +13 -0
- data/spec/unit/support/valid_single_old_config.yml +10 -0
- metadata +72 -30
data/lib/resque/pool/patches.rb
CHANGED
data/resque-cluster.gemspec
CHANGED
@@ -19,7 +19,7 @@ Gem::Specification.new do |s|
|
|
19
19
|
s.require_paths = ["lib"]
|
20
20
|
|
21
21
|
s.add_dependency 'resque-pool', '~> 0.5.0'
|
22
|
-
s.add_dependency 'gru', '0.1.
|
22
|
+
s.add_dependency 'gru', '0.1.3'
|
23
23
|
|
24
24
|
s.add_development_dependency 'pry', '> 0.0'
|
25
25
|
s.add_development_dependency 'awesome_print', '> 0.0'
|
@@ -2,9 +2,13 @@ require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
|
|
2
2
|
|
3
3
|
LOCAL_CONFIG = "spec/integration/config/local_config.yml"
|
4
4
|
GLOBAL_CONFIG = "spec/integration/config/global_config.yml"
|
5
|
+
BAD_GLOBAL_CONFIG = "spec/integration/config/bad_global_config.yml"
|
6
|
+
BAD_LOCAL_CONFIG = "spec/integration/config/bad_local_config.yml"
|
5
7
|
LOCAL_CONFIG2 = "spec/integration/config/local_config2.yml"
|
6
8
|
GLOBAL_CONFIG2 = "spec/integration/config/global_config2.yml"
|
7
9
|
GLOBAL_REBALANCE_CONFIG2 = "spec/integration/config/global_rebalance_config2.yml"
|
10
|
+
GLOBAL_REBALANCE_CONFIG3 = "spec/integration/config/global_rebalance_config3.yml"
|
11
|
+
REBALANCE_CONFIG = "spec/integration/config/rebalance_config.yml"
|
8
12
|
GLOBAL_CONFIG3 = "spec/integration/config/global_config3.yml"
|
9
13
|
GLOBAL_CONFIG4 = "spec/integration/config/global_config4.yml"
|
10
14
|
|
@@ -49,6 +53,32 @@ RSpec.describe "Resque test-cluster" do
|
|
49
53
|
|
50
54
|
end
|
51
55
|
|
56
|
+
context "Cluster with bad configs" do
|
57
|
+
before :all do
|
58
|
+
@d = TestMemberManager.new(LOCAL_CONFIG2, BAD_GLOBAL_CONFIG)
|
59
|
+
@e = TestMemberManager.new(BAD_LOCAL_CONFIG, GLOBAL_REBALANCE_CONFIG2)
|
60
|
+
@f = TestMemberManager.new("", "")
|
61
|
+
@d.start
|
62
|
+
@e.start
|
63
|
+
@f.start
|
64
|
+
sleep(5) # rebalance time
|
65
|
+
end
|
66
|
+
|
67
|
+
it 'expects counts to be correct after workers get spun up' do
|
68
|
+
expect(TestMemberManager.counts).to eq({})
|
69
|
+
expect(@d.is_running?).to eq(false)
|
70
|
+
expect(@e.is_running?).to eq(false)
|
71
|
+
expect(@f.is_running?).to eq(false)
|
72
|
+
expect(TestMemberManager.resque_cluster_members.count).to eq(0)
|
73
|
+
end
|
74
|
+
|
75
|
+
after :all do
|
76
|
+
TestMemberManager.stop_all
|
77
|
+
end
|
78
|
+
|
79
|
+
end
|
80
|
+
|
81
|
+
|
52
82
|
context "Cluster with Rebalancing" do
|
53
83
|
before :all do
|
54
84
|
@d = TestMemberManager.new(LOCAL_CONFIG2, GLOBAL_REBALANCE_CONFIG2)
|
@@ -106,29 +136,29 @@ RSpec.describe "Resque test-cluster" do
|
|
106
136
|
end
|
107
137
|
end
|
108
138
|
|
109
|
-
context "
|
139
|
+
context "Rebalance after global maximums change" do
|
110
140
|
before :all do
|
111
141
|
@a = TestMemberManager.new(LOCAL_CONFIG, GLOBAL_CONFIG)
|
112
|
-
@b = TestMemberManager.new(
|
113
|
-
@c = TestMemberManager.new(LOCAL_CONFIG,
|
142
|
+
@b = TestMemberManager.new(LOCAL_CONFIG, GLOBAL_CONFIG)
|
143
|
+
@c = TestMemberManager.new(LOCAL_CONFIG, GLOBAL_REBALANCE_CONFIG3)
|
114
144
|
@a.start
|
115
145
|
@b.start
|
116
146
|
sleep(3) # rebalance time
|
117
147
|
end
|
118
148
|
|
119
|
-
it 'expects to have each cluster member only running workers in
|
120
|
-
expect(TestMemberManager.counts).to eq(
|
121
|
-
expect(@a.counts).to eq(
|
122
|
-
expect(@b.counts).to
|
149
|
+
it 'expects to have each cluster member only running workers in its config' do
|
150
|
+
expect(TestMemberManager.counts).to eq('par' => 2, 'tar' => 6, 'par,tar,var' => 1)
|
151
|
+
expect(@a.counts).to eq('par' => 1, 'tar' => 3, 'par,tar,var' => 1)
|
152
|
+
expect(@b.counts).to eq('par' => 1, 'tar' => 3)
|
123
153
|
end
|
124
154
|
|
125
155
|
it 'expects the cluster to redistribute correctly after global config change' do
|
126
156
|
@c.start
|
127
157
|
sleep(8) # rebalance time
|
128
|
-
expect(TestMemberManager.counts).to eq(
|
129
|
-
expect(@a.counts).to
|
130
|
-
expect(@b.counts).to eq(
|
131
|
-
expect(@c.counts).to
|
158
|
+
expect(TestMemberManager.counts).to eq('par' => 3, 'tar' => 6, 'par,tar,var' => 2)
|
159
|
+
expect(@a.counts).to eq('par' => 1, 'tar' => 2, 'par,tar,var' => 1)
|
160
|
+
expect(@b.counts).to eq('par' => 1, 'tar' => 2)
|
161
|
+
expect(@c.counts).to eq('par' => 1, 'tar' => 2, 'par,tar,var' => 1)
|
132
162
|
end
|
133
163
|
|
134
164
|
after :all do
|
@@ -1,4 +1,7 @@
|
|
1
1
|
class TestMemberManager
|
2
|
+
include Sys
|
3
|
+
|
4
|
+
attr_accessor :pid
|
2
5
|
|
3
6
|
def initialize(local_config_path, global_config_path, cluster_name = "test-cluster", environment = "test")
|
4
7
|
@local_config_path = local_config_path
|
@@ -12,53 +15,71 @@ class TestMemberManager
|
|
12
15
|
def start
|
13
16
|
ENV['GRU_HOSTNAME'] = hostname
|
14
17
|
@pid = spawn("bundle exec spec/integration/bin/resque-cluster_member_test -c #{@local_config_path} -E #{@environment}#{@cluster_name.nil? ? "" : " -C "+@cluster_name} -G #{@global_config_path}")
|
18
|
+
count = 0
|
15
19
|
|
16
|
-
while ( @pool_master_pid.nil? ) do
|
20
|
+
while ( @pool_master_pid.nil? && count <= 100 ) do
|
17
21
|
sleep(0.1)
|
18
|
-
|
19
|
-
|
20
|
-
|
22
|
+
|
23
|
+
if (ProcTable.ps(@pid) &&
|
24
|
+
ProcTable.ps(@pid).cmdline =~ /resque-pool-master\[resque-cluster\]:\smanaging\s\[/)
|
25
|
+
pool_pid = ProcTable.ps(@pid).pid
|
26
|
+
end
|
27
|
+
|
28
|
+
@pool_master_pid = pool_pid ? pool_pid : nil
|
29
|
+
count += 1
|
21
30
|
end
|
22
|
-
|
31
|
+
|
32
|
+
puts "Pool Master pid is ---------- #{@pool_master_pid}" if @pool_master_pid
|
23
33
|
end
|
24
34
|
|
25
35
|
def stop
|
26
36
|
puts "************************************************ About to kill : Pool Master pid ---------- #{@pool_master_pid}"
|
27
|
-
Process.kill(:
|
37
|
+
Process.kill(:QUIT, @pool_master_pid)
|
28
38
|
while ( @pool_master_pid ) do
|
29
|
-
|
30
|
-
|
39
|
+
if (ProcTable.ps(@pool_master_pid) &&
|
40
|
+
! (ProcTable.ps(@pool_master_pid).cmdline =~ /resque-pool-master\[resque-cluster\]:\smanaging\s\[/))
|
41
|
+
@pool_master_pid = nil
|
42
|
+
end
|
31
43
|
end
|
32
44
|
@pid = nil
|
33
|
-
sleep(
|
45
|
+
sleep(3)
|
46
|
+
end
|
47
|
+
|
48
|
+
def is_running?
|
49
|
+
(ProcTable.ps(@pid).instance_of? (Struct::ProcTableStruct)) &&
|
50
|
+
! (ProcTable.ps(@pid).cmdline =~ /resque-pool-master\[resque-cluster\]:\smanaging\s\[/).nil?
|
34
51
|
end
|
35
52
|
|
36
53
|
def kill
|
37
54
|
puts "************************************************ About to kill -9 : Pool Master pid ---------- #{@pool_master_pid}"
|
38
|
-
|
55
|
+
Process.kill(:TERM, @pool_master_pid)
|
39
56
|
while ( @pool_master_pid ) do
|
40
|
-
|
41
|
-
|
57
|
+
if (ProcTable.ps(@pool_master_pid) &&
|
58
|
+
! (ProcTable.ps(@pool_master_pid).cmdline =~ /resque-pool-master\[resque-cluster\]:\smanaging\s\[/))
|
59
|
+
@pool_master_pid = nil
|
60
|
+
end
|
42
61
|
end
|
43
62
|
@pid = nil
|
44
|
-
sleep(
|
63
|
+
sleep(3)
|
45
64
|
end
|
46
65
|
|
47
66
|
def counts
|
48
67
|
return {} unless @pool_master_pid
|
49
|
-
local_workers =
|
68
|
+
local_workers = ProcTable.ps.select{|p| p.ppid == @pool_master_pid}.map(&:cmdline)
|
50
69
|
TestMemberManager.worker_counts(local_workers)
|
51
70
|
end
|
52
71
|
|
53
72
|
def self.counts
|
54
|
-
|
73
|
+
pool_pids = resque_cluster_members.map(&:pid)
|
74
|
+
all_workers = ProcTable.ps.select{|p| pool_pids.include? p.ppid}.map(&:cmdline)
|
55
75
|
worker_counts(all_workers)
|
56
76
|
end
|
57
77
|
|
58
78
|
def self.worker_counts(worker_array)
|
59
79
|
final_counts = Hash.new(0)
|
60
80
|
|
61
|
-
worker_array.each do |
|
81
|
+
worker_array.each do |worker_cmdline|
|
82
|
+
worker = parse_worker_name(worker_cmdline)
|
62
83
|
final_counts[worker] += 1
|
63
84
|
end
|
64
85
|
|
@@ -69,13 +90,23 @@ class TestMemberManager
|
|
69
90
|
@hostname ||= "#{Socket.gethostname}-#{member_count+1}"
|
70
91
|
end
|
71
92
|
|
93
|
+
def self.parse_worker_name(worker_cmdline)
|
94
|
+
worker_cmdline.gsub(/resque(\d|\.|-)*:\sWaiting\sfor\s/, '')
|
95
|
+
end
|
96
|
+
|
72
97
|
def self.stop_all
|
73
|
-
|
74
|
-
|
98
|
+
TestMemberManager.resque_cluster_members.each do |member|
|
99
|
+
Process.kill(:TERM, member.pid)
|
100
|
+
end
|
75
101
|
sleep(3)
|
76
102
|
end
|
77
103
|
|
78
104
|
def member_count
|
79
|
-
|
105
|
+
TestMemberManager.resque_cluster_members.count
|
106
|
+
end
|
107
|
+
|
108
|
+
def self.resque_cluster_members
|
109
|
+
ProcTable.ps.select{|p| p.cmdline =~ /resque-pool-master/}
|
80
110
|
end
|
111
|
+
|
81
112
|
end
|
@@ -0,0 +1,86 @@
|
|
1
|
+
require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
|
2
|
+
|
3
|
+
module Resque
|
4
|
+
RSpec.describe Cluster::Config::Verifier do
|
5
|
+
let(:valid_local_config) { Cluster::Config::File.new(support_dir + 'valid_local_config.yml') }
|
6
|
+
let(:valid_global_config) { Cluster::Config::File.new(support_dir + 'valid_global_config.yml') }
|
7
|
+
let(:broken_yaml_config) { Cluster::Config::File.new(support_dir + 'broken_yaml_config.yml') }
|
8
|
+
let(:non_hash_config) { Cluster::Config::File.new(support_dir + 'non_hash_config.yml') }
|
9
|
+
let(:empty_config) { Cluster::Config::File.new(support_dir + 'empty_config.yml') }
|
10
|
+
let(:missing_config) { Cluster::Config::File.new(support_dir + 'missing') }
|
11
|
+
|
12
|
+
subject { Cluster::Config::Verifier.new(configs) }
|
13
|
+
|
14
|
+
shared_examples_for 'valid config' do
|
15
|
+
it 'verifies' do
|
16
|
+
expect(subject).to be_verified
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
shared_examples_for 'invalid config' do
|
21
|
+
it "doesn't verify" do
|
22
|
+
expect(subject).not_to be_verified
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
context 'with valid configs' do
|
27
|
+
let(:configs) { [valid_local_config, valid_global_config] }
|
28
|
+
|
29
|
+
it_behaves_like 'valid config'
|
30
|
+
end
|
31
|
+
|
32
|
+
context 'with a single config file' do
|
33
|
+
let(:configs) { [valid_local_config] }
|
34
|
+
|
35
|
+
it_behaves_like 'valid config'
|
36
|
+
end
|
37
|
+
|
38
|
+
context 'with a missing config' do
|
39
|
+
let(:configs) { [missing_config] }
|
40
|
+
|
41
|
+
it_behaves_like 'invalid config'
|
42
|
+
|
43
|
+
it 'reports the error' do
|
44
|
+
subject.verified?
|
45
|
+
|
46
|
+
expect(subject.configs.flat_map { |config| config.errors.to_a }).to include("Configuration file doesn't exist")
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
context 'with a non-hash config' do
|
51
|
+
let(:configs) { [non_hash_config] }
|
52
|
+
|
53
|
+
it_behaves_like 'invalid config'
|
54
|
+
|
55
|
+
it 'reports the error' do
|
56
|
+
subject.verified?
|
57
|
+
|
58
|
+
expect(subject.configs.flat_map { |config| config.errors.to_a }).to include("Parsed config as invalid type: expected Hash, got FalseClass")
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
context 'with an empty config' do
|
63
|
+
let(:configs) { [empty_config] }
|
64
|
+
|
65
|
+
it_behaves_like 'invalid config'
|
66
|
+
|
67
|
+
it 'reports the error' do
|
68
|
+
subject.verified?
|
69
|
+
|
70
|
+
expect(subject.configs.flat_map { |config| config.errors.to_a }).to include("Config file is empty")
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
74
|
+
context 'with broken YAML' do
|
75
|
+
let(:configs) { [broken_yaml_config] }
|
76
|
+
|
77
|
+
it_behaves_like 'invalid config'
|
78
|
+
|
79
|
+
it 'reports the error' do
|
80
|
+
subject.verified?
|
81
|
+
|
82
|
+
expect(subject.configs.flat_map { |config| config.errors.to_a }).to include('(<unknown>): did not find expected comment or line break while scanning a block scalar at line 1 column 1')
|
83
|
+
end
|
84
|
+
end
|
85
|
+
end
|
86
|
+
end
|
@@ -0,0 +1,194 @@
|
|
1
|
+
require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
|
2
|
+
|
3
|
+
RSpec.describe Resque::Cluster::Config do
|
4
|
+
let(:redis) { Resque.redis }
|
5
|
+
|
6
|
+
before do
|
7
|
+
config.verified?
|
8
|
+
|
9
|
+
Resque::Cluster.config = {
|
10
|
+
cluster_name: 'unit-test-cluster',
|
11
|
+
environment: 'unit-test'
|
12
|
+
}
|
13
|
+
end
|
14
|
+
|
15
|
+
shared_examples_for 'a valid config' do
|
16
|
+
it 'is verified' do
|
17
|
+
expect(config).to be_verified
|
18
|
+
end
|
19
|
+
|
20
|
+
it "gru_format should return a correct hash" do
|
21
|
+
expect(config.gru_format).to eql(correct_hash)
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
describe 'with a single config file' do
|
26
|
+
let(:config) { Resque::Cluster::Config.new(config_path) }
|
27
|
+
let(:correct_hash) do
|
28
|
+
{
|
29
|
+
cluster_maximums: { 'foo' => 2, 'bar' => 50, "foo,bar,baz" => 1 },
|
30
|
+
host_maximums: { 'foo' => 1, 'bar' => 9, "foo,bar,baz" => 1 },
|
31
|
+
client_settings: redis.client.options,
|
32
|
+
rebalance_flag: true,
|
33
|
+
presume_host_dead_after: 60,
|
34
|
+
max_workers_per_host: 10,
|
35
|
+
cluster_name: "unit-test-cluster",
|
36
|
+
environment_name: "unit-test",
|
37
|
+
manage_worker_heartbeats: true,
|
38
|
+
version_hash: `git rev-parse --verify HEAD`.strip
|
39
|
+
}
|
40
|
+
end
|
41
|
+
|
42
|
+
context 'old style' do
|
43
|
+
let(:config_path) { support_dir + 'valid_single_old_config.yml' }
|
44
|
+
|
45
|
+
it_behaves_like 'a valid config'
|
46
|
+
|
47
|
+
context 'with a missing local maximum' do
|
48
|
+
let(:config) { Resque::Cluster::Config.new(config_path) }
|
49
|
+
let(:config_path) { support_dir + 'single_old_missing_local.yml' }
|
50
|
+
|
51
|
+
it 'should not be verified' do
|
52
|
+
expect(config).not_to be_verified
|
53
|
+
end
|
54
|
+
|
55
|
+
it 'should not be verified' do
|
56
|
+
expect(config.errors).to contain_exactly("Every worker configuration must contain a local and a global maximum.")
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
context 'with a missing global maximum' do
|
61
|
+
let(:config) { Resque::Cluster::Config.new(config_path) }
|
62
|
+
let(:config_path) { support_dir + 'single_old_missing_global.yml' }
|
63
|
+
|
64
|
+
it 'should not be verified' do
|
65
|
+
expect(config).not_to be_verified
|
66
|
+
end
|
67
|
+
|
68
|
+
it 'should not be verified' do
|
69
|
+
expect(config.errors).to contain_exactly("Every worker configuration must contain a local and a global maximum.")
|
70
|
+
end
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
74
|
+
context 'new style' do
|
75
|
+
let(:config_path) { support_dir + 'valid_single_new_config.yml' }
|
76
|
+
|
77
|
+
it_behaves_like 'a valid config'
|
78
|
+
|
79
|
+
context 'with a missing local maximum' do
|
80
|
+
let(:config) { Resque::Cluster::Config.new(config_path) }
|
81
|
+
let(:config_path) { support_dir + 'missing_local_maximum.yml' }
|
82
|
+
|
83
|
+
it 'should not be verified' do
|
84
|
+
expect(config).not_to be_verified
|
85
|
+
end
|
86
|
+
|
87
|
+
it 'should not be verified' do
|
88
|
+
expect(config.errors).to contain_exactly("Every worker configuration must contain a local and a global maximum.")
|
89
|
+
end
|
90
|
+
end
|
91
|
+
|
92
|
+
context 'with a missing global maximum' do
|
93
|
+
let(:config) { Resque::Cluster::Config.new(config_path) }
|
94
|
+
let(:config_path) { support_dir + 'missing_global_maximum.yml' }
|
95
|
+
|
96
|
+
it 'should not be verified' do
|
97
|
+
expect(config).not_to be_verified
|
98
|
+
end
|
99
|
+
|
100
|
+
it 'should not be verified' do
|
101
|
+
expect(config.errors).to contain_exactly("Every worker configuration must contain a local and a global maximum.")
|
102
|
+
end
|
103
|
+
end
|
104
|
+
end
|
105
|
+
end
|
106
|
+
|
107
|
+
describe 'separate config files' do
|
108
|
+
context "with valid config files" do
|
109
|
+
let(:config) { Resque::Cluster::Config.new(local_config_path, global_config_path) }
|
110
|
+
let(:local_config_path) { File.expand_path(File.dirname(__FILE__) + '/../local_config.yml') }
|
111
|
+
let(:global_config_path) { File.expand_path(File.dirname(__FILE__) + '/../global_config.yml') }
|
112
|
+
|
113
|
+
let(:correct_hash) do
|
114
|
+
{
|
115
|
+
cluster_maximums: { 'foo' => 2, 'bar' => 50, "foo,bar,baz" => 1 },
|
116
|
+
host_maximums: { 'foo' => 1, 'bar' => 9, "foo,bar,baz" => 1 },
|
117
|
+
client_settings: redis.client.options,
|
118
|
+
rebalance_flag: false,
|
119
|
+
presume_host_dead_after: 120,
|
120
|
+
max_workers_per_host: nil,
|
121
|
+
cluster_name: "unit-test-cluster",
|
122
|
+
environment_name: "unit-test",
|
123
|
+
manage_worker_heartbeats: true,
|
124
|
+
version_hash: `git rev-parse --verify HEAD`.strip
|
125
|
+
}
|
126
|
+
end
|
127
|
+
|
128
|
+
it_behaves_like 'a valid config'
|
129
|
+
|
130
|
+
it "config should have no warnings or errors" do
|
131
|
+
expect(config.errors.count).to eql(0)
|
132
|
+
expect(config.warnings.count).to eql(0)
|
133
|
+
end
|
134
|
+
|
135
|
+
it "git_version_hash should be set" do
|
136
|
+
expect(config.version_git_hash).to eql(`git rev-parse --verify HEAD`.strip)
|
137
|
+
end
|
138
|
+
end
|
139
|
+
|
140
|
+
context 'with a missing local maximum' do
|
141
|
+
let(:config) { Resque::Cluster::Config.new(local_config_path, global_config_path) }
|
142
|
+
let(:local_config_path) { support_dir + 'separate_missing_local.yml' }
|
143
|
+
let(:global_config_path) { File.expand_path(File.dirname(__FILE__) + '/../global_config.yml') }
|
144
|
+
|
145
|
+
it 'should not be verified' do
|
146
|
+
expect(config).not_to be_verified
|
147
|
+
end
|
148
|
+
|
149
|
+
it 'should not be verified' do
|
150
|
+
expect(config.errors).to contain_exactly("Every worker configuration must contain a local and a global maximum.")
|
151
|
+
end
|
152
|
+
end
|
153
|
+
|
154
|
+
context 'with a missing global maximum' do
|
155
|
+
let(:config) { Resque::Cluster::Config.new(local_config_path, global_config_path) }
|
156
|
+
let(:local_config_path) { File.expand_path(File.dirname(__FILE__) + '/../local_config.yml') }
|
157
|
+
let(:global_config_path) { support_dir + 'separate_missing_global.yml' }
|
158
|
+
|
159
|
+
it 'should not be verified' do
|
160
|
+
expect(config).not_to be_verified
|
161
|
+
end
|
162
|
+
|
163
|
+
it 'should not be verified' do
|
164
|
+
expect(config.errors).to contain_exactly("Every worker configuration must contain a local and a global maximum.")
|
165
|
+
end
|
166
|
+
end
|
167
|
+
|
168
|
+
context "with invalid config file" do
|
169
|
+
let(:local_config_path) { File.expand_path(File.dirname(__FILE__) + '/../local_configuration.yml') }
|
170
|
+
let(:global_config_path) { File.expand_path(File.dirname(__FILE__) + '/../../README.rdoc') }
|
171
|
+
let(:config) { Resque::Cluster::Config.new(local_config_path, global_config_path) }
|
172
|
+
let(:correct_hash) { {} }
|
173
|
+
|
174
|
+
it "should not be verified" do
|
175
|
+
expect(config.verified?).to eql(false)
|
176
|
+
end
|
177
|
+
|
178
|
+
it "config should have no warnings but 2 errors" do
|
179
|
+
expect(config.errors.count).to eql(1)
|
180
|
+
expect(config.warnings.count).to eql(0)
|
181
|
+
expect(config.errors).to contain_exactly(
|
182
|
+
"#{local_config_path}: Configuration file doesn't exist")
|
183
|
+
end
|
184
|
+
|
185
|
+
it "gru_format should return a an empty hash" do
|
186
|
+
expect(config.gru_format).to eql(correct_hash)
|
187
|
+
end
|
188
|
+
|
189
|
+
it "git_version_hash should not be set" do
|
190
|
+
expect(config.version_git_hash).to be_nil
|
191
|
+
end
|
192
|
+
end
|
193
|
+
end
|
194
|
+
end
|