sidejob 3.0.1 → 4.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.
@@ -4,23 +4,19 @@ describe SideJob::Port do
4
4
  before do
5
5
  @job = SideJob.queue('testq', 'TestWorker', inports: {
6
6
  port1: {},
7
- memory: { mode: :memory },
8
7
  default: { default: 'default' },
9
8
  default_null: { default: nil },
10
9
  default_false: { default: false},
11
- memory_with_default: { mode: :memory, default: 'memory default' },
12
10
  }, outports: {
13
11
  out1: {},
14
12
  })
15
13
  @port1 = @job.input(:port1)
16
14
  @out1 = @job.output(:out1)
17
- @memory = @job.input(:memory)
18
15
  @default = @job.input(:default)
19
16
  @defaults = [
20
17
  @default,
21
18
  @job.input(:default_null),
22
19
  @job.input(:default_false),
23
- @job.input(:memory_with_default)
24
20
  ]
25
21
  end
26
22
 
@@ -32,9 +28,24 @@ describe SideJob::Port do
32
28
  it 'raises error if name is empty' do
33
29
  expect { SideJob::Port.new(@job, :in, '')}.to raise_error
34
30
  end
31
+
32
+ it 'raises error on non-existent port' do
33
+ expect { SideJob::Port.new(@job, :in, 'missing')}.to raise_error
34
+ end
35
+
36
+ it 'can dynamically create a port' do
37
+ @job.inports = {
38
+ '*' => { default: 123 },
39
+ }
40
+ expect(@job.input('abc').default).to eq 123
41
+ end
35
42
  end
36
43
 
37
44
  describe '#==, #eql?' do
45
+ before do
46
+ @job.inports = { '*' => {}}
47
+ end
48
+
38
49
  it 'two ports with the same job, type, and name are eq' do
39
50
  expect(SideJob::Port.new(@job, :in, :port1)).to eq(@port1)
40
51
  expect(SideJob::Port.new(@job, :in, 'port1')).to eq(@port1)
@@ -58,57 +69,6 @@ describe SideJob::Port do
58
69
  end
59
70
  end
60
71
 
61
- describe '#options' do
62
- it 'returns port options' do
63
- expect(@port1.options).to eq({mode: :queue})
64
- expect(@memory.options).to eq({mode: :memory})
65
- expect(@default.options).to eq({mode: :queue, default: 'default'})
66
- end
67
- end
68
-
69
- describe '#options=' do
70
- it 'can change mode to memory' do
71
- expect(@port1.mode).to eq :queue
72
- @port1.options = { mode: :memory }
73
- expect(@port1.mode).to eq :memory
74
- end
75
-
76
- it 'can change mode to queue' do
77
- expect(@memory.mode).to eq :memory
78
- @memory.options = { mode: :queue }
79
- expect(@memory.mode).to eq :queue
80
- end
81
-
82
- it 'can set default value' do
83
- expect(@port1.default?).to be false
84
- @port1.options = { default: [1,2] }
85
- expect(@port1.default).to eq [1,2]
86
- expect(@port1.read).to eq [1,2]
87
- end
88
-
89
- it 'can remove default value' do
90
- expect(@default.default?).to be true
91
- @default.options = { }
92
- expect(@default.default?).to be false
93
- end
94
- end
95
-
96
- describe '#mode' do
97
- it 'returns nil for non-existent ports' do
98
- expect(SideJob::Port.new(@job, :in, 'missing').mode).to be nil
99
- end
100
-
101
- it 'returns the port mode for queue ports' do
102
- expect(@port1.mode).to eq :queue
103
- expect(@default.mode).to eq :queue
104
- end
105
-
106
- it 'returns the port mode for memory ports' do
107
- expect(@memory.mode).to eq :memory
108
- expect(@job.input(:memory_with_default).mode).to eq :memory
109
- end
110
- end
111
-
112
72
  describe '#size' do
113
73
  it 'returns 0 when the port is empty' do
114
74
  expect(@port1.size).to eq 0
@@ -142,29 +102,23 @@ describe SideJob::Port do
142
102
  expect(@port1.data?).to be true
