polyphony 0.99.4 → 0.99.6

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.
Files changed (49) hide show
  1. checksums.yaml +4 -4
  2. data/.rubocop.yml +11 -0
  3. data/.yardopts +0 -2
  4. data/README.md +1 -1
  5. data/docs/readme.md +1 -1
  6. data/docs/tutorial.md +2 -2
  7. data/examples/pipes/gzip_http_server.rb +2 -2
  8. data/examples/pipes/http_server.rb +1 -1
  9. data/examples/pipes/tcp_proxy.rb +1 -1
  10. data/ext/polyphony/backend_common.c +4 -4
  11. data/ext/polyphony/backend_io_uring.c +8 -8
  12. data/ext/polyphony/backend_libev.c +5 -5
  13. data/ext/polyphony/fiber.c +33 -42
  14. data/ext/polyphony/io_extensions.c +50 -37
  15. data/ext/polyphony/pipe.c +6 -20
  16. data/ext/polyphony/polyphony.c +72 -144
  17. data/ext/polyphony/queue.c +23 -63
  18. data/ext/polyphony/thread.c +4 -13
  19. data/lib/polyphony/adapters/process.rb +2 -5
  20. data/lib/polyphony/adapters/sequel.rb +2 -2
  21. data/lib/polyphony/core/debug.rb +1 -4
  22. data/lib/polyphony/core/exceptions.rb +1 -5
  23. data/lib/polyphony/core/resource_pool.rb +7 -8
  24. data/lib/polyphony/core/sync.rb +5 -8
  25. data/lib/polyphony/core/thread_pool.rb +3 -10
  26. data/lib/polyphony/core/throttler.rb +1 -5
  27. data/lib/polyphony/core/timer.rb +23 -30
  28. data/lib/polyphony/extensions/fiber.rb +513 -543
  29. data/lib/polyphony/extensions/io.rb +5 -14
  30. data/lib/polyphony/extensions/object.rb +283 -2
  31. data/lib/polyphony/extensions/openssl.rb +5 -26
  32. data/lib/polyphony/extensions/pipe.rb +6 -17
  33. data/lib/polyphony/extensions/socket.rb +24 -118
  34. data/lib/polyphony/extensions/thread.rb +3 -18
  35. data/lib/polyphony/extensions/timeout.rb +0 -1
  36. data/lib/polyphony/net.rb +5 -9
  37. data/lib/polyphony/version.rb +1 -1
  38. data/lib/polyphony.rb +2 -6
  39. data/test/test_io.rb +221 -221
  40. data/test/test_socket.rb +3 -3
  41. data/test/test_trace.rb +2 -2
  42. metadata +5 -9
  43. data/docs/index.md +0 -94
  44. data/docs/link_rewriter.rb +0 -17
  45. data/docs/main-concepts/index.md +0 -9
  46. data/lib/polyphony/core/global_api.rb +0 -309
  47. /data/{assets → docs/assets}/echo-fibers.svg +0 -0
  48. /data/{assets → docs/assets}/polyphony-logo.png +0 -0
  49. /data/{assets → docs/assets}/sleeping-fiber.svg +0 -0
data/test/test_io.rb CHANGED
@@ -8,7 +8,7 @@ class IOTest < MiniTest::Test
8
8
  super
9
9
  @i, @o = IO.pipe
10
10
  end
11
-
11
+
12
12
  def test_that_io_op_yields_to_other_fibers
13
13
  count = 0
14
14
  msg = nil
@@ -17,20 +17,20 @@ class IOTest < MiniTest::Test
17
17
  @o.write('hello')
18
18
  @o.close
19
19
  end,
20
-
20
+
21
21
  spin do
22
22
  while count < 5
23
23
  sleep 0.01
24
24
  count += 1
25
25
  end
26
26
  end,
27
-
27
+
28
28
  spin { msg = @i.read }
29
29
  ].each(&:await)
30
30
  assert_equal 5, count
31
31
  assert_equal 'hello', msg
32
32
  end
33
-
33
+
34
34
  def test_write_multiple_arguments
35
35
  i, o = IO.pipe
36
36
  count = o.write('a', 'b', "\n", 'c')
@@ -38,15 +38,15 @@ class IOTest < MiniTest::Test
38
38
  o.close
39
39
  assert_equal "ab\nc", i.read
40
40
  end
41
-
41
+
42
42
  def test_that_double_chevron_method_returns_io
43
43
  assert_equal @o, @o << 'foo'
44
-
44
+
45
45
  @o << 'bar' << 'baz'
46
46
  @o.close
47
47
  assert_equal 'foobarbaz', @i.read
48
48
  end
49
-
49
+
50
50
  def test_wait_io
51
51
  results = []
52
52
  i, o = IO.pipe
@@ -62,67 +62,67 @@ class IOTest < MiniTest::Test
62
62
  end
63
63
  end
64
64
  end
65
-
65
+
66
66
  snooze
67
67
  o.write('foo')
68
68
  o.close
69
-
69
+
70
70
  result = f.await
71
-
71
+
72
72
  assert_equal 'foo', f.await
73
73
  assert_equal [:wait_readable, 'foo'], results
74
74
  end
75
-
75
+
76
76
  def test_read
77
77
  i, o = IO.pipe
78
-
78
+
79
79
  o << 'hi'
