rrrspec-server 0.4.2 → 0.4.3

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 8b1b9535524848e0a99da3e43112dd61f7172857
4
- data.tar.gz: bcd9b01442e53052e1d7b8fbdc2f5e8e6657f79d
3
+ metadata.gz: 9625ccb0410299f07a3d0ef6930c82b5098e988d
4
+ data.tar.gz: 53072551cd5d091fde57fe140c13fcd7bca9604e
5
5
  SHA512:
6
- metadata.gz: 5c6cd8ede5b4b339b584f2bade3a4ce24b732be8b04478beecd7251234a43310b40f73e700940109dc3e06ce2eb45130cd40298018b2f7b0714765d3440c04a1
7
- data.tar.gz: 0018d23b28093ea4177556bf4bb1a1e40b4ad1b10c4179c863ec42a5b27b354f584799baf0e037d96b448bd026c76a8eb9443248182cbc12e82438f39661b01c
6
+ metadata.gz: 59b97dbd4247ff5596a2274eb40f1b5cea27142421de0d983853087ef186e5d2bd385b8bec4c58359e8b473937bf6149a2ec55b9f36b0af63414659d8e87a189
7
+ data.tar.gz: 4b4089c4edd6c9d966a20333c6d8ce16bd91ed2457de6098ad2fcbabf708c90dc6efd229378b15b787741ca0748e1ac855a24f847af74d5e96c6e592ff3276af
@@ -17,7 +17,6 @@ module RRRSpec
17
17
  end
18
18
  Process.daemon(false, true)
19
19
  File.write(pidfile, Process.pid.to_s)
20
- File.umask(0)
21
20
  setup_signal_handlers
22
21
  setup_atexit_handlers(pidfile)
23
22
  monitor_fork do
@@ -71,7 +71,7 @@ module RRRSpec
71
71
  h.delete('taskset')
72
72
  h.delete('trials')
73
73
  p_task = Persistence::Task.new(h)
74
- p_task.taskset_id = p_taskset
74
+ p_task.taskset_id = p_taskset.id
75
75
  p_task
76
76
  end
77
77
  Persistence::Task.import(p_tasks)
@@ -92,8 +92,8 @@ module RRRSpec
92
92
  slave_key = h.delete('slave')['key']
93
93
  h.delete('task')
94
94
  p_trial = Persistence::Trial.new(h)
95
- p_trial.task_id = p_task
96
- p_trial.slave_id = p_slaves[slave_key]
95
+ p_trial.task_id = p_task.id
96
+ p_trial.slave_id = p_slaves[slave_key].id
97
97
 
98
98
  p_trials << p_trial
99
99
  end
@@ -109,7 +109,7 @@ module RRRSpec
109
109
  h.delete('worker')
110
110
  h.delete('taskset')
111
111
  p_worker_log = Persistence::WorkerLog.new(h)
112
- p_worker_log.taskset_id = p_taskset
112
+ p_worker_log.taskset_id = p_taskset.id
113
113
  p_worker_log
114
114
  end
115
115
  Persistence::WorkerLog.import(p_worker_logs)
@@ -1,5 +1,5 @@
1
1
  module RRRSpec
2
2
  module Server
3
- VERSION = "0.4.2"
3
+ VERSION = "0.4.3"
4
4
  end
5
5
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rrrspec-server
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.4.2
4
+ version: 0.4.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - Masaya Suzuki
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2015-11-30 00:00:00.000000000 Z
11
+ date: 2016-06-28 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: database_cleaner
@@ -98,36 +98,30 @@ dependencies:
98
98
  name: activerecord
99
99
  requirement: !ruby/object:Gem::Requirement
100
100
  requirements:
101
- - - ">="
102
- - !ruby/object:Gem::Version
103
- version: '4.0'
104
- - - "<"
101
+ - - "~>"
105
102
  - !ruby/object:Gem::Version
106
- version: '4.2'
103
+ version: 4.2.0
107
104
  type: :runtime
108
105
  prerelease: false
109
106
  version_requirements: !ruby/object:Gem::Requirement
110
107
  requirements:
111
- - - ">="
112
- - !ruby/object:Gem::Version
113
- version: '4.0'
114
- - - "<"
108
+ - - "~>"
115
109
  - !ruby/object:Gem::Version
116
- version: '4.2'
110
+ version: 4.2.0
117
111
  - !ruby/object:Gem::Dependency
118
112
  name: activerecord-import
119
113
  requirement: !ruby/object:Gem::Requirement
120
114
  requirements:
121
- - - "~>"
115
+ - - ">="
122
116
  - !ruby/object:Gem::Version
123
- version: 0.4.1
117
+ version: 0.7.0
124
118
  type: :runtime
125
119
  prerelease: false
126
120
  version_requirements: !ruby/object:Gem::Requirement
127
121
  requirements:
128
- - - "~>"
122
+ - - ">="
129
123
  - !ruby/object:Gem::Version
130
- version: 0.4.1
124
+ version: 0.7.0
131
125
  - !ruby/object:Gem::Dependency
132
126
  name: activesupport
133
127
  requirement: !ruby/object:Gem::Requirement
@@ -204,14 +198,14 @@ dependencies:
204
198
  requirements:
205
199
  - - ">="
