resque-cluster 0.1.1.1 → 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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
|