80
80
  assert_equal 'hi', i.read(2)
81
-
81
+
82
82
  o << 'foobarbaz'
83
83
  assert_equal 'foo', i.read(3)
84
84
  assert_equal 'bar', i.read(3)
85
-
85
+
86
86
  buf = +'abc'
87
87
  assert_equal 'baz', i.read(3, buf)
88
88
  assert_equal 'baz', buf
89
-
89
+
90
90
  buf = +'def'
91
91
  o << 'foobar'
92
92
  assert_equal 'deffoobar', i.read(6, buf, -1)
93
93
  assert_equal 'deffoobar', buf
94
94
  end
95
-
95
+
96
96
  def test_read_zero
97
97
  i, o = IO.pipe
98
98
 
99
99
  o << 'hi'
100
100
  assert_equal '', i.read(0)
101
101
  end
102
-
102
+
103
103
  def test_readpartial
104
104
  i, o = IO.pipe
105
-
105
+
106
106
  o << 'hi'
107
107
  assert_equal 'hi', i.readpartial(3)
108
-
108
+
109
109
  o << 'hi'
110
110
  assert_equal 'h', i.readpartial(1)
111
111
  assert_equal 'i', i.readpartial(1)
112
-
112
+
113
113
  spin {
114
114
  sleep 0.01
115
115
  o << 'hi'
116
116
  }
117
117
  assert_equal 'hi', i.readpartial(2)
118
118
  o.close
119
-
119
+
120
120
  assert_raises(EOFError) { i.readpartial(1) }
121
121
  end
122
-
122
+
123
123
  def test_gets
124
124
  i, o = IO.pipe
125
-
125
+
126
126
  buf = []
127
127
  f = spin do
128
128
  peer = receive
@@ -131,37 +131,37 @@ class IOTest < MiniTest::Test
131
131
  peer << true
132
132
  end
133
133
  end
134
-
134
+
135
135
  snooze
136
136
  assert_equal [], buf
137
-
137
+
138
138
  o << 'fab'
139
139
  f << Fiber.current
140
140
  sleep 0.05
141
141
  assert_equal [], buf
142
-
142
+
143
143
  o << "ulous\n"
144
144
  receive
145
145
  assert_equal ["fabulous\n"], buf
146
-
146
+
147
147
  o.close
148
148
  f.await
149
149
  assert_equal ["fabulous\n"], buf
150
150
  end
151
-
151
+
152
152
  def test_getc
153
153
  i, o = IO.pipe
154
-
154
+
155
155
  buf = []
156
156
  f = spin do
157
157
  while (c = i.getc)
158
158
  buf << c
159
159
  end
160
160
  end
161
-
161
+
162
162
  snooze
163
163
  assert_equal [], buf
164
-
164
+
165
165
  o << 'f'
166
166
  snooze
167
167
  o << 'g'
@@ -169,20 +169,20 @@ class IOTest < MiniTest::Test
169
169
  f.await
170
170
  assert_equal ['f', 'g'], buf
171
171
  end
172
-
172
+
173
173
  def test_getbyte
174
174
  i, o = IO.pipe
175
-
175
+
176
176
  buf = []
177
177
  f = spin do
178
178
  while (b = i.getbyte)
179
179
  buf << b
180
180
  end
181
181
  end
182
-
182
+
183
183
  snooze
184
184
  assert_equal [], buf
185
-
185
+
186
186
  o << 'f'
187
187
  snooze
188
188
  o << 'g'
@@ -190,21 +190,21 @@ class IOTest < MiniTest::Test
190
190
  f.await
191
191
  assert_equal [102, 103], buf
192
192
  end
193
-
193
+
194
194
  # see https://github.com/digital-fabric/polyphony/issues/30
195
195
  def test_reopened_tempfile
196
196
  file = Tempfile.new
197
197
  file << 'hello: world'
198
198
  file.close
199
-
199
+
200
200
  buf = nil
201
201
  File.open(file, 'r:bom|utf-8') do |f|
202
202
  buf = f.read(16384)
203
203
  end
204
-
204
+
205
205
  assert_equal 'hello: world', buf
206
206
  end
207
-
207
+
208
208
  def test_feed_loop_with_block
209
209
  i, o = IO.pipe
210
210
  unpacker = MessagePack::Unpacker.new
@@ -215,28 +215,28 @@ class IOTest < MiniTest::Test
215
215
  o << 'foo'.to_msgpack
216
216
  sleep 0.01
217
217
  assert_equal ['foo'], buffer
218
-
218
+
219
219
  o << 'bar'.to_msgpack
220
220
  sleep 0.01
221
221
  assert_equal ['foo', 'bar'], buffer
222
-
222
+
223
223
  o << 'baz'.to_msgpack
224
224
  sleep 0.01
225
225
  assert_equal ['foo', 'bar', 'baz'], buffer
226
226
  end
227
-
227
+
228
228
  class Receiver1
229
229
  attr_reader :buffer
230
-
230
+
231
231
  def initialize
232
232
  @buffer = []
233
233
  end
234
-
234
+
235
235
  def recv(obj)
236
236
  @buffer << obj
237
237
  end
238
238
  end
239
-
239
+
240
240
  def test_feed_loop_without_block
241
241
  i, o = IO.pipe
242
242
  receiver = Receiver1.new