206
200
  - !ruby/object:Gem::Version
207
- version: '0'
201
+ version: 0.18.0
208
202
  type: :runtime
209
203
  prerelease: false
210
204
  version_requirements: !ruby/object:Gem::Requirement
211
205
  requirements:
212
206
  - - ">="
213
207
  - !ruby/object:Gem::Version
214
- version: '0'
208
+ version: 0.18.0
215
209
  description: Execute RSpec in a distributed manner
216
210
  email:
217
211
  - draftcode@gmail.com
@@ -220,9 +214,6 @@ executables:
220
214
  extensions: []
221
215
  extra_rdoc_files: []
222
216
  files:
223
- - ".rspec"
224
- - Gemfile
225
- - Rakefile
226
217
  - bin/rrrspec-server
227
218
  - db/migrate/20131105050718_create_tables.rb
228
219
  - db/migrate/20140221062741_expand_log.rb
@@ -241,15 +232,6 @@ files:
241
232
  - lib/rrrspec/server/statistics_updater.rb
242
233
  - lib/rrrspec/server/version.rb
243
234
  - lib/rrrspec/server/worker_runner.rb
244
- - rrrspec-server.gemspec
245
- - spec/fixture.rb
246
- - spec/rrrspec/server/arbiter_spec.rb
247
- - spec/rrrspec/server/dispatcher_spec.rb
248
- - spec/rrrspec/server/log_file_persister_spec.rb
249
- - spec/rrrspec/server/persistent_models_spec.rb
250
- - spec/rrrspec/server/persister_spec.rb
251
- - spec/rrrspec/server/statistics_updater_spec.rb
252
- - spec/spec_helper.rb
253
235
  - tasks/db.rake
254
236
  homepage: https://github.com/cookpad/rrrspec
255
237
  licenses:
@@ -271,16 +253,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
271
253
  version: '0'
272
254
  requirements: []
273
255
  rubyforge_project:
274
- rubygems_version: 2.4.5.1
256
+ rubygems_version: 2.5.1
275
257
  signing_key:
276
258
  specification_version: 4
277
259
  summary: Execute RSpec in a distributed manner