143
103
  end
144
104
 
145
- it 'works for memory ports' do
146
- expect(@memory.data?).to be false
147
- @memory.write 1
148
- expect(@memory.data?).to be true
149
- end
150
-
151
- it 'works when there is a default value on the port' do
105
+ it 'returns true when there is a default value on the port' do
152
106
  @defaults.each {|port| expect(port.data?).to be true }
153
107
  end
154
108
  end
155
109
 
156
110
  describe '#default' do
157
- it 'returns nil for no default' do
158
- expect(@port1.default).to be nil
159
- end
160
-
161
111
  it 'returns default value' do
162
- @port1.options = {default: [1,2]}
112
+ @port1.default = [1,2]
163
113
  expect(@port1.default).to eq [1,2]
164
114
  end
165
115
 
116
+ it 'returns None for no default' do
117
+ expect(@port1.default).to be SideJob::Port::None
118
+ end
119
+
166
120
  it 'can return null default value' do
167
- @port1.options = {default: nil}
121
+ @port1.default = nil
168
122
  expect(@port1.default).to be nil
169
123
  expect(@port1.default?).to be true
170
124
  end
@@ -175,17 +129,24 @@ describe SideJob::Port do
175
129
  expect(@port1.default?).to be false
176
130
  end
177
131
 
178
- it 'returns false for memory port with no data written' do
179
- expect(@memory.default?).to be false
132
+ it 'returns true for port with default value' do
133
+ @defaults.each {|port| expect(port.default?).to be true }
180
134
  end
135
+ end
181
136
 
182
- it 'returns true for memory port after writing data' do
183
- @memory.write 1
184
- expect(@memory.default?).to be true
137
+ describe '#default=' do
138
+ it 'can set and overwrite the default' do
139
+ [true, false, nil, 123, 'abc', {'xyz' => [1,2]}, [5,6]].each do |val|
140
+ @port1.default = val
141
+ expect(@port1.default).to eq(val)
142
+ end
185
143
  end
186
144
 
187
- it 'returns true for port with default value' do
188
- @defaults.each {|port| expect(port.default?).to be true }
145
+ it 'can clear the default' do
146
+ @port1.default = 1234
147
+ expect(@port1.default?).to be true
148
+ @port1.default = SideJob::Port::None
149
+ expect(@port1.default?).to be false
189
150
  end
190
151
  end
191
152
 
@@ -196,22 +157,14 @@ describe SideJob::Port do
196
157
  expect(data).to eq(['"abc"', '123', 'true', 'false', 'null', '{"abc":123}', '[1,{"foo":true}]'])
197
158
  end
198
159
 
199
- it 'writing to a memory port should only set default value to latest value' do
200
- @memory.write 'abc'
201
- @memory.write [1, {foo: true}]
202
- @memory.write 'latest'
203
- expect(@memory.size).to eq 0
204
- expect(@memory.default).to eq 'latest'
205
- end
206
-
207
160
  it 'logs writes' do
208
161
  now = Time.now
209
162
  allow(Time).to receive(:now) { now }
210
- @job.group_port_logs do
163
+ SideJob::Port.log_group do
211
164
  @port1.write 'abc'
212
165
  @port1.write 123
213
166
  end