@@ -246,28 +246,28 @@ class IOTest < MiniTest::Test
246
246
  o << 'foo'
247
247
  sleep 0.01
248
248
  assert_equal ['foo'], receiver.buffer
249
-
249
+
250
250
  o << 'bar'
251
251
  sleep 0.01
252
252
  assert_equal ['foo', 'bar'], receiver.buffer
253
-
253
+
254
254
  o << 'baz'
255
255
  sleep 0.01
256
256
  assert_equal ['foo', 'bar', 'baz'], receiver.buffer
257
257
  end
258
-
258
+
259
259
  class Receiver2
260
260
  attr_reader :buffer
261
-
261
+
262
262
  def initialize
263
263
  @buffer = []
264
264
  end
265
-
265
+
266
266
  def call(obj)
267
267
  @buffer << obj
268
268
  end
269
269
  end
270
-
270
+
271
271
  def test_feed_loop_without_method
272
272
  i, o = IO.pipe
273
273
  receiver = Receiver2.new
@@ -277,64 +277,64 @@ class IOTest < MiniTest::Test
277
277
  o << 'foo'
278
278
  sleep 0.01
279
279
  assert_equal ['foo'], receiver.buffer
280
-
280
+
281
281
  o << 'bar'
282
282
  sleep 0.01
283
283
  assert_equal ['foo', 'bar'], receiver.buffer
284
-
284
+
285
285
  o << 'baz'
286
286
  sleep 0.01
287
287
  assert_equal ['foo', 'bar', 'baz'], receiver.buffer
288
288
  end
289
-
289
+
290
290
  def test_splice_from
291
291
  i1, o1 = IO.pipe
292
292
  i2, o2 = IO.pipe
293
293
  len = nil
294
-
294
+
295
295
  spin {
296
296
  len = o2.splice_from(i1, 1000)
297
297
  o2.close
298
298
  }
299
-
299
+
300
300
  o1.write('foobar')
301
301
  result = i2.read
302
-
302
+
303
303
  assert_equal 'foobar', result
304
304
  assert_equal 6, len
305
305
  end
306
-
306
+
307
307
  def test_splice_class_method
308
308
  i1, o1 = IO.pipe
309
309
  i2, o2 = IO.pipe
310
310
  len = nil
311
-
311
+
312
312
  spin {
313
313
  len = IO.splice(i1, o2, 1000)
314
314
  o2.close
315
315
  }
316
-
316
+
317
317
  o1.write('foobar')
318
318
  result = i2.read
319
-
319
+
320
320
  assert_equal 'foobar', result
321
321
  assert_equal 6, len
322
322
  end
323
-
323
+
324
324
  def test_splice_from_to_eof
325
325
  i1, o1 = IO.pipe
326
326
  i2, o2 = IO.pipe
327
327
  len = nil
328
-
328
+
329
329
  f = spin {
330
330
  len = o2.splice_from(i1, -1000)
331
331
  o2.close
332
332
  }
333
-
333
+
334
334
  o1.write('foo')
335
335
  result = i2.readpartial(1000)
336
336
  assert_equal 'foo', result
337
-
337
+
338
338
  o1.write('bar')
339
339
  result = i2.readpartial(1000)
340
340
  assert_equal 'bar', result
@@ -347,21 +347,21 @@ class IOTest < MiniTest::Test
347
347
  f.await
348
348
  end
349
349
  end
350
-
350
+
351
351
  def test_splice_class_method_to_eof
352
352
  i1, o1 = IO.pipe
353
353
  i2, o2 = IO.pipe
354
354
  len = nil
355
-
355
+
356
356
  f = spin {
357
357
  len = IO.splice(i1, o2, -1000)
358
358
  o2.close
359
359
  }
360
-
360
+
361
361
  o1.write('foo')
362
362
  result = i2.readpartial(1000)
363
363
  assert_equal 'foo', result
364
-
364
+
365
365
  o1.write('bar')
366
366
  result = i2.readpartial(1000)
367
367
  assert_equal 'bar', result
@@ -374,90 +374,90 @@ class IOTest < MiniTest::Test
374
374
  f.await
375
375
  end
376
376
  end
377
-
377
+
378
378
  def test_double_splice
379
379
  if Thread.current.backend.kind != :io_uring
380
380
  skip "IO.double_splice available only on io_uring backend"
381
381
  end
382
-
382
+
383
383
  src = Polyphony.pipe
384
384
  dest = Polyphony.pipe
385
385
  ret = nil
386
386
  data = 'foobar' * 10
387
-
387
+
388
388
  f1 = spin {
389
389
  ret = IO.double_splice(src, dest)
390
390
  dest.close
391
391
  }
392
-
392
+
393
393
  src << data
394
394
  src.close
395
-
395
+
396
396
  f1.await
397
-
397
+
398
398
  spliced = dest.read
399
399
  assert_equal data, spliced
400
400
  assert_equal data.bytesize, ret
401
401
  end
402
-
402
+
403
403
  def test_tee_from
404
404
  skip "tested only on Linux" unless RUBY_PLATFORM =~ /linux/
405
-
405
+
406
406
  src = Polyphony.pipe
407
407
  dest1 = Polyphony.pipe
408
408
  dest2 = Polyphony.pipe
409
-
409
+
410
410
  len1 = len2 = nil
