qtrix 0.0.1
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.
- data/.gitignore +18 -0
- data/Gemfile +4 -0
- data/LICENSE.txt +22 -0
- data/README.md +317 -0
- data/Rakefile +1 -0
- data/bin/qtrix +15 -0
- data/lib/qtrix.rb +178 -0
- data/lib/qtrix/cli.rb +80 -0
- data/lib/qtrix/cli/config_sets.rb +87 -0
- data/lib/qtrix/cli/overrides.rb +121 -0
- data/lib/qtrix/cli/queues.rb +97 -0
- data/lib/qtrix/matrix.rb +83 -0
- data/lib/qtrix/matrix/analyzer.rb +46 -0
- data/lib/qtrix/matrix/common.rb +22 -0
- data/lib/qtrix/matrix/model.rb +16 -0
- data/lib/qtrix/matrix/queue_picker.rb +52 -0
- data/lib/qtrix/matrix/queue_prioritizer.rb +70 -0
- data/lib/qtrix/matrix/reader.rb +25 -0
- data/lib/qtrix/matrix/row_builder.rb +72 -0
- data/lib/qtrix/namespacing.rb +198 -0
- data/lib/qtrix/override.rb +77 -0
- data/lib/qtrix/queue.rb +77 -0
- data/lib/qtrix/version.rb +3 -0
- data/qtrix.gemspec +24 -0
- data/spec/qtrix/cli/config_sets_spec.rb +94 -0
- data/spec/qtrix/cli/overrides_spec.rb +101 -0
- data/spec/qtrix/cli/queues_spec.rb +70 -0
- data/spec/qtrix/cli/spec_helper.rb +18 -0
- data/spec/qtrix/matrix/analyzer_spec.rb +38 -0
- data/spec/qtrix/matrix/queue_picker_spec.rb +73 -0
- data/spec/qtrix/matrix_profile_spec.rb +72 -0
- data/spec/qtrix/matrix_spec.rb +71 -0
- data/spec/qtrix/namespacing_spec.rb +207 -0
- data/spec/qtrix/override_spec.rb +155 -0
- data/spec/qtrix/queue_spec.rb +183 -0
- data/spec/qtrix_spec.rb +204 -0
- data/spec/spec_helper.rb +48 -0
- metadata +178 -0
@@ -0,0 +1,155 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Qtrix::Override do
|
4
|
+
include Qtrix::Namespacing
|
5
|
+
include_context "established default and night namespaces"
|
6
|
+
|
7
|
+
let(:queues) {[:a, :b, :c]}
|
8
|
+
let(:matrix) {Qtrix::Matrix}
|
9
|
+
let(:default_overrides) {raw_redis.llen("qtrix:default:overrides")}
|
10
|
+
let(:night_overrides) {raw_redis.llen("qtrix:night:overrides")}
|
11
|
+
|
12
|
+
before do
|
13
|
+
raw_redis.del "qtrix:default:overrides"
|
14
|
+
raw_redis.del "qtrix:night:overrides"
|
15
|
+
end
|
16
|
+
|
17
|
+
def override_count(ns=:current)
|
18
|
+
override = Qtrix::Override.all(ns).detect{|o| o.queues == queues}
|
19
|
+
override ? override.processes : 0
|
20
|
+
end
|
21
|
+
|
22
|
+
describe "#add" do
|
23
|
+
describe "with no namespace passed" do
|
24
|
+
it "should persist the override in the current ns" do
|
25
|
+
Qtrix::Override.add(queues, 1)
|
26
|
+
default_overrides.should == 1
|
27
|
+
end
|
28
|
+
|
29
|
+
it "should persist multiple processes as multiple rows" do
|
30
|
+
Qtrix::Override.add(queues, 1)
|
31
|
+
Qtrix::Override.add(queues, 1)
|
32
|
+
default_overrides.should == 2
|
33
|
+
end
|
34
|
+
|
35
|
+
it "should raise errors if the processes are zero" do
|
36
|
+
expect{Qtrix::Override.add(queues, 0)}.to raise_error
|
37
|
+
end
|
38
|
+
|
39
|
+
it "should blow away the matrix in the current ns" do
|
40
|
+
Qtrix::Override.add(queues, 1)
|
41
|
+
matrix.to_table.should be_empty
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
describe "with namespace passed" do
|
46
|
+
it "should persist the override in the target ns" do
|
47
|
+
Qtrix::Override.add(:night, queues, 1)
|
48
|
+
night_overrides.should == 1
|
49
|
+
default_overrides.should == 0
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
describe "#remove" do
|
55
|
+
describe "with no namespace passed" do
|
56
|
+
it "should remove the override in the current ns" do
|
57
|
+
Qtrix::Override.add(queues, 1)
|
58
|
+
Qtrix::Override.remove(queues, 1)
|
59
|
+
default_overrides.should == 0
|
60
|
+
end
|
61
|
+
|
62
|
+
it "should blow away the matrix in the current ns" do
|
63
|
+
Qtrix::Override.remove(queues, 100)
|
64
|
+
matrix.to_table.should be_empty
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
describe "with namespace passed" do
|
69
|
+
it "should remove the override in the target ns" do
|
70
|
+
Qtrix::Override.add(:night, queues, 2)
|
71
|
+
Qtrix::Override.remove(:night, queues, 1)
|
72
|
+
night_overrides.should == 1
|
73
|
+
default_overrides.should == 0
|
74
|
+
end
|
75
|
+
|
76
|
+
it "should blow away the matrix in the target ns" do
|
77
|
+
Qtrix::Override.remove(:night, queues, 100)
|
78
|
+
matrix.to_table(:night).should be_empty
|
79
|
+
end
|
80
|
+
end
|
81
|
+
end
|
82
|
+
|
83
|
+
describe "#clear!" do
|
84
|
+
describe "with no namespace passed" do
|
85
|
+
it "should drop all override data from redis" do
|
86
|
+
Qtrix::Override.add(queues, 1)
|
87
|
+
Qtrix::Override.clear!
|
88
|
+
redis.exists(Qtrix::Override::REDIS_KEY).should_not == true
|
89
|
+
end
|
90
|
+
|
91
|
+
it "should blow away the matrix" do
|
92
|
+
Qtrix::Override.clear!
|
93
|
+
matrix.to_table.should be_empty
|
94
|
+
end
|
95
|
+
end
|
96
|
+
|
97
|
+
describe "with namespace passed" do
|
98
|
+
it "should drop override data from the target namespace" do
|
99
|
+
Qtrix::Override.add(:night, queues, 1)
|
100
|
+
Qtrix::Override.clear! :night
|
101
|
+
raw_redis.llen("qtrix:night:overrides").should == 0
|
102
|
+
end
|
103
|
+
|
104
|
+
it "should blow away the matrix in target namespace" do
|
105
|
+
Qtrix::Override.clear!(:night)
|
106
|
+
matrix.to_table(:night).should be_empty
|
107
|
+
end
|
108
|
+
end
|
109
|
+
end
|
110
|
+
|
111
|
+
describe "#overrides_for" do
|
112
|
+
describe "with no namespace passed" do
|
113
|
+
it "should return an empty list if no overrides are present" do
|
114
|
+
Qtrix::Override.overrides_for("host1", 1).should == []
|
115
|
+
end
|
116
|
+
|
117
|
+
it "should return a list of queues from an unclaimed override" do
|
118
|
+
Qtrix::Override.add(queues, 1)
|
119
|
+
Qtrix::Override.overrides_for("host1", 1).should == [queues]
|
120
|
+
end
|
121
|
+
|
122
|
+
it "should associate the host with the override" do
|
123
|
+
Qtrix::Override.add(queues, 1)
|
124
|
+
Qtrix::Override.overrides_for("host1", 1)
|
125
|
+
result = Qtrix::Override.all.detect{|override| override.host == "host1"}
|
126
|
+
result.should_not be_nil
|
127
|
+
end
|
128
|
+
|
129
|
+
it "should return existing claims on subsequent invocations" do
|
130
|
+
Qtrix::Override.add(queues, 1)
|
131
|
+
expected = Qtrix::Override.overrides_for("host1", 1)
|
132
|
+
result = Qtrix::Override.overrides_for("host1", 1)
|
133
|
+
result.should == expected
|
134
|
+
end
|
135
|
+
|
136
|
+
it "should not return overrides beyond the current count of overrides" do
|
137
|
+
Qtrix::Override.add(queues, 1)
|
138
|
+
Qtrix::Override.overrides_for("host1", 3).should == [queues]
|
139
|
+
end
|
140
|
+
|
141
|
+
it "should not return overrides beyond the requested number of overrides" do
|
142
|
+
Qtrix::Override.add(queues, 5)
|
143
|
+
Qtrix::Override.overrides_for("host1", 1).should == [queues]
|
144
|
+
end
|
145
|
+
end
|
146
|
+
|
147
|
+
describe "with namespace passed" do
|
148
|
+
it "should limit the operation to the passed namespace" do
|
149
|
+
Qtrix::Override.add(:night, queues, 1)
|
150
|
+
Qtrix::Override.overrides_for(:current, "host", 1).should == []
|
151
|
+
Qtrix::Override.overrides_for(:night, "host", 1).should == [queues]
|
152
|
+
end
|
153
|
+
end
|
154
|
+
end
|
155
|
+
end
|
@@ -0,0 +1,183 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
class DummyJob
|
4
|
+
@queue = :test_queue
|
5
|
+
end
|
6
|
+
|
7
|
+
describe Qtrix::Queue do
|
8
|
+
include Qtrix::Namespacing
|
9
|
+
before(:each) do
|
10
|
+
Qtrix::Queue.map_queue_weights a: 2, b: 3
|
11
|
+
end
|
12
|
+
let(:all_queues) {Qtrix::Queue.all_queues}
|
13
|
+
let(:queue1) {all_queues[1]}
|
14
|
+
let(:queue2) {all_queues[0]}
|
15
|
+
let(:matrix) {Qtrix::Matrix}
|
16
|
+
|
17
|
+
context "comparing two queues with the same name and weights" do
|
18
|
+
let(:other_queue) {Qtrix::Queue.new(:current, :a, 2)}
|
19
|
+
describe "#==" do
|
20
|
+
it "should return true" do
|
21
|
+
queue1.should == other_queue
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
describe "#hash" do
|
26
|
+
it "should return the same result" do
|
27
|
+
queue1.hash.should == other_queue.hash
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
context "comparing two queues with the same name and different weights" do
|
33
|
+
let(:other_queue) {other_queue = Qtrix::Queue.new(:current, :a, 3)}
|
34
|
+
describe "#==" do
|
35
|
+
it "should return false" do
|
36
|
+
queue1.should_not == other_queue
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
describe "#hash" do
|
41
|
+
it "should return different results" do
|
42
|
+
queue1.hash.should_not == other_queue.hash
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
context "comparing two queues with the same weight and different names" do
|
48
|
+
let(:other_queue) {other_queue = Qtrix::Queue.new(:default, :b, 2)}
|
49
|
+
describe "#==" do
|
50
|
+
it "should return false" do
|
51
|
+
queue1.should_not == other_queue
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
describe "#hash" do
|
56
|
+
it "should return different results" do
|
57
|
+
queue1.hash.should_not == other_queue.hash
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
describe "#resource_percentage" do
|
63
|
+
it "should equal weight / total weight of all queues" do
|
64
|
+
queue1.resource_percentage.should == 0.4
|
65
|
+
queue2.resource_percentage.should == 0.6
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
context "class instance methods" do
|
70
|
+
include_context "established default and night namespaces"
|
71
|
+
describe "#map_queue_weights" do
|
72
|
+
context "no namespace specified" do
|
73
|
+
it "should remove old queues" do
|
74
|
+
Qtrix::Queue.map_queue_weights A: 100
|
75
|
+
result = Qtrix::Queue.all_queues.map(&:name)
|
76
|
+
result.include?(:B).should_not be_true
|
77
|
+
result.include?(:C).should_not be_true
|
78
|
+
end
|
79
|
+
|
80
|
+
it "should add new queues ordered according to weight" do
|
81
|
+
results = Qtrix::Queue.all_queues
|
82
|
+
results.map(&:name).should == [:A, :B, :C]
|
83
|
+
results.map(&:weight).should == [3, 2, 1]
|
84
|
+
end
|
85
|
+
|
86
|
+
it "should error when trying to save empty queue name" do
|
87
|
+
expect{Qtrix::Queue.map_queue_weights('' => 1)}.to raise_error
|
88
|
+
end
|
89
|
+
|
90
|
+
it "should error when trying to save nil weight" do
|
91
|
+
expect{Qtrix::Queue.map_queue_weights(c: nil)}.to raise_error
|
92
|
+
end
|
93
|
+
|
94
|
+
it "should error when trying to save weight of 0" do
|
95
|
+
expect{Qtrix::Queue.map_queue_weights(c: 0)}.to raise_error
|
96
|
+
end
|
97
|
+
|
98
|
+
it "should blow away the matrix" do
|
99
|
+
matrix.queues_for!('host1', 1)
|
100
|
+
matrix.to_table.should_not be_empty
|
101
|
+
Qtrix::Queue.map_queue_weights \
|
102
|
+
A: 1,
|
103
|
+
B: 2
|
104
|
+
matrix.to_table.should be_empty
|
105
|
+
end
|
106
|
+
end
|
107
|
+
|
108
|
+
context "namespace specified" do
|
109
|
+
it "should affect targetted namespace" do
|
110
|
+
Qtrix::Queue.map_queue_weights :night, Z: 10, X: 1, Y: 5
|
111
|
+
Qtrix::Queue.all_queues(:night).map(&:name).should == [:Z, :Y, :X]
|
112
|
+
end
|
113
|
+
end
|
114
|
+
end
|
115
|
+
|
116
|
+
describe "#all_queues" do
|
117
|
+
describe "with no namepsace specified" do
|
118
|
+
it "should contain all queues in the default ns sorted by weight desc" do
|
119
|
+
Qtrix::Queue.all_queues.map(&:name).should == [:A, :B, :C]
|
120
|
+
end
|
121
|
+
end
|
122
|
+
|
123
|
+
describe "with namespace specified" do
|
124
|
+
it "should contain all queues in the default ns sorted by weight desc" do
|
125
|
+
result = Qtrix::Queue.all_queues(:night)
|
126
|
+
result.map(&:name).should == [:X, :Y, :Z]
|
127
|
+
end
|
128
|
+
end
|
129
|
+
end
|
130
|
+
|
131
|
+
describe "#count" do
|
132
|
+
context "with no namespace specified" do
|
133
|
+
it "should be the number of queues mapped in the current namespace" do
|
134
|
+
Qtrix::Queue.count.should == 3
|
135
|
+
end
|
136
|
+
end
|
137
|
+
context "with namespace specifeid" do
|
138
|
+
it "should be the number of queues mapped in the target namespace" do
|
139
|
+
Qtrix::Queue.map_queue_weights(:night, a: 2)
|
140
|
+
Qtrix::Queue.count(:night).should == 1
|
141
|
+
end
|
142
|
+
end
|
143
|
+
end
|
144
|
+
|
145
|
+
describe "#total_weight" do
|
146
|
+
context "with no namespace specified" do
|
147
|
+
it "should contain the sum of all weights" do
|
148
|
+
Qtrix::Queue.total_weight == 6
|
149
|
+
end
|
150
|
+
end
|
151
|
+
|
152
|
+
context "with namespace provided" do
|
153
|
+
it "should contain the sum of all weights in the namespace" do
|
154
|
+
Qtrix::Queue.total_weight(:night) == 7
|
155
|
+
end
|
156
|
+
end
|
157
|
+
end
|
158
|
+
|
159
|
+
describe "#clear!" do
|
160
|
+
context "with no namespace specified" do
|
161
|
+
before(:each) {Qtrix::Queue.clear!}
|
162
|
+
it "should remove all existing queue weights" do
|
163
|
+
redis.exists(Qtrix::Queue::REDIS_KEY).should_not == true
|
164
|
+
end
|
165
|
+
|
166
|
+
it "should blow away the matrix" do
|
167
|
+
matrix.to_table.should be_empty
|
168
|
+
end
|
169
|
+
end
|
170
|
+
|
171
|
+
context "with namespace specified" do
|
172
|
+
before(:each) {Qtrix::Queue.clear! :night}
|
173
|
+
it "should remove all existing queue weights" do
|
174
|
+
redis(:night).exists(Qtrix::Queue::REDIS_KEY).should_not == true
|
175
|
+
end
|
176
|
+
|
177
|
+
it "should blow away the matrix" do
|
178
|
+
matrix.to_table(:night).should be_empty
|
179
|
+
end
|
180
|
+
end
|
181
|
+
end
|
182
|
+
end
|
183
|
+
end
|
data/spec/qtrix_spec.rb
ADDED
@@ -0,0 +1,204 @@
|
|
1
|
+
require 'set'
|
2
|
+
require 'spec_helper'
|
3
|
+
|
4
|
+
describe Qtrix do
|
5
|
+
|
6
|
+
let(:namespace_manager) {Qtrix::Namespacing::Manager.instance}
|
7
|
+
|
8
|
+
describe "operations for configuration sets" do
|
9
|
+
describe "#configuration_sets" do
|
10
|
+
it "should return all namespaces" do
|
11
|
+
Qtrix.configuration_sets.should == [:default]
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
describe "#create_configuration_set" do
|
16
|
+
it "should create a namespace" do
|
17
|
+
Qtrix.create_configuration_set :weekend
|
18
|
+
namespace_manager.namespaces.sort.should == [:default, :weekend]
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
describe "#remove_configuration_set!" do
|
23
|
+
it "should remove a namespace" do
|
24
|
+
namespace_manager.add_namespace :daytime
|
25
|
+
Qtrix.remove_configuration_set! :daytime
|
26
|
+
namespace_manager.namespaces.should == [:default]
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
describe "#current_configuration_set" do
|
31
|
+
it "should return the current namespace" do
|
32
|
+
Qtrix.current_configuration_set.should == :default
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
describe "#activate_configuration_set!" do
|
37
|
+
it "should set the current namespace" do
|
38
|
+
namespace_manager.add_namespace :weekend
|
39
|
+
Qtrix.map_queue_weights :weekend, A: 10
|
40
|
+
Qtrix.activate_configuration_set! :weekend
|
41
|
+
namespace_manager.current_namespace.should == :weekend
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
describe "#desired_distribution" do
|
47
|
+
include_context "established default and night namespaces"
|
48
|
+
let(:desired_dist) {Qtrix.desired_distribution}
|
49
|
+
let(:qtrix_queues) {Set.new(desired_dist.map(&:name)).to_a}
|
50
|
+
|
51
|
+
it "should include the list of known queues" do
|
52
|
+
known_queues = Qtrix::Queue.all_queues
|
53
|
+
Qtrix.desired_distribution.should == known_queues
|
54
|
+
end
|
55
|
+
|
56
|
+
it "should be constrainable to a config set." do
|
57
|
+
known_queues = Qtrix::Queue.all_queues :night
|
58
|
+
Qtrix.desired_distribution(:night).should == known_queues
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
describe "#map_queue_weights" do
|
63
|
+
include_context "established default and night namespaces"
|
64
|
+
it "should persist the mappings of queues to weights" do
|
65
|
+
Qtrix.map_queue_weights \
|
66
|
+
B: 0.3,
|
67
|
+
A: 0.4,
|
68
|
+
D: 0.1,
|
69
|
+
C: 0.2
|
70
|
+
effects = Qtrix.desired_distribution
|
71
|
+
effects.map(&:name).should == [:A, :B, :C, :D]
|
72
|
+
effects.map(&:weight).should == [0.4, 0.3, 0.2, 0.1]
|
73
|
+
end
|
74
|
+
|
75
|
+
it "should be constrainable to a config set" do
|
76
|
+
Qtrix.map_queue_weights(:night, A: 100)
|
77
|
+
known_queues = Qtrix::Queue.all_queues :night
|
78
|
+
Qtrix.desired_distribution(:night).should == known_queues
|
79
|
+
end
|
80
|
+
end
|
81
|
+
|
82
|
+
describe "override methods" do
|
83
|
+
include_context "established default and night namespaces"
|
84
|
+
def override_counts
|
85
|
+
[Qtrix::Override.all.size, Qtrix::Override.all(:night).size]
|
86
|
+
end
|
87
|
+
|
88
|
+
let(:default_overrides) {Qtrix::Override.all.map{|o| o.queues}}
|
89
|
+
let(:night_overrides) {Qtrix::Override.all(:night).map{|o| o.queues}}
|
90
|
+
let(:default_size) {Qtrix::Override.all.size}
|
91
|
+
let(:night_size) {Qtrix::Override.all(:night).size}
|
92
|
+
|
93
|
+
describe "#add_override" do
|
94
|
+
it "should persist the override to redis" do
|
95
|
+
Qtrix.add_override([:a, :b, :c], 2)
|
96
|
+
default_overrides[-2..-1].should == [[:a, :b, :c], [:a, :b, :c]]
|
97
|
+
end
|
98
|
+
|
99
|
+
it "should be directable to a config set" do
|
100
|
+
default_before, night_before = override_counts
|
101
|
+
Qtrix.add_override(:night, [:abc], 2)
|
102
|
+
default_after, night_after = override_counts
|
103
|
+
default_after.should == default_before
|
104
|
+
(night_after > night_before).should == true
|
105
|
+
end
|
106
|
+
end
|
107
|
+
|
108
|
+
describe "#remove_override" do
|
109
|
+
it "should remove the override from redis" do
|
110
|
+
Qtrix.add_override([:abc], 2)
|
111
|
+
Qtrix.remove_override([:abc], 2)
|
112
|
+
default_overrides.select{|ql| ql == [:abc]}.should be_empty
|
113
|
+
end
|
114
|
+
|
115
|
+
it "should be directable to a config set" do
|
116
|
+
Qtrix.add_override(:night, [:abc], 2)
|
117
|
+
default_before, night_before = override_counts
|
118
|
+
Qtrix.remove_override(:night, [:abc], 2)
|
119
|
+
default_after, night_after = override_counts
|
120
|
+
default_after.should == default_before
|
121
|
+
(night_after < night_before).should == true
|
122
|
+
end
|
123
|
+
end
|
124
|
+
|
125
|
+
describe "#overrides" do
|
126
|
+
it "should return all overrides from redis" do
|
127
|
+
Qtrix.add_override([:a, :b, :c], 1)
|
128
|
+
Qtrix.add_override([:x, :y, :z], 1)
|
129
|
+
default_overrides[-2..-1].should == [[:a, :b, :c], [:x, :y, :z]]
|
130
|
+
end
|
131
|
+
|
132
|
+
it "should be directable to a config set" do
|
133
|
+
Qtrix.add_override(:night, [:abc], 1)
|
134
|
+
default_cnt, night_cnt = override_counts
|
135
|
+
default_cnt.should == (night_cnt - 1)
|
136
|
+
end
|
137
|
+
end
|
138
|
+
end
|
139
|
+
|
140
|
+
describe "#queues_for!" do
|
141
|
+
before(:each) do
|
142
|
+
Qtrix.map_queue_weights \
|
143
|
+
A: 4,
|
144
|
+
B: 3,
|
145
|
+
C: 2,
|
146
|
+
D: 1
|
147
|
+
end
|
148
|
+
|
149
|
+
context "no overrides" do
|
150
|
+
it "should pick a queue list for a worker from the matrix" do
|
151
|
+
result = Qtrix.queues_for!('host1', 1)
|
152
|
+
result.should == [[:A, :B, :C, :D, :__orchestrated__]]
|
153
|
+
end
|
154
|
+
end
|
155
|
+
|
156
|
+
context "with overrides" do
|
157
|
+
before(:each) do
|
158
|
+
Qtrix.add_override([:Z], 1)
|
159
|
+
end
|
160
|
+
|
161
|
+
context "when requesting queus for fewer or equal workers as there are overrides" do
|
162
|
+
it "should pick a queue list from the overrides" do
|
163
|
+
Qtrix.queues_for!('host1', 1).should == [[:Z]]
|
164
|
+
end
|
165
|
+
end
|
166
|
+
|
167
|
+
context "when requeues queues for more workers than there are overrides" do
|
168
|
+
it "should choose queue lists from both overrides and the matrix" do
|
169
|
+
Qtrix.queues_for!('host1', 2)
|
170
|
+
.should == [[:Z],[:A,:B,:C,:D,:__orchestrated__]]
|
171
|
+
end
|
172
|
+
end
|
173
|
+
end
|
174
|
+
|
175
|
+
context "across hosts" do
|
176
|
+
it "it should appropriately distribute the queues." do
|
177
|
+
first_expected = [[:A, :B, :C, :D, :__orchestrated__],
|
178
|
+
[:B, :A, :C, :D, :__orchestrated__]]
|
179
|
+
Qtrix.queues_for!('host1', 2).should == first_expected
|
180
|
+
second_expected = [[:C, :A, :B, :D, :__orchestrated__],
|
181
|
+
[:D, :A, :B, :C, :__orchestrated__]]
|
182
|
+
Qtrix.queues_for!('host2', 2).should == second_expected
|
183
|
+
end
|
184
|
+
end
|
185
|
+
end
|
186
|
+
|
187
|
+
describe "#clear!" do
|
188
|
+
let(:queue_key) {Qtrix::Queue::REDIS_KEY}
|
189
|
+
let(:override_key) {Qtrix::Override::REDIS_KEY}
|
190
|
+
let(:matrix_key) {Qtrix::Matrix::REDIS_KEY}
|
191
|
+
before do
|
192
|
+
Qtrix.map_queue_weights A: 0.4
|
193
|
+
Qtrix::Matrix.queues_for!("localhost", 2)
|
194
|
+
Qtrix.add_override([:D, :A, :B, :C], 1)
|
195
|
+
end
|
196
|
+
|
197
|
+
it "should clear redis of all keys related to qtrix" do
|
198
|
+
Qtrix.clear!
|
199
|
+
Qtrix.redis.keys("#{matrix_key}*").should be_empty
|
200
|
+
Qtrix.redis.keys("#{queue_key}*").should_not be_empty
|
201
|
+
Qtrix.redis.keys("#{override_key}*").should_not be_empty
|
202
|
+
end
|
203
|
+
end
|
204
|
+
end
|