278
- test_files:
279
- - spec/fixture.rb
280
- - spec/rrrspec/server/arbiter_spec.rb
281
- - spec/rrrspec/server/dispatcher_spec.rb
282
- - spec/rrrspec/server/log_file_persister_spec.rb
283
- - spec/rrrspec/server/persistent_models_spec.rb
284
- - spec/rrrspec/server/persister_spec.rb
285
- - spec/rrrspec/server/statistics_updater_spec.rb
286
- - spec/spec_helper.rb
260
+ test_files: []
data/.rspec DELETED
@@ -1,2 +0,0 @@
1
- --color
2
- --format progress
data/Gemfile DELETED
@@ -1,4 +0,0 @@
1
- source 'https://rubygems.org'
2
-
3
- gem 'rrrspec-client', path: '../'
4
- gemspec
data/Rakefile DELETED
@@ -1,2 +0,0 @@
1
- require "bundler/gem_tasks"
2
- load File.expand_path('../tasks/db.rake', __FILE__)
@@ -1,40 +0,0 @@
1
- # coding: utf-8
2
- lib = File.expand_path('../lib', __FILE__)
3
- $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
- require 'rrrspec/server/version'
5
- require 'pathname'
6
-
7
- Gem::Specification.new do |spec|
8
- spec.name = "rrrspec-server"
9
- spec.version = RRRSpec::Server::VERSION
10
- spec.authors = ["Masaya Suzuki"]
11
- spec.email = ["draftcode@gmail.com"]
12
- spec.description = "Execute RSpec in a distributed manner"
13
- spec.summary = "Execute RSpec in a distributed manner"
14
- spec.homepage = "https://github.com/cookpad/rrrspec"
15
- spec.license = "MIT"
16
-
17
- gemspec_dir = File.expand_path('..', __FILE__)
18
- spec.files = `git ls-files`.split($/).
19
- map { |f| File.absolute_path(f) }.
20
- select { |f| f.start_with?(gemspec_dir) }.
21
- map { |f| Pathname(f).relative_path_from(Pathname(gemspec_dir)).to_s }
22
- spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
23
- spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
24
- spec.require_paths = ["lib"]
25
-
26
- spec.add_development_dependency "database_cleaner", "~> 1.2.0"
27
- spec.add_development_dependency "mysql2"
28
- spec.add_development_dependency "rake"
29
- spec.add_development_dependency "rspec"
30
- spec.add_development_dependency "sqlite3"
31
- spec.add_development_dependency "timecop"
32
- spec.add_dependency "activerecord", ">= 4.0", "< 4.2"
33
- spec.add_dependency "activerecord-import", "~> 0.4.1"
34
- spec.add_dependency "activesupport"
35
- spec.add_dependency "bundler"
36
- spec.add_dependency "facter"
37
- spec.add_dependency "redis"
38
- spec.add_dependency "rrrspec-client"
39
- spec.add_dependency "thor"
40
- end
@@ -1,32 +0,0 @@
1
- module RRRSpec
2
- def self.finished_fullset
3
- worker = Worker.create('default')
4
- taskset = Taskset.create(
5
- 'testuser', 'echo 1', 'echo 2', 'default', 'default', 3, 3, 5, 5
6
- )
7
- task = Task.create(taskset, 10, 'spec/test_spec.rb')
8
- taskset.add_task(task)
9
- taskset.enqueue_task(task)
10
- ActiveTaskset.add(taskset)
11
- worker_log = WorkerLog.create(worker, taskset)
12
- worker_log.set_rsync_finished_time
13
- worker_log.append_log('worker_log log body')
14
- worker_log.set_setup_finished_time
15
- slave = Slave.create
16
- taskset.add_slave(slave)
17
- slave.append_log('slave log body')
18
- trial = Trial.create(task, slave)
19
- trial.start
20
- trial.finish('pending', 'stdout body', 'stderr body', 10, 2, 0)
21
- task.update_status('pending')
22
- taskset.incr_succeeded_count
23
- taskset.finish_task(task)
24
- taskset.update_status('succeeded')
25
- taskset.set_finished_time
26
- ActiveTaskset.remove(taskset)
27
- slave.update_status('normal_exit')
28
- worker_log.set_finished_time
29
-
30
- return worker, taskset, task, worker_log, slave, trial
31
- end
32
- end
@@ -1,497 +0,0 @@
1
- require 'spec_helper'
2
-
3
- module RRRSpec
4
- module Server
5
- RSpec.describe Arbiter do
6
- before do
7
- RRRSpec.configuration = Configuration.new
8
- RRRSpec.configuration.redis = @redis
9
- end
10
-
11
- let(:taskset) do
12
- Taskset.create(
13
- 'testuser', 'echo 1', 'echo 2', 'default', 'default', 3, 3, 5, 5
14
- )
15
- end
16
-
17
- let(:task1) do
18
- Task.create(taskset, 10, 'spec/test_spec.rb')
19
- end
20
-
21
- before do
22
- ActiveTaskset.add(taskset)
23
- end
24
-
25
- describe '.cancel' do
26
- context 'with the taskset running' do
27
- before { taskset.update_status('running') }
28
-
29
- it 'cancels the taskset' do
30
- Arbiter.cancel(taskset)
31
- expect(taskset.status).to eq('cancelled')
32
- expect(taskset).to be_queue_empty
33
- expect(taskset.finished_at).not_to be_nil
34
- expect(ActiveTaskset.list).not_to include(taskset)
35
- expect(PersisterQueue).not_to be_empty
36
- end
37
- end
38
-
39
- context 'with the taskset failed' do
40
- before { taskset.update_status('failed') }
41
-
42
- it 'does nothing' do
43
- Arbiter.cancel(taskset)
44
- expect(taskset.status).not_to eq('cancelled')
45
- expect(ActiveTaskset.list).not_to include(taskset)
46
- expect(PersisterQueue).not_to be_empty
47
- end
48
- end
49
- end
50
-
51
- describe '.check' do
52
- before do
53
- taskset.add_task(task1)
54
- taskset.enqueue_task(task1)
55
- end
56
-
57
- context 'when the taskset is succeeded or failed or cancelled' do
58
- before { taskset.update_status('failed') }
59
- it 'does nothing' do
60
- Arbiter.check(taskset)
61
- expect(ActiveTaskset.list).not_to include(taskset)
62
- expect(PersisterQueue).not_to be_empty
63
- end
64
- end
65
-
66
- context 'with the taskset running' do
67
- before { taskset.update_status('running') }
68
-
69
- context 'with tasks_left having item' do
70
- it 'calls check_task' do
71
- expect(Arbiter).to receive(:check_task)
72
- Arbiter.check(taskset)
73
- end
74
- end
75
-
76
- context 'with tasks_left non-empty after check_task' do
77
- context 'with the queue empty' do
78
- before do
79
- taskset.dequeue_task(0)
80
- end
81
- it 'calls requeue_speculative' do
82
- expect(Arbiter).to receive(:requeue_speculative)
83
- Arbiter.check(taskset)
84
- end
85
- end
86
-
87
- context 'with the queue non-empty' do
88
- it 'does nothing' do
89
- Arbiter.check(taskset)
90
- expect(taskset.status).to eq('running')
91
- expect(taskset.finished_at).to be_blank
92
- expect(ActiveTaskset.list).to include(taskset)
93
- expect(PersisterQueue).to be_empty
94
- end
95
- end
96
- end
97
-
98
- context 'with tasks_left empty after check_task' do
99
- before { taskset.finish_task(task1) }
100
-
101
- context 'with all tasks succeeded' do
102
- before { taskset.incr_succeeded_count }
103
-
104
- it 'marks the taskset as succeeded' do
105
- Arbiter.check(taskset)
106
- expect(taskset.status).to eq("succeeded")
107
- expect(taskset.finished_at).not_to be_blank
108
- expect(ActiveTaskset.list).not_to include(taskset)
109
- expect(PersisterQueue).not_to be_empty
110
- end
111
- end
112
-
113
- context 'with some tasks failed' do
114
- before { taskset.incr_failed_count }
115
-
116
- it 'marks the taskset as failed' do
117
- Arbiter.check(taskset)
118
- expect(taskset.status).to eq("failed")
119
- expect(taskset.finished_at).not_to be_nil
120
- expect(ActiveTaskset.list).not_to include(taskset)
121
- expect(PersisterQueue).not_to be_empty
122
- end
123
- end
124
- end
125
- end
126
- end
127
-
128
- describe '.check_task' do
129
- before do
130
- taskset.add_task(task1)
131
- taskset.enqueue_task(task1)
132
- end
133
-
134
- let(:logger) { TimedLogger.new(taskset) }
135
- let(:slave) { Slave.create }
136
-
137
- context 'with some trials running' do
138
- let(:trial1) { Trial.create(task1, slave) }
139
-
140
- before do
141
- trial1.start
142
- end
143
-
144
- context 'with the slave alive' do
145
- before { slave.heartbeat(30) }
146
-
147
- it 'does nothing' do
148
- Arbiter.check_task(logger, taskset, task1)
149
- expect(trial1.status).to be_blank
150
- end
151
- end
152
-
153
- context 'with the slave failed' do
154
- it 'marks error' do
155
- Arbiter.check_task(logger, taskset, task1)
156
- expect(trial1.status).to eq('error')
157
- end
158
- end
159
- end
160
-
161
- context 'with a trial passed' do
162
- let(:trial1) { Trial.create(task1, slave) }
163
- let(:trial2) { Trial.create(task1, slave) }
164
-
165
- before do
166
- trial1.start
167
- trial1.finish('passed', '', '', nil, nil, nil)
168
- trial2.start
169
- trial2.finish('error', '', '', nil, nil, nil)
170
- end
171
-
172
- it 'sets status passed' do
173
- Arbiter.check_task(logger, taskset, task1)
174
- expect(task1.status).to eq('passed')
175
- expect(taskset.tasks_left).not_to include(task1)
176
- expect(taskset.succeeded_count).to eq(1)
177
- expect(taskset.failed_count).to eq(0)
178
- end
179
- end
180
-
181
- context 'with a trial pending' do
182
- let(:trial1) { Trial.create(task1, slave) }
183
- let(:trial2) { Trial.create(task1, slave) }
184
-
185
- before do
186
- trial1.start
187
- trial1.finish('pending', '', '', nil, nil, nil)
188
- trial2.start
189
- trial2.finish('error', '', '', nil, nil, nil)
190
- end
191
-
192
- it 'sets status pending' do
193
- Arbiter.check_task(logger, taskset, task1)
194
- expect(task1.status).to eq('pending')
195
- expect(taskset.tasks_left).not_to include(task1)
196
- expect(taskset.succeeded_count).to eq(1)
197
- expect(taskset.failed_count).to eq(0)
198
- end
199
- end
200
-
201
- context 'with the task fully tried' do
202
- let(:trial1) { Trial.create(task1, slave) }
203
- let(:trial2) { Trial.create(task1, slave) }
204
- let(:trial3) { Trial.create(task1, slave) }
205
-
206
- before do
207
- trial1.start
208
- trial1.finish('error', '', '', nil, nil, nil)
209
- trial2.start
210
- trial2.finish('error', '', '', nil, nil, nil)
211
- trial3.start
212
- trial3.finish('error', '', '', nil, nil, nil)
213
- end
214
-
215
- it 'marks failed' do
216
- Arbiter.check_task(logger, taskset, task1)
217
- expect(task1.status).to eq('failed')
218
- expect(taskset.tasks_left).not_to include(task1)
219
- expect(taskset.succeeded_count).to eq(0)
220
- expect(taskset.failed_count).to eq(1)
221
- end
222
- end
223
-
224
- context 'when re-triable' do
225
- let(:trial1) { Trial.create(task1, slave) }
226
- let(:trial2) { Trial.create(task1, slave) }
227
-
228
- before do
229
- trial1.start
230
- trial1.finish('error', '', '', nil, nil, nil)
231
- trial2.start
232
- trial2.finish('error', '', '', nil, nil, nil)
233
- end
234
-
235
- it 'does nothing' do
236
- Arbiter.check_task(logger, taskset, task1)
237
- expect(task1.status).to be_blank
238
- expect(taskset.tasks_left).to include(task1)
239
- expect(taskset.succeeded_count).to eq(0)
240
- expect(taskset.failed_count).to eq(0)
241
- end
242
- end
243
- end
244
-
245
- describe '.requeue_speculative' do
246
- let(:logger) { TimedLogger.new(taskset) }
247
- let(:slave) { Slave.create }
248
-
249
- let(:task2) do
250
- Task.create(taskset, 10, 'spec/test_spec2.rb')
251
- end
252
-
253
- before do
254
- taskset.add_task(task1)
255
- taskset.add_task(task2)
256
- end
257
-
258
- context 'with some no-running-trial tasks' do
259
- let(:trial1_1) { Trial.create(task1, slave) }
260
-
261
- before do
262
- trial1_1.start
263
- end
264
-
265
- it 'enqueues one no-running-trial task' do
266
- Arbiter.requeue_speculative(logger, taskset, [task1, task2])
267
- expect(taskset).not_to be_queue_empty
268
- expect(taskset.dequeue_task(0)).to eq(task2)
269
- end
270
- end
271
-
272
- context 'with all tasks running' do
273
- let(:trial1_1) { Trial.create(task1, slave) }
274
- let(:trial1_2) { Trial.create(task2, slave) }
275
- let(:trial2_2) { Trial.create(task2, slave) }
276
-
277
- before do
278
- trial1_1.start
279
- trial1_2.start
280
- trial2_2.start
281
- end
282
-
283
- it 'enqueues one least tried task' do
284
- Arbiter.requeue_speculative(logger, taskset, [task1, task2])
285
- expect(taskset).not_to be_queue_empty
286
- expect(taskset.dequeue_task(0)).to eq(task1)
287
- end
288
- end
289
- end
290
-
291
- describe '.fail' do
292
- context 'with the taskset running' do
293
- before { taskset.update_status('running') }
294
-
295
- it 'fails the taskset' do
296
- Arbiter.fail(taskset)
297
- expect(taskset.status).to eq('failed')
298
- expect(taskset).to be_queue_empty
299
- expect(taskset.finished_at).not_to be_nil
300
- expect(ActiveTaskset.list).not_to include(taskset)
301
- expect(PersisterQueue).not_to be_empty
302
- end
303
- end
304
-
305
- context 'with the taskset cancelled' do
306
- before { taskset.update_status('cancelled') }
307
-
308
- it 'does nothing' do
309
- Arbiter.fail(taskset)
310
- expect(taskset.status).not_to eq('failed')
311
- expect(ActiveTaskset.list).not_to include(taskset)
312
- expect(PersisterQueue).not_to be_empty
313
- end
314
- end
315
- end
316
-
317
- describe '.trial' do
318
- before do
319
- taskset.add_task(task1)
320
- taskset.enqueue_task(task1)
321
- end
322
-
323
- before do
324
- taskset.dequeue_task(0)
325
- end
326
-
327
- let(:slave) { Slave.create }
328
- let(:trial) { Trial.create(task1, slave) }
329
-
330
- context 'when the task is already finished' do
331
- before { task1.update_status('passed') }
332
-
333
- it 'does nothing' do
334
- Arbiter.trial(trial)
335
- expect(trial.status).to be_nil
336
- expect(task1.status).to eq('passed')
337
- end
338
- end
339
-
340
- context 'with the trial not-running' do
341
- context 'with maximally retried' do
342
- let(:trial2) { Trial.create(task1, slave) }
343
- let(:trial3) { Trial.create(task1, slave) }
344
-
345
- before do
346
- trial2.finish('error', '', '', nil, nil, nil)
347
- trial3.finish('error', '', '', nil, nil, nil)
348
- end
349
-
350
- it 'finishes the trial and marks the task failed' do
351
- Arbiter.trial(trial)
352
- expect(trial.status).to eq('error')
353
- expect(task1.status).to eq('failed')
354
- expect(taskset.tasks_left).not_to include(task1)
355
- expect(taskset).to be_queue_empty
356
- expect(taskset.succeeded_count).to eq(0)
357
- expect(taskset.failed_count).to eq(1)
358
- end
359
- end
360
-
361
- context 'when re-triable' do
362
- it 'finishes the trial and requeues the task' do
363
- Arbiter.trial(trial)
364
- expect(trial.status).to eq('error')
365
- expect(task1.status).to be_nil
366
- expect(taskset.tasks_left).to include(task1)
367
- expect(taskset.dequeue_task(0)).to eq(task1)
368
- expect(taskset.succeeded_count).to eq(0)
369
- expect(taskset.failed_count).to eq(0)
370
- end
371
- end
372
- end
373
-
374
- context 'with the trial passed' do
375
- before do
376
- trial.finish('passed', '', '', nil, nil, nil)
377
- end
378
-
379
- it 'marks the task as passed' do
380
- Arbiter.trial(trial)
381
- expect(task1.status).to eq('passed')
382
- expect(taskset.tasks_left).not_to include(task1)
383
- expect(taskset).to be_queue_empty
384
- expect(taskset.succeeded_count).to eq(1)
385
- expect(taskset.failed_count).to eq(0)
386
- end
387
- end
388
-
389
- context 'with the trial pending' do
390
- before { trial.finish('pending', '', '', 0, 1, 0) }
391
-
392
- it 'marks the task as pending' do
393
- Arbiter.trial(trial)
394
- expect(task1.status).to eq('pending')
395
- expect(taskset.tasks_left).not_to include(task1)
396
- expect(taskset).to be_queue_empty
397
- expect(taskset.succeeded_count).to eq(1)
398
- expect(taskset.failed_count).to eq(0)
399
- end
400
- end
401
-
402
- context 'with the trial failed' do
403
- before { trial.finish('failed', '', '', 0, 0, 1) }
404
-
405
- context 'with another trial running' do
406
- let(:trial2) { Trial.create(task1, slave) }
407
-
408
- before { trial2 }
409
-
410
- context 'maximally retried' do
411
- let(:trial3) { Trial.create(task1, slave) }
412
- let(:trial4) { Trial.create(task1, slave) }
413
-
414
- before do
415
- trial3
416
- trial4
417
- end
418
-
419
- context 'enough to judge failed' do
420
- before do
421
- trial3.finish('error', '', '', nil, nil, nil)
422
- trial4.finish('error', '', '', nil, nil, nil)
423
- end
424
-
425
- it 'finishes the trial and marks the task failed' do
426
- Arbiter.trial(trial)
427
- expect(trial.status).to eq('failed')
428
- expect(task1.status).to eq('failed')
429
- expect(taskset.tasks_left).not_to include(task1)
430
- expect(taskset).to be_queue_empty
431
- expect(taskset.succeeded_count).to eq(0)
432
- expect(taskset.failed_count).to eq(1)
433
- end
434
- end
435
-
436
- context 'not-enough to judge failed' do
437
- it 'does nothing' do
438
- Arbiter.trial(trial)
439
- expect(task1.status).to be_blank
440
- expect(taskset.tasks_left).to include(task1)
441
- expect(taskset).to be_queue_empty
442
- expect(taskset.succeeded_count).to eq(0)
443
- expect(taskset.failed_count).to eq(0)
444
- end
445
- end
446
- end
447
-
448
- context 'retriable' do
449
- before do
450
- trial2.finish('error', '', '', nil, nil, nil)
451
- end
452
-
453
- it 'requeue the task' do
454
- Arbiter.trial(trial)
455
- expect(task1.status).to be_nil
456
- expect(taskset.tasks_left).to include(task1)
457
- expect(taskset.dequeue_task(0)).to eq(task1)
458
- expect(taskset.succeeded_count).to eq(0)
459
- expect(taskset.failed_count).to eq(0)
460
- end
461
- end
462
- end
463
-
464
- context 'maximally retried' do
465
- let(:trial2) { Trial.create(task1, slave) }
466
- let(:trial3) { Trial.create(task1, slave) }
467
-
468
- before do
469
- trial2.finish('error', '', '', nil, nil, nil)
470
- trial3.finish('error', '', '', nil, nil, nil)
471
- end
472
-
473
- it 'marks the task as failed' do
474
- Arbiter.trial(trial)
475
- expect(task1.status).to eq('failed')
476
- expect(taskset.tasks_left).not_to include(task1)
477
- expect(taskset).to be_queue_empty
478
- expect(taskset.succeeded_count).to eq(0)
479
- expect(taskset.failed_count).to eq(1)
480
- end
481
- end
482
-
483
- context 'when re-triable' do
484
- it 'requeue the task' do
485
- Arbiter.trial(trial)
486
- expect(task1.status).to be_nil
487
- expect(taskset.tasks_left).to include(task1)
488
- expect(taskset.dequeue_task(0)).to eq(task1)
489
- expect(taskset.succeeded_count).to eq(0)
490
- expect(taskset.failed_count).to eq(0)
491
- end
492
- end
493
- end
494
- end
495
- end
496
- end
497
- end
@@ -1,53 +0,0 @@
1
- require 'spec_helper'
2
-
3
- module RRRSpec
4
- module Server
5
- RSpec.describe Dispatcher do
6
- before do
7
- RRRSpec.configuration = Configuration.new
8
- RRRSpec.configuration.redis = @redis
9
- end
10
-
11
- describe '#work' do
12
- context 'when the worker no longer exists' do
13
- let(:worker) { Worker.create('default', 'hostname1') }
14
- before { worker }
15
-
16
- it 'evicts the worker' do
17
- Dispatcher.work
18
- expect(Worker.list).not_to include(worker)
19
- end
20
- end
21
-
22
- context 'a worker exists' do
23
- let(:taskset) do
24
- Taskset.create(
25
- 'testuser', 'echo 1', 'echo 2', 'default', 'default', 3, 3, 5, 5
26
- )
27
- end
28
-
29
- let(:worker1) { Worker.create('default', 'hostname1') }
30
- let(:worker2) { Worker.create('default', 'hostname2') }
31
- let(:worker3) { Worker.create('default', 'hostname3') }
32
- let(:worker4) { Worker.create('default', 'hostname4') }
33
-
34
- before do
35
- ActiveTaskset.add(taskset)
36
- worker1.update_current_taskset(taskset)
37
- worker1.heartbeat(30)
38
- worker2.heartbeat(30)
39
- worker3.heartbeat(30)
40
- worker4.heartbeat(30)
41
- end
42
-
43
- it 'assignes worker upto the max_workers' do
44
- Dispatcher.work
45
- expect(worker1).to be_queue_empty
46
- workers = [worker1, worker2, worker3, worker4]
47
- expect(workers.count { |worker| worker.queue_empty? }).to eq(2)
48
- end
49
- end
50
- end
51
- end
52
- end
53
- end
@@ -1,34 +0,0 @@
1
- require 'spec_helper'
2
-
3
- module RRRSpec
4
- module Server
5
- class TestClass
6
- include LogFilePersister
7
- def self.after_save(&block); end
8
- save_as_file :log, suffix: 'log'
9
-
10
- attr_accessor :key
11
- end
12
-
13
- RSpec.describe LogFilePersister do
14
- before do
15
- RRRSpec.configuration = ServerConfiguration.new
16
- RRRSpec.configuration.execute_log_text_path = '/tmp/log_path'
17
- end
18
-
19
- describe '#log_log_path' do
20
- subject { TestClass.new }
21
-
22
- it 'subsitutes colons in the key' do
23
- subject.key = 'rrrspec:test'
24
- expect(subject.log_log_path).to eq('/tmp/log_path/rrrspec/test_log.log')
25
- end
26
-
27
- it 'subsitutes slashes in the key' do
28
- subject.key = 'rrrspec:test/path'
29
- expect(subject.log_log_path).to eq('/tmp/log_path/rrrspec/test_path_log.log')
30
- end
31
- end
32
- end
33
- end
34
- end
@@ -1,55 +0,0 @@
1
- require 'spec_helper'
2
-
3
- module RRRSpec
4
- module Server
5
- module Persistence
6
- RSpec.describe Taskset do
7
- before do
8
- RRRSpec.configuration = ServerConfiguration.new
9
- RRRSpec.configuration.redis = @redis
10
- RRRSpec.configuration.execute_log_text_path = Dir.mktmpdir
11
- end
12
-
13
- before do
14
- @worker, @taskset, @task, @worker_log, @slave, @trial =
15
- RRRSpec.finished_fullset
16
- Persister.persist(@taskset)
17
- end
18
-
19
- describe '#as_nodetail_json' do
20
- it 'produces a json object' do
21
- h = @taskset.to_h
22
- h.delete('slaves')
23
- h.delete('tasks')
24
- h.delete('worker_logs')
25
-
26
- expect(
27
- JSON.parse(JSON.generate(Taskset.first.as_nodetail_json()))
28
- ).to eq(
29
- JSON.parse(JSON.generate(h))
30
- )
31
- end
32
- end
33
-
34
- describe '#as_full_json' do
35
- it 'produces a json object' do
36
- h = @taskset.to_h
37
- h['slaves'] = [@slave.to_h]
38
-
39
- task_h = @task.to_h
40
- task_h['trials'] = [@trial.to_h]
41
- h['tasks'] = [task_h]
42
-
43
- h['worker_logs'] = [@worker_log.to_h]
44
-
45
- expect(
46
- JSON.parse(JSON.generate(Taskset.first.as_full_json()))
47
- ).to eq(
48
- JSON.parse(JSON.generate(h))
49
- )
50
- end
51
- end
52
- end
53
- end
54
- end
55
- end
@@ -1,125 +0,0 @@
1
- require 'spec_helper'
2
-
3
- module RRRSpec
4
- module Server
5
- RSpec.describe Persister do
6
- before do
7
- RRRSpec.configuration = ServerConfiguration.new
8
- RRRSpec.configuration.redis = @redis
9
- RRRSpec.configuration.execute_log_text_path = Dir.mktmpdir
10
- end
11
-
12
- before do
13
- @worker, @taskset, @task, @worker_log, @slave, @trial =
14
- RRRSpec.finished_fullset
15
- end
16
-
17
- after do
18
- FileUtils.remove_entry_secure(RRRSpec.configuration.execute_log_text_path)
19
- end
20
-
21
- describe '.persist' do
22
- let(:task_json) do
23
- {
24
- taskset: {key: @taskset.key},
25
- estimate_sec: @task.estimate_sec,
26
- key: @task.key,
27
- spec_file: @task.spec_file,
28
- status: @task.status,
29
- trials: [{key: @trial.key}],
30
- }
31
- end
32
-
33
- let(:slave_json) do
34
- {
35
- key: @slave.key,
36
- log: @slave.log,
37
- status: @slave.status,
38
- trials: [{key: @trial.key}],
39
- }
40
- end
41
-
42
- def log_path_of(filename)
43
- File.join(RRRSpec.configuration.execute_log_text_path, filename)
44
- end
45
-
46
- let(:taskset_log_name) { @taskset.key.gsub(/\//, '_').gsub(/:/, '/') + "_log.log" }
47
- let(:worker_log_name) { @worker_log.key.gsub(/\//, '_').gsub(/:/, '/') + "_worker_log.log" }
48
- let(:slave_log_name) { @slave.key.gsub(/\//, '_').gsub(/:/, '/') + "_slave_log.log" }
49
- let(:trial_stdout_name) { @trial.key.gsub(/\//, '_').gsub(/:/, '/') + "_stdout.log" }
50
- let(:trial_stderr_name) { @trial.key.gsub(/\//, '_').gsub(/:/, '/') + "_stderr.log" }
51
-
52
- def eq_json(actual, expected)
53
- expect(
54
- JSON.parse(JSON.generate(actual))
55
- ).to eq(
56
- JSON.parse(JSON.generate(expected))
57
- )
58
- end
59
-
60
- def check_persistence
61
- Persister.persist(@taskset)
62
- p_taskset = Persistence::Taskset.first
63
- eq_json(p_taskset.as_short_json, @taskset)
64
-
65
- expect(p_taskset.tasks.size).to eq(1)
66
- p_task = p_taskset.tasks.first
67
- eq_json(p_task.as_short_json, task_json)
68
-
69
- trial = @task.trials[0]
70
- expect(p_task.trials.size).to eq(1)
71
- p_trial = p_task.trials.first
72
- eq_json(p_trial.as_short_json, @trial)
73
-
74
- expect(p_taskset.slaves.size).to eq(1)
75
- p_slave = p_taskset.slaves.first
76
- eq_json(p_slave.as_short_json, slave_json)
77
-
78
- expect(p_taskset.worker_logs.size).to eq(1)
79
- p_worker_log = p_taskset.worker_logs.first
80
- eq_json(p_worker_log.as_short_json, @worker_log)
81
- end
82
-
83
- it 'persists the whole taskset' do
84
- check_persistence
85
- end
86
-
87
- context 'when logs are too long' do
88
- before do
89
- RRRSpec.redis.hset(@trial.key, 'stdout', 'out' * 30000)
90
- end
91
-
92
- it 'saves full logs to the files' do
93
- Persister.persist(@taskset)
94
- expect(File.read(log_path_of(trial_stdout_name))).to eq(@trial.stdout)
95
- end
96
- end
97
-
98
-
99
- it 'creates log text files' do
100
- Persister.persist(@taskset)
101
-
102
- expect(File.read(log_path_of(taskset_log_name))).to eq(@taskset.log)
103
- expect(File.read(log_path_of(worker_log_name))).to eq(@worker_log.log)
104
- expect(File.read(log_path_of(slave_log_name))).to eq(@slave.log)
105
- expect(File.read(log_path_of(trial_stdout_name))).to eq(@trial.stdout)
106
- expect(File.read(log_path_of(trial_stderr_name))).to eq(@trial.stderr)
107
- end
108
-
109
- context "trial is finished after the taskset's finish" do
110
- before do
111
- @late_trial = Trial.create(@task, @slave)
112
- @late_trial.start
113
- Timecop.freeze(Time.now+1) do
114
- @late_trial.finish('error', '', '', nil, nil, nil)
115
- end
116
- end
117
-
118
- it "does not persist trials finished after taskset's finish" do
119
- check_persistence
120
- end
121
- end
122
- end
123
- end
124
- end
125
- end
@@ -1,28 +0,0 @@
1
- require 'spec_helper'
2
-
3
- module RRRSpec
4
- module Server
5
- RSpec.describe StatisticsUpdater do
6
- before do
7
- RRRSpec.configuration = ServerConfiguration.new
8
- RRRSpec.configuration.redis = @redis
9
-
10
- @worker, @taskset, @task, @worker_log, @slave, @trial =
11
- RRRSpec.finished_fullset
12
- end
13
-
14
- describe '.update_estimate_sec' do
15
- before { Persister.persist(@taskset) }
16
-
17
- xit 'updates estimation of the time taken to finish the tasks' do
18
- pending "sqlite3 doesn't have UNIT_TIMESTAMP function"
19
- Persister.update_estimate_sec(@taskset)
20
- expect(RRRSpec::TasksetEstimation.estimate_secs(@taskset.taskset_class)).to eq(
21
- {"spec/test_spec.rb" => 0}
22
- )
23
- end
24
- end
25
- end
26
- end
27
- end
28
-
@@ -1,76 +0,0 @@
1
- # This file was generated by the `rspec --init` command. Conventionally, all
2
- # specs live under a `spec` directory, which RSpec adds to the `$LOAD_PATH`.
3
- # Require this file using `require "spec_helper"` to ensure that it is only
4
- # loaded once.
5
- #
6
- # See http://rubydoc.info/gems/rspec-core/RSpec/Core/Configuration
7
- require 'rrrspec/server'
8
- require 'tmpdir'
9
- require 'database_cleaner'
10
- require 'timecop'
11
- require 'fixture'
12
-
13
- RSpec.configure do |config|
14
- config.raise_errors_for_deprecations!
15
- config.disable_monkey_patching!
16
- config.run_all_when_everything_filtered = true
17
- config.filter_run :focus
18
-
19
- # Run specs in random order to surface order dependencies. If you find an
20
- # order dependency and want to debug it, you can fix the order by providing
21
- # the seed, which is printed after each run.
22
- # --seed 1234
23
- config.order = 'random'
24
-
25
- pid = nil
26
- config.before(:suite) do
27
- pid = Kernel.spawn("redis-server --port 9999 --save ''",
28
- in: '/dev/null', out: '/dev/null', err: '/dev/null')
29
- redis = Redis.new(port: 9999)
30
- retry_count = 1
31
- loop do
32
- begin
33
- redis.client.connect
34
- break
35
- rescue Redis::CannotConnectError
36
- if retry_count < 10
37
- retry_count += 1
38
- sleep 0.01
39
- retry
40
- end
41
- raise
42
- end
43
- end
44
- end
45
-
46
- config.before(:each) do
47
- @redis = Redis.new(port: 9999)
48
- @redis.flushall
49
-
50
- RRRSpec.configuration = nil
51
- RRRSpec.flushredis
52
- RRRSpec.hostname = 'testhostname'
53
- end
54
-
55
- config.after(:suite) do
56
- Process.kill('KILL', pid) if pid
57
- end
58
-
59
- config.before(:suite) do
60
- ActiveRecord::Base.establish_connection(
61
- adapter: "sqlite3", database: ":memory:"
62
- )
63
- ActiveRecord::Migration.verbose = false
64
- ActiveRecord::Migrator.up "db/migrate"
65
- DatabaseCleaner.strategy = :transaction
66
- DatabaseCleaner.clean_with(:truncation)
67
- end
68
-
69
- config.before(:each) do
70
- DatabaseCleaner.start
71
- end
72
-
73
- config.after(:each) do
74
- DatabaseCleaner.clean
75
- end
76
- end