411
-
411
+
412
412
  spin {
413
413
  len1 = dest1.tee_from(src, 1000)
414
414
  dest1.close
415
415
  len2 = IO.splice(src, dest2, 1000)
416
416
  dest2.close
417
417
  }
418
-
418
+
419
419
  src << 'foobar'
420
420
  src.close
421
421
  result1 = dest1.read
422
422
  result2 = dest2.read
423
-
423
+
424
424
  assert_equal 'foobar', result1
425
425
  assert_equal 6, len1
426
-
426
+
427
427
  assert_equal 'foobar', result2
428
428
  assert_equal 6, len2
429
429
  end
430
-
430
+
431
431
  def test_tee_class_method
432
432
  skip "tested only on Linux" unless RUBY_PLATFORM =~ /linux/
433
-
433
+
434
434
  src = Polyphony.pipe
435
435
  dest1 = Polyphony.pipe
436
436
  dest2 = Polyphony.pipe
437
-
437
+
438
438
  len1 = len2 = nil
439
-
439
+
440
440
  spin {
441
441
  len1 = IO.tee(src, dest1, 1000)
442
442
  dest1.close
443
443
  len2 = IO.splice(src, dest2, 1000)
444
444
  dest2.close
445
445
  }
446
-
446
+
447
447
  src << 'foobar'
448
448
  src.close
449
449
  result1 = dest1.read
450
450
  result2 = dest2.read
451
-
451
+
452
452
  assert_equal 'foobar', result1
453
453
  assert_equal 6, len1
454
-
454
+
455
455
  assert_equal 'foobar', result2
456
456
  assert_equal 6, len2
457
457
  end
458
-
459
-
460
-
458
+
459
+
460
+
461
461
  end
462
462
 
463
463
  class IOWithRawBufferTest < MiniTest::Test
@@ -465,18 +465,18 @@ class IOWithRawBufferTest < MiniTest::Test
465
465
  super
466
466
  @i, @o = IO.pipe
467
467
  end
468
-
468
+
469
469
  def test_write_with_raw_buffer
470
470
  Polyphony.__with_raw_buffer__(64) do |b|
471
471
  Polyphony.__raw_buffer_set__(b, 'foobar')
472
472
  @o << b
473
473
  @o.close
474
474
  end
475
-
475
+
476
476
  str = @i.read
477
477
  assert_equal 'foobar', str
478
478
  end
479
-
479
+
480
480
  def test_read_with_raw_buffer
481
481
  @o << '*' * 65
482
482
  @o.close
@@ -485,7 +485,7 @@ class IOWithRawBufferTest < MiniTest::Test
485
485
  res = @i.read(64, b)
486
486
  assert_equal 64, res
487
487
  chunks << Polyphony.__raw_buffer_get__(b, res)
488
-
488
+
489
489
  res = @i.read(64, b)
490
490
  assert_equal 1, res
491
491
  assert_equal 64, Polyphony.__raw_buffer_size__(b)
@@ -501,88 +501,88 @@ class IOClassMethodsTest < MiniTest::Test
501
501
  assert_kind_of String, s
502
502
  assert !s.empty?
503
503
  assert_equal IO.orig_binread(__FILE__), s
504
-
504
+
505
505
  s = IO.binread(__FILE__, 100)
506
506
  assert_equal 100, s.bytesize
507
507
  assert_equal IO.orig_binread(__FILE__, 100), s
508
-
508
+
509
509
  s = IO.binread(__FILE__, 100, 2)
510
510
  assert_equal 100, s.bytesize
511
511
  assert_equal 'frozen', s[0..5]
512
512
  end
513
-
513
+
514
514
  BIN_DATA = "\x00\x01\x02\x03"
515
-
515
+
516
516
  def test_binwrite
517
517
  fn = '/tmp/test_binwrite'
518
518
  FileUtils.rm(fn) rescue nil
519
-
519
+
520
520
  len = IO.binwrite(fn, BIN_DATA)
521
521
  assert_equal 4, len
522
522
  s = IO.binread(fn)
523
523
  assert_equal BIN_DATA, s
524
524
  end
525
-
525
+
526
526
  def test_foreach
527
527
  lines = []
528
528
  IO.foreach(__FILE__) { |l| lines << l }
529
529
  assert_equal "# frozen_string_literal: true\n", lines[0]
530
530
  assert_equal "end\n", lines[-1]
531
531
  end
532
-
532
+
533
533
  def test_read_class_method
534
534
  s = IO.read(__FILE__)
535
535
  assert_kind_of String, s
536
536
  assert(!s.empty?)
537
537
  assert_equal IO.orig_read(__FILE__), s
538
-
538
+
539
539
  s = IO.read(__FILE__, 100)
540
540
  assert_equal 100, s.bytesize
541
541
  assert_equal IO.orig_read(__FILE__, 100), s
542
-
542
+
543
543
  s = IO.read(__FILE__, 100, 2)
544
544
  assert_equal 100, s.bytesize
545
545
  assert_equal 'frozen', s[0..5]
546
546
  end
547
-
547
+
548
548
  def test_readlines
549
549
  lines = IO.readlines(__FILE__)
550
550
  assert_equal "# frozen_string_literal: true\n", lines[0]
551
551
  assert_equal "end\n", lines[-1]
552
552
  end
553
-
553
+
554
554
  WRITE_DATA = "foo\nbar קוקו"
