uringmachine 0.5 → 0.5.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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +2 -0
- data/examples/bm_sqlite.rb +89 -0
- data/examples/http_server.rb +1 -1
- data/examples/pg.rb +85 -0
- data/examples/stream.rb +85 -0
- data/ext/um/extconf.rb +57 -0
- data/ext/um/um.c +5 -5
- data/ext/um/um.h +23 -4
- data/ext/um/um_async_op.c +40 -0
- data/ext/um/um_async_op_class.c +136 -0
- data/ext/um/um_class.c +39 -31
- data/ext/um/um_const.c +145 -9
- data/ext/um/um_ext.c +4 -0
- data/ext/um/um_op.c +5 -2
- data/ext/um/um_ssl.c +850 -0
- data/ext/um/um_ssl.h +22 -0
- data/ext/um/um_ssl_class.c +138 -0
- data/lib/uringmachine/ssl/context_builder.rb +96 -0
- data/lib/uringmachine/ssl.rb +394 -0
- data/lib/uringmachine/version.rb +1 -1
- data/lib/uringmachine.rb +8 -0
- data/test/helper.rb +6 -0
- data/test/test_async_op.rb +119 -0
- data/test/test_ssl.rb +155 -0
- data/test/test_um.rb +0 -2
- data/uringmachine.gemspec +3 -2
- metadata +32 -6
@@ -0,0 +1,119 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative 'helper'
|
4
|
+
require 'socket'
|
5
|
+
|
6
|
+
class AsyncOpTest < UMBaseTest
|
7
|
+
def setup
|
8
|
+
super
|
9
|
+
@t0 = monotonic_clock
|
10
|
+
@op = machine.prep_timeout(0.05)
|
11
|
+
end
|
12
|
+
|
13
|
+
def test_async_op_await
|
14
|
+
assert_equal 1, machine.pending_count
|
15
|
+
res = @op.await
|
16
|
+
t1 = monotonic_clock
|
17
|
+
assert_in_range 0.04..0.08, t1 - @t0
|
18
|
+
assert_equal 0, machine.pending_count
|
19
|
+
assert_equal (-ETIME), res
|
20
|
+
assert_equal true, @op.done?
|
21
|
+
assert_equal false, @op.cancelled?
|
22
|
+
end
|
23
|
+
|
24
|
+
def test_async_op_join
|
25
|
+
assert_equal 1, machine.pending_count
|
26
|
+
res = @op.join
|
27
|
+
t1 = monotonic_clock
|
28
|
+
assert_in_range 0.04..0.08, t1 - @t0
|
29
|
+
assert_equal 0, machine.pending_count
|
30
|
+
assert_equal (-ETIME), res
|
31
|
+
assert_equal true, @op.done?
|
32
|
+
assert_equal false, @op.cancelled?
|
33
|
+
end
|
34
|
+
|
35
|
+
def test_async_op_cancel
|
36
|
+
machine.sleep(0.01)
|
37
|
+
assert_equal 1, machine.pending_count
|
38
|
+
@op.cancel
|
39
|
+
assert_equal false, @op.done?
|
40
|
+
|
41
|
+
machine.sleep(0.01)
|
42
|
+
|
43
|
+
assert_equal 0, machine.pending_count
|
44
|
+
assert_equal true, @op.done?
|
45
|
+
assert_equal (-ECANCELED), @op.result
|
46
|
+
assert_equal true, @op.cancelled?
|
47
|
+
end
|
48
|
+
|
49
|
+
def test_async_op_await_with_cancel
|
50
|
+
machine.spin do
|
51
|
+
@op.cancel
|
52
|
+
end
|
53
|
+
|
54
|
+
res = @op.await
|
55
|
+
|
56
|
+
assert_equal 0, machine.pending_count
|
57
|
+
assert_equal true, @op.done?
|
58
|
+
assert_equal (-ECANCELED), res
|
59
|
+
assert_equal true, @op.cancelled?
|
60
|
+
end
|
61
|
+
|
62
|
+
class TOError < RuntimeError; end
|
63
|
+
|
64
|
+
def test_async_op_await_with_timeout
|
65
|
+
e = nil
|
66
|
+
|
67
|
+
begin
|
68
|
+
machine.timeout(0.01, TOError) do
|
69
|
+
@op.await
|
70
|
+
end
|
71
|
+
rescue => e
|
72
|
+
end
|
73
|
+
|
74
|
+
assert_equal 0, machine.pending_count
|
75
|
+
assert_kind_of TOError, e
|
76
|
+
assert_equal true, @op.done?
|
77
|
+
assert_equal (-ECANCELED), @op.result
|
78
|
+
assert_equal true, @op.cancelled?
|
79
|
+
end
|
80
|
+
|
81
|
+
def test_async_op_await_with_timeout2
|
82
|
+
e = nil
|
83
|
+
|
84
|
+
begin
|
85
|
+
machine.timeout(0.1, TOError) do
|
86
|
+
@op.await
|
87
|
+
end
|
88
|
+
rescue => e
|
89
|
+
end
|
90
|
+
|
91
|
+
# machine.timeout is cancelled async, so CQE is not yet reaped
|
92
|
+
assert_equal 1, machine.pending_count
|
93
|
+
assert_nil e
|
94
|
+
assert_equal true, @op.done?
|
95
|
+
assert_equal (-ETIME), @op.result
|
96
|
+
assert_equal false, @op.cancelled?
|
97
|
+
|
98
|
+
# wait for timeout cancellation
|
99
|
+
machine.sleep(0.01)
|
100
|
+
assert_equal 0, machine.pending_count
|
101
|
+
end
|
102
|
+
end
|
103
|
+
|
104
|
+
class PrepTimeoutTest < UMBaseTest
|
105
|
+
def test_prep_timeout
|
106
|
+
op = machine.prep_timeout(0.03)
|
107
|
+
assert_kind_of UM::AsyncOp, op
|
108
|
+
assert_equal :timeout, op.kind
|
109
|
+
|
110
|
+
assert_equal false, op.done?
|
111
|
+
assert_nil op.result
|
112
|
+
|
113
|
+
machine.sleep(0.05)
|
114
|
+
|
115
|
+
assert_equal true, op.done?
|
116
|
+
assert_equal (-ETIME), op.result
|
117
|
+
assert_equal false, op.cancelled?
|
118
|
+
end
|
119
|
+
end
|
data/test/test_ssl.rb
ADDED
@@ -0,0 +1,155 @@
|
|
1
|
+
require_relative "helper"
|
2
|
+
|
3
|
+
__END__
|
4
|
+
|
5
|
+
require 'uringmachine/ssl'
|
6
|
+
require 'openssl'
|
7
|
+
require 'localhost'
|
8
|
+
|
9
|
+
class TestSSLContext < Minitest::Test
|
10
|
+
|
11
|
+
if false
|
12
|
+
def test_raises_with_invalid_keystore_file
|
13
|
+
ctx = UM::SSL::Context.new
|
14
|
+
|
15
|
+
exception = assert_raises(ArgumentError) { ctx.keystore = "/no/such/keystore" }
|
16
|
+
assert_equal("Keystore file '/no/such/keystore' does not exist", exception.message)
|
17
|
+
end
|
18
|
+
|
19
|
+
def test_raises_with_unreadable_keystore_file
|
20
|
+
ctx = UM::SSL::Context.new
|
21
|
+
|
22
|
+
File.stub(:exist?, true) do
|
23
|
+
File.stub(:readable?, false) do
|
24
|
+
exception = assert_raises(ArgumentError) { ctx.keystore = "/unreadable/keystore" }
|
25
|
+
assert_equal("Keystore file '/unreadable/keystore' is not readable", exception.message)
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
else
|
30
|
+
def test_raises_with_invalid_key_file
|
31
|
+
ctx = UM::SSL::Context.new
|
32
|
+
|
33
|
+
exception = assert_raises(ArgumentError) { ctx.key = "/no/such/key" }
|
34
|
+
assert_equal("Key file '/no/such/key' does not exist", exception.message)
|
35
|
+
end
|
36
|
+
|
37
|
+
def test_raises_with_unreadable_key_file
|
38
|
+
ctx = UM::SSL::Context.new
|
39
|
+
|
40
|
+
File.stub(:exist?, true) do
|
41
|
+
File.stub(:readable?, false) do
|
42
|
+
exception = assert_raises(ArgumentError) { ctx.key = "/unreadable/key" }
|
43
|
+
assert_equal("Key file '/unreadable/key' is not readable", exception.message)
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
def test_raises_with_invalid_cert_file
|
49
|
+
ctx = UM::SSL::Context.new
|
50
|
+
|
51
|
+
exception = assert_raises(ArgumentError) { ctx.cert = "/no/such/cert" }
|
52
|
+
assert_equal("Cert file '/no/such/cert' does not exist", exception.message)
|
53
|
+
end
|
54
|
+
|
55
|
+
def test_raises_with_unreadable_cert_file
|
56
|
+
ctx = UM::SSL::Context.new
|
57
|
+
|
58
|
+
File.stub(:exist?, true) do
|
59
|
+
File.stub(:readable?, false) do
|
60
|
+
exception = assert_raises(ArgumentError) { ctx.key = "/unreadable/cert" }
|
61
|
+
assert_equal("Key file '/unreadable/cert' is not readable", exception.message)
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
def test_raises_with_invalid_key_pem
|
67
|
+
ctx = UM::SSL::Context.new
|
68
|
+
|
69
|
+
exception = assert_raises(ArgumentError) { ctx.key_pem = nil }
|
70
|
+
assert_equal("'key_pem' is not a String", exception.message)
|
71
|
+
end
|
72
|
+
|
73
|
+
def test_raises_with_unreadable_ca_file
|
74
|
+
ctx = UM::SSL::Context.new
|
75
|
+
|
76
|
+
File.stub(:exist?, true) do
|
77
|
+
File.stub(:readable?, false) do
|
78
|
+
exception = assert_raises(ArgumentError) { ctx.ca = "/unreadable/cert" }
|
79
|
+
assert_equal("ca file '/unreadable/cert' is not readable", exception.message)
|
80
|
+
end
|
81
|
+
end
|
82
|
+
end
|
83
|
+
|
84
|
+
def test_raises_with_invalid_cert_pem
|
85
|
+
ctx = UM::SSL::Context.new
|
86
|
+
|
87
|
+
exception = assert_raises(ArgumentError) { ctx.cert_pem = nil }
|
88
|
+
assert_equal("'cert_pem' is not a String", exception.message)
|
89
|
+
end
|
90
|
+
|
91
|
+
def test_raises_with_invalid_key_password_command
|
92
|
+
ctx = UM::SSL::Context.new
|
93
|
+
ctx.key_password_command = '/unreadable/decrypt_command'
|
94
|
+
|
95
|
+
assert_raises(Errno::ENOENT) { ctx.key_password }
|
96
|
+
end
|
97
|
+
end
|
98
|
+
end
|
99
|
+
|
100
|
+
class TestSSLServer < UMBaseTest
|
101
|
+
def setup
|
102
|
+
super
|
103
|
+
@port = assign_port
|
104
|
+
@ssl_ctx = create_ssl_ctx
|
105
|
+
end
|
106
|
+
|
107
|
+
def create_ssl_ctx
|
108
|
+
authority = Localhost::Authority.fetch
|
109
|
+
authority.server_context
|
110
|
+
end
|
111
|
+
|
112
|
+
def test_ssl_accept
|
113
|
+
server_fd = machine.socket(UM::AF_INET, UM::SOCK_STREAM, 0, 0)
|
114
|
+
machine.bind(server_fd, '127.0.0.1', @port)
|
115
|
+
res = machine.listen(server_fd, 5)
|
116
|
+
assert_equal 0, res
|
117
|
+
assert_equal 0, machine.pending_count
|
118
|
+
|
119
|
+
fd = nil
|
120
|
+
sock = nil
|
121
|
+
|
122
|
+
reply = nil
|
123
|
+
t = Thread.new do
|
124
|
+
p 21
|
125
|
+
sleep 0.1
|
126
|
+
p 22
|
127
|
+
sock = TCPSocket.new('127.0.0.1', @port)
|
128
|
+
p 23
|
129
|
+
sleep 0.1
|
130
|
+
p 24
|
131
|
+
client = OpenSSL::SSL::SSLSocket.new(sock)
|
132
|
+
p 25
|
133
|
+
client.connect
|
134
|
+
p 26
|
135
|
+
client.write('foobar')
|
136
|
+
p 27
|
137
|
+
reply = client.read(8192)
|
138
|
+
p 28
|
139
|
+
end
|
140
|
+
|
141
|
+
p 11
|
142
|
+
fd = machine.accept(server_fd)
|
143
|
+
p 12
|
144
|
+
sock = machine.ssl_accept(fd, @ssl_ctx)
|
145
|
+
msg = +''
|
146
|
+
p 13
|
147
|
+
ret = sock.recv(msg, 8192)
|
148
|
+
p 14
|
149
|
+
sock.send("Hello: #{msg} (#{ret})", 0)
|
150
|
+
p 15
|
151
|
+
machine.close(fd)
|
152
|
+
|
153
|
+
assert_equal 'Hello: foobar (6)', reply
|
154
|
+
end
|
155
|
+
end
|
data/test/test_um.rb
CHANGED
data/uringmachine.gemspec
CHANGED
@@ -20,8 +20,9 @@ Gem::Specification.new do |s|
|
|
20
20
|
s.require_paths = ["lib"]
|
21
21
|
s.required_ruby_version = '>= 3.3'
|
22
22
|
|
23
|
-
s.add_development_dependency 'rake-compiler', '1.2.
|
23
|
+
s.add_development_dependency 'rake-compiler', '1.2.8'
|
24
24
|
s.add_development_dependency 'minitest', '5.25.1'
|
25
25
|
s.add_development_dependency 'http_parser.rb', '0.8.0'
|
26
|
-
s.add_development_dependency 'benchmark-ips', '2.
|
26
|
+
s.add_development_dependency 'benchmark-ips', '2.14.0'
|
27
|
+
s.add_development_dependency 'localhost', '1.3.1'
|
27
28
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: uringmachine
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version:
|
4
|
+
version: 0.5.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Sharon Rosner
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2024-11
|
11
|
+
date: 2024-12-11 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rake-compiler
|
@@ -16,14 +16,14 @@ dependencies:
|
|
16
16
|
requirements:
|
17
17
|
- - '='
|
18
18
|
- !ruby/object:Gem::Version
|
19
|
-
version: 1.2.
|
19
|
+
version: 1.2.8
|
20
20
|
type: :development
|
21
21
|
prerelease: false
|
22
22
|
version_requirements: !ruby/object:Gem::Requirement
|
23
23
|
requirements:
|
24
24
|
- - '='
|
25
25
|
- !ruby/object:Gem::Version
|
26
|
-
version: 1.2.
|
26
|
+
version: 1.2.8
|
27
27
|
- !ruby/object:Gem::Dependency
|
28
28
|
name: minitest
|
29
29
|
requirement: !ruby/object:Gem::Requirement
|
@@ -58,14 +58,28 @@ dependencies:
|
|
58
58
|
requirements:
|
59
59
|
- - '='
|
60
60
|
- !ruby/object:Gem::Version
|
61
|
-
version: 2.
|
61
|
+
version: 2.14.0
|
62
62
|
type: :development
|
63
63
|
prerelease: false
|
64
64
|
version_requirements: !ruby/object:Gem::Requirement
|
65
65
|
requirements:
|
66
66
|
- - '='
|
67
67
|
- !ruby/object:Gem::Version
|
68
|
-
version: 2.
|
68
|
+
version: 2.14.0
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: localhost
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
72
|
+
requirements:
|
73
|
+
- - '='
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
version: 1.3.1
|
76
|
+
type: :development
|
77
|
+
prerelease: false
|
78
|
+
version_requirements: !ruby/object:Gem::Requirement
|
79
|
+
requirements:
|
80
|
+
- - '='
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
version: 1.3.1
|
69
83
|
description:
|
70
84
|
email: sharon@noteflakes.com
|
71
85
|
executables: []
|
@@ -85,18 +99,23 @@ files:
|
|
85
99
|
- Rakefile
|
86
100
|
- TODO.md
|
87
101
|
- examples/bm_snooze.rb
|
102
|
+
- examples/bm_sqlite.rb
|
88
103
|
- examples/bm_write.rb
|
89
104
|
- examples/dns_client.rb
|
90
105
|
- examples/echo_server.rb
|
91
106
|
- examples/http_server.rb
|
92
107
|
- examples/inout.rb
|
93
108
|
- examples/nc.rb
|
109
|
+
- examples/pg.rb
|
94
110
|
- examples/server_client.rb
|
95
111
|
- examples/snooze.rb
|
112
|
+
- examples/stream.rb
|
96
113
|
- examples/write_dev_null.rb
|
97
114
|
- ext/um/extconf.rb
|
98
115
|
- ext/um/um.c
|
99
116
|
- ext/um/um.h
|
117
|
+
- ext/um/um_async_op.c
|
118
|
+
- ext/um/um_async_op_class.c
|
100
119
|
- ext/um/um_buffer.c
|
101
120
|
- ext/um/um_class.c
|
102
121
|
- ext/um/um_const.c
|
@@ -104,13 +123,20 @@ files:
|
|
104
123
|
- ext/um/um_mutex_class.c
|
105
124
|
- ext/um/um_op.c
|
106
125
|
- ext/um/um_queue_class.c
|
126
|
+
- ext/um/um_ssl.c
|
127
|
+
- ext/um/um_ssl.h
|
128
|
+
- ext/um/um_ssl_class.c
|
107
129
|
- ext/um/um_sync.c
|
108
130
|
- ext/um/um_utils.c
|
109
131
|
- lib/uringmachine.rb
|
110
132
|
- lib/uringmachine/dns_resolver.rb
|
133
|
+
- lib/uringmachine/ssl.rb
|
134
|
+
- lib/uringmachine/ssl/context_builder.rb
|
111
135
|
- lib/uringmachine/version.rb
|
112
136
|
- supressions/ruby.supp
|
113
137
|
- test/helper.rb
|
138
|
+
- test/test_async_op.rb
|
139
|
+
- test/test_ssl.rb
|
114
140
|
- test/test_um.rb
|
115
141
|
- uringmachine.gemspec
|
116
142
|
- vendor/liburing/.github/actions/codespell/stopwords
|