fiber_scheduler_spec 0.0.1 → 0.0.2
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/lib/fiber_scheduler_spec/address_resolve.rb +47 -0
- data/lib/fiber_scheduler_spec/block_unblock.rb +53 -0
- data/lib/fiber_scheduler_spec/close.rb +83 -0
- data/lib/fiber_scheduler_spec/context.rb +30 -0
- data/lib/fiber_scheduler_spec/fiber.rb +48 -0
- data/lib/fiber_scheduler_spec/io_wait.rb +82 -0
- data/lib/fiber_scheduler_spec/kernel_sleep.rb +97 -0
- data/lib/fiber_scheduler_spec/process_wait.rb +61 -0
- data/lib/fiber_scheduler_spec/socket_io.rb +62 -0
- data/lib/fiber_scheduler_spec/timeout_after.rb +87 -0
- data/lib/fiber_scheduler_spec/version.rb +1 -1
- data/lib/fiber_scheduler_spec.rb +20 -1
- metadata +12 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: c1e20ced7c55e6f9566d1a0e802f217e0981be4ab4d2ccbd5c27ac9604e43f7b
|
4
|
+
data.tar.gz: 5b2234c2a5dee08864e7cbbd27105c9e1b70e610c379afbd74b6c86ab38e2d88
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: a7baa25d93db508fb5dde06e91979c30df901b817e5dc878369873c9932af07a0c2be2e4587be3160c1c43e0672e0872470032dc600135585cf6fe9b97200405
|
7
|
+
data.tar.gz: 20471ba20badf88e691affb068309e7734a67d1f73e9d8d272d6de460040795b1b8e305fb09221908cdcdf9a281d6d066309d56d7f733c4cd126499669c33928
|
@@ -0,0 +1,47 @@
|
|
1
|
+
require "rspec"
|
2
|
+
require "socket"
|
3
|
+
require_relative "context"
|
4
|
+
|
5
|
+
module FiberSchedulerSpec
|
6
|
+
module AddressResolve
|
7
|
+
end
|
8
|
+
end
|
9
|
+
|
10
|
+
RSpec.shared_examples FiberSchedulerSpec::AddressResolve do
|
11
|
+
include_context FiberSchedulerSpec::Context
|
12
|
+
|
13
|
+
context "Addrinfo.getaddrinfo" do
|
14
|
+
let(:order) { [] }
|
15
|
+
|
16
|
+
def operations
|
17
|
+
Fiber.schedule do
|
18
|
+
order << 1
|
19
|
+
Addrinfo.getaddrinfo("example.com", 80, :AF_INET, :STREAM)
|
20
|
+
order << 5
|
21
|
+
end
|
22
|
+
|
23
|
+
order << 2
|
24
|
+
|
25
|
+
Fiber.schedule do
|
26
|
+
order << 3
|
27
|
+
Addrinfo.getaddrinfo("example.com", 80, :AF_INET, :STREAM)
|
28
|
+
order << 6
|
29
|
+
end
|
30
|
+
order << 4
|
31
|
+
end
|
32
|
+
|
33
|
+
it "calls #address_resolve" do
|
34
|
+
expect_any_instance_of(scheduler_class)
|
35
|
+
.to receive(:address_resolve).exactly(2).times
|
36
|
+
.and_call_original
|
37
|
+
|
38
|
+
setup
|
39
|
+
end
|
40
|
+
|
41
|
+
it "behaves async" do
|
42
|
+
setup
|
43
|
+
|
44
|
+
expect(order).to eq (1..6).to_a
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
@@ -0,0 +1,53 @@
|
|
1
|
+
require_relative "context"
|
2
|
+
|
3
|
+
module FiberSchedulerSpec
|
4
|
+
module BlockUnblock
|
5
|
+
end
|
6
|
+
end
|
7
|
+
|
8
|
+
RSpec.shared_examples FiberSchedulerSpec::BlockUnblock do
|
9
|
+
include_context FiberSchedulerSpec::Context
|
10
|
+
|
11
|
+
context "Addrinfo.getaddrinfo" do
|
12
|
+
let(:order) { [] }
|
13
|
+
let(:queue) { Thread::Queue.new }
|
14
|
+
let(:item) { "item" }
|
15
|
+
let(:popped_items) { [] }
|
16
|
+
|
17
|
+
def operations
|
18
|
+
Fiber.schedule do
|
19
|
+
order << 1
|
20
|
+
popped_items << queue.pop
|
21
|
+
order << 6
|
22
|
+
end
|
23
|
+
|
24
|
+
order << 2
|
25
|
+
|
26
|
+
Fiber.schedule do
|
27
|
+
order << 3
|
28
|
+
queue.push(item)
|
29
|
+
order << 4
|
30
|
+
end
|
31
|
+
|
32
|
+
order << 5
|
33
|
+
end
|
34
|
+
|
35
|
+
it "calls #block and #unblock" do
|
36
|
+
expect_any_instance_of(scheduler_class)
|
37
|
+
.to receive(:block).once
|
38
|
+
.and_call_original
|
39
|
+
expect_any_instance_of(scheduler_class)
|
40
|
+
.to receive(:unblock).once
|
41
|
+
.and_call_original
|
42
|
+
|
43
|
+
setup
|
44
|
+
end
|
45
|
+
|
46
|
+
it "behaves async" do
|
47
|
+
setup
|
48
|
+
|
49
|
+
expect(popped_items).to contain_exactly(item)
|
50
|
+
expect(order).to eq (1..6).to_a
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
@@ -0,0 +1,83 @@
|
|
1
|
+
require "rspec"
|
2
|
+
require_relative "context"
|
3
|
+
|
4
|
+
module FiberSchedulerSpec
|
5
|
+
module Close
|
6
|
+
end
|
7
|
+
end
|
8
|
+
|
9
|
+
RSpec.shared_examples FiberSchedulerSpec::Close do
|
10
|
+
include_context FiberSchedulerSpec::Context
|
11
|
+
|
12
|
+
# TODO: should closing a scheduler also set Fiber.scheduler to nil?
|
13
|
+
context "without #run" do
|
14
|
+
let(:order) { [] }
|
15
|
+
|
16
|
+
def operations
|
17
|
+
Fiber.schedule do
|
18
|
+
order << 2
|
19
|
+
end
|
20
|
+
order << 1
|
21
|
+
end
|
22
|
+
|
23
|
+
# NOTE: this example does not use 'setup', #run should not be invoked
|
24
|
+
if method_defined?(:default_setup)
|
25
|
+
# skipping if user overrode setup
|
26
|
+
it "calls #close" do
|
27
|
+
expect(scheduler)
|
28
|
+
.to receive(:close).once
|
29
|
+
.and_call_original
|
30
|
+
|
31
|
+
Thread.new do
|
32
|
+
Fiber.set_scheduler(scheduler)
|
33
|
+
|
34
|
+
operations
|
35
|
+
end.join
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
it "behaves async" do
|
40
|
+
setup
|
41
|
+
|
42
|
+
expect(order).to contain_exactly(1, 2)
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
context "with #run" do
|
47
|
+
let(:order) { [] }
|
48
|
+
|
49
|
+
def operations
|
50
|
+
Fiber.schedule do
|
51
|
+
order << 2
|
52
|
+
end
|
53
|
+
|
54
|
+
order << 1
|
55
|
+
Fiber.scheduler.run
|
56
|
+
order << 3
|
57
|
+
|
58
|
+
Fiber.schedule do
|
59
|
+
order << 4
|
60
|
+
end
|
61
|
+
|
62
|
+
order << 5
|
63
|
+
end
|
64
|
+
|
65
|
+
it "calls #close" do
|
66
|
+
expect(scheduler)
|
67
|
+
.to receive(:close).once
|
68
|
+
.and_call_original
|
69
|
+
|
70
|
+
Thread.new do
|
71
|
+
Fiber.set_scheduler(scheduler)
|
72
|
+
operations
|
73
|
+
scheduler.run
|
74
|
+
end.join
|
75
|
+
end
|
76
|
+
|
77
|
+
it "behaves async" do
|
78
|
+
setup
|
79
|
+
|
80
|
+
expect(order).to contain_exactly(1, 2, 3, 4, 5)
|
81
|
+
end
|
82
|
+
end
|
83
|
+
end
|
@@ -0,0 +1,30 @@
|
|
1
|
+
require "rspec"
|
2
|
+
|
3
|
+
module FiberSchedulerSpec
|
4
|
+
module Context
|
5
|
+
end
|
6
|
+
end
|
7
|
+
|
8
|
+
RSpec.shared_context FiberSchedulerSpec::Context do
|
9
|
+
unless method_defined?(:scheduler_class)
|
10
|
+
let(:scheduler_class) { described_class }
|
11
|
+
end
|
12
|
+
unless method_defined?(:scheduler)
|
13
|
+
subject(:scheduler) { scheduler_class.new }
|
14
|
+
end
|
15
|
+
def setup
|
16
|
+
::Fiber.set_scheduler(scheduler)
|
17
|
+
|
18
|
+
operations
|
19
|
+
|
20
|
+
scheduler.run
|
21
|
+
end
|
22
|
+
|
23
|
+
around do |example|
|
24
|
+
result = Thread.new do
|
25
|
+
example.run
|
26
|
+
end.join(1)
|
27
|
+
|
28
|
+
expect(result).to be_a Thread # failure means spec timed out
|
29
|
+
end
|
30
|
+
end
|
@@ -0,0 +1,48 @@
|
|
1
|
+
require_relative "context"
|
2
|
+
|
3
|
+
module FiberSchedulerSpec
|
4
|
+
module Fiber
|
5
|
+
end
|
6
|
+
end
|
7
|
+
|
8
|
+
RSpec.shared_examples FiberSchedulerSpec::Fiber do
|
9
|
+
include_context FiberSchedulerSpec::Context
|
10
|
+
|
11
|
+
context "Fiber.schedule" do
|
12
|
+
let(:fibers) { [] }
|
13
|
+
let(:fiber) { fibers.first }
|
14
|
+
|
15
|
+
def operations
|
16
|
+
fibers << Fiber.schedule {}
|
17
|
+
end
|
18
|
+
|
19
|
+
it "calls #fiber" do
|
20
|
+
expect_any_instance_of(scheduler_class)
|
21
|
+
.to receive(:fiber).once
|
22
|
+
.and_call_original
|
23
|
+
|
24
|
+
setup
|
25
|
+
end
|
26
|
+
|
27
|
+
it "creates a fiber" do
|
28
|
+
# Prevent GC running inbetween two ObjectSpace calls.
|
29
|
+
GC.disable
|
30
|
+
|
31
|
+
before = ObjectSpace.each_object(Fiber).count
|
32
|
+
setup
|
33
|
+
after = ObjectSpace.each_object(Fiber).count
|
34
|
+
|
35
|
+
# The after - before is > 1 with the built-in selector.
|
36
|
+
expect(after - before).to be >= 1
|
37
|
+
ensure
|
38
|
+
GC.enable
|
39
|
+
end
|
40
|
+
|
41
|
+
it "creates a non-blocking fiber" do
|
42
|
+
setup
|
43
|
+
|
44
|
+
expect(fiber).to be_a Fiber
|
45
|
+
expect(fiber).not_to be_blocking
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
@@ -0,0 +1,82 @@
|
|
1
|
+
require_relative "context"
|
2
|
+
|
3
|
+
module FiberSchedulerSpec
|
4
|
+
module IOWait
|
5
|
+
end
|
6
|
+
end
|
7
|
+
|
8
|
+
RSpec.shared_examples FiberSchedulerSpec::IOWait do
|
9
|
+
include_context FiberSchedulerSpec::Context
|
10
|
+
|
11
|
+
context "UNIXSocket#wait_readable" do
|
12
|
+
context "without a timeout" do
|
13
|
+
let(:order) { [] }
|
14
|
+
let(:pair) { UNIXSocket.pair }
|
15
|
+
let(:reader) { pair.first }
|
16
|
+
let(:writer) { pair.last }
|
17
|
+
|
18
|
+
def operations
|
19
|
+
Fiber.schedule do
|
20
|
+
order << 1
|
21
|
+
reader.wait_readable
|
22
|
+
reader.close
|
23
|
+
order << 6
|
24
|
+
end
|
25
|
+
|
26
|
+
order << 2
|
27
|
+
|
28
|
+
Fiber.schedule do
|
29
|
+
order << 3
|
30
|
+
writer.write(".")
|
31
|
+
writer.close
|
32
|
+
order << 4
|
33
|
+
end
|
34
|
+
order << 5
|
35
|
+
end
|
36
|
+
|
37
|
+
it "behaves async" do
|
38
|
+
setup
|
39
|
+
|
40
|
+
expect(order).to eq (1..6).to_a
|
41
|
+
end
|
42
|
+
|
43
|
+
it "calls #io_wait" do
|
44
|
+
expect_any_instance_of(scheduler_class)
|
45
|
+
.to receive(:io_wait).once
|
46
|
+
.and_call_original
|
47
|
+
|
48
|
+
setup
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
context "with a timeout" do
|
53
|
+
let(:order) { [] }
|
54
|
+
let(:pair) { UNIXSocket.pair }
|
55
|
+
let(:reader) { pair.first }
|
56
|
+
let(:writer) { pair.last }
|
57
|
+
|
58
|
+
def operations
|
59
|
+
Fiber.schedule do
|
60
|
+
order << 1
|
61
|
+
reader.wait_readable(0.001)
|
62
|
+
order << 3
|
63
|
+
end
|
64
|
+
order << 2
|
65
|
+
end
|
66
|
+
|
67
|
+
it "behaves async" do
|
68
|
+
setup
|
69
|
+
|
70
|
+
expect(order).to eq (1..3).to_a
|
71
|
+
end
|
72
|
+
|
73
|
+
it "calls #io_wait" do
|
74
|
+
expect_any_instance_of(scheduler_class)
|
75
|
+
.to receive(:io_wait).once
|
76
|
+
.and_call_original
|
77
|
+
|
78
|
+
setup
|
79
|
+
end
|
80
|
+
end
|
81
|
+
end
|
82
|
+
end
|
@@ -0,0 +1,97 @@
|
|
1
|
+
require_relative "context"
|
2
|
+
|
3
|
+
module FiberSchedulerSpec
|
4
|
+
module KernelSleep
|
5
|
+
end
|
6
|
+
end
|
7
|
+
|
8
|
+
RSpec.shared_examples FiberSchedulerSpec::KernelSleep do
|
9
|
+
include_context FiberSchedulerSpec::Context
|
10
|
+
|
11
|
+
context "Kernel.sleep" do
|
12
|
+
let(:order) { [] }
|
13
|
+
let(:times) { [] }
|
14
|
+
let(:duration) { times[1] - times[0] }
|
15
|
+
|
16
|
+
context "multiple sleep operations" do
|
17
|
+
let(:interval) { 0.1 }
|
18
|
+
|
19
|
+
def operations
|
20
|
+
times << Process.clock_gettime(Process::CLOCK_MONOTONIC)
|
21
|
+
|
22
|
+
Fiber.schedule do
|
23
|
+
order << 1
|
24
|
+
sleep interval
|
25
|
+
order << 5
|
26
|
+
end
|
27
|
+
|
28
|
+
order << 2
|
29
|
+
|
30
|
+
Fiber.schedule do
|
31
|
+
order << 3
|
32
|
+
sleep interval
|
33
|
+
order << 6
|
34
|
+
end
|
35
|
+
|
36
|
+
order << 4
|
37
|
+
end
|
38
|
+
|
39
|
+
it "calls #kernel_sleep" do
|
40
|
+
expect_any_instance_of(scheduler_class)
|
41
|
+
.to receive(:kernel_sleep).exactly(2).times
|
42
|
+
.and_call_original
|
43
|
+
|
44
|
+
setup
|
45
|
+
end
|
46
|
+
|
47
|
+
it "behaves async" do
|
48
|
+
setup
|
49
|
+
|
50
|
+
expect(order).to eq (1..6).to_a
|
51
|
+
end
|
52
|
+
|
53
|
+
it "runs operations in parallel" do
|
54
|
+
setup
|
55
|
+
times << Process.clock_gettime(Process::CLOCK_MONOTONIC)
|
56
|
+
|
57
|
+
expect(duration).to be >= interval
|
58
|
+
expect(duration).to be < (interval * 1.2)
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
context "sleep 0" do
|
63
|
+
def operations
|
64
|
+
times << Process.clock_gettime(Process::CLOCK_MONOTONIC)
|
65
|
+
|
66
|
+
Fiber.schedule do
|
67
|
+
order << 1
|
68
|
+
sleep 0
|
69
|
+
times << Process.clock_gettime(Process::CLOCK_MONOTONIC)
|
70
|
+
order << 3
|
71
|
+
end
|
72
|
+
order << 2
|
73
|
+
end
|
74
|
+
|
75
|
+
it "calls #kernel_sleep" do
|
76
|
+
expect_any_instance_of(scheduler_class)
|
77
|
+
.to receive(:kernel_sleep).once
|
78
|
+
.and_call_original
|
79
|
+
|
80
|
+
setup
|
81
|
+
end
|
82
|
+
|
83
|
+
it "behaves async" do
|
84
|
+
setup
|
85
|
+
|
86
|
+
expect(order).to eq (1..3).to_a
|
87
|
+
end
|
88
|
+
|
89
|
+
it "runs the operation in no time" do
|
90
|
+
setup
|
91
|
+
|
92
|
+
# No sleeping was performed at all.
|
93
|
+
expect(duration).to be < 0.0005
|
94
|
+
end
|
95
|
+
end
|
96
|
+
end
|
97
|
+
end
|
@@ -0,0 +1,61 @@
|
|
1
|
+
require_relative "context"
|
2
|
+
|
3
|
+
module FiberSchedulerSpec
|
4
|
+
module ProcessWait
|
5
|
+
end
|
6
|
+
end
|
7
|
+
|
8
|
+
RSpec.shared_examples FiberSchedulerSpec::ProcessWait do
|
9
|
+
include_context FiberSchedulerSpec::Context
|
10
|
+
|
11
|
+
context "Process.wait" do
|
12
|
+
let(:interval_short) { 0.09 }
|
13
|
+
let(:interval) { 0.1 }
|
14
|
+
let(:order) { [] }
|
15
|
+
let(:times) { [] }
|
16
|
+
let(:duration) { times[1] - times[0] }
|
17
|
+
def operations
|
18
|
+
times << Process.clock_gettime(Process::CLOCK_MONOTONIC)
|
19
|
+
|
20
|
+
Fiber.schedule do
|
21
|
+
order << 1
|
22
|
+
# This interval is shorter so we're certain it will finish before the
|
23
|
+
# other fiber.
|
24
|
+
Process.wait(spawn("sleep #{interval_short}"))
|
25
|
+
order << 5
|
26
|
+
end
|
27
|
+
|
28
|
+
order << 2
|
29
|
+
|
30
|
+
Fiber.schedule do
|
31
|
+
order << 3
|
32
|
+
Process.wait(spawn("sleep #{interval}"))
|
33
|
+
order << 6
|
34
|
+
end
|
35
|
+
|
36
|
+
order << 4
|
37
|
+
end
|
38
|
+
|
39
|
+
it "calls #process_wait" do
|
40
|
+
expect_any_instance_of(scheduler_class)
|
41
|
+
.to receive(:process_wait).exactly(2).times
|
42
|
+
.and_call_original
|
43
|
+
|
44
|
+
setup
|
45
|
+
end
|
46
|
+
|
47
|
+
it "behaves async" do
|
48
|
+
setup
|
49
|
+
|
50
|
+
expect(order).to eq (1..6).to_a
|
51
|
+
end
|
52
|
+
|
53
|
+
it "runs operations in parallel" do
|
54
|
+
setup
|
55
|
+
times << Process.clock_gettime(Process::CLOCK_MONOTONIC)
|
56
|
+
|
57
|
+
expect(duration).to be >= interval
|
58
|
+
expect(duration).to be < (interval * 1.5)
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
@@ -0,0 +1,62 @@
|
|
1
|
+
require_relative "context"
|
2
|
+
|
3
|
+
module FiberSchedulerSpec
|
4
|
+
module SocketIO
|
5
|
+
end
|
6
|
+
end
|
7
|
+
|
8
|
+
RSpec.shared_examples FiberSchedulerSpec::SocketIO do
|
9
|
+
include_context FiberSchedulerSpec::Context
|
10
|
+
|
11
|
+
context "UNIXSocket.pair" do
|
12
|
+
let(:order) { [] }
|
13
|
+
let(:pair) { UNIXSocket.pair }
|
14
|
+
let(:reader) { pair.first }
|
15
|
+
let(:writer) { pair.last }
|
16
|
+
let(:messages) { [] }
|
17
|
+
let(:sent) { "ruby" }
|
18
|
+
let(:received) { messages.first }
|
19
|
+
|
20
|
+
def operations
|
21
|
+
Fiber.schedule do
|
22
|
+
order << 1
|
23
|
+
messages << reader.read(sent.size)
|
24
|
+
reader.close
|
25
|
+
order << 6
|
26
|
+
end
|
27
|
+
|
28
|
+
order << 2
|
29
|
+
|
30
|
+
Fiber.schedule do
|
31
|
+
order << 3
|
32
|
+
writer.write(sent)
|
33
|
+
writer.close
|
34
|
+
order << 4
|
35
|
+
end
|
36
|
+
order << 5
|
37
|
+
end
|
38
|
+
|
39
|
+
it "calls #io_read and #io_write" do
|
40
|
+
expect_any_instance_of(scheduler_class)
|
41
|
+
.to receive(:io_read).once
|
42
|
+
.and_call_original
|
43
|
+
expect_any_instance_of(scheduler_class)
|
44
|
+
.to receive(:io_write).once
|
45
|
+
.and_call_original
|
46
|
+
|
47
|
+
setup
|
48
|
+
end
|
49
|
+
|
50
|
+
it "writes and reads a message" do
|
51
|
+
setup
|
52
|
+
|
53
|
+
expect(received).to eq sent
|
54
|
+
end
|
55
|
+
|
56
|
+
it "behaves async" do
|
57
|
+
setup
|
58
|
+
|
59
|
+
expect(order).to eq (1..6).to_a
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
@@ -0,0 +1,87 @@
|
|
1
|
+
require "timeout"
|
2
|
+
require_relative "context"
|
3
|
+
|
4
|
+
module FiberSchedulerSpec
|
5
|
+
module TimeoutAfter
|
6
|
+
end
|
7
|
+
end
|
8
|
+
|
9
|
+
RSpec.shared_examples FiberSchedulerSpec::TimeoutAfter do
|
10
|
+
include_context FiberSchedulerSpec::Context
|
11
|
+
|
12
|
+
context "Timeout.timeout" do
|
13
|
+
let(:order) { [] }
|
14
|
+
let(:times) { [] }
|
15
|
+
let(:duration) { times[1] - times[0] }
|
16
|
+
let(:sleep_duration) { 0.01 }
|
17
|
+
|
18
|
+
def operations
|
19
|
+
times << Process.clock_gettime(Process::CLOCK_MONOTONIC)
|
20
|
+
Fiber.schedule do
|
21
|
+
begin
|
22
|
+
order << 1
|
23
|
+
Timeout.timeout(timeout) do
|
24
|
+
order << 2
|
25
|
+
sleep sleep_duration
|
26
|
+
order << 4
|
27
|
+
end
|
28
|
+
order << 5
|
29
|
+
rescue Timeout::Error
|
30
|
+
order << 6
|
31
|
+
end
|
32
|
+
times << Process.clock_gettime(Process::CLOCK_MONOTONIC)
|
33
|
+
end
|
34
|
+
order << 3
|
35
|
+
end
|
36
|
+
|
37
|
+
context "when the operation times out" do
|
38
|
+
let(:timeout) { 0.001 }
|
39
|
+
|
40
|
+
it "calls #timeout_after" do
|
41
|
+
expect_any_instance_of(scheduler_class)
|
42
|
+
.to receive(:timeout_after)
|
43
|
+
.and_call_original
|
44
|
+
|
45
|
+
setup
|
46
|
+
end
|
47
|
+
|
48
|
+
it "behaves async" do
|
49
|
+
setup
|
50
|
+
|
51
|
+
expect(order).to eq [1, 2, 3, 6]
|
52
|
+
end
|
53
|
+
|
54
|
+
it "times out early" do
|
55
|
+
setup
|
56
|
+
|
57
|
+
expect(duration).to be >= timeout
|
58
|
+
expect(duration).to be < (timeout * 10)
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
context "when the operation doesn't time out" do
|
63
|
+
let(:timeout) { 0.1 }
|
64
|
+
|
65
|
+
it "calls #timeout_after" do
|
66
|
+
expect_any_instance_of(scheduler_class)
|
67
|
+
.to receive(:timeout_after)
|
68
|
+
.and_call_original
|
69
|
+
|
70
|
+
setup
|
71
|
+
end
|
72
|
+
|
73
|
+
it "behaves async" do
|
74
|
+
setup
|
75
|
+
|
76
|
+
expect(order).to eq (1..5).to_a
|
77
|
+
end
|
78
|
+
|
79
|
+
it "finishes the operation" do
|
80
|
+
setup
|
81
|
+
|
82
|
+
expect(duration).to be >= sleep_duration
|
83
|
+
expect(duration).to be < (sleep_duration * 1.5)
|
84
|
+
end
|
85
|
+
end
|
86
|
+
end
|
87
|
+
end
|
data/lib/fiber_scheduler_spec.rb
CHANGED
@@ -1,2 +1,21 @@
|
|
1
|
-
|
1
|
+
require_relative "fiber_scheduler_spec/address_resolve"
|
2
|
+
require_relative "fiber_scheduler_spec/block_unblock"
|
3
|
+
require_relative "fiber_scheduler_spec/close"
|
4
|
+
require_relative "fiber_scheduler_spec/fiber"
|
5
|
+
require_relative "fiber_scheduler_spec/io_wait"
|
6
|
+
require_relative "fiber_scheduler_spec/kernel_sleep"
|
7
|
+
require_relative "fiber_scheduler_spec/process_wait"
|
8
|
+
require_relative "fiber_scheduler_spec/socket_io"
|
9
|
+
require_relative "fiber_scheduler_spec/timeout_after"
|
10
|
+
|
11
|
+
RSpec.shared_examples FiberSchedulerSpec do
|
12
|
+
include_examples FiberSchedulerSpec::AddressResolve
|
13
|
+
include_examples FiberSchedulerSpec::BlockUnblock
|
14
|
+
include_examples FiberSchedulerSpec::Close
|
15
|
+
include_examples FiberSchedulerSpec::Fiber
|
16
|
+
include_examples FiberSchedulerSpec::IOWait
|
17
|
+
include_examples FiberSchedulerSpec::KernelSleep
|
18
|
+
include_examples FiberSchedulerSpec::ProcessWait
|
19
|
+
include_examples FiberSchedulerSpec::SocketIO
|
20
|
+
include_examples FiberSchedulerSpec::TimeoutAfter
|
2
21
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: fiber_scheduler_spec
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Bruno Sutic
|
@@ -17,7 +17,7 @@ dependencies:
|
|
17
17
|
- - "~>"
|
18
18
|
- !ruby/object:Gem::Version
|
19
19
|
version: '3.11'
|
20
|
-
type: :
|
20
|
+
type: :runtime
|
21
21
|
prerelease: false
|
22
22
|
version_requirements: !ruby/object:Gem::Requirement
|
23
23
|
requirements:
|
@@ -45,6 +45,16 @@ extensions: []
|
|
45
45
|
extra_rdoc_files: []
|
46
46
|
files:
|
47
47
|
- lib/fiber_scheduler_spec.rb
|
48
|
+
- lib/fiber_scheduler_spec/address_resolve.rb
|
49
|
+
- lib/fiber_scheduler_spec/block_unblock.rb
|
50
|
+
- lib/fiber_scheduler_spec/close.rb
|
51
|
+
- lib/fiber_scheduler_spec/context.rb
|
52
|
+
- lib/fiber_scheduler_spec/fiber.rb
|
53
|
+
- lib/fiber_scheduler_spec/io_wait.rb
|
54
|
+
- lib/fiber_scheduler_spec/kernel_sleep.rb
|
55
|
+
- lib/fiber_scheduler_spec/process_wait.rb
|
56
|
+
- lib/fiber_scheduler_spec/socket_io.rb
|
57
|
+
- lib/fiber_scheduler_spec/timeout_after.rb
|
48
58
|
- lib/fiber_scheduler_spec/version.rb
|
49
59
|
homepage: https://github.com/bruno-/fiber_scheduler_spec
|
50
60
|
licenses:
|