555
-
555
+
556
556
  def test_write_class_method
557
557
  fn = '/tmp/test_write'
558
558
  FileUtils.rm(fn) rescue nil
559
-
559
+
560
560
  len = IO.write(fn, WRITE_DATA)
561
561
  assert_equal WRITE_DATA.bytesize, len
562
562
  s = IO.read(fn)
563
563
  assert_equal WRITE_DATA, s
564
564
  end
565
-
565
+
566
566
  def test_popen
567
567
  skip unless IS_LINUX
568
-
568
+
569
569
  counter = 0
570
570
  timer = spin { throttled_loop(20) { counter += 1 } }
571
-
571
+
572
572
  IO.popen('sleep 0.5') { |io| io.read(8192) }
573
573
  assert(counter >= 5)
574
-
574
+
575
575
  result = nil
576
576
  IO.popen('echo "foo"') { |io| result = io.read(8192) }
577
577
  assert_equal "foo\n", result
578
578
  ensure
579
579
  timer&.stop
580
580
  end
581
-
581
+
582
582
  def test_kernel_gets
583
583
  counter = 0
584
584
  timer = spin { throttled_loop(200) { counter += 1 } }
585
-
585
+
586
586
  i, o = IO.pipe
587
587
  orig_stdin = $stdin
588
588
  $stdin = i
@@ -591,26 +591,26 @@ class IOClassMethodsTest < MiniTest::Test
591
591
  o.puts 'foo'
592
592
  o.close
593
593
  end
594
-
594
+
595
595
  assert(counter >= 0)
596
596
  assert_equal "foo\n", gets
597
597
  ensure
598
598
  $stdin = orig_stdin
599
599
  timer&.stop
600
600
  end
601
-
601
+
602
602
  def test_kernel_gets_with_argv
603
603
  ARGV << __FILE__
604
-
604
+
605
605
  s = StringIO.new(IO.orig_read(__FILE__))
606
-
606
+
607
607
  while (l = s.gets)
608
608
  assert_equal l, gets
609
609
  end
610
610
  ensure
611
611
  ARGV.delete __FILE__
612
612
  end
613
-
613
+
614
614
  def test_kernel_puts
615
615
  orig_stdout = $stdout
616
616
  o = eg(
@@ -619,15 +619,15 @@ class IOClassMethodsTest < MiniTest::Test
619
619
  flush: -> {},
620
620
  buf: -> { @buf }
621
621
  )
622
-
622
+
623
623
  $stdout = o
624
-
624
+
625
625
  puts 'foobar'
626
626
  assert_equal "foobar\n", o.buf
627
627
  ensure
628
628
  $stdout = orig_stdout
629
629
  end
630
-
630
+
631
631
  def test_read_large_file
632
632
  fn = '/tmp/test.txt'
633
633
  File.open(fn, 'w') { |f| f << ('*' * 1e6) }
@@ -635,7 +635,7 @@ class IOClassMethodsTest < MiniTest::Test
635
635
  assert_equal 1e6, s.bytesize
636
636
  assert s == IO.orig_read(fn)
637
637
  end
638
-
638
+
639
639
  def pipe_read
640
640
  i, o = IO.pipe
641
641
  yield o
@@ -644,37 +644,37 @@ class IOClassMethodsTest < MiniTest::Test
644
644
  ensure
645
645
  i.close
646
646
  end
647
-
647
+
648
648
  def test_puts
649
649
  assert_equal "foo\n", pipe_read { |f| f.puts 'foo' }
650
650
  assert_equal "foo\n", pipe_read { |f| f.puts "foo\n" }
651
651
  assert_equal "foo\nbar\n", pipe_read { |f| f.puts 'foo', 'bar' }
652
652
  assert_equal "foo\nbar\n", pipe_read { |f| f.puts 'foo', "bar\n" }
653
653
  end
654
-
654
+
655
655
  def test_read_loop
656
656
  i, o = IO.pipe
657
-
657
+
658
658
  buf = []
659
659
  f = spin do
660
660
  buf << :ready
661
661
  i.read_loop { |d| buf << d }
662
662
  buf << :done
663
663
  end
664
-
664
+
665
665
  # writing always causes snoozing
666
666
  o << 'foo'
667
667
  3.times { snooze }
668
668
  o << 'bar'
669
669
  o.close
670
-
670
+
671
671
  f.await
672
672
  assert_equal [:ready, 'foo', 'bar', :done], buf
673
673
  end
674
-
674
+
675
675
  def test_read_loop_with_max_len
676
676
  r, w = IO.pipe
677
-
677
+
678
678
  w << 'foobar'
679
679
  w.close
680
680
  buf = []
@@ -687,135 +687,135 @@ class IOExtensionsTest < MiniTest::Test
687
687
  def test_deflate
688
688
  i, o = IO.pipe
689
689
  r, w = IO.pipe
690
-
690
+
691
691
  ret = nil
692
692
  f = spin {
693
693
  ret = IO.deflate(i, w)
694
694
  w.close
695
695
  }
696
-
696
+
697
697
  o << 'foobar' * 20
698
698
  o.close
699
-
699
+
700
700
  f.await
701
701
  assert_equal 17, ret
702
-
702
+
703
703
  data = r.read
704
704
  msg = Zlib::Inflate.inflate(data)
705
705
  assert_equal 'foobar' * 20, msg
