uringmachine 0.21.0 → 0.22.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/.rubocop.yml +2 -0
- data/CHANGELOG.md +14 -0
- data/TODO.md +144 -0
- data/benchmark/README.md +173 -0
- data/benchmark/bm_io_pipe.rb +70 -0
- data/benchmark/bm_io_socketpair.rb +71 -0
- data/benchmark/bm_mutex_cpu.rb +57 -0
- data/benchmark/bm_mutex_io.rb +64 -0
- data/benchmark/bm_pg_client.rb +109 -0
- data/benchmark/bm_queue.rb +76 -0
- data/benchmark/chart.png +0 -0
- data/benchmark/common.rb +135 -0
- data/benchmark/dns_client.rb +47 -0
- data/{examples/bm_http_parse.rb → benchmark/http_parse.rb} +1 -1
- data/benchmark/run_bm.rb +8 -0
- data/benchmark/sqlite.rb +108 -0
- data/{examples/bm_write.rb → benchmark/write.rb} +4 -4
- data/ext/um/um.c +189 -100
- data/ext/um/um.h +36 -10
- data/ext/um/um_async_op.c +1 -1
- data/ext/um/um_class.c +87 -13
- data/ext/um/um_op.c +6 -0
- data/ext/um/um_sync.c +2 -2
- data/ext/um/um_utils.c +16 -0
- data/grant-2025/journal.md +118 -1
- data/grant-2025/tasks.md +48 -22
- data/lib/uringmachine/actor.rb +8 -0
- data/lib/uringmachine/dns_resolver.rb +1 -2
- data/lib/uringmachine/fiber_scheduler.rb +127 -81
- data/lib/uringmachine/version.rb +1 -1
- data/lib/uringmachine.rb +32 -3
- data/test/helper.rb +7 -18
- data/test/test_actor.rb +12 -3
- data/test/test_async_op.rb +10 -10
- data/test/test_fiber.rb +84 -1
- data/test/test_fiber_scheduler.rb +950 -47
- data/test/test_um.rb +297 -120
- data/uringmachine.gemspec +2 -1
- metadata +38 -16
- data/examples/bm_fileno.rb +0 -33
- data/examples/bm_queue.rb +0 -111
- data/examples/bm_side_running.rb +0 -83
- data/examples/bm_sqlite.rb +0 -89
- data/examples/dns_client.rb +0 -12
- /data/{examples/bm_mutex.rb → benchmark/mutex.rb} +0 -0
- /data/{examples/bm_mutex_single.rb → benchmark/mutex_single.rb} +0 -0
- /data/{examples/bm_send.rb → benchmark/send.rb} +0 -0
- /data/{examples/bm_snooze.rb → benchmark/snooze.rb} +0 -0
data/test/test_um.rb
CHANGED
|
@@ -11,15 +11,15 @@ class UringMachineTest < Minitest::Test
|
|
|
11
11
|
end
|
|
12
12
|
end
|
|
13
13
|
|
|
14
|
-
class
|
|
15
|
-
def
|
|
14
|
+
class SizeTest < Minitest::Test
|
|
15
|
+
def test_default_size
|
|
16
16
|
m = UM.new
|
|
17
|
-
assert_equal 4096, m.
|
|
17
|
+
assert_equal 4096, m.size
|
|
18
18
|
end
|
|
19
19
|
|
|
20
|
-
def
|
|
20
|
+
def test_custom_size_value
|
|
21
21
|
m = UM.new(13)
|
|
22
|
-
assert_equal 13, m.
|
|
22
|
+
assert_equal 13, m.size
|
|
23
23
|
end
|
|
24
24
|
end
|
|
25
25
|
|
|
@@ -73,15 +73,17 @@ class SubmitTest < UMBaseTest
|
|
|
73
73
|
def test_submit
|
|
74
74
|
_r, w = UM.pipe
|
|
75
75
|
|
|
76
|
+
assert_equal 0, machine.pending_fibers.size
|
|
76
77
|
machine.write_async(w, 'foo')
|
|
77
78
|
machine.write_async(w, 'bar')
|
|
78
79
|
machine.write_async(w, 'baz')
|
|
80
|
+
assert_equal 0, machine.pending_fibers.size
|
|
79
81
|
|
|
80
|
-
assert_equal 3, machine.
|
|
82
|
+
assert_equal 3, machine.metrics[:ops_pending]
|
|
81
83
|
assert_equal 3, machine.submit
|
|
82
84
|
assert_equal 0, machine.submit
|
|
83
85
|
machine.snooze
|
|
84
|
-
assert_equal 0, machine.
|
|
86
|
+
assert_equal 0, machine.metrics[:ops_pending]
|
|
85
87
|
end
|
|
86
88
|
end
|
|
87
89
|
|
|
@@ -109,7 +111,7 @@ end
|
|
|
109
111
|
|
|
110
112
|
class SnoozeTest < UMBaseTest
|
|
111
113
|
def test_snooze_while_sleeping_fiber
|
|
112
|
-
machine.spin do
|
|
114
|
+
f = machine.spin do
|
|
113
115
|
machine.sleep(0.1)
|
|
114
116
|
end
|
|
115
117
|
|
|
@@ -122,6 +124,9 @@ class SnoozeTest < UMBaseTest
|
|
|
122
124
|
machine.snooze
|
|
123
125
|
t1 = monotonic_clock
|
|
124
126
|
assert_in_range 0..0.001, t1 - t0
|
|
127
|
+
ensure
|
|
128
|
+
machine.schedule(f, nil)
|
|
129
|
+
machine.join(f)
|
|
125
130
|
end
|
|
126
131
|
end
|
|
127
132
|
|
|
@@ -133,7 +138,7 @@ class ScheduleTest < UMBaseTest
|
|
|
133
138
|
buf << [21, x]
|
|
134
139
|
machine.schedule(main, 21)
|
|
135
140
|
buf << 22
|
|
136
|
-
x = machine.
|
|
141
|
+
x = machine.switch
|
|
137
142
|
buf << [23, x]
|
|
138
143
|
end
|
|
139
144
|
|
|
@@ -152,11 +157,10 @@ class ScheduleTest < UMBaseTest
|
|
|
152
157
|
def test_schedule_exception
|
|
153
158
|
buf = []
|
|
154
159
|
f = Fiber.new do
|
|
155
|
-
# this should raise
|
|
156
|
-
machine.yield
|
|
160
|
+
machine.yield # this should raise
|
|
157
161
|
rescue Exception => e
|
|
158
162
|
buf << e
|
|
159
|
-
machine.
|
|
163
|
+
machine.switch
|
|
160
164
|
end
|
|
161
165
|
|
|
162
166
|
machine.schedule(f, nil)
|
|
@@ -176,19 +180,19 @@ class ScheduleTest < UMBaseTest
|
|
|
176
180
|
e = CustomError.new
|
|
177
181
|
f = Fiber.new do
|
|
178
182
|
machine.schedule(main, e)
|
|
179
|
-
machine.
|
|
183
|
+
machine.switch
|
|
180
184
|
end
|
|
181
185
|
|
|
182
186
|
machine.schedule(f, nil)
|
|
183
187
|
t0 = monotonic_clock
|
|
184
188
|
|
|
185
189
|
# the call to schedule means an op is checked out
|
|
186
|
-
assert_equal 0, machine.
|
|
190
|
+
assert_equal 0, machine.metrics[:ops_pending]
|
|
187
191
|
begin
|
|
188
192
|
machine.sleep(1)
|
|
189
193
|
rescue Exception => e2
|
|
190
194
|
end
|
|
191
|
-
assert_equal 0, machine.
|
|
195
|
+
assert_equal 0, machine.metrics[:ops_pending]
|
|
192
196
|
t1 = monotonic_clock
|
|
193
197
|
|
|
194
198
|
assert_equal e2, e
|
|
@@ -211,7 +215,7 @@ class ScheduleTest < UMBaseTest
|
|
|
211
215
|
buf << 5
|
|
212
216
|
end
|
|
213
217
|
|
|
214
|
-
assert_equal 0, machine.
|
|
218
|
+
assert_equal 0, machine.metrics[:ops_pending]
|
|
215
219
|
assert_equal [1, 2, 5], buf
|
|
216
220
|
assert_kind_of TOError, e
|
|
217
221
|
end
|
|
@@ -250,9 +254,9 @@ class ScheduleTest < UMBaseTest
|
|
|
250
254
|
rescue => e
|
|
251
255
|
end
|
|
252
256
|
|
|
253
|
-
assert_equal 1, machine.
|
|
257
|
+
assert_equal 1, machine.metrics[:ops_pending]
|
|
254
258
|
machine.sleep(0.01) # wait for cancelled CQEs
|
|
255
|
-
assert_equal 0, machine.
|
|
259
|
+
assert_equal 0, machine.metrics[:ops_pending]
|
|
256
260
|
|
|
257
261
|
assert_kind_of RuntimeError, e
|
|
258
262
|
assert_equal 'hi', e.message
|
|
@@ -263,9 +267,9 @@ class ScheduleTest < UMBaseTest
|
|
|
263
267
|
|
|
264
268
|
assert_equal 42, v
|
|
265
269
|
|
|
266
|
-
assert_equal 1, machine.
|
|
270
|
+
assert_equal 1, machine.metrics[:ops_pending]
|
|
267
271
|
machine.sleep 0.01 # wait for cancelled CQE
|
|
268
|
-
assert_equal 0, machine.
|
|
272
|
+
assert_equal 0, machine.metrics[:ops_pending]
|
|
269
273
|
end
|
|
270
274
|
|
|
271
275
|
def test_timeout_with_no_timeout
|
|
@@ -274,9 +278,9 @@ class ScheduleTest < UMBaseTest
|
|
|
274
278
|
|
|
275
279
|
assert_equal 3, v
|
|
276
280
|
|
|
277
|
-
assert_equal 1, machine.
|
|
281
|
+
assert_equal 1, machine.metrics[:ops_pending]
|
|
278
282
|
machine.sleep 0.01 # wait for cancelled CQE
|
|
279
|
-
assert_equal 0, machine.
|
|
283
|
+
assert_equal 0, machine.metrics[:ops_pending]
|
|
280
284
|
end
|
|
281
285
|
|
|
282
286
|
class TO2Error < RuntimeError; end
|
|
@@ -289,7 +293,7 @@ class ScheduleTest < UMBaseTest
|
|
|
289
293
|
machine.timeout(0.04, TOError) do
|
|
290
294
|
machine.timeout(0.02, TO2Error) do
|
|
291
295
|
machine.timeout(0.03, TO3Error) do
|
|
292
|
-
buf << machine.
|
|
296
|
+
buf << machine.metrics[:ops_pending]
|
|
293
297
|
machine.sleep(1)
|
|
294
298
|
end
|
|
295
299
|
end
|
|
@@ -297,9 +301,9 @@ class ScheduleTest < UMBaseTest
|
|
|
297
301
|
rescue => e
|
|
298
302
|
end
|
|
299
303
|
|
|
300
|
-
assert_equal 2, machine.
|
|
304
|
+
assert_equal 2, machine.metrics[:ops_pending]
|
|
301
305
|
machine.sleep(0.01) # wait for cancelled CQEs
|
|
302
|
-
assert_equal 0, machine.
|
|
306
|
+
assert_equal 0, machine.metrics[:ops_pending]
|
|
303
307
|
|
|
304
308
|
assert_kind_of TO2Error, e
|
|
305
309
|
assert_equal [3], buf
|
|
@@ -309,9 +313,9 @@ end
|
|
|
309
313
|
class SleepTest < UMBaseTest
|
|
310
314
|
def test_sleep
|
|
311
315
|
t0 = monotonic_clock
|
|
312
|
-
assert_equal 0, machine.
|
|
316
|
+
assert_equal 0, machine.metrics[:ops_pending]
|
|
313
317
|
res = machine.sleep(0.1)
|
|
314
|
-
assert_equal 0, machine.
|
|
318
|
+
assert_equal 0, machine.metrics[:ops_pending]
|
|
315
319
|
t1 = monotonic_clock
|
|
316
320
|
assert_in_range 0.09..0.13, t1 - t0
|
|
317
321
|
assert_equal 0.1, res
|
|
@@ -368,7 +372,7 @@ class PeriodicallyTest < UMBaseTest
|
|
|
368
372
|
cancel = 0
|
|
369
373
|
|
|
370
374
|
t0 = monotonic_clock
|
|
371
|
-
assert_equal 0, machine.
|
|
375
|
+
assert_equal 0, machine.metrics[:ops_pending]
|
|
372
376
|
begin
|
|
373
377
|
machine.periodically(0.01) do
|
|
374
378
|
count += 1
|
|
@@ -378,7 +382,7 @@ class PeriodicallyTest < UMBaseTest
|
|
|
378
382
|
cancel = 1
|
|
379
383
|
end
|
|
380
384
|
machine.snooze
|
|
381
|
-
assert_equal 0, machine.
|
|
385
|
+
assert_equal 0, machine.metrics[:ops_pending]
|
|
382
386
|
t1 = monotonic_clock
|
|
383
387
|
assert_in_range 0.05..0.09, t1 - t0
|
|
384
388
|
assert_equal 5, count
|
|
@@ -390,7 +394,7 @@ class PeriodicallyTest < UMBaseTest
|
|
|
390
394
|
cancel = 0
|
|
391
395
|
|
|
392
396
|
t0 = monotonic_clock
|
|
393
|
-
assert_equal 0, machine.
|
|
397
|
+
assert_equal 0, machine.metrics[:ops_pending]
|
|
394
398
|
begin
|
|
395
399
|
machine.timeout(0.05, Cancel) do
|
|
396
400
|
machine.periodically(0.01) do
|
|
@@ -413,21 +417,21 @@ class StatsTest < UMBaseTest
|
|
|
413
417
|
def test_op_counts
|
|
414
418
|
_r, w = IO.pipe
|
|
415
419
|
|
|
416
|
-
assert_equal 0, machine.
|
|
417
|
-
assert_equal 0, machine.
|
|
420
|
+
assert_equal 0, machine.metrics[:ops_pending]
|
|
421
|
+
assert_equal 0, machine.metrics[:total_ops]
|
|
418
422
|
machine.write_async(w.fileno, 'foo')
|
|
419
|
-
assert_equal 1, machine.
|
|
420
|
-
assert_equal 1, machine.
|
|
423
|
+
assert_equal 1, machine.metrics[:ops_pending]
|
|
424
|
+
assert_equal 1, machine.metrics[:total_ops]
|
|
421
425
|
machine.snooze
|
|
422
|
-
assert_equal 0, machine.
|
|
423
|
-
assert_equal 1, machine.
|
|
426
|
+
assert_equal 0, machine.metrics[:ops_pending]
|
|
427
|
+
assert_equal 1, machine.metrics[:total_ops]
|
|
424
428
|
|
|
425
429
|
machine.write_async(w.fileno, 'foo')
|
|
426
|
-
assert_equal 1, machine.
|
|
427
|
-
assert_equal 2, machine.
|
|
430
|
+
assert_equal 1, machine.metrics[:ops_pending]
|
|
431
|
+
assert_equal 2, machine.metrics[:total_ops]
|
|
428
432
|
machine.snooze
|
|
429
|
-
assert_equal 0, machine.
|
|
430
|
-
assert_equal 2, machine.
|
|
433
|
+
assert_equal 0, machine.metrics[:ops_pending]
|
|
434
|
+
assert_equal 2, machine.metrics[:total_ops]
|
|
431
435
|
end
|
|
432
436
|
end
|
|
433
437
|
|
|
@@ -437,9 +441,9 @@ class ReadTest < UMBaseTest
|
|
|
437
441
|
w << 'foobar'
|
|
438
442
|
|
|
439
443
|
buf = +''
|
|
440
|
-
assert_equal 0, machine.
|
|
444
|
+
assert_equal 0, machine.metrics[:ops_pending]
|
|
441
445
|
res = machine.read(r.fileno, buf, 3)
|
|
442
|
-
assert_equal 0, machine.
|
|
446
|
+
assert_equal 0, machine.metrics[:ops_pending]
|
|
443
447
|
assert_equal 3, res
|
|
444
448
|
assert_equal 'foo', buf
|
|
445
449
|
|
|
@@ -461,7 +465,7 @@ class ReadTest < UMBaseTest
|
|
|
461
465
|
assert_raises(Errno::EBADF) do
|
|
462
466
|
machine.read(w.fileno, +'', 8192)
|
|
463
467
|
end
|
|
464
|
-
assert_equal 0, machine.
|
|
468
|
+
assert_equal 0, machine.metrics[:ops_pending]
|
|
465
469
|
end
|
|
466
470
|
|
|
467
471
|
def test_read_with_buffer_offset
|
|
@@ -560,7 +564,7 @@ class ReadTest < UMBaseTest
|
|
|
560
564
|
end
|
|
561
565
|
|
|
562
566
|
def test_read_with_file_offset
|
|
563
|
-
fn = "/tmp
|
|
567
|
+
fn = "/tmp/um_#{SecureRandom.hex}"
|
|
564
568
|
IO.write(fn, 'foobar')
|
|
565
569
|
|
|
566
570
|
fd = machine.open(fn, UM::O_RDONLY)
|
|
@@ -570,6 +574,7 @@ class ReadTest < UMBaseTest
|
|
|
570
574
|
assert_equal 'obar', buffer
|
|
571
575
|
ensure
|
|
572
576
|
machine.close(fd)
|
|
577
|
+
FileUtils.rm(fn) rescue nil
|
|
573
578
|
end
|
|
574
579
|
end
|
|
575
580
|
|
|
@@ -590,7 +595,7 @@ class ReadEachTest < UMBaseTest
|
|
|
590
595
|
w << 'baz'
|
|
591
596
|
machine.sleep 0.02
|
|
592
597
|
w.close
|
|
593
|
-
machine.
|
|
598
|
+
machine.switch
|
|
594
599
|
end
|
|
595
600
|
|
|
596
601
|
machine.schedule(f, nil)
|
|
@@ -600,7 +605,7 @@ class ReadEachTest < UMBaseTest
|
|
|
600
605
|
end
|
|
601
606
|
|
|
602
607
|
assert_equal ['foo', 'bar', 'baz'], bufs
|
|
603
|
-
assert_equal 0, machine.
|
|
608
|
+
assert_equal 0, machine.metrics[:ops_pending]
|
|
604
609
|
end
|
|
605
610
|
|
|
606
611
|
# send once and close write fd
|
|
@@ -624,7 +629,7 @@ class ReadEachTest < UMBaseTest
|
|
|
624
629
|
|
|
625
630
|
assert_kind_of RuntimeError, e
|
|
626
631
|
assert_equal 'hi', e.message
|
|
627
|
-
assert_equal 0, machine.
|
|
632
|
+
assert_equal 0, machine.metrics[:ops_pending]
|
|
628
633
|
end
|
|
629
634
|
|
|
630
635
|
# send once and leave write fd open
|
|
@@ -649,7 +654,7 @@ class ReadEachTest < UMBaseTest
|
|
|
649
654
|
assert_equal 'hi', e.message
|
|
650
655
|
|
|
651
656
|
machine.snooze # in case the final CQE has not yet arrived
|
|
652
|
-
assert_equal 0, machine.
|
|
657
|
+
assert_equal 0, machine.metrics[:ops_pending]
|
|
653
658
|
end
|
|
654
659
|
|
|
655
660
|
# send twice
|
|
@@ -675,7 +680,7 @@ class ReadEachTest < UMBaseTest
|
|
|
675
680
|
assert_equal 'hi', e.message
|
|
676
681
|
|
|
677
682
|
machine.snooze # in case the final CQE has not yet arrived
|
|
678
|
-
assert_equal 0, machine.
|
|
683
|
+
assert_equal 0, machine.metrics[:ops_pending]
|
|
679
684
|
end
|
|
680
685
|
|
|
681
686
|
def test_read_each_break
|
|
@@ -699,7 +704,7 @@ class ReadEachTest < UMBaseTest
|
|
|
699
704
|
|
|
700
705
|
assert_equal ['foo'], bufs
|
|
701
706
|
machine.snooze # in case the final CQE has not yet arrived
|
|
702
|
-
assert_equal 0, machine.
|
|
707
|
+
assert_equal 0, machine.metrics[:ops_pending]
|
|
703
708
|
ensure
|
|
704
709
|
t&.kill
|
|
705
710
|
end
|
|
@@ -720,10 +725,10 @@ class WriteTest < UMBaseTest
|
|
|
720
725
|
def test_write
|
|
721
726
|
r, w = IO.pipe
|
|
722
727
|
|
|
723
|
-
assert_equal 0, machine.
|
|
728
|
+
assert_equal 0, machine.metrics[:ops_pending]
|
|
724
729
|
res = machine.write(w.fileno, 'foo')
|
|
725
730
|
assert_equal 3, res
|
|
726
|
-
assert_equal 0, machine.
|
|
731
|
+
assert_equal 0, machine.metrics[:ops_pending]
|
|
727
732
|
assert_equal 'foo', r.readpartial(3)
|
|
728
733
|
|
|
729
734
|
res = machine.write(w.fileno, 'bar', 2)
|
|
@@ -734,11 +739,11 @@ class WriteTest < UMBaseTest
|
|
|
734
739
|
def test_write_bad_fd
|
|
735
740
|
r, _w = IO.pipe
|
|
736
741
|
|
|
737
|
-
assert_equal 0, machine.
|
|
742
|
+
assert_equal 0, machine.metrics[:ops_pending]
|
|
738
743
|
assert_raises(Errno::EBADF) do
|
|
739
744
|
machine.write(r.fileno, 'foo')
|
|
740
745
|
end
|
|
741
|
-
assert_equal 0, machine.
|
|
746
|
+
assert_equal 0, machine.metrics[:ops_pending]
|
|
742
747
|
end
|
|
743
748
|
|
|
744
749
|
def test_write_zero_length
|
|
@@ -808,7 +813,7 @@ class WriteTest < UMBaseTest
|
|
|
808
813
|
end
|
|
809
814
|
|
|
810
815
|
def test_write_with_file_offset
|
|
811
|
-
fn = "/tmp
|
|
816
|
+
fn = "/tmp/um_#{SecureRandom.hex}"
|
|
812
817
|
IO.write(fn, 'foobar')
|
|
813
818
|
|
|
814
819
|
fd = machine.open(fn, UM::O_WRONLY)
|
|
@@ -817,47 +822,47 @@ class WriteTest < UMBaseTest
|
|
|
817
822
|
assert_equal 'fobazr', IO.read(fn)
|
|
818
823
|
ensure
|
|
819
824
|
machine.close(fd)
|
|
825
|
+
FileUtils.rm(fn) rescue nil
|
|
820
826
|
end
|
|
821
|
-
|
|
822
827
|
end
|
|
823
828
|
|
|
824
829
|
class WriteAsyncTest < UMBaseTest
|
|
825
830
|
def test_write_async
|
|
826
831
|
r, w = IO.pipe
|
|
827
832
|
|
|
828
|
-
assert_equal 0, machine.
|
|
833
|
+
assert_equal 0, machine.metrics[:ops_pending]
|
|
829
834
|
machine.write_async(w.fileno, 'foo')
|
|
830
|
-
assert_equal 1, machine.
|
|
835
|
+
assert_equal 1, machine.metrics[:ops_pending]
|
|
831
836
|
|
|
832
|
-
machine.snooze while machine.
|
|
833
|
-
assert_equal 0, machine.
|
|
837
|
+
machine.snooze while machine.metrics[:ops_pending] > 0
|
|
838
|
+
assert_equal 0, machine.metrics[:ops_pending]
|
|
834
839
|
assert_equal 'foo', r.readpartial(3)
|
|
835
840
|
end
|
|
836
841
|
|
|
837
842
|
def test_write_async_dynamic_string
|
|
838
843
|
r, w = IO.pipe
|
|
839
844
|
|
|
840
|
-
assert_equal 0, machine.
|
|
845
|
+
assert_equal 0, machine.metrics[:ops_pending]
|
|
841
846
|
str = "foo#{123}#{'bar' * 48}"
|
|
842
847
|
len = str.bytesize
|
|
843
848
|
machine.write_async(w.fileno, str)
|
|
844
849
|
str = nil
|
|
845
|
-
GC.start
|
|
846
|
-
assert_equal 1, machine.
|
|
850
|
+
# GC.start
|
|
851
|
+
assert_equal 1, machine.metrics[:ops_pending]
|
|
847
852
|
|
|
848
|
-
machine.snooze while machine.
|
|
849
|
-
assert_equal 0, machine.
|
|
853
|
+
machine.snooze while machine.metrics[:ops_pending] > 0
|
|
854
|
+
assert_equal 0, machine.metrics[:ops_pending]
|
|
850
855
|
assert_equal "foo#{123}#{'bar' * 48}", r.readpartial(len)
|
|
851
856
|
end
|
|
852
857
|
|
|
853
858
|
def test_write_async_bad_fd
|
|
854
859
|
r, _w = IO.pipe
|
|
855
860
|
|
|
856
|
-
assert_equal 0, machine.
|
|
861
|
+
assert_equal 0, machine.metrics[:ops_pending]
|
|
857
862
|
machine.write_async(r.fileno, 'foo')
|
|
858
|
-
assert_equal 1, machine.
|
|
863
|
+
assert_equal 1, machine.metrics[:ops_pending]
|
|
859
864
|
machine.snooze
|
|
860
|
-
assert_equal 0, machine.
|
|
865
|
+
assert_equal 0, machine.metrics[:ops_pending]
|
|
861
866
|
end
|
|
862
867
|
|
|
863
868
|
def test_write_async_io_buffer
|
|
@@ -868,7 +873,7 @@ class WriteAsyncTest < UMBaseTest
|
|
|
868
873
|
write_buffer.set_string(msg)
|
|
869
874
|
|
|
870
875
|
machine.write_async(w, write_buffer)
|
|
871
|
-
machine.snooze while machine.
|
|
876
|
+
machine.snooze while machine.metrics[:ops_pending] > 0
|
|
872
877
|
machine.close(w)
|
|
873
878
|
|
|
874
879
|
str = +''
|
|
@@ -885,27 +890,28 @@ class WriteAsyncTest < UMBaseTest
|
|
|
885
890
|
def test_write_async_with_len
|
|
886
891
|
r, w = IO.pipe
|
|
887
892
|
|
|
888
|
-
assert_equal 0, machine.
|
|
893
|
+
assert_equal 0, machine.metrics[:ops_pending]
|
|
889
894
|
machine.write_async(w.fileno, 'foobar', 4)
|
|
890
895
|
|
|
891
|
-
assert_equal 1, machine.
|
|
892
|
-
machine.snooze while machine.
|
|
893
|
-
assert_equal 0, machine.
|
|
896
|
+
assert_equal 1, machine.metrics[:ops_pending]
|
|
897
|
+
machine.snooze while machine.metrics[:ops_pending] > 0
|
|
898
|
+
assert_equal 0, machine.metrics[:ops_pending]
|
|
894
899
|
assert_equal 'foob', r.readpartial(6)
|
|
895
900
|
end
|
|
896
901
|
|
|
897
902
|
def test_write_async_with_file_offset
|
|
898
|
-
fn = "/tmp
|
|
903
|
+
fn = "/tmp/um_#{SecureRandom.hex}"
|
|
899
904
|
IO.write(fn, 'foobar')
|
|
900
905
|
|
|
901
906
|
fd = machine.open(fn, UM::O_WRONLY)
|
|
902
907
|
machine.write_async(fd, 'baz', -1, 2)
|
|
903
908
|
|
|
904
|
-
assert_equal 1, machine.
|
|
905
|
-
machine.snooze while machine.
|
|
909
|
+
assert_equal 1, machine.metrics[:ops_pending]
|
|
910
|
+
machine.snooze while machine.metrics[:ops_pending] > 0
|
|
906
911
|
assert_equal 'fobazr', IO.read(fn)
|
|
907
912
|
ensure
|
|
908
913
|
machine.close(fd)
|
|
914
|
+
FileUtils.rm(fn) rescue nil
|
|
909
915
|
end
|
|
910
916
|
end
|
|
911
917
|
|
|
@@ -915,9 +921,9 @@ class CloseTest < UMBaseTest
|
|
|
915
921
|
machine.write(w.fileno, 'foo')
|
|
916
922
|
assert_equal 'foo', r.readpartial(3)
|
|
917
923
|
|
|
918
|
-
assert_equal 0, machine.
|
|
924
|
+
assert_equal 0, machine.metrics[:ops_pending]
|
|
919
925
|
machine.close(w.fileno)
|
|
920
|
-
assert_equal 0, machine.
|
|
926
|
+
assert_equal 0, machine.metrics[:ops_pending]
|
|
921
927
|
assert_equal '', r.read
|
|
922
928
|
|
|
923
929
|
assert_raises(Errno::EBADF) { machine.close(w.fileno) }
|
|
@@ -937,18 +943,18 @@ class CloseAsyncTest < UMBaseTest
|
|
|
937
943
|
machine.write(w.fileno, 'foo')
|
|
938
944
|
assert_equal 'foo', r.readpartial(3)
|
|
939
945
|
|
|
940
|
-
assert_equal 0, machine.
|
|
941
|
-
machine.close_async(w.fileno)
|
|
942
|
-
assert_equal 1, machine.
|
|
946
|
+
assert_equal 0, machine.metrics[:ops_pending]
|
|
947
|
+
machine.close_async(w.fileno) # fire and forget
|
|
948
|
+
assert_equal 1, machine.metrics[:ops_pending]
|
|
943
949
|
machine.snooze
|
|
944
|
-
assert_equal 0, machine.
|
|
950
|
+
assert_equal 0, machine.metrics[:ops_pending]
|
|
945
951
|
assert_equal '', r.read
|
|
946
952
|
end
|
|
947
953
|
end
|
|
948
954
|
|
|
949
955
|
class ShutdownTest < UMBaseTest
|
|
950
956
|
def test_shutdown
|
|
951
|
-
c_fd, s_fd =
|
|
957
|
+
c_fd, s_fd = UM.socketpair(UM::AF_UNIX, UM::SOCK_STREAM, 0)
|
|
952
958
|
res = @machine.send(c_fd, 'abc', 3, 0)
|
|
953
959
|
assert_equal 3, res
|
|
954
960
|
|
|
@@ -980,7 +986,7 @@ end
|
|
|
980
986
|
|
|
981
987
|
class ShutdownAsyncTest < UMBaseTest
|
|
982
988
|
def test_shutdown_async
|
|
983
|
-
c_fd, s_fd =
|
|
989
|
+
c_fd, s_fd = UM.socketpair(UM::AF_UNIX, UM::SOCK_STREAM, 0)
|
|
984
990
|
res = @machine.send(c_fd, 'abc', 3, 0)
|
|
985
991
|
assert_equal 3, res
|
|
986
992
|
|
|
@@ -1024,9 +1030,9 @@ class AcceptTest < UMBaseTest
|
|
|
1024
1030
|
def test_accept
|
|
1025
1031
|
conn = TCPSocket.new('127.0.0.1', @port)
|
|
1026
1032
|
|
|
1027
|
-
assert_equal 0, machine.
|
|
1033
|
+
assert_equal 0, machine.metrics[:ops_pending]
|
|
1028
1034
|
fd = machine.accept(@server.fileno)
|
|
1029
|
-
assert_equal 0, machine.
|
|
1035
|
+
assert_equal 0, machine.metrics[:ops_pending]
|
|
1030
1036
|
assert_kind_of Integer, fd
|
|
1031
1037
|
assert fd > 0
|
|
1032
1038
|
|
|
@@ -1063,7 +1069,7 @@ class AcceptEachTest < UMBaseTest
|
|
|
1063
1069
|
end
|
|
1064
1070
|
|
|
1065
1071
|
assert_equal 3, count
|
|
1066
|
-
assert_equal 0, machine.
|
|
1072
|
+
assert_equal 0, machine.metrics[:ops_pending]
|
|
1067
1073
|
ensure
|
|
1068
1074
|
t&.kill
|
|
1069
1075
|
end
|
|
@@ -1098,9 +1104,9 @@ end
|
|
|
1098
1104
|
|
|
1099
1105
|
class SocketTest < UMBaseTest
|
|
1100
1106
|
def test_socket
|
|
1101
|
-
assert_equal 0, machine.
|
|
1107
|
+
assert_equal 0, machine.metrics[:ops_pending]
|
|
1102
1108
|
fd = machine.socket(UM::AF_INET, UM::SOCK_DGRAM, 0, 0);
|
|
1103
|
-
assert_equal 0, machine.
|
|
1109
|
+
assert_equal 0, machine.metrics[:ops_pending]
|
|
1104
1110
|
assert_kind_of Integer, fd
|
|
1105
1111
|
assert fd > 0
|
|
1106
1112
|
|
|
@@ -1128,9 +1134,9 @@ class ConnectTest < UMBaseTest
|
|
|
1128
1134
|
end
|
|
1129
1135
|
|
|
1130
1136
|
fd = machine.socket(UM::AF_INET, UM::SOCK_STREAM, 0, 0)
|
|
1131
|
-
assert_equal 0, machine.
|
|
1137
|
+
assert_equal 0, machine.metrics[:ops_pending]
|
|
1132
1138
|
res = machine.connect(fd, '127.0.0.1', @port)
|
|
1133
|
-
assert_equal 0, machine.
|
|
1139
|
+
assert_equal 0, machine.metrics[:ops_pending]
|
|
1134
1140
|
assert_equal 0, res
|
|
1135
1141
|
|
|
1136
1142
|
buf = +''
|
|
@@ -1143,9 +1149,9 @@ class ConnectTest < UMBaseTest
|
|
|
1143
1149
|
|
|
1144
1150
|
def test_connect_with_bad_addr
|
|
1145
1151
|
fd = machine.socket(UM::AF_INET, UM::SOCK_STREAM, 0, 0);
|
|
1146
|
-
assert_equal 0, machine.
|
|
1152
|
+
assert_equal 0, machine.metrics[:ops_pending]
|
|
1147
1153
|
assert_raises(Errno::ENETUNREACH) { machine.connect(fd, 'a.b.c.d', @port) }
|
|
1148
|
-
assert_equal 0, machine.
|
|
1154
|
+
assert_equal 0, machine.metrics[:ops_pending]
|
|
1149
1155
|
end
|
|
1150
1156
|
end
|
|
1151
1157
|
|
|
@@ -1361,11 +1367,11 @@ class BindTest < UMBaseTest
|
|
|
1361
1367
|
end
|
|
1362
1368
|
|
|
1363
1369
|
def test_bind
|
|
1364
|
-
assert_equal 0, machine.
|
|
1370
|
+
assert_equal 0, machine.metrics[:ops_pending]
|
|
1365
1371
|
fd = machine.socket(UM::AF_INET, UM::SOCK_DGRAM, 0, 0)
|
|
1366
1372
|
res = machine.bind(fd, '127.0.0.1', @port)
|
|
1367
1373
|
assert_equal 0, res
|
|
1368
|
-
assert_equal 0, machine.
|
|
1374
|
+
assert_equal 0, machine.metrics[:ops_pending]
|
|
1369
1375
|
|
|
1370
1376
|
peer = UDPSocket.new
|
|
1371
1377
|
peer.connect('127.0.0.1', @port)
|
|
@@ -1378,13 +1384,13 @@ class BindTest < UMBaseTest
|
|
|
1378
1384
|
end
|
|
1379
1385
|
|
|
1380
1386
|
def test_bind_invalid_args
|
|
1381
|
-
assert_equal 0, machine.
|
|
1387
|
+
assert_equal 0, machine.metrics[:ops_pending]
|
|
1382
1388
|
|
|
1383
1389
|
fd = machine.socket(UM::AF_INET, UM::SOCK_DGRAM, 0, 0)
|
|
1384
1390
|
assert_raises(Errno::EACCES) { machine.bind(fd, 'foo.bar.baz', 3) }
|
|
1385
1391
|
assert_raises(Errno::EBADF) { machine.bind(-3, '127.0.01', 1234) }
|
|
1386
1392
|
|
|
1387
|
-
assert_equal 0, machine.
|
|
1393
|
+
assert_equal 0, machine.metrics[:ops_pending]
|
|
1388
1394
|
end
|
|
1389
1395
|
end
|
|
1390
1396
|
|
|
@@ -1399,7 +1405,7 @@ class ListenTest < UMBaseTest
|
|
|
1399
1405
|
machine.bind(fd, '127.0.0.1', @port)
|
|
1400
1406
|
res = machine.listen(fd, 5)
|
|
1401
1407
|
assert_equal 0, res
|
|
1402
|
-
assert_equal 0, machine.
|
|
1408
|
+
assert_equal 0, machine.metrics[:ops_pending]
|
|
1403
1409
|
|
|
1404
1410
|
conn = nil
|
|
1405
1411
|
t = Thread.new do
|
|
@@ -1453,12 +1459,11 @@ class SynchronizeTest < UMBaseTest
|
|
|
1453
1459
|
end
|
|
1454
1460
|
|
|
1455
1461
|
assert_equal [1, 2], buf
|
|
1456
|
-
assert_equal 0, machine.
|
|
1462
|
+
assert_equal 0, machine.metrics[:ops_pending]
|
|
1457
1463
|
end
|
|
1458
1464
|
|
|
1459
1465
|
def test_synchronize_pair
|
|
1460
1466
|
m = UM::Mutex.new
|
|
1461
|
-
|
|
1462
1467
|
buf = []
|
|
1463
1468
|
|
|
1464
1469
|
f1 = Fiber.new do
|
|
@@ -1468,7 +1473,7 @@ class SynchronizeTest < UMBaseTest
|
|
|
1468
1473
|
buf << 12
|
|
1469
1474
|
end
|
|
1470
1475
|
buf << 13
|
|
1471
|
-
machine.
|
|
1476
|
+
machine.switch
|
|
1472
1477
|
end
|
|
1473
1478
|
|
|
1474
1479
|
f2 = Fiber.new do
|
|
@@ -1478,7 +1483,7 @@ class SynchronizeTest < UMBaseTest
|
|
|
1478
1483
|
buf << 22
|
|
1479
1484
|
end
|
|
1480
1485
|
buf << 23
|
|
1481
|
-
machine.
|
|
1486
|
+
machine.switch
|
|
1482
1487
|
end
|
|
1483
1488
|
|
|
1484
1489
|
machine.schedule(f1, nil)
|
|
@@ -1486,7 +1491,7 @@ class SynchronizeTest < UMBaseTest
|
|
|
1486
1491
|
|
|
1487
1492
|
machine.sleep(0.03)
|
|
1488
1493
|
assert_equal [11, 12, 13, 21, 22, 23], buf
|
|
1489
|
-
assert_equal 0, machine.
|
|
1494
|
+
assert_equal 0, machine.metrics[:ops_pending]
|
|
1490
1495
|
end
|
|
1491
1496
|
|
|
1492
1497
|
def test_synchronize_multi
|
|
@@ -1537,12 +1542,12 @@ class QueueTest < UMBaseTest
|
|
|
1537
1542
|
|
|
1538
1543
|
machine.snooze
|
|
1539
1544
|
assert_equal [], buf
|
|
1540
|
-
assert_equal 2, machine.
|
|
1545
|
+
assert_equal 2, machine.metrics[:ops_pending]
|
|
1541
1546
|
|
|
1542
1547
|
machine.push(q, :foo)
|
|
1543
1548
|
assert_equal 1, q.count
|
|
1544
1549
|
machine.snooze
|
|
1545
|
-
assert_equal 1, machine.
|
|
1550
|
+
assert_equal 1, machine.metrics[:ops_pending]
|
|
1546
1551
|
assert_equal [[1, :foo]], buf
|
|
1547
1552
|
|
|
1548
1553
|
machine.push(q, :bar)
|
|
@@ -1563,13 +1568,13 @@ class QueueTest < UMBaseTest
|
|
|
1563
1568
|
|
|
1564
1569
|
f1 = Fiber.new do
|
|
1565
1570
|
buf << [1, machine.pop(q)]
|
|
1566
|
-
machine.
|
|
1571
|
+
machine.switch
|
|
1567
1572
|
end
|
|
1568
1573
|
machine.schedule(f1, nil)
|
|
1569
1574
|
|
|
1570
1575
|
f2 = Fiber.new do
|
|
1571
1576
|
buf << [2, machine.pop(q)]
|
|
1572
|
-
machine.
|
|
1577
|
+
machine.switch
|
|
1573
1578
|
end
|
|
1574
1579
|
machine.schedule(f2, nil)
|
|
1575
1580
|
|
|
@@ -1588,13 +1593,13 @@ class QueueTest < UMBaseTest
|
|
|
1588
1593
|
|
|
1589
1594
|
f1 = Fiber.new do
|
|
1590
1595
|
buf << [1, machine.pop(q)]
|
|
1591
|
-
machine.
|
|
1596
|
+
machine.switch
|
|
1592
1597
|
end
|
|
1593
1598
|
machine.schedule(f1, nil)
|
|
1594
1599
|
|
|
1595
1600
|
f2 = Fiber.new do
|
|
1596
1601
|
buf << [2, machine.pop(q)]
|
|
1597
|
-
machine.
|
|
1602
|
+
machine.switch
|
|
1598
1603
|
end
|
|
1599
1604
|
machine.schedule(f2, nil)
|
|
1600
1605
|
|
|
@@ -1701,38 +1706,40 @@ class QueueTest < UMBaseTest
|
|
|
1701
1706
|
end
|
|
1702
1707
|
|
|
1703
1708
|
class OpenTest < UMBaseTest
|
|
1704
|
-
PATH = '/tmp/um_open_test'
|
|
1705
|
-
|
|
1706
1709
|
def setup
|
|
1707
1710
|
super
|
|
1708
|
-
|
|
1711
|
+
@fn = "/tmp/um_#{SecureRandom.hex}"
|
|
1712
|
+
end
|
|
1713
|
+
|
|
1714
|
+
def teardown
|
|
1715
|
+
FileUtils.rm(@fn) rescue nil
|
|
1709
1716
|
end
|
|
1710
1717
|
|
|
1711
1718
|
def test_open
|
|
1712
|
-
fd = machine.open(
|
|
1719
|
+
fd = machine.open(@fn, UM::O_CREAT | UM::O_WRONLY)
|
|
1713
1720
|
assert_kind_of Integer, fd
|
|
1714
|
-
assert File.file?(
|
|
1721
|
+
assert File.file?(@fn)
|
|
1715
1722
|
|
|
1716
1723
|
machine.write(fd, 'foo')
|
|
1717
1724
|
machine.close(fd)
|
|
1718
1725
|
|
|
1719
|
-
assert_equal 'foo', IO.read(
|
|
1726
|
+
assert_equal 'foo', IO.read(@fn)
|
|
1720
1727
|
end
|
|
1721
1728
|
|
|
1722
1729
|
def test_open_with_block
|
|
1723
|
-
res = machine.open(
|
|
1730
|
+
res = machine.open(@fn, UM::O_CREAT | UM::O_WRONLY) do |fd|
|
|
1724
1731
|
machine.write(fd, 'bar')
|
|
1725
1732
|
fd
|
|
1726
1733
|
end
|
|
1727
1734
|
|
|
1728
1735
|
assert_kind_of Integer, res
|
|
1729
1736
|
assert_raises(Errno::EBADF) { machine.close(res) }
|
|
1730
|
-
assert_equal 'bar', IO.read(
|
|
1737
|
+
assert_equal 'bar', IO.read(@fn)
|
|
1731
1738
|
end
|
|
1732
1739
|
|
|
1733
1740
|
def test_open_bad_arg
|
|
1734
|
-
assert_raises(Errno::ENOENT) { machine.open(
|
|
1735
|
-
assert_raises(Errno::ENOENT) { machine.open(
|
|
1741
|
+
assert_raises(Errno::ENOENT) { machine.open(@fn, UM::O_RDONLY) }
|
|
1742
|
+
assert_raises(Errno::ENOENT) { machine.open(@fn, UM::O_RDONLY) {} }
|
|
1736
1743
|
end
|
|
1737
1744
|
end
|
|
1738
1745
|
|
|
@@ -1756,6 +1763,26 @@ class PipeTest < UMBaseTest
|
|
|
1756
1763
|
end
|
|
1757
1764
|
end
|
|
1758
1765
|
|
|
1766
|
+
class SocketpairTest < UMBaseTest
|
|
1767
|
+
def test_socketpair
|
|
1768
|
+
rfd, wfd = UM.socketpair(UM::AF_UNIX, UM::SOCK_STREAM, 0)
|
|
1769
|
+
ret = machine.write(wfd, 'foo')
|
|
1770
|
+
assert_equal 3, ret
|
|
1771
|
+
|
|
1772
|
+
ret = machine.close(wfd)
|
|
1773
|
+
assert_equal wfd, ret
|
|
1774
|
+
|
|
1775
|
+
buf = +''
|
|
1776
|
+
ret = machine.read(rfd, buf, 8192)
|
|
1777
|
+
|
|
1778
|
+
assert_equal 3, ret
|
|
1779
|
+
assert_equal 'foo', buf
|
|
1780
|
+
|
|
1781
|
+
ret = machine.close(rfd)
|
|
1782
|
+
assert_equal rfd, ret
|
|
1783
|
+
end
|
|
1784
|
+
end
|
|
1785
|
+
|
|
1759
1786
|
class PidfdTest < UMBaseTest
|
|
1760
1787
|
def test_pidfd_open
|
|
1761
1788
|
pid = fork { exit 13 }
|
|
@@ -2167,7 +2194,7 @@ end
|
|
|
2167
2194
|
class SendBundleTest < UMBaseTest
|
|
2168
2195
|
def setup
|
|
2169
2196
|
super
|
|
2170
|
-
@client_fd, @server_fd =
|
|
2197
|
+
@client_fd, @server_fd = UM.socketpair(UM::AF_UNIX, UM::SOCK_STREAM, 0)
|
|
2171
2198
|
end
|
|
2172
2199
|
|
|
2173
2200
|
def test_send_bundle_splat
|
|
@@ -2241,3 +2268,153 @@ class NonBlockTest < UMBaseTest
|
|
|
2241
2268
|
assert_equal true, UM.io_nonblock?(r)
|
|
2242
2269
|
end
|
|
2243
2270
|
end
|
|
2271
|
+
|
|
2272
|
+
class MetricsTest < UMBaseTest
|
|
2273
|
+
def test_metrics_empty
|
|
2274
|
+
assert_equal({
|
|
2275
|
+
size: 4096,
|
|
2276
|
+
total_ops: 0,
|
|
2277
|
+
total_switches: 0,
|
|
2278
|
+
total_waits: 0,
|
|
2279
|
+
ops_pending: 0,
|
|
2280
|
+
ops_unsubmitted: 0,
|
|
2281
|
+
ops_runqueue: 0,
|
|
2282
|
+
ops_free: 0,
|
|
2283
|
+
ops_transient: 0
|
|
2284
|
+
}, machine.metrics)
|
|
2285
|
+
end
|
|
2286
|
+
|
|
2287
|
+
def test_metrics_size
|
|
2288
|
+
m = UM.new(13)
|
|
2289
|
+
assert_equal 13, m.metrics[:size]
|
|
2290
|
+
end
|
|
2291
|
+
|
|
2292
|
+
def test_metrics_total_counters
|
|
2293
|
+
r, w = UM.pipe
|
|
2294
|
+
machine.write(w, 'foo')
|
|
2295
|
+
assert_equal 1, machine.metrics[:total_ops]
|
|
2296
|
+
assert_equal 1, machine.metrics[:total_switches]
|
|
2297
|
+
assert_equal 1, machine.metrics[:total_waits]
|
|
2298
|
+
machine.write_async(w, 'bar')
|
|
2299
|
+
assert_equal 2, machine.metrics[:total_ops]
|
|
2300
|
+
assert_equal 1, machine.metrics[:total_switches]
|
|
2301
|
+
assert_equal 1, machine.metrics[:total_waits]
|
|
2302
|
+
machine.snooze
|
|
2303
|
+
assert_equal 2, machine.metrics[:total_ops]
|
|
2304
|
+
assert_equal 2, machine.metrics[:total_switches]
|
|
2305
|
+
assert_equal 2, machine.metrics[:total_waits]
|
|
2306
|
+
machine.close(w)
|
|
2307
|
+
assert_equal 3, machine.metrics[:total_ops]
|
|
2308
|
+
assert_equal 3, machine.metrics[:total_switches]
|
|
2309
|
+
assert_equal 3, machine.metrics[:total_waits]
|
|
2310
|
+
ensure
|
|
2311
|
+
machine.close(r) rescue nil
|
|
2312
|
+
machine.close(w) rescue nil
|
|
2313
|
+
end
|
|
2314
|
+
|
|
2315
|
+
def test_metrics_total_switches
|
|
2316
|
+
f1 = machine.spin { 3.times { machine.snooze } }
|
|
2317
|
+
f2 = machine.spin { machine.sleep(0.01) }
|
|
2318
|
+
assert_equal 0, machine.metrics[:total_switches]
|
|
2319
|
+
machine.snooze
|
|
2320
|
+
assert_equal 3, machine.metrics[:total_switches]
|
|
2321
|
+
machine.snooze
|
|
2322
|
+
assert_equal 5, machine.metrics[:total_switches]
|
|
2323
|
+
machine.join(f2)
|
|
2324
|
+
assert_equal 9, machine.metrics[:total_switches]
|
|
2325
|
+
ensure
|
|
2326
|
+
machine.join(f1, f2)
|
|
2327
|
+
end
|
|
2328
|
+
|
|
2329
|
+
def test_metrics_total_waits
|
|
2330
|
+
r, w = UM.pipe
|
|
2331
|
+
|
|
2332
|
+
machine.sleep(0.001)
|
|
2333
|
+
assert_equal 1, machine.metrics[:total_waits]
|
|
2334
|
+
|
|
2335
|
+
machine.write_async(w, 'foo')
|
|
2336
|
+
assert_equal 1, machine.metrics[:total_waits]
|
|
2337
|
+
|
|
2338
|
+
res = machine.read(r, +'', 3)
|
|
2339
|
+
assert_equal 2, machine.metrics[:total_waits]
|
|
2340
|
+
assert_equal 3, res
|
|
2341
|
+
|
|
2342
|
+
machine.close_async(w)
|
|
2343
|
+
assert_equal 2, machine.metrics[:total_waits]
|
|
2344
|
+
|
|
2345
|
+
machine.snooze
|
|
2346
|
+
assert_equal 3, machine.metrics[:total_waits]
|
|
2347
|
+
ensure
|
|
2348
|
+
machine.close(r) rescue nil
|
|
2349
|
+
machine.close(w) rescue nil
|
|
2350
|
+
end
|
|
2351
|
+
|
|
2352
|
+
def ops_metrics
|
|
2353
|
+
machine.metrics.values_at(
|
|
2354
|
+
:ops_pending,
|
|
2355
|
+
:ops_unsubmitted,
|
|
2356
|
+
:ops_runqueue,
|
|
2357
|
+
:ops_free,
|
|
2358
|
+
:ops_transient
|
|
2359
|
+
)
|
|
2360
|
+
end
|
|
2361
|
+
|
|
2362
|
+
def test_metrics_ops
|
|
2363
|
+
r, w = UM.pipe
|
|
2364
|
+
|
|
2365
|
+
f = machine.spin { machine.sleep(0.001) }
|
|
2366
|
+
assert_equal [0, 0, 1, 0, 0], ops_metrics
|
|
2367
|
+
machine.snooze
|
|
2368
|
+
assert_equal [1, 1, 0, 2, 0], ops_metrics
|
|
2369
|
+
machine.submit
|
|
2370
|
+
assert_equal [1, 0, 0, 2, 0], ops_metrics
|
|
2371
|
+
machine.join(f)
|
|
2372
|
+
assert_equal [0, 0, 0, 2, 0], ops_metrics
|
|
2373
|
+
|
|
2374
|
+
machine.write_async(w, 'foo')
|
|
2375
|
+
assert_equal [1, 1, 0, 1, 1], ops_metrics
|
|
2376
|
+
machine.submit
|
|
2377
|
+
assert_equal [1, 0, 0, 1, 1], ops_metrics
|
|
2378
|
+
machine.snooze
|
|
2379
|
+
assert_equal [0, 0, 0, 2, 0], ops_metrics
|
|
2380
|
+
|
|
2381
|
+
machine.write_async(w, 'foo')
|
|
2382
|
+
assert_equal [1, 1, 0, 1, 1], ops_metrics
|
|
2383
|
+
machine.snooze
|
|
2384
|
+
assert_equal [0, 0, 0, 2, 0], ops_metrics
|
|
2385
|
+
ensure
|
|
2386
|
+
machine.join(f)
|
|
2387
|
+
end
|
|
2388
|
+
end
|
|
2389
|
+
|
|
2390
|
+
class ProfileModeTest < UMBaseTest
|
|
2391
|
+
def test_profile_mode_empty
|
|
2392
|
+
assert_equal false, machine.profile?
|
|
2393
|
+
assert_equal([
|
|
2394
|
+
:size, :total_ops, :total_switches, :total_waits, :ops_pending,
|
|
2395
|
+
:ops_unsubmitted, :ops_runqueue, :ops_free, :ops_transient
|
|
2396
|
+
], machine.metrics.keys)
|
|
2397
|
+
|
|
2398
|
+
machine.profile(true)
|
|
2399
|
+
assert_equal true, machine.profile?
|
|
2400
|
+
assert_equal([
|
|
2401
|
+
:size, :total_ops, :total_switches, :total_waits, :ops_pending,
|
|
2402
|
+
:ops_unsubmitted, :ops_runqueue, :ops_free, :ops_transient,
|
|
2403
|
+
:time_total_cpu, :time_total_wait,
|
|
2404
|
+
], machine.metrics.keys)
|
|
2405
|
+
|
|
2406
|
+
machine.profile(false)
|
|
2407
|
+
assert_equal false, machine.profile?
|
|
2408
|
+
assert_equal([
|
|
2409
|
+
:size, :total_ops, :total_switches, :total_waits, :ops_pending,
|
|
2410
|
+
:ops_unsubmitted, :ops_runqueue, :ops_free, :ops_transient
|
|
2411
|
+
], machine.metrics.keys)
|
|
2412
|
+
end
|
|
2413
|
+
|
|
2414
|
+
def test_profile_mode_total_times
|
|
2415
|
+
machine.profile(true)
|
|
2416
|
+
machine.sleep(0.01)
|
|
2417
|
+
assert_in_range 0.0..0.0005, machine.metrics[:time_total_cpu]
|
|
2418
|
+
assert_in_range 0.01..0.015, machine.metrics[:time_total_wait]
|
|
2419
|
+
end
|
|
2420
|
+
end
|