cuboid 0.0.3alpha → 0.1.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 +4 -4
- data/CHANGELOG.md +5 -0
- data/Gemfile +1 -1
- data/README.md +14 -13
- data/cuboid.gemspec +1 -1
- data/lib/cuboid/application.rb +10 -10
- data/lib/cuboid/option_groups/agent.rb +54 -0
- data/lib/cuboid/option_groups/paths.rb +13 -4
- data/lib/cuboid/options.rb +1 -1
- data/lib/cuboid/processes/{dispatchers.rb → agents.rb} +40 -26
- data/lib/cuboid/processes/executables/agent.rb +5 -0
- data/lib/cuboid/processes/helpers/agents.rb +23 -0
- data/lib/cuboid/processes/helpers/instances.rb +4 -4
- data/lib/cuboid/processes/helpers.rb +1 -1
- data/lib/cuboid/processes/instances.rb +22 -10
- data/lib/cuboid/processes/schedulers.rb +16 -3
- data/lib/cuboid/processes.rb +2 -2
- data/lib/cuboid/rest/server/instance_helpers.rb +13 -13
- data/lib/cuboid/rest/server/routes/dispatcher.rb +11 -11
- data/lib/cuboid/rest/server/routes/grid.rb +8 -8
- data/lib/cuboid/rest/server/routes/instances.rb +1 -1
- data/lib/cuboid/rest/server.rb +5 -5
- data/lib/cuboid/rpc/client/{dispatcher.rb → agent.rb} +4 -4
- data/lib/cuboid/rpc/client/instance.rb +2 -2
- data/lib/cuboid/rpc/client.rb +1 -1
- data/lib/cuboid/rpc/server/agent/node.rb +247 -0
- data/lib/cuboid/rpc/server/{dispatcher → agent}/service.rb +13 -13
- data/lib/cuboid/rpc/server/{dispatcher.rb → agent.rb} +62 -32
- data/lib/cuboid/rpc/server/application_wrapper.rb +5 -4
- data/lib/cuboid/rpc/server/instance.rb +4 -4
- data/lib/cuboid/rpc/server/scheduler.rb +13 -12
- data/lib/version +1 -1
- data/spec/cuboid/option_groups/dispatcher_spec.rb +2 -2
- data/spec/cuboid/option_groups/paths_spec.rb +6 -3
- data/spec/cuboid/rest/server_spec.rb +45 -45
- data/spec/cuboid/rpc/client/dispatcher_spec.rb +2 -2
- data/spec/cuboid/rpc/server/dispatcher/node_spec.rb +65 -65
- data/spec/cuboid/rpc/server/dispatcher/service_spec.rb +16 -16
- data/spec/cuboid/rpc/server/dispatcher_spec.rb +187 -72
- data/spec/cuboid/rpc/server/scheduler_spec.rb +8 -8
- data/spec/support/fixtures/executables/node.rb +3 -3
- data/spec/support/fixtures/mock_app/test_service.rb +8 -8
- data/spec/support/fixtures/mock_app.rb +1 -1
- data/spec/support/fixtures/services/echo.rb +6 -6
- data/spec/support/helpers/resets.rb +1 -1
- data/spec/support/lib/web_server_client.rb +2 -2
- data/spec/support/lib/web_server_dispatcher.rb +1 -1
- metadata +18 -58
- data/lib/cuboid/option_groups/dispatcher.rb +0 -38
- data/lib/cuboid/processes/executables/dispatcher.rb +0 -5
- data/lib/cuboid/processes/helpers/dispatchers.rb +0 -23
- data/lib/cuboid/rpc/server/dispatcher/node.rb +0 -247
- data/spec/support/logs/Dispatcher - 51489-29703.log +0 -6
- data/spec/support/logs/Scheduler - 51474-42556.log +0 -3
- data/spec/support/logs/Scheduler - 51477-63074.log +0 -6
- data/spec/support/logs/Scheduler - 51496-16039.log +0 -3
- data/spec/support/logs/Scheduler - 51499-40309.log +0 -6
- data/spec/support/logs/Scheduler - 51521-54983.log +0 -4
- data/spec/support/logs/Scheduler - 51533-50145.log +0 -1
- data/spec/support/logs/Scheduler - 51537-26476.log +0 -3
- data/spec/support/logs/Scheduler - 51541-33347.log +0 -6
- data/spec/support/logs/Scheduler - 51556-5765.log +0 -3
- data/spec/support/logs/Scheduler - 51559-22349.log +0 -6
- data/spec/support/logs/Scheduler - 51567-20476.log +0 -3
- data/spec/support/logs/Scheduler - 51570-37548.log +0 -6
- data/spec/support/logs/Scheduler - 52668-26175.log +0 -3
- data/spec/support/reports/3480c2e4463df854d3457b247e3ba679.crf +0 -0
- data/spec/support/reports/45958408cb49a7f3391a973e05bf673b.crf +0 -0
- data/spec/support/reports/62a7f8d6c8914bb086e7e5f8c418d974.crf +0 -0
- data/spec/support/reports/6363927e13ec27b5cbd973b86bd8e52c.crf +0 -0
- data/spec/support/reports/b68f94be3aa96d0c27477dcfe1e25143.crf +0 -0
- data/spec/support/reports/bbb7496056393de17e72855a63d3acfb.crf +0 -0
@@ -1,16 +1,16 @@
|
|
1
1
|
require 'spec_helper'
|
2
2
|
require 'fileutils'
|
3
3
|
|
4
|
-
require "#{Cuboid::Options.paths.lib}/rpc/server/
|
4
|
+
require "#{Cuboid::Options.paths.lib}/rpc/server/agent"
|
5
5
|
|
6
|
-
describe Cuboid::RPC::Server::
|
6
|
+
describe Cuboid::RPC::Server::Agent do
|
7
7
|
before( :each ) do
|
8
8
|
Cuboid::Options.system.max_slots = slots
|
9
9
|
end
|
10
10
|
|
11
11
|
let(:instance_info_keys) { %w(token application pid url owner birthdate helpers now age) }
|
12
12
|
let(:slots) { 3 }
|
13
|
-
let(:subject) {
|
13
|
+
let(:subject) { agent_spawn( application: "#{fixtures_path}/mock_app.rb" ) }
|
14
14
|
|
15
15
|
describe '#alive?' do
|
16
16
|
it 'returns true' do
|
@@ -19,38 +19,71 @@ describe Cuboid::RPC::Server::Dispatcher do
|
|
19
19
|
end
|
20
20
|
|
21
21
|
describe '#preferred' do
|
22
|
-
context 'when the
|
23
|
-
|
24
|
-
|
25
|
-
|
22
|
+
context 'when the agent is a grid member' do
|
23
|
+
context 'and strategy is' do
|
24
|
+
context :horizontal do
|
25
|
+
it 'returns the URL of least burdened Agent' do
|
26
|
+
agent_spawn( peer: subject.url ).spawn( load_balance: false )
|
27
|
+
agent_spawn( peer: subject.url ).spawn( load_balance: false )
|
28
|
+
|
29
|
+
expect(subject.preferred( :horizontal )).to eq(subject.url)
|
30
|
+
end
|
31
|
+
end
|
26
32
|
|
27
|
-
|
33
|
+
context :vertical do
|
34
|
+
it 'returns the URL of most burdened Agent' do
|
35
|
+
agent_spawn( peer: subject.url ).spawn( load_balance: false )
|
36
|
+
d = agent_spawn( peer: subject.url )
|
37
|
+
d.spawn( load_balance: false )
|
38
|
+
d.spawn( load_balance: false )
|
39
|
+
|
40
|
+
expect(subject.preferred( :vertical )).to eq(d.url)
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
context 'default' do
|
45
|
+
it 'returns the URL of least burdened Agent' do
|
46
|
+
agent_spawn( peer: subject.url ).spawn( load_balance: false )
|
47
|
+
agent_spawn( peer: subject.url ).spawn( load_balance: false )
|
48
|
+
|
49
|
+
expect(subject.preferred).to eq(subject.url)
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
context 'other' do
|
54
|
+
it 'returns :error_unknown_strategy' do
|
55
|
+
agent_spawn( peer: subject.url ).spawn( load_balance: false )
|
56
|
+
agent_spawn( peer: subject.url ).spawn( load_balance: false )
|
57
|
+
|
58
|
+
expect(subject.preferred( :blah )).to eq('error_unknown_strategy')
|
59
|
+
end
|
60
|
+
end
|
28
61
|
end
|
29
62
|
|
30
|
-
context 'and all
|
63
|
+
context 'and all Agents are at max utilization' do
|
31
64
|
before :each do
|
32
|
-
subject.
|
65
|
+
subject.spawn( load_balance: false )
|
33
66
|
end
|
34
67
|
|
35
68
|
let(:slots) { 1 }
|
36
69
|
|
37
70
|
it 'returns nil' do
|
38
|
-
|
39
|
-
|
71
|
+
agent_spawn( peer: subject.url ).spawn( load_balance: false )
|
72
|
+
agent_spawn( peer: subject.url ).spawn( load_balance: false )
|
40
73
|
|
41
74
|
expect(subject.preferred).to be_nil
|
42
75
|
end
|
43
76
|
end
|
44
77
|
end
|
45
78
|
|
46
|
-
context 'when the
|
47
|
-
it 'returns the URL of the
|
79
|
+
context 'when the agent is not a grid member' do
|
80
|
+
it 'returns the URL of the Agent' do
|
48
81
|
expect(subject.preferred).to eq(subject.url)
|
49
82
|
end
|
50
83
|
|
51
84
|
context 'and it is at max utilization' do
|
52
85
|
before :each do
|
53
|
-
subject.
|
86
|
+
subject.spawn( load_balance: false )
|
54
87
|
end
|
55
88
|
|
56
89
|
let(:slots) { 1 }
|
@@ -68,20 +101,20 @@ describe Cuboid::RPC::Server::Dispatcher do
|
|
68
101
|
end
|
69
102
|
end
|
70
103
|
|
71
|
-
describe '#
|
104
|
+
describe '#spawn' do
|
72
105
|
it 'does not leak Instances' do
|
73
106
|
slots.times do
|
74
|
-
subject.
|
107
|
+
subject.spawn
|
75
108
|
end
|
76
109
|
|
77
110
|
expect(subject.instances.size).to eq(slots)
|
78
111
|
end
|
79
112
|
|
80
|
-
it 'sets OptionGroups::
|
81
|
-
info = subject.
|
113
|
+
it 'sets OptionGroups::Agent#url' do
|
114
|
+
info = subject.spawn
|
82
115
|
instance = instance_connect( info['url'], info['token'] )
|
83
116
|
|
84
|
-
expect(instance.
|
117
|
+
expect(instance.agent_url).to eq subject.url
|
85
118
|
end
|
86
119
|
|
87
120
|
context "when #{Cuboid::OptionGroups::RPC}#server_external_address has been set" do
|
@@ -92,13 +125,13 @@ describe Cuboid::RPC::Server::Dispatcher do
|
|
92
125
|
let(:address) { '127.0.0.2' }
|
93
126
|
|
94
127
|
it 'advertises that address' do
|
95
|
-
expect(subject.
|
128
|
+
expect(subject.spawn['url']).to start_with "#{address}:"
|
96
129
|
end
|
97
130
|
end
|
98
131
|
|
99
132
|
context 'when not a Grid member' do
|
100
133
|
it 'returns Instance info' do
|
101
|
-
info = subject.
|
134
|
+
info = subject.spawn( owner: 'rspec' )
|
102
135
|
|
103
136
|
%w(token application pid url owner birthdate helpers).each do |k|
|
104
137
|
expect(info[k]).to be_truthy
|
@@ -110,19 +143,19 @@ describe Cuboid::RPC::Server::Dispatcher do
|
|
110
143
|
|
111
144
|
it 'assigns an optional owner' do
|
112
145
|
owner = 'blah'
|
113
|
-
expect(subject.
|
146
|
+
expect(subject.spawn( owner: owner )['owner']).to eq(owner)
|
114
147
|
end
|
115
148
|
|
116
149
|
context 'when the there are no available slots' do
|
117
150
|
let(:slots) { 5 }
|
118
151
|
before :each do
|
119
152
|
slots.times do
|
120
|
-
subject.
|
153
|
+
subject.spawn
|
121
154
|
end
|
122
155
|
end
|
123
156
|
|
124
157
|
it 'returns nil' do
|
125
|
-
expect(subject.
|
158
|
+
expect(subject.spawn).to be nil
|
126
159
|
end
|
127
160
|
|
128
161
|
context 'and slots are freed' do
|
@@ -140,12 +173,12 @@ describe Cuboid::RPC::Server::Dispatcher do
|
|
140
173
|
|
141
174
|
instances = []
|
142
175
|
free.times do
|
143
|
-
instances << subject.
|
176
|
+
instances << subject.spawn
|
144
177
|
end
|
145
178
|
instances.compact!
|
146
179
|
|
147
180
|
expect(instances.size).to eq free
|
148
|
-
expect(subject.
|
181
|
+
expect(subject.spawn).to be nil
|
149
182
|
end
|
150
183
|
end
|
151
184
|
end
|
@@ -154,68 +187,150 @@ describe Cuboid::RPC::Server::Dispatcher do
|
|
154
187
|
context 'when a Grid member' do
|
155
188
|
let(:slots) { 4 }
|
156
189
|
|
157
|
-
|
158
|
-
|
159
|
-
|
160
|
-
|
161
|
-
|
190
|
+
context 'and strategy is' do
|
191
|
+
context :horizontal do
|
192
|
+
it 'provides Instances from the least burdened Agent' do
|
193
|
+
d1 = agent_spawn(
|
194
|
+
address: '127.0.0.1',
|
195
|
+
application: "#{fixtures_path}/mock_app.rb"
|
196
|
+
)
|
197
|
+
|
198
|
+
3.times do
|
199
|
+
d1.spawn( load_balance: false )
|
200
|
+
end
|
201
|
+
|
202
|
+
d2 = agent_spawn(
|
203
|
+
address: '127.0.0.2',
|
204
|
+
peer: d1.url,
|
205
|
+
application: "#{fixtures_path}/mock_app.rb"
|
206
|
+
)
|
162
207
|
|
163
|
-
|
164
|
-
|
208
|
+
2.times do
|
209
|
+
d2.spawn( load_balance: false )
|
210
|
+
end
|
211
|
+
|
212
|
+
d3 = agent_spawn(
|
213
|
+
address: '127.0.0.3',
|
214
|
+
peer: d1.url,
|
215
|
+
application: "#{fixtures_path}/mock_app.rb"
|
216
|
+
)
|
217
|
+
d3.spawn( load_balance: false )
|
218
|
+
preferred = d3.url.split( ':' ).first
|
219
|
+
|
220
|
+
expect(d3.spawn(strategy: :horizontal )['url'].split( ':' ).first).to eq(preferred)
|
221
|
+
expect(%W{127.0.0.3 127.0.0.2}).to include d1.spawn['url'].split( ':' ).first
|
222
|
+
expect(d2.spawn(strategy: :horizontal )['url'].split( ':' ).first).to eq(preferred)
|
223
|
+
expect(%W{127.0.0.1 127.0.0.3}).to include d3.spawn(strategy: :horizontal )['url'].split( ':' ).first
|
224
|
+
expect(%W{127.0.0.2 127.0.0.3}).to include d3.spawn(strategy: :horizontal )['url'].split( ':' ).first
|
225
|
+
expect(%W{127.0.0.2 127.0.0.3}).to include d1.spawn(strategy: :horizontal )['url'].split( ':' ).first
|
226
|
+
end
|
165
227
|
end
|
166
228
|
|
167
|
-
|
168
|
-
|
169
|
-
|
170
|
-
|
171
|
-
|
229
|
+
context :vertical do
|
230
|
+
it 'provides Instances from the most burdened Agent' do
|
231
|
+
d1 = agent_spawn(
|
232
|
+
address: '127.0.0.1',
|
233
|
+
application: "#{fixtures_path}/mock_app.rb"
|
234
|
+
)
|
235
|
+
|
236
|
+
3.times do
|
237
|
+
d1.spawn( load_balance: false )
|
238
|
+
end
|
239
|
+
|
240
|
+
d2 = agent_spawn(
|
241
|
+
address: '127.0.0.2',
|
242
|
+
peer: d1.url,
|
243
|
+
application: "#{fixtures_path}/mock_app.rb"
|
244
|
+
)
|
245
|
+
|
246
|
+
2.times do
|
247
|
+
d2.spawn( load_balance: false )
|
248
|
+
end
|
249
|
+
|
250
|
+
d3 = agent_spawn(
|
251
|
+
address: '127.0.0.3',
|
252
|
+
peer: d1.url,
|
253
|
+
application: "#{fixtures_path}/mock_app.rb"
|
254
|
+
)
|
255
|
+
d3.spawn( load_balance: false )
|
172
256
|
|
173
|
-
|
174
|
-
|
257
|
+
preferred = d1.url.split( ':' ).first
|
258
|
+
expect(d3.spawn( strategy: :vertical )['url'].split( ':' ).first).to eq(preferred)
|
259
|
+
end
|
175
260
|
end
|
176
261
|
|
177
|
-
|
178
|
-
|
179
|
-
|
180
|
-
|
181
|
-
|
182
|
-
|
183
|
-
|
184
|
-
|
185
|
-
|
186
|
-
|
187
|
-
|
188
|
-
|
189
|
-
|
190
|
-
|
262
|
+
context 'default' do
|
263
|
+
it 'provides Instances from the least burdened Agent' do
|
264
|
+
d1 = agent_spawn(
|
265
|
+
address: '127.0.0.1',
|
266
|
+
application: "#{fixtures_path}/mock_app.rb"
|
267
|
+
)
|
268
|
+
|
269
|
+
3.times do
|
270
|
+
d1.spawn( load_balance: false )
|
271
|
+
end
|
272
|
+
|
273
|
+
d2 = agent_spawn(
|
274
|
+
address: '127.0.0.2',
|
275
|
+
peer: d1.url,
|
276
|
+
application: "#{fixtures_path}/mock_app.rb"
|
277
|
+
)
|
278
|
+
|
279
|
+
2.times do
|
280
|
+
d2.spawn( load_balance: false )
|
281
|
+
end
|
282
|
+
|
283
|
+
d3 = agent_spawn(
|
284
|
+
address: '127.0.0.3',
|
285
|
+
peer: d1.url,
|
286
|
+
application: "#{fixtures_path}/mock_app.rb"
|
287
|
+
)
|
288
|
+
d3.spawn( load_balance: false )
|
289
|
+
preferred = d3.url.split( ':' ).first
|
290
|
+
|
291
|
+
expect(d3.spawn['url'].split( ':' ).first).to eq(preferred)
|
292
|
+
expect(%W{127.0.0.3 127.0.0.2}).to include d1.spawn['url'].split( ':' ).first
|
293
|
+
expect(d2.spawn['url'].split( ':' ).first).to eq(preferred)
|
294
|
+
expect(%W{127.0.0.1 127.0.0.3}).to include d3.spawn['url'].split( ':' ).first
|
295
|
+
expect(%W{127.0.0.2 127.0.0.3}).to include d3.spawn['url'].split( ':' ).first
|
296
|
+
expect(%W{127.0.0.2 127.0.0.3}).to include d1.spawn['url'].split( ':' ).first
|
297
|
+
end
|
298
|
+
end
|
299
|
+
|
300
|
+
context 'other' do
|
301
|
+
it 'returns :error_unknown_strategy' do
|
302
|
+
expect(agent_spawn( peer: subject.url ).
|
303
|
+
spawn( strategy: 'blah' )).to eq('error_unknown_strategy')
|
304
|
+
end
|
305
|
+
end
|
191
306
|
end
|
192
307
|
|
193
308
|
context 'when the load-balance option is set to false' do
|
194
|
-
it 'returns an Instance from the requested
|
195
|
-
d1 =
|
309
|
+
it 'returns an Instance from the requested Agent' do
|
310
|
+
d1 = agent_spawn(
|
196
311
|
address: '127.0.0.1',
|
197
312
|
application: "#{fixtures_path}/mock_app.rb"
|
198
313
|
)
|
199
314
|
|
200
|
-
d1.
|
315
|
+
d1.spawn( load_balance: false )
|
201
316
|
|
202
|
-
d2 =
|
317
|
+
d2 = agent_spawn(
|
203
318
|
address: '127.0.0.2',
|
204
|
-
|
319
|
+
peer: d1.url,
|
205
320
|
application: "#{fixtures_path}/mock_app.rb"
|
206
321
|
)
|
207
|
-
d2.
|
322
|
+
d2.spawn( load_balance: false )
|
208
323
|
|
209
|
-
d3 =
|
324
|
+
d3 = agent_spawn(
|
210
325
|
address: '127.0.0.3',
|
211
|
-
|
326
|
+
peer: d1.url,
|
212
327
|
application: "#{fixtures_path}/mock_app.rb"
|
213
328
|
)
|
214
329
|
2.times do
|
215
|
-
d3.
|
330
|
+
d3.spawn( load_balance: false )
|
216
331
|
end
|
217
332
|
|
218
|
-
expect(d3.
|
333
|
+
expect(d3.spawn( load_balance: false )['url'].
|
219
334
|
split( ':' ).first).to eq('127.0.0.3')
|
220
335
|
end
|
221
336
|
end
|
@@ -224,7 +339,7 @@ describe Cuboid::RPC::Server::Dispatcher do
|
|
224
339
|
|
225
340
|
describe '#instance' do
|
226
341
|
it 'returns proc info by PID' do
|
227
|
-
instance = subject.
|
342
|
+
instance = subject.spawn( owner: 'rspec' )
|
228
343
|
info = subject.instance( instance['pid'] )
|
229
344
|
instance_info_keys.each do |k|
|
230
345
|
expect(info[k]).to be_truthy
|
@@ -234,7 +349,7 @@ describe Cuboid::RPC::Server::Dispatcher do
|
|
234
349
|
|
235
350
|
describe '#instances' do
|
236
351
|
it 'returns proc info by PID for all instances' do
|
237
|
-
slots.times { subject.
|
352
|
+
slots.times { subject.spawn( owner: 'rspec' ) }
|
238
353
|
|
239
354
|
subject.instances.each do |instance|
|
240
355
|
instance_info_keys.each do |k|
|
@@ -246,7 +361,7 @@ describe Cuboid::RPC::Server::Dispatcher do
|
|
246
361
|
|
247
362
|
describe '#running_instances' do
|
248
363
|
it 'returns proc info for running instances' do
|
249
|
-
slots.times { subject.
|
364
|
+
slots.times { subject.spawn }
|
250
365
|
|
251
366
|
expect(subject.running_instances.size).to eq(slots)
|
252
367
|
end
|
@@ -254,7 +369,7 @@ describe Cuboid::RPC::Server::Dispatcher do
|
|
254
369
|
|
255
370
|
describe '#finished_instances' do
|
256
371
|
it 'returns proc info for finished instances' do
|
257
|
-
3.times { Cuboid::Processes::Manager.kill subject.
|
372
|
+
3.times { Cuboid::Processes::Manager.kill subject.spawn['pid'] }
|
258
373
|
|
259
374
|
expect(subject.finished_instances.size).to eq(3)
|
260
375
|
end
|
@@ -263,7 +378,7 @@ describe Cuboid::RPC::Server::Dispatcher do
|
|
263
378
|
describe '#utilization' do
|
264
379
|
it 'returns a float signifying the amount of workload' do
|
265
380
|
3.times do
|
266
|
-
subject.
|
381
|
+
subject.spawn
|
267
382
|
end
|
268
383
|
|
269
384
|
expect(subject.utilization).to eq(3 / Float(slots))
|
@@ -272,7 +387,7 @@ describe Cuboid::RPC::Server::Dispatcher do
|
|
272
387
|
|
273
388
|
describe '#statistics' do
|
274
389
|
it 'returns general statistics' do
|
275
|
-
subject.
|
390
|
+
subject.spawn
|
276
391
|
instances = subject.instances
|
277
392
|
Cuboid::Processes::Manager.kill( instances.first['pid'] )
|
278
393
|
|
@@ -291,7 +406,7 @@ describe Cuboid::RPC::Server::Dispatcher do
|
|
291
406
|
|
292
407
|
context 'when there are snapshots' do
|
293
408
|
it 'lists them' do
|
294
|
-
info = subject.
|
409
|
+
info = subject.spawn
|
295
410
|
|
296
411
|
instance = Cuboid::RPC::Client::Instance.new(
|
297
412
|
info['url'], info['token']
|
@@ -52,20 +52,20 @@ describe Cuboid::RPC::Server::Scheduler do
|
|
52
52
|
end
|
53
53
|
end
|
54
54
|
|
55
|
-
context 'when a
|
56
|
-
subject { Cuboid::Processes::Schedulers.spawn
|
57
|
-
let(:
|
58
|
-
Cuboid::Processes::
|
55
|
+
context 'when a Agent has been set' do
|
56
|
+
subject { Cuboid::Processes::Schedulers.spawn agent: agent.url }
|
57
|
+
let(:agent) do
|
58
|
+
Cuboid::Processes::Agents.spawn( application: "#{fixtures_path}/mock_app.rb" )
|
59
59
|
end
|
60
60
|
|
61
61
|
it 'gets Instances from it' do
|
62
|
-
expect(
|
62
|
+
expect(agent.finished_instances).to be_empty
|
63
63
|
|
64
64
|
subject.push( options )
|
65
65
|
sleep 0.1 while subject.completed.empty?
|
66
66
|
sleep 2
|
67
67
|
|
68
|
-
expect(
|
68
|
+
expect(agent.finished_instances).to be_any
|
69
69
|
end
|
70
70
|
|
71
71
|
it 'sets OptionGroups::Scheduler#url' do
|
@@ -80,7 +80,7 @@ describe Cuboid::RPC::Server::Scheduler do
|
|
80
80
|
it 'does not consume the queue' do
|
81
81
|
subject
|
82
82
|
|
83
|
-
Cuboid::Processes::
|
83
|
+
Cuboid::Processes::Agents.killall
|
84
84
|
sleep 3
|
85
85
|
|
86
86
|
expect(subject.size).to be 0
|
@@ -89,7 +89,7 @@ describe Cuboid::RPC::Server::Scheduler do
|
|
89
89
|
sleep 5
|
90
90
|
|
91
91
|
expect(subject.size).to be 1
|
92
|
-
expect(subject.errors.join("\n")).to include "Failed to contact
|
92
|
+
expect(subject.errors.join("\n")).to include "Failed to contact Agent at: #{agent.url}"
|
93
93
|
end
|
94
94
|
end
|
95
95
|
end
|
@@ -1,14 +1,14 @@
|
|
1
1
|
require Options.paths.lib + 'ui/output'
|
2
|
-
require Options.paths.lib + 'rpc/server/
|
2
|
+
require Options.paths.lib + 'rpc/server/agent'
|
3
3
|
require Options.paths.lib + 'processes/manager'
|
4
4
|
|
5
|
-
class Node < Cuboid::RPC::Server::
|
5
|
+
class Node < Cuboid::RPC::Server::Agent::Node
|
6
6
|
|
7
7
|
def initialize
|
8
8
|
@options = Options.instance
|
9
9
|
|
10
10
|
methods.each do |m|
|
11
|
-
next if method( m ).owner != Cuboid::RPC::Server::
|
11
|
+
next if method( m ).owner != Cuboid::RPC::Server::Agent::Node
|
12
12
|
self.class.send :private, m
|
13
13
|
self.class.send :public, m
|
14
14
|
end
|
@@ -1,20 +1,20 @@
|
|
1
|
-
require 'cuboid/rpc/server/
|
1
|
+
require 'cuboid/rpc/server/agent'
|
2
2
|
|
3
|
-
class TestService < Cuboid::RPC::Server::
|
3
|
+
class TestService < Cuboid::RPC::Server::Agent::Service
|
4
4
|
|
5
5
|
private :instances
|
6
6
|
public :instances
|
7
7
|
|
8
|
-
def
|
9
|
-
|
8
|
+
def test_agent
|
9
|
+
agent.class == Cuboid::RPC::Server::Agent
|
10
10
|
end
|
11
11
|
|
12
12
|
def test_opts
|
13
|
-
|
13
|
+
agent.instance_eval{ @options } == options
|
14
14
|
end
|
15
15
|
|
16
16
|
def test_node
|
17
|
-
node.class == Cuboid::RPC::Server::
|
17
|
+
node.class == Cuboid::RPC::Server::Agent::Node
|
18
18
|
end
|
19
19
|
|
20
20
|
def test_map_instances( &block )
|
@@ -39,8 +39,8 @@ class TestService < Cuboid::RPC::Server::Dispatcher::Service
|
|
39
39
|
iterator_for( instances ).class == Arachni::Reactor::Iterator
|
40
40
|
end
|
41
41
|
|
42
|
-
def
|
43
|
-
|
42
|
+
def test_connect_to_agent( url, &block )
|
43
|
+
connect_to_agent( url ).alive? { |b| block.call b }
|
44
44
|
end
|
45
45
|
|
46
46
|
def test_connect_to_instance( *args, &block )
|
@@ -1,15 +1,15 @@
|
|
1
|
-
class Cuboid::RPC::Server::
|
1
|
+
class Cuboid::RPC::Server::Agent
|
2
2
|
class Service::Echo < Service
|
3
3
|
|
4
4
|
private :instances
|
5
5
|
public :instances
|
6
6
|
|
7
|
-
def
|
8
|
-
|
7
|
+
def test_agent
|
8
|
+
agent.class == Cuboid::RPC::Server::Agent
|
9
9
|
end
|
10
10
|
|
11
11
|
def test_opts
|
12
|
-
|
12
|
+
agent.instance_eval{ @options } == options
|
13
13
|
end
|
14
14
|
|
15
15
|
def test_node
|
@@ -38,8 +38,8 @@ class Service::Echo < Service
|
|
38
38
|
iterator_for( instances ).class == Arachni::Reactor::Iterator
|
39
39
|
end
|
40
40
|
|
41
|
-
def
|
42
|
-
|
41
|
+
def test_connect_to_agent( url, &block )
|
42
|
+
connect_to_agent( url ).alive? { |b| block.call b }
|
43
43
|
end
|
44
44
|
|
45
45
|
def test_connect_to_instance( *args, &block )
|
@@ -2,9 +2,9 @@ require 'arachni/rpc'
|
|
2
2
|
|
3
3
|
# @note Needs `ENV['WEB_SERVER_DISPATCHER']` in the format of `host:port`.
|
4
4
|
#
|
5
|
-
# {WebServerManager}-API-compatible client for the {
|
5
|
+
# {WebServerManager}-API-compatible client for the {WebServerAgent}.
|
6
6
|
#
|
7
|
-
# Delegates test webserver creation to the machine running {
|
7
|
+
# Delegates test webserver creation to the machine running {WebServerAgent},
|
8
8
|
# for hosts that lack support for fast servers (like Windows, which can't run
|
9
9
|
# Thin, Puma etc.).
|
10
10
|
#
|
@@ -9,7 +9,7 @@ require 'arachni/rpc'
|
|
9
9
|
# Exposes the {WebServerManager} over RPC.
|
10
10
|
#
|
11
11
|
# @author Tasos "Zapotek" Laskos <tasos.laskos@gmail.com>
|
12
|
-
class
|
12
|
+
class WebServerAgent
|
13
13
|
|
14
14
|
def initialize( options = {} )
|
15
15
|
host, port = ENV['WEB_SERVER_DISPATCHER'].split( ':' )
|