706
706
  end
707
-
707
+
708
708
  def test_deflate_to_string
709
709
  i, o = IO.pipe
710
710
  r, w = IO.pipe
711
711
  str = +''
712
-
712
+
713
713
  ret = nil
714
714
  f = spin {
715
715
  ret = IO.deflate(i, str)
716
716
  w << str
717
717
  w.close
718
718
  }
719
-
719
+
720
720
  o << 'foobar' * 20
721
721
  o.close
722
-
722
+
723
723
  f.await
724
724
  assert_equal 17, ret
725
-
725
+
726
726
  data = r.read
727
727
  msg = Zlib::Inflate.inflate(data)
728
728
  assert_equal 'foobar' * 20, msg
729
729
  end
730
-
730
+
731
731
  def test_deflate_to_frozen_string
732
732
  i, o = IO.pipe
733
733
  str = '' # frozen
734
-
734
+
735
735
  f = spin {
736
736
  o << 'foobar' * 20
737
737
  o.close
738
738
  }
739
-
739
+
740
740
  assert_raises(FrozenError) { IO.deflate(i, str) }
741
741
  end
742
-
742
+
743
743
  def test_deflate_from_string
744
744
  r, w = IO.pipe
745
745
  str = 'foobar' * 10000
746
746
  ret = nil
747
-
747
+
748
748
  f = spin {
749
749
  ret = IO.deflate(str, w)
750
750
  w.close
751
751
  }
752
752
  f.await
753
753
  assert_equal 118, ret
754
-
754
+
755
755
  data = r.read
756
756
  msg = Zlib::Inflate.inflate(data)
757
757
  assert_equal str, msg
758
758
  end
759
-
759
+
760
760
  def test_inflate
761
761
  i, o = IO.pipe
762
762
  r, w = IO.pipe
763
-
763
+
764
764
  spin {
765
765
  data = Zlib::Deflate.deflate('foobar', 9)
766
766
  o << data
767
767
  o.close
768
768
  }
769
-
769
+
770
770
  ret = IO.inflate(i, w)
771
771
  assert_equal 6, ret
772
772
  w.close
773
773
  msg = r.read
774
774
  assert_equal 'foobar', msg
775
775
  end
776
-
776
+
777
777
  def test_inflate_to_string
778
778
  i, o = IO.pipe
779
779
  str = +''
780
-
780
+
781
781
  spin {
782
782
  data = Zlib::Deflate.deflate('foobar', 9)
783
783
  o << data
784
784
  o.close
785
785
  }
786
-
786
+
787
787
  ret = IO.inflate(i, str)
788
788
  assert_equal 6, ret
789
789
  assert_equal 6, str.bytesize
790
790
  assert_equal 'foobar', str
791
791
  end
792
-
792
+
793
793
  def test_inflate_from_string
794
794
  r, w = IO.pipe
795
795
  str = Zlib::Deflate.deflate('foobar', 9)
796
-
796
+
797
797
  ret = IO.inflate(str, w)
798
798
  assert_equal 6, ret
799
799
  w.close
800
800
  msg = r.read
801
801
  assert_equal 'foobar', msg
802
802
  end
803
-
803
+
804
804
  def test_gzip
805
805
  src = Polyphony.pipe
806
806
  dest = Polyphony.pipe
807
807
  now = nil
808
-
808
+
809
809
  f = spin {
810
810
  now = Time.now
811
811
  IO.gzip(src, dest)
812
812
  dest.close
813
813
  }
814
-
814
+
815
815
  src << IO.read(__FILE__)
816
816
  src.close
817
817
  f.await
818
-
818
+
819
819
  gz = Zlib::GzipReader.new(dest)
820
820
  data = gz.read
821
821
  assert_equal IO.read(__FILE__), data
@@ -823,24 +823,24 @@ class IOExtensionsTest < MiniTest::Test
823
823
  assert_nil gz.orig_name
824
824
  assert_nil gz.comment
825
825
  end
826
-
826
+
827
827
  def test_gzip_to_string
828
828
  src = Polyphony.pipe
829
829
  dest = Polyphony.pipe
830
830
  str = +''
831
831
  now = nil
832
-
832
+
833
833
  f = spin {
834
834
  now = Time.now
835
835
  IO.gzip(src, str)
836
836
  dest << str
837
837
  dest.close
838
838
  }
839
-
839
+
840
840
  src << IO.read(__FILE__)
841
841
  src.close
842
842
  f.await
843
-
843
+
844
844
  gz = Zlib::GzipReader.new(dest)
845
845
  data = gz.read
846
846
  assert_equal IO.read(__FILE__), data
@@ -848,276 +848,276 @@ class IOExtensionsTest < MiniTest::Test
848
848
  assert_nil gz.orig_name
849
849
  assert_nil gz.comment
850
850
  end
851
-
851
+
852
852
  def test_gzip_from_string
853
853
  str = IO.read(__FILE__)
854
854
  dest = Polyphony.pipe
855
855
  now = nil
856
-
856
+
857
857
  IO.gzip(str, dest)
858
858
  dest.close
859
-
859
+
860
860
  gz = Zlib::GzipReader.new(dest)
861
861
  data = gz.read
862
862
  assert_equal IO.read(__FILE__), data
863
863
  end
864
-
864
+
865
865
  def test_gzip_return_value
