async-dns 0.12.0 → 1.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.rspec +0 -1
- data/.travis.yml +11 -8
- data/Gemfile +6 -0
- data/README.md +5 -1
- data/Rakefile +1 -1
- data/async-dns.gemspec +1 -1
- data/lib/async/dns/handler.rb +5 -5
- data/lib/async/dns/replace.rb +1 -1
- data/lib/async/dns/resolver.rb +25 -25
- data/lib/async/dns/server.rb +10 -10
- data/lib/async/dns/version.rb +1 -1
- data/spec/async/dns/handler_spec.rb +2 -2
- data/spec/async/dns/ipv6_spec.rb +2 -2
- data/spec/async/dns/server_performance_spec.rb +48 -25
- data/spec/async/dns/slow_server_spec.rb +1 -1
- data/spec/async/dns/socket_spec.rb +2 -2
- data/spec/async/dns/truncation_spec.rb +1 -1
- data/spec/spec_helper.rb +20 -1
- metadata +4 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: a69c3e892e1022681eb81ec89cf6953b27f2dd65
|
4
|
+
data.tar.gz: f4b1bbfe1e36b9bae37681343c4eb1bc71f5b621
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 0dc107b7e33810d8a45fdb660dfc7421ad95383d8e14db6006175a335b0cc80500065e2c78c3d80ef53291a2ae8f3617a5cdb081475009ddff5c0edf3ff06576
|
7
|
+
data.tar.gz: 3209d74dc8a3ae956acb687da50ac5049f5c5a4be820ae8e5f1ca88c3c02b1bcd077e02ba33a23a498d90f8cd86b2ad52b2582907c734ccfee45f4372487cb42
|
data/.rspec
CHANGED
data/.travis.yml
CHANGED
@@ -6,14 +6,17 @@ addons:
|
|
6
6
|
apt:
|
7
7
|
packages:
|
8
8
|
- bind9
|
9
|
-
|
10
|
-
- 2.1
|
11
|
-
- 2.2
|
12
|
-
- 2.3
|
13
|
-
- 2.4
|
14
|
-
- ruby-head
|
15
|
-
- jruby-head
|
9
|
+
|
16
10
|
matrix:
|
11
|
+
include:
|
12
|
+
- rvm: 2.1
|
13
|
+
- rvm: 2.2
|
14
|
+
- rvm: 2.3
|
15
|
+
- rvm: 2.4
|
16
|
+
- rvm: ruby-head
|
17
|
+
- rvm: jruby-head
|
18
|
+
env:
|
19
|
+
- JRUBY_OPTS="--debug -X+O"
|
17
20
|
allow_failures:
|
18
21
|
- rvm: ruby-head
|
19
|
-
- rvm: jruby-head
|
22
|
+
- rvm: jruby-head
|
data/Gemfile
CHANGED
data/README.md
CHANGED
@@ -28,6 +28,7 @@ Or install it yourself as:
|
|
28
28
|
|
29
29
|
Here is a simple example showing how to use the resolver:
|
30
30
|
|
31
|
+
```ruby
|
31
32
|
Async::Reactor.run do
|
32
33
|
resolver = Async::DNS::Resolver.new([[:udp, "8.8.8.8", 53], [:tcp, "8.8.8.8", 53]])
|
33
34
|
|
@@ -36,11 +37,13 @@ Here is a simple example showing how to use the resolver:
|
|
36
37
|
puts addresses.inspect
|
37
38
|
end
|
38
39
|
=> [#<Resolv::IPv4 202.124.127.240>, #<Resolv::IPv4 202.124.127.216>, #<Resolv::IPv4 202.124.127.223>, #<Resolv::IPv4 202.124.127.227>, #<Resolv::IPv4 202.124.127.234>, #<Resolv::IPv4 202.124.127.230>, #<Resolv::IPv4 202.124.127.208>, #<Resolv::IPv4 202.124.127.249>, #<Resolv::IPv4 202.124.127.219>, #<Resolv::IPv4 202.124.127.218>, #<Resolv::IPv4 202.124.127.212>, #<Resolv::IPv4 202.124.127.241>, #<Resolv::IPv4 202.124.127.238>, #<Resolv::IPv4 202.124.127.245>, #<Resolv::IPv4 202.124.127.251>, #<Resolv::IPv4 202.124.127.229>]
|
40
|
+
```
|
39
41
|
|
40
42
|
### Server
|
41
43
|
|
42
44
|
Here is a simple example showing how to use the server:
|
43
45
|
|
46
|
+
```ruby
|
44
47
|
require 'async/dns'
|
45
48
|
|
46
49
|
class TestServer < Async::DNS::Server
|
@@ -51,9 +54,10 @@ Here is a simple example showing how to use the server:
|
|
51
54
|
end
|
52
55
|
end
|
53
56
|
|
54
|
-
server = TestServer.new(
|
57
|
+
server = TestServer.new([[:udp, '127.0.0.1', 2346]])
|
55
58
|
|
56
59
|
server.run
|
60
|
+
```
|
57
61
|
|
58
62
|
Then to test you could use `dig` like so:
|
59
63
|
|
data/Rakefile
CHANGED
data/async-dns.gemspec
CHANGED
@@ -21,7 +21,7 @@ Gem::Specification.new do |spec|
|
|
21
21
|
spec.require_paths = ["lib"]
|
22
22
|
spec.has_rdoc = "yard"
|
23
23
|
|
24
|
-
spec.add_dependency("async-io", "~> 0
|
24
|
+
spec.add_dependency("async-io", "~> 1.0")
|
25
25
|
|
26
26
|
spec.add_development_dependency "async-rspec", "~> 1.0"
|
27
27
|
spec.add_development_dependency "process-daemon", "~> 1.0"
|
data/lib/async/dns/handler.rb
CHANGED
@@ -22,15 +22,15 @@ require_relative 'transport'
|
|
22
22
|
|
23
23
|
module Async::DNS
|
24
24
|
class GenericHandler
|
25
|
-
def initialize(server,
|
25
|
+
def initialize(server, endpoint)
|
26
26
|
@server = server
|
27
|
-
@
|
27
|
+
@endpoint = endpoint
|
28
28
|
|
29
29
|
@logger = @server.logger || Async.logger
|
30
30
|
end
|
31
31
|
|
32
32
|
attr :server
|
33
|
-
attr :
|
33
|
+
attr :endpoint
|
34
34
|
|
35
35
|
def error_response(query = nil, code = Resolv::DNS::RCode::ServFail)
|
36
36
|
# Encoding may fail, so we need to handle this particular case:
|
@@ -68,7 +68,7 @@ module Async::DNS
|
|
68
68
|
# Handling incoming UDP requests, which are single data packets, and pass them on to the given server.
|
69
69
|
class DatagramHandler < GenericHandler
|
70
70
|
def run(task: Async::Task.current)
|
71
|
-
@
|
71
|
+
@endpoint.bind do |socket|
|
72
72
|
while true
|
73
73
|
Async.logger.debug(self.class.name) {"-> socket.recvfrom"}
|
74
74
|
input_data, remote_address = socket.recvmsg(UDP_TRUNCATION_SIZE)
|
@@ -110,7 +110,7 @@ module Async::DNS
|
|
110
110
|
|
111
111
|
class StreamHandler < GenericHandler
|
112
112
|
def run(task: Async::Task.current)
|
113
|
-
@
|
113
|
+
@endpoint.accept do |client, address|
|
114
114
|
handle_connection(client)
|
115
115
|
end
|
116
116
|
end
|
data/lib/async/dns/replace.rb
CHANGED
data/lib/async/dns/resolver.rb
CHANGED
@@ -46,8 +46,8 @@ module Async::DNS
|
|
46
46
|
# Servers are specified in the same manor as options[:listen], e.g.
|
47
47
|
# [:tcp/:udp, address, port]
|
48
48
|
# In the case of multiple servers, they will be checked in sequence.
|
49
|
-
def initialize(
|
50
|
-
@
|
49
|
+
def initialize(endpoints, origin: nil, logger: Async.logger, timeout: DEFAULT_TIMEOUT)
|
50
|
+
@endpoints = endpoints
|
51
51
|
|
52
52
|
@origin = origin
|
53
53
|
@logger = logger
|
@@ -97,14 +97,14 @@ module Async::DNS
|
|
97
97
|
retries = options.fetch(:retries, DEFAULT_RETRIES)
|
98
98
|
delay = options.fetch(:delay, DEFAULT_DELAY)
|
99
99
|
|
100
|
-
records = lookup(name, resource_class, cache) do |
|
100
|
+
records = lookup(name, resource_class, cache) do |lookup_name, lookup_resource_class|
|
101
101
|
response = nil
|
102
102
|
|
103
103
|
retries.times do |i|
|
104
104
|
# Wait 10ms before trying again:
|
105
105
|
sleep delay if delay and i > 0
|
106
106
|
|
107
|
-
response = query(
|
107
|
+
response = query(lookup_name, lookup_resource_class)
|
108
108
|
|
109
109
|
break if response
|
110
110
|
end
|
@@ -134,18 +134,18 @@ module Async::DNS
|
|
134
134
|
|
135
135
|
# Send the message to available servers. If no servers respond correctly, nil is returned. This result indicates a failure of the resolver to correctly contact any server and get a valid response.
|
136
136
|
def dispatch_request(message, task: Async::Task.current)
|
137
|
-
request = Request.new(message, @
|
137
|
+
request = Request.new(message, @endpoints)
|
138
138
|
|
139
|
-
request.each do |
|
140
|
-
@logger.debug "[#{message.id}] Sending request #{message.question.inspect} to address #{
|
139
|
+
request.each do |endpoint|
|
140
|
+
@logger.debug "[#{message.id}] Sending request #{message.question.inspect} to address #{endpoint.inspect}" if @logger
|
141
141
|
|
142
142
|
begin
|
143
143
|
response = nil
|
144
144
|
|
145
145
|
task.timeout(@timeout) do
|
146
|
-
@logger.debug "[#{message.id}] -> Try address #{
|
147
|
-
response = try_server(request,
|
148
|
-
@logger.debug "[#{message.id}] <- Try address #{
|
146
|
+
@logger.debug "[#{message.id}] -> Try address #{endpoint}" if @logger
|
147
|
+
response = try_server(request, endpoint)
|
148
|
+
@logger.debug "[#{message.id}] <- Try address #{endpoint} = #{response}" if @logger
|
149
149
|
end
|
150
150
|
|
151
151
|
if valid_response(message, response)
|
@@ -175,8 +175,8 @@ module Async::DNS
|
|
175
175
|
response = yield(name, resource_class)
|
176
176
|
|
177
177
|
if response
|
178
|
-
response.answer.each do |
|
179
|
-
(records[
|
178
|
+
response.answer.each do |name_in_answer, ttl, record|
|
179
|
+
(records[name_in_answer] ||= []) << record
|
180
180
|
end
|
181
181
|
end
|
182
182
|
|
@@ -184,14 +184,14 @@ module Async::DNS
|
|
184
184
|
end
|
185
185
|
end
|
186
186
|
|
187
|
-
def try_server(request,
|
188
|
-
case
|
187
|
+
def try_server(request, endpoint)
|
188
|
+
case endpoint.socket_type
|
189
189
|
when Socket::SOCK_DGRAM
|
190
|
-
try_datagram_server(request,
|
190
|
+
try_datagram_server(request, endpoint)
|
191
191
|
when Socket::SOCK_STREAM
|
192
|
-
try_stream_server(request,
|
192
|
+
try_stream_server(request, endpoint)
|
193
193
|
else
|
194
|
-
raise InvalidProtocolError.new(
|
194
|
+
raise InvalidProtocolError.new(endpoint)
|
195
195
|
end
|
196
196
|
end
|
197
197
|
|
@@ -209,8 +209,8 @@ module Async::DNS
|
|
209
209
|
return false
|
210
210
|
end
|
211
211
|
|
212
|
-
def try_datagram_server(request,
|
213
|
-
|
212
|
+
def try_datagram_server(request, endpoint, task: Async::Task.current)
|
213
|
+
endpoint.connect do |socket|
|
214
214
|
socket.sendmsg(request.packet, 0)
|
215
215
|
|
216
216
|
data, peer = socket.recvmsg(UDP_TRUNCATION_SIZE)
|
@@ -219,10 +219,10 @@ module Async::DNS
|
|
219
219
|
end
|
220
220
|
end
|
221
221
|
|
222
|
-
def try_stream_server(request,
|
222
|
+
def try_stream_server(request, endpoint)
|
223
223
|
context = Async::Task.current
|
224
224
|
|
225
|
-
|
225
|
+
endpoint.connect do |socket|
|
226
226
|
StreamTransport.write_chunk(socket, request.packet)
|
227
227
|
|
228
228
|
input_data = StreamTransport.read_chunk(socket)
|
@@ -233,15 +233,15 @@ module Async::DNS
|
|
233
233
|
|
234
234
|
# Manages a single DNS question message across one or more servers.
|
235
235
|
class Request
|
236
|
-
def initialize(message,
|
236
|
+
def initialize(message, endpoints)
|
237
237
|
@message = message
|
238
238
|
@packet = message.encode
|
239
239
|
|
240
|
-
@
|
240
|
+
@endpoints = endpoints.dup
|
241
241
|
|
242
242
|
# We select the protocol based on the size of the data:
|
243
243
|
if @packet.bytesize > UDP_TRUNCATION_SIZE
|
244
|
-
@
|
244
|
+
@endpoints.delete_if{|server| server[0] == :udp}
|
245
245
|
end
|
246
246
|
end
|
247
247
|
|
@@ -250,7 +250,7 @@ module Async::DNS
|
|
250
250
|
attr :logger
|
251
251
|
|
252
252
|
def each(&block)
|
253
|
-
Async::IO::
|
253
|
+
Async::IO::Endpoint.each(@endpoints, &block)
|
254
254
|
end
|
255
255
|
|
256
256
|
def update_id!(id)
|
data/lib/async/dns/server.rb
CHANGED
@@ -19,7 +19,7 @@
|
|
19
19
|
# THE SOFTWARE.
|
20
20
|
|
21
21
|
require 'async'
|
22
|
-
require 'async/io/
|
22
|
+
require 'async/io/endpoint'
|
23
23
|
|
24
24
|
require_relative 'transaction'
|
25
25
|
require_relative 'logger'
|
@@ -27,7 +27,7 @@ require_relative 'logger'
|
|
27
27
|
module Async::DNS
|
28
28
|
class Server
|
29
29
|
# The default server interfaces
|
30
|
-
|
30
|
+
DEFAULT_ENDPOINTS = [[:udp, "0.0.0.0", 53], [:tcp, "0.0.0.0", 53]]
|
31
31
|
|
32
32
|
# Instantiate a server with a block
|
33
33
|
#
|
@@ -37,8 +37,8 @@ module Async::DNS
|
|
37
37
|
# end
|
38
38
|
# end
|
39
39
|
#
|
40
|
-
def initialize(
|
41
|
-
@
|
40
|
+
def initialize(endpoints = DEFAULT_ENDPOINTS, origin: '.', logger: Async.logger)
|
41
|
+
@endpoints = endpoints
|
42
42
|
@origin = origin
|
43
43
|
@logger = logger
|
44
44
|
|
@@ -124,14 +124,14 @@ module Async::DNS
|
|
124
124
|
def setup_handlers
|
125
125
|
fire(:setup)
|
126
126
|
|
127
|
-
Async::IO::
|
128
|
-
case
|
127
|
+
Async::IO::Endpoint.each(@endpoints) do |endpoint|
|
128
|
+
case endpoint.socket_type
|
129
129
|
when Socket::SOCK_DGRAM
|
130
|
-
@logger.info "<> Listening for datagrams on #{
|
131
|
-
@handlers << DatagramHandler.new(self,
|
130
|
+
@logger.info "<> Listening for datagrams on #{endpoint.inspect}"
|
131
|
+
@handlers << DatagramHandler.new(self, endpoint)
|
132
132
|
when Socket::SOCK_STREAM
|
133
|
-
@logger.info "<> Listening for connections on #{
|
134
|
-
@handlers << StreamHandler.new(self,
|
133
|
+
@logger.info "<> Listening for connections on #{endpoint.inspect}"
|
134
|
+
@handlers << StreamHandler.new(self, endpoint)
|
135
135
|
else
|
136
136
|
raise ArgumentError.new("Don't know how to handle #{address}")
|
137
137
|
end
|
data/lib/async/dns/version.rb
CHANGED
@@ -25,7 +25,7 @@ describe Async::DNS::StreamHandler do
|
|
25
25
|
include_context Async::RSpec::Reactor
|
26
26
|
|
27
27
|
let(:server) {Async::DNS::Server.new}
|
28
|
-
let(:address) {Async::IO::
|
28
|
+
let(:address) {Async::IO::Endpoint.tcp('127.0.0.1', 6666)}
|
29
29
|
|
30
30
|
subject {described_class.new(server, address)}
|
31
31
|
|
@@ -44,7 +44,7 @@ describe Async::DNS::DatagramHandler do
|
|
44
44
|
include_context Async::RSpec::Reactor
|
45
45
|
|
46
46
|
let(:server) {Async::DNS::Server.new}
|
47
|
-
let(:address) {Async::IO::
|
47
|
+
let(:address) {Async::IO::Endpoint.udp('127.0.0.1', 6666)}
|
48
48
|
|
49
49
|
subject {described_class.new(server, address)}
|
50
50
|
|
data/spec/async/dns/ipv6_spec.rb
CHANGED
@@ -38,7 +38,7 @@ module Async::DNS::IPv6Spec
|
|
38
38
|
include_context Async::RSpec::Reactor
|
39
39
|
|
40
40
|
let(:server_interfaces) {[[:tcp, '::', 2004]]}
|
41
|
-
let(:server) {TestServer.new(
|
41
|
+
let(:server) {TestServer.new(server_interfaces)}
|
42
42
|
|
43
43
|
it "should connect to the server using TCP via IPv6" do
|
44
44
|
task = server.run
|
@@ -59,7 +59,7 @@ module Async::DNS::IPv6Spec
|
|
59
59
|
include_context Async::RSpec::Reactor
|
60
60
|
|
61
61
|
let(:server_interfaces) {[[:udp, '::', 2006]]}
|
62
|
-
let(:server) {TestServer.new(
|
62
|
+
let(:server) {TestServer.new(server_interfaces)}
|
63
63
|
|
64
64
|
it "should connect to the server using UDP via IPv6" do
|
65
65
|
task = server.run
|
@@ -25,28 +25,49 @@ require 'benchmark'
|
|
25
25
|
require 'process/daemon'
|
26
26
|
|
27
27
|
module Async::DNS::ServerPerformanceSpec
|
28
|
-
|
29
|
-
|
28
|
+
class MillionServer < Async::DNS::Server
|
29
|
+
def initialize(*)
|
30
|
+
super
|
31
|
+
|
32
|
+
@domains = {}
|
33
|
+
|
34
|
+
(1..5_000).each do |i|
|
35
|
+
domain = "domain#{i}.local"
|
36
|
+
|
37
|
+
@domains[domain] = "#{69}.#{(i >> 16)%256}.#{(i >> 8)%256}.#{i%256}"
|
38
|
+
end
|
39
|
+
end
|
30
40
|
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
(1..5_000).each do |i|
|
39
|
-
domain = "domain#{i}.local"
|
41
|
+
attr :domains
|
42
|
+
|
43
|
+
def process(name, resource_class, transaction)
|
44
|
+
transaction.respond!(@domains[name])
|
45
|
+
end
|
46
|
+
end
|
40
47
|
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
+
RSpec.describe MillionServer do
|
49
|
+
# include_context "profile"
|
50
|
+
include_context Async::RSpec::Reactor
|
51
|
+
|
52
|
+
let(:interfaces) {[[:udp, '127.0.0.1', 8899]]}
|
53
|
+
let(:server) {MillionServer.new(interfaces)}
|
54
|
+
let(:resolver) {Async::DNS::Resolver.new(interfaces)}
|
55
|
+
|
56
|
+
it "should be fast" do
|
57
|
+
task = server.run
|
58
|
+
|
59
|
+
server.domains.each do |name, address|
|
60
|
+
resolved = resolver.addresses_for(name)
|
48
61
|
end
|
49
62
|
|
63
|
+
task.stop
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
67
|
+
RSpec.describe Async::DNS::Server do
|
68
|
+
include_context Async::RSpec::Reactor
|
69
|
+
|
70
|
+
context 'benchmark' do
|
50
71
|
class AsyncServerDaemon < Process::Daemon
|
51
72
|
def working_directory
|
52
73
|
File.expand_path("../tmp", __FILE__)
|
@@ -58,7 +79,7 @@ module Async::DNS::ServerPerformanceSpec
|
|
58
79
|
|
59
80
|
def startup
|
60
81
|
puts "Starting DNS server..."
|
61
|
-
@server = MillionServer.new(
|
82
|
+
@server = MillionServer.new([[:udp, '0.0.0.0', 5300]])
|
62
83
|
|
63
84
|
reactor.async do
|
64
85
|
@task = @server.run
|
@@ -121,13 +142,15 @@ module Async::DNS::ServerPerformanceSpec
|
|
121
142
|
resolver = Async::DNS::Resolver.new([[:udp, '127.0.0.1', port]])
|
122
143
|
|
123
144
|
x.report(name) do
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
resolved = @domains.collect{|domain| resolver.addresses_for(domain)}
|
145
|
+
Async::Reactor.run do
|
146
|
+
# Number of requests remaining since this is an asynchronous event loop:
|
147
|
+
5.times do
|
148
|
+
pending = @domains.size
|
129
149
|
|
130
|
-
|
150
|
+
resolved = @domains.collect{|domain| resolver.addresses_for(domain)}
|
151
|
+
|
152
|
+
expect(resolved).to_not include(nil)
|
153
|
+
end
|
131
154
|
end
|
132
155
|
end
|
133
156
|
end
|
@@ -39,7 +39,7 @@ module Async::DNS::SlowServerSpec
|
|
39
39
|
include_context Async::RSpec::Reactor
|
40
40
|
|
41
41
|
let(:server_interfaces) {[[:udp, '0.0.0.0', 5330], [:tcp, '0.0.0.0', 5330]]}
|
42
|
-
let(:server) {SlowServer.new(
|
42
|
+
let(:server) {SlowServer.new(server_interfaces)}
|
43
43
|
|
44
44
|
around(:each) do |example|
|
45
45
|
begin
|
@@ -38,7 +38,7 @@ module Async::DNS::SocketSpec
|
|
38
38
|
include_context Async::RSpec::Reactor
|
39
39
|
|
40
40
|
let(:server_interfaces) {[TCPServer.new('127.0.0.1', 2002)]}
|
41
|
-
let(:server) {TestServer.new(
|
41
|
+
let(:server) {TestServer.new(server_interfaces)}
|
42
42
|
|
43
43
|
it "should create server with existing TCP socket" do
|
44
44
|
task = server.run
|
@@ -56,7 +56,7 @@ module Async::DNS::SocketSpec
|
|
56
56
|
include_context Async::RSpec::Reactor
|
57
57
|
|
58
58
|
let(:server_interfaces) {[UDPSocket.new.tap{|socket| socket.bind('127.0.0.1', 2002)}]}
|
59
|
-
let(:server) {TestServer.new(
|
59
|
+
let(:server) {TestServer.new(server_interfaces)}
|
60
60
|
|
61
61
|
it "should create server with existing UDP socket" do
|
62
62
|
task = server.run
|
@@ -42,7 +42,7 @@ module Async::DNS::TruncationSpec
|
|
42
42
|
describe "Async::DNS Truncation Server" do
|
43
43
|
include_context Async::RSpec::Reactor
|
44
44
|
|
45
|
-
let(:server) {TestServer.new(
|
45
|
+
let(:server) {TestServer.new(SERVER_PORTS)}
|
46
46
|
|
47
47
|
it "should use tcp because of large response" do
|
48
48
|
task = server.run
|
data/spec/spec_helper.rb
CHANGED
@@ -26,7 +26,26 @@ require "bundler/setup"
|
|
26
26
|
require "async/rspec"
|
27
27
|
require "async/dns"
|
28
28
|
|
29
|
-
|
29
|
+
begin
|
30
|
+
require 'ruby-prof'
|
31
|
+
|
32
|
+
RSpec.shared_context "profile" do
|
33
|
+
around(:each) do |example|
|
34
|
+
profile = RubyProf.profile(merge_fibers: true) do
|
35
|
+
example.run
|
36
|
+
end
|
37
|
+
|
38
|
+
printer = RubyProf::FlatPrinter.new(profile)
|
39
|
+
printer.print(STDOUT)
|
40
|
+
end
|
41
|
+
end
|
42
|
+
rescue LoadError
|
43
|
+
RSpec.shared_context "profile" do
|
44
|
+
before(:all) do
|
45
|
+
puts "Profiling not supported on this platform."
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
30
49
|
|
31
50
|
RSpec.configure do |config|
|
32
51
|
# Enable flags like --only-failures and --next-failure
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: async-dns
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 1.0.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Samuel Williams
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2017-
|
11
|
+
date: 2017-07-30 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: async-io
|
@@ -16,14 +16,14 @@ dependencies:
|
|
16
16
|
requirements:
|
17
17
|
- - "~>"
|
18
18
|
- !ruby/object:Gem::Version
|
19
|
-
version: '0
|
19
|
+
version: '1.0'
|
20
20
|
type: :runtime
|
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: '0
|
26
|
+
version: '1.0'
|
27
27
|
- !ruby/object:Gem::Dependency
|
28
28
|
name: async-rspec
|
29
29
|
requirement: !ruby/object:Gem::Requirement
|