214
- expect(SideJob.logs).to eq [{'timestamp' => SideJob.timestamp, 'job' => @job.id, 'read' => [],
167
+ expect(SideJob.logs).to eq [{'timestamp' => SideJob.timestamp, 'read' => [],
215
168
  'write' => ['job' => @job.id, 'inport' => 'port1', 'data' => ['abc', 123]]}]
216
169
  end
217
170
 
@@ -219,36 +172,30 @@ describe SideJob::Port do
219
172
  expect { SideJob::Port.new(@job, :in, 'foo').write true }.to raise_error
220
173
  end
221
174
 
222
- it 'raises error if port mode is unknown ' do
223
- SideJob.redis.hset "#{@job.redis_key}:inports:mode", 'foo', '???'
224
- expect { SideJob::Port.new(@job, :in, 'foo').write true }.to raise_error
225
- end
226
-
227
175
  it 'runs the job if it is an input port' do
228
- expect(@port1.job).to receive(:run)
176
+ parent = SideJob.queue('testq', 'TestWorker')
177
+ parent.adopt(@job, 'child')
178
+ parent.status = 'completed'
179
+ @job.status = 'completed'
229
180
  @port1.write 3
181
+ expect(@job.status).to eq 'queued'
182
+ expect(parent.status).to eq 'completed'
230
183
  end
231
184
 
232
- it 'does not run the job if it is an output port' do
233
- expect(@out1.job).not_to receive(:run)
185
+ it 'runs the parent job if it is an output port' do
186
+ parent = SideJob.queue('testq', 'TestWorker')
187
+ parent.adopt(@job, 'child')
188
+ parent.status = 'completed'
189
+ @job.status = 'completed'
234
190
  @out1.write 3
235
- end
236
-
237
- it 'does not run the job if it is a memory port' do
238
- expect(@memory.job).not_to receive(:run)
239
- @memory.write 3
191
+ expect(@job.status).to eq 'completed'
192
+ expect(parent.status).to eq 'queued'
240
193
  end
241
194
  end
242
195
 
243
196
  describe '#read' do
244
- it 'can distinguish reading nil data and no data' do
245
- expect { @port1.read }.to raise_error(EOFError)
246
- @port1.write nil
247
- expect(@port1.read).to be nil
248
- end
249
-
250
- it 'can read data from a queue port' do
251
- expect { @port1.read }.to raise_error(EOFError)
197
+ it 'can read different kinds of data' do
198
+ expect(@port1.read).to eq SideJob::Port::None
252
199
  ['abc', 123, true, false, nil, {}, ['data1', 1, {key: 'val'}]].each {|x| @port1.write x}
253
200
  expect(@port1.size).to be(7)
254
201
  expect(@port1.read).to eq('abc')
@@ -258,22 +205,16 @@ describe SideJob::Port do
258
205
  expect(@port1.read).to eq(nil)
259
206
  expect(@port1.read).to eq({})
260
207
  expect(@port1.read).to eq(['data1', 1, {'key' => 'val'}])
261
- expect { @port1.read }.to raise_error(EOFError)
208
+ expect(@port1.read).to eq SideJob::Port::None
262
209
  expect(@port1.size).to be(0)
263
210
  end
264
211
 
265
- it 'can read data from a memory port' do
266
- expect { @memory.read }.to raise_error(EOFError)
267
- 5.times {|i| @memory.write i }
268
- 3.times { expect(@memory.read).to eq(4) }
269
- end
270
-
271
212
  it 'can use default value' do
272
213
  @defaults.each do |port|
273
214
  3.times { expect(port.read).to eq port.default }
274
215
  port.write 'mydata'
275
216
  expect(port.read).to eq 'mydata'
276
- 3.times { expect(port.read).to eq port.mode == :memory ? 'mydata' : port.default }
217
+ 3.times { expect(port.read).to eq port.default }
277
218
  end
278
219
  end
279
220
 
@@ -292,11 +233,11 @@ describe SideJob::Port do
292
233
  allow(Time).to receive(:now) { now }
293
234
  ['abc', 123].each {|x| @port1.write x}
294
235
  SideJob.logs
295
- @job.group_port_logs do
236
+ SideJob::Port.log_group do
296
237
  expect(@port1.read).to eq('abc')
297
238
  expect(@port1.read).to eq(123)
298
239
  end
299
- expect(SideJob.logs).to eq [{'timestamp' => SideJob.timestamp, 'job' => @job.id,
240
+ expect(SideJob.logs).to eq [{'timestamp' => SideJob.timestamp,
300
241
  'read' => ['job' => @job.id, 'inport' => 'port1', 'data' => ['abc', 123]],
301
242
  'write' => []}]
302
243
  end
@@ -319,52 +260,65 @@ describe SideJob::Port do
319
260
  end
320
261
 
321
262
  it 'sends data to all destination ports' do
322
- dest = [@port1, @memory, @default]
263
+ dest = [@port1, @default]
323
264
  @out1.write 1
324
265
  @out1.write [2,3]
325
266
  @out1.connect_to dest
326
267
  expect(@port1.read).to eq 1
327
268
  expect(@port1.read).to eq [2,3]
328
269
  expect(@port1.data?).to be false
329
- expect(@memory.size).to eq 0
330
- expect(@memory.read).to eq [2,3]
331
270
  expect(@default.read).to eq 1
332
271
  expect(@default.read).to eq [2,3]
333
272
  expect(@default.read).to eq 'default'
334
273
  end
335
274
 
336
275
  it 'passes port default values to all destinations' do
337
- dest = [@port1, @memory, @out1]
276
+ dest = [@port1, @out1]
338
277
  @default.write 1
339
278
  @default.write [2,3]
340
279
  @default.connect_to dest
341
280
  expect(@port1.read).to eq 1
342
281
  expect(@port1.read).to eq [2,3]
343
282
  expect(@port1.default).to eq 'default'
344
- expect(@memory.size).to eq 0
345
- expect(@memory.default).to eq 'default'
346
283
  expect(@out1.read).to eq 1
347
284
  expect(@out1.read).to eq [2,3]
348
285
  expect(@out1.default).to eq 'default'
349
286
  end
350
287
 
351
- it 'runs job for normal input port' do
288
+ it 'runs job if the default value has changed' do
352
289
  expect(@port1.job).to receive(:run)
290
+ @default.connect_to @port1
291
+ end
292
+
293
+ it 'does not run job if the default value has not changed' do
294
+ @default.connect_to @port1
295
+ expect(@port1.job).not_to receive(:run)
296
+ @default.connect_to @port1
297
+ end
298
+
299
+ it 'runs job for normal input port' do
353
300
  @out1.write true
301
+ expect(@port1.job).to receive(:run)
354
302
  @out1.connect_to @port1
355
303
  end
356
304
 
305
+ it 'runs parent job for outport' do
306
+ parent = SideJob.queue('testq', 'TestWorker')
307
+ parent.adopt(@job, 'child')
308
+ parent.status = 'completed'
309
+ @job.status = 'completed'
310
+ j2 = SideJob.queue('testq', 'TestWorker', inports: {in: {}})
311
+ j2.input(:in).write true
312
+ j2.input(:in).connect_to @out1
313
+ expect(@job.status).to eq 'completed'
314
+ expect(parent.status).to eq 'queued'
315
+ end
316
+
357
317
  it 'does not run job if no data sent' do
358
318
  expect(@port1.job).not_to receive(:run)
359
319
  @out1.connect_to @port1
360
320
  end
361
321
 
362
- it 'does not run job for memory port' do
363
- expect(@memory.job).not_to receive(:run)
364
- @out1.write true
365
- @out1.connect_to @memory
366
- end
367
-
368
322
  it 'logs data' do
369
323
  now = Time.now
370
324
  allow(Time).to receive(:now) { now }
@@ -377,21 +331,21 @@ describe SideJob::Port do
377
331
  'write' => [{'job' => @job.id, 'inport' => 'port1', 'data' => [1,[2,3]]}] }])
378
332
  end
379
333
 
380
- it 'can specify additional metadata to add to log' do
334
+ it 'can use SideJob.log_context to specify additional metadata' do
381
335
  now = Time.now
382
336
  allow(Time).to receive(:now) { now }
383
- job2 = SideJob.queue('testq', 'TestWorker')
384
337
  @out1.write 1
385
338
  @out1.write [2,3]
386
339
  SideJob.logs(clear: true)
387
- @out1.connect_to(@port1, user: 'test')
340
+ SideJob.log_context(user: 'test') do
341
+ @out1.connect_to(@port1)
342
+ end
388
343
  expect(SideJob.logs).to eq([{'timestamp' => SideJob.timestamp, 'user' => 'test',
389
344
  'read' => [{'job' => @job.id, 'outport' => 'out1', 'data' => [1,[2,3]]}],
390
345
  'write' => [{'job' => @job.id, 'inport' => 'port1', 'data' => [1,[2,3]]}] }])
391
346
  end
392
347
 
393
348
  it 'does not log if no data on port' do
394
- job2 = SideJob.queue('testq', 'TestWorker')
395
349
  @out1.connect_to(@port1)
396
350
  expect(SideJob.logs).to eq([])
397
351
  end
@@ -419,11 +373,7 @@ describe SideJob::Port do
419
373
  @defaults.each do |port|
420
374
  expect(port.entries).to eq []
421
375
  port.write 'mydata'
422
- if port.mode == :memory
423
- expect(port.entries).to eq []
424
- else
425
- expect(port.entries).to eq ['mydata']
426
- end
376
+ expect(port.entries).to eq ['mydata']
427
377
  end
428
378
  end
429
379
  end
@@ -449,4 +399,68 @@ describe SideJob::Port do
449
399
  expect(h[@port1]).to be(3)
450
400
  end
451
401
  end
402
+
403
+ describe '.log_group' do
404
+ before do
405
+ now = Time.now
406
+ allow(Time).to receive(:now) { now }
407
+ end
408
+
409
+ it 'does not log anything if no port operations occur within the block' do
410
+ SideJob::Port.log_group {}
411
+ expect(SideJob.logs.length).to eq 0
412
+ end
413
+
414
+ it 'groups all port logs within the block' do
415
+ SideJob::Port.log_group do
416
+ @port1.write 'abc'
417
+ @port1.read
418
+ @port1.write 'def'
419
+ @out1.write 'xyz'
420
+ end
421
+ expect(SideJob.logs).to eq [{'timestamp' => SideJob.timestamp,
422
+ 'read' => [{'job' => @port1.job.id, 'inport' => 'port1', 'data' => ['abc']}],
423
+ 'write' => [{'job' => @port1.job.id, 'inport' => 'port1', 'data' => ['abc', 'def']}, {'job' => @out1.job.id, 'outport' => 'out1', 'data' => ['xyz']} ]}]
424
+ end
425
+
426
+ it 'does not write out log until the end of outermost group' do
427
+ SideJob::Port.log_group do
428
+ @port1.write 'hello'
429
+ SideJob::Port.log_group do
430
+ @port1.write 2
431
+ end
432
+ expect(SideJob.logs.length).to eq 0
433
+ end
434
+ expect(SideJob.logs).to eq [{'timestamp' => SideJob.timestamp,
435
+ 'read' => [],
436
+ 'write' => [{'job' => @port1.job.id, 'inport' => 'port1', 'data' => ['hello', 2]}]}]
437
+ end
438
+
439
+ it 'works with SideJob.log_context' do
440
+ SideJob.log_context(user: 'foo') do
441
+ SideJob::Port.log_group do
442
+ @port1.write 'abc'
443
+ @port1.read
444
+ end
445
+ end
446
+ expect(SideJob.logs).to eq [{'timestamp' => SideJob.timestamp, 'user' => 'foo',
447
+ 'read' => [{'job' => @port1.job.id, 'inport' => 'port1', 'data' => ['abc']}],
448
+ 'write' => [{'job' => @port1.job.id, 'inport' => 'port1', 'data' => ['abc']}]}]
449
+ end
450
+
451
+ it 'logs correctly even if data is changed' do
452
+ data = {'x' => [1,2]}
453
+ SideJob::Port.log_group do
454
+ @port1.write data
455
+ expect(@port1.read).to eq data
456
+ data['x'].push 3
457
+ @port1.write data
458
+ expect(@port1.read).to eq data
459
+ end
460
+ expect(SideJob.logs).to eq [{'timestamp' => SideJob.timestamp,
461
+ 'read' => [{'job' => @port1.job.id, 'inport' => 'port1', 'data' => [{'x' => [1,2]},{'x' => [1,2,3]}]}],
462
+ 'write' => [{'job' => @port1.job.id, 'inport' => 'port1', 'data' => [{'x' => [1,2]},{'x' => [1,2,3]}]}],
463
+ }]
464
+ end
465
+ end
452
466
  end