866
866
  src = Polyphony.pipe
867
867
  dest = Polyphony.pipe
868
868
  now = nil
869
869
  ret = nil
870
-
870
+
871
871
  f = spin {
872
872
  now = Time.now
873
873
  ret = IO.gzip(src, dest)
874
874
  dest.close
875
875
  }
876
-
876
+
877
877
  src << IO.read(__FILE__)
878
878
  src.close
879
879
  f.await
880
-
880
+
881
881
  gzipped = dest.read
882
882
  assert_equal gzipped.bytesize, ret
883
883
  end
884
-
884
+
885
885
  def test_gzip_with_mtime_int
886
886
  src = Polyphony.pipe
887
887
  dest = Polyphony.pipe
888
-
888
+
889
889
  spin {
890
890
  IO.gzip(src, dest, mtime: 42)
891
891
  dest.close
892
892
  }
893
-
893
+
894
894
  src << IO.read(__FILE__)
895
895
  src.close
896
-
896
+
897
897
  gz = Zlib::GzipReader.new(dest)
898
898
  data = gz.read
899
899
  assert_equal IO.read(__FILE__), data
900
900
  assert_equal Time.at(42), gz.mtime
901
901
  end
902
-
902
+
903
903
  def test_gzip_with_mtime_false
904
904
  src = Polyphony.pipe
905
905
  dest = Polyphony.pipe
906
-
906
+
907
907
  spin {
908
908
  IO.gzip(src, dest, mtime: false)
909
909
  dest.close
910
910
  }
911
-
911
+
912
912
  src << IO.read(__FILE__)
913
913
  src.close
914
-
914
+
915
915
  gz = Zlib::GzipReader.new(dest)
916
916
  data = gz.read
917
917
  assert_equal IO.read(__FILE__), data
918
918
  assert_equal Time.at(0), gz.mtime
919
919
  end
920
-
920
+
921
921
  def test_gzip_with_mtime_time
922
922
  src = Polyphony.pipe
923
923
  dest = Polyphony.pipe
924
924
  t = Time.at(Time.now.to_i) - rand(300000)
925
-
925
+
926
926
  spin {
927
927
  IO.gzip(src, dest, mtime: t)
928
928
  dest.close
929
929
  }
930
-
930
+
931
931
  src << IO.read(__FILE__)
932
932
  src.close
933
-
933
+
934
934
  gz = Zlib::GzipReader.new(dest)
935
935
  data = gz.read
936
936
  assert_equal IO.read(__FILE__), data
937
937
  assert_equal t, gz.mtime
938
938
  end
939
-
939
+
940
940
  def test_gzip_with_orig_name
941
941
  src = Polyphony.pipe
942
942
  dest = Polyphony.pipe
943
-
943
+
944
944
  spin {
945
945
  IO.gzip(src, dest, orig_name: '/foo/bar')
946
946
  dest.close
947
947
  }
948
-
948
+
949
949
  src << IO.read(__FILE__)
950
950
  src.close
951
-
951
+
952
952
  gz = Zlib::GzipReader.new(dest)
953
953
  data = gz.read
954
954
  assert_equal IO.read(__FILE__), data
955
955
  assert_equal '/foo/bar', gz.orig_name
956
956
  end
957
-
957
+
958
958
  def test_gzip_with_comment
959
959
  src = Polyphony.pipe
960
960
  dest = Polyphony.pipe
961
-
961
+
962
962
  spin {
963
963
  IO.gzip(src, dest, comment: 'hello!')
964
964
  dest.close
965
965
  }
966
-
966
+
967
967
  src << IO.read(__FILE__)
968
968
  src.close
969
-
969
+
970
970
  gz = Zlib::GzipReader.new(dest)
971
971
  data = gz.read
972
972
  assert_equal IO.read(__FILE__), data
973
973
  assert_equal 'hello!', gz.comment
974
974
  end
975
-
975
+
976
976
  def test_gunzip
977
977
  src = Polyphony.pipe
978
978
  dest = Polyphony.pipe
979
979
  ret = nil
980
-
980
+
981
981
  f = spin {
982
982
  ret = IO.gunzip(src, dest)
983
983
  dest.close
984
984
  }
985
-
985
+
986
986
  gz = Zlib::GzipWriter.new(src, 9)
987
987
  gz << IO.read(__FILE__)
988
988
  gz.close
989
989
  f.await
990
-
990
+
991
991
  data = dest.read
992
992
  assert_equal IO.read(__FILE__).bytesize, ret
993
993
  assert_equal IO.read(__FILE__), data
994
994
  end
995
-
995
+
996
996
  def test_gunzip_to_string
997
997
  src = Polyphony.pipe
998
998
  str = +''
999
999
  ret = nil
1000
-
1000
+
1001
1001
  f = spin {
1002
1002
  ret = IO.gunzip(src, str)
1003
1003
  }
1004
-
1004
+
1005
1005
  gz = Zlib::GzipWriter.new(src, 9)
1006
1006
  gz << IO.read(__FILE__)
1007
1007
  gz.close
1008
1008
  f.await
1009
-
1009
+
1010
1010
  assert_equal IO.read(__FILE__).bytesize, ret
1011
1011
  assert_equal IO.read(__FILE__), str
1012
1012
  end
1013
-
1013
+
1014
1014
  def test_gunzip_from_string
1015
1015
  src_data = 'foobar' * 1000
1016
1016
  str = Zlib.gzip(src_data, level: 9)
1017
1017
  dest = Polyphony.pipe
1018
1018
  ret = IO.gunzip(str, dest)
1019
1019
  dest.close
1020
-
1020
+
1021
1021
  dest_data = dest.read
1022
1022
  assert_equal src_data.bytesize, ret
1023
1023
  assert_equal src_data, dest_data
1024
1024
  end
1025
-
1025
+
1026
1026
  def test_gunzip_multi
1027
1027
  src1 = Polyphony.pipe
1028
1028
  src2 = Polyphony.pipe
1029
1029
  dest = Polyphony.pipe
1030
-
1030
+
1031
1031
  spin {
1032
1032
  IO.gunzip(src1, dest)
1033
1033
  IO.gunzip(src2, dest)
1034
1034
  dest.close
1035
1035
  }
1036
-
1036
+
1037
1037
  gz1 = Zlib::GzipWriter.new(src1)
1038
1038
  gz1 << 'foobar'
1039
1039
  gz1.close
1040
-
1040
+
1041
1041
  gz1 = Zlib::GzipWriter.new(src2)
1042
1042
  gz1 << 'raboof'
1043
1043
  gz1.close
1044
-
1044
+
1045
1045
  data = dest.read
1046
1046
  assert_equal 'foobarraboof', data
1047
1047
  end
1048
-
1048
+
1049
1049
  def test_gzip_gunzip
1050
1050
  gzipped = Polyphony.pipe
1051
1051
  gunzipped = Polyphony.pipe
1052
-
1052
+
1053
1053
  spin { File.open(__FILE__, 'r') { |f| IO.gzip(f, gzipped) }; gzipped.close }
1054
1054
  spin { IO.gunzip(gzipped, gunzipped); gunzipped.close }
1055
-
1055
+
1056
1056
  data = gunzipped.read
1057
1057
  assert_equal IO.read(__FILE__), data
1058
1058
  end
1059
-
1059
+
1060
1060
  def test_gunzip_with_empty_info
1061
1061
  gzipped = Polyphony.pipe
1062
1062
  gunzipped = Polyphony.pipe
1063
1063
  info = {}
1064
-
1064
+
1065
1065
  spin {
1066
1066
  File.open(__FILE__, 'r') { |f| IO.gzip(f, gzipped, mtime: false) }
1067
1067
  gzipped.close
1068
1068
  }
1069
1069
  spin { IO.gunzip(gzipped, gunzipped, info); gunzipped.close }
1070
-
1070
+
1071
1071
  data = gunzipped.read
1072
1072
  assert_equal IO.read(__FILE__), data
1073
1073
  assert_equal Time.at(0), info[:mtime]
1074
1074
  assert_nil info[:orig_name]
1075
1075
  assert_nil info[:comment]
1076
1076
  end
1077
-
1077
+
1078
1078
  def test_gunzip_with_info
1079
1079
  src = Polyphony.pipe
1080
1080
  gzipped = Polyphony.pipe
1081
1081
  gunzipped = Polyphony.pipe
1082
-
1082
+
1083
1083
  src_info = {
1084
1084
  mtime: 42,
1085
1085
  orig_name: 'foo.bar',
1086
1086
  comment: 'hello!'
1087
1087
  }
1088
-
1088
+
1089
1089
  dest_info = {}
1090
-
1090
+
1091
1091
  spin { IO.gzip(src, gzipped, src_info); gzipped.close }
1092
1092
  spin { IO.gunzip(gzipped, gunzipped, dest_info); gunzipped.close }
1093
-
1093
+
1094
1094
  src << 'foobar'
1095
1095
  src.close
1096
-
1096
+
1097
1097
  data = gunzipped.read
1098
1098
  assert_equal 'foobar', data
1099
1099
  assert_equal Time.at(42), dest_info[:mtime]
1100
1100
  assert_equal 'foo.bar', dest_info[:orig_name]
1101
1101
  assert_equal 'hello!', dest_info[:comment]
1102
1102
  end
1103
-
1103
+
1104
1104
  def test_deflate_inflate_strings
1105
1105
  src_data = IO.read(__FILE__)
1106
1106
  deflated = +''
1107
1107
  IO.deflate(src_data, deflated)
1108
1108
  inflated = +''
1109
1109
  IO.inflate(deflated, inflated)
1110
-
1110
+
1111
1111
  assert_equal src_data, inflated
1112
1112
  end
1113
-
1113
+
1114
1114
  def test_gzip_gunzip_strings
1115
1115
  src_data = IO.read(__FILE__)
1116
1116
  gzipped = +''
1117
1117
  IO.gzip(src_data, gzipped)
1118
1118
  gunzipped = +''
1119
1119
  IO.gunzip(gzipped, gunzipped)
1120
-
1120
+
1121
1121
  assert_equal src_data, gunzipped
1122
1122
  end
1123
1123
  end
@@ -1135,7 +1135,7 @@ class IOIssuesTest < MiniTest::Test
1135
1135
  gz = Zlib::GzipReader.open('/tmp/test.gz')
1136
1136
  count = 0
1137
1137
  it = gz.each_line
1138
-
1138
+
1139
1139
  loop do
1140
1140
  it.next
1141
1141
  count += 1