random-port 0.5.1 → 0.6.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/.github/workflows/codecov.yml +20 -0
- data/.github/workflows/pdd.yml +11 -0
- data/.github/workflows/rake.yml +24 -0
- data/.github/workflows/xcop.yml +11 -0
- data/.rubocop.yml +6 -0
- data/.rultor.yml +6 -8
- data/Gemfile +8 -0
- data/README.md +1 -2
- data/Rakefile +1 -1
- data/lib/random-port/module.rb +31 -0
- data/lib/random-port/pool.rb +99 -97
- data/lib/random-port.rb +2 -1
- data/random-port.gemspec +3 -13
- data/test/test__helper.rb +1 -6
- data/test/test_pool.rb +79 -58
- metadata +13 -93
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: ac043d33cc466631184efebe238cac398d491f15191cf9d9079ae8608c33f278
|
4
|
+
data.tar.gz: 3813ccfe1a6a03f5a2492b68fde9f2108a44c9c72dffb7d98472f21198e31ba8
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 720f803ac3d1913208418a00c53bfb53b17b6c391b8f567dca601c66424e035b53d994607d40c9f166bc660ff5e3cda4a9000f057fea5d3a8cd24c1b69732086
|
7
|
+
data.tar.gz: 677c5930e62518598d7a626cb3d246ca4e7264fb237d2cd010f7f0c64fc291d294354ceaa7b7363caf1fe32a4aae70dcdfc4363a69788b5525eb00adcc444c04
|
@@ -0,0 +1,20 @@
|
|
1
|
+
---
|
2
|
+
name: codecov
|
3
|
+
on:
|
4
|
+
push:
|
5
|
+
branches:
|
6
|
+
- master
|
7
|
+
jobs:
|
8
|
+
codecov:
|
9
|
+
runs-on: ubuntu-20.04
|
10
|
+
steps:
|
11
|
+
- uses: actions/checkout@v3
|
12
|
+
- uses: ruby/setup-ruby@v1
|
13
|
+
with:
|
14
|
+
ruby-version: 2.7
|
15
|
+
- run: bundle update
|
16
|
+
- run: bundle exec rake
|
17
|
+
- uses: codecov/codecov-action@v3
|
18
|
+
with:
|
19
|
+
file: coverage/.resultset.json
|
20
|
+
fail_ci_if_error: true
|
@@ -0,0 +1,24 @@
|
|
1
|
+
---
|
2
|
+
name: rake
|
3
|
+
on:
|
4
|
+
push:
|
5
|
+
branches:
|
6
|
+
- master
|
7
|
+
pull_request:
|
8
|
+
branches:
|
9
|
+
- master
|
10
|
+
jobs:
|
11
|
+
test:
|
12
|
+
name: test
|
13
|
+
strategy:
|
14
|
+
matrix:
|
15
|
+
os: [ubuntu-20.04, macos-12]
|
16
|
+
ruby: [2.7, 3.2]
|
17
|
+
runs-on: ${{ matrix.os }}
|
18
|
+
steps:
|
19
|
+
- uses: actions/checkout@v3
|
20
|
+
- uses: ruby/setup-ruby@v1
|
21
|
+
with:
|
22
|
+
ruby-version: ${{ matrix.ruby }}
|
23
|
+
- run: bundle update
|
24
|
+
- run: bundle exec rake
|
data/.rubocop.yml
CHANGED
@@ -1,7 +1,13 @@
|
|
1
1
|
AllCops:
|
2
2
|
DisplayCopNames: true
|
3
3
|
TargetRubyVersion: 2.3.3
|
4
|
+
NewCops: enable
|
5
|
+
SuggestExtensions: false
|
4
6
|
|
7
|
+
Layout/EmptyLineAfterGuardClause:
|
8
|
+
Enabled: false
|
9
|
+
Style/ClassAndModuleChildren:
|
10
|
+
Enabled: false
|
5
11
|
Naming/FileName:
|
6
12
|
Enabled: false
|
7
13
|
Metrics/MethodLength:
|
data/.rultor.yml
CHANGED
@@ -1,10 +1,12 @@
|
|
1
|
+
docker:
|
2
|
+
image: yegor256/rultor-image:1.19.0
|
1
3
|
assets:
|
2
|
-
rubygems.yml:
|
4
|
+
rubygems.yml: yegor256/home#assets/rubygems.yml
|
3
5
|
install: |-
|
4
|
-
|
5
|
-
|
6
|
-
bundle install --no-color
|
6
|
+
pdd -f /dev/null
|
7
|
+
sudo bundle install --no-color "--gemfile=$(pwd)/Gemfile"
|
7
8
|
release:
|
9
|
+
pre: false
|
8
10
|
script: |-
|
9
11
|
bundle exec rake
|
10
12
|
rm -rf *.gem
|
@@ -17,7 +19,3 @@ release:
|
|
17
19
|
merge:
|
18
20
|
script: |-
|
19
21
|
bundle exec rake
|
20
|
-
deploy:
|
21
|
-
script: |-
|
22
|
-
echo Nothing to deploy
|
23
|
-
exit -1
|
data/Gemfile
CHANGED
@@ -22,3 +22,11 @@
|
|
22
22
|
|
23
23
|
source 'https://rubygems.org'
|
24
24
|
gemspec
|
25
|
+
|
26
|
+
gem 'minitest', '5.18.0', require: false
|
27
|
+
gem 'rake', '13.0.6', require: false
|
28
|
+
gem 'rdoc', '6.5.0', require: false
|
29
|
+
gem 'rubocop', '1.51.0', require: false
|
30
|
+
gem 'rubocop-rspec', '2.22.0', require: false
|
31
|
+
gem 'simplecov', '0.22.0', require: false
|
32
|
+
gem 'threads', '0.3.0', require: false
|
data/README.md
CHANGED
@@ -1,12 +1,11 @@
|
|
1
1
|
[](http://www.rultor.com/p/yegor256/random-port)
|
2
2
|
[](https://www.jetbrains.com/ruby/)
|
3
3
|
|
4
|
-
[](https://github.com/yegor256/random-port/actions/workflows/rake.yml)
|
5
5
|
[](http://badge.fury.io/rb/random-port)
|
6
6
|
[](https://codeclimate.com/github/yegor256/random-port/maintainability)
|
7
7
|
[](http://rubydoc.info/github/yegor256/random-port/master/frames)
|
8
8
|
[](https://github.com/yegor256/random-port/blob/master/LICENSE.txt)
|
9
|
-
|
10
9
|
[](https://codecov.io/github/yegor256/random-port?branch=master)
|
11
10
|
[](https://hitsofcode.com/view/github/random-port/mailanes)
|
12
11
|
|
data/Rakefile
CHANGED
@@ -0,0 +1,31 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# (The MIT License)
|
4
|
+
#
|
5
|
+
# Copyright (c) 2018 Yegor Bugayenko
|
6
|
+
#
|
7
|
+
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
8
|
+
# of this software and associated documentation files (the 'Software'), to deal
|
9
|
+
# in the Software without restriction, including without limitation the rights
|
10
|
+
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
11
|
+
# copies of the Software, and to permit persons to whom the Software is
|
12
|
+
# furnished to do so, subject to the following conditions:
|
13
|
+
#
|
14
|
+
# The above copyright notice and this permission notice shall be included in all
|
15
|
+
# copies or substantial portions of the Software.
|
16
|
+
#
|
17
|
+
# THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
18
|
+
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
19
|
+
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
20
|
+
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
21
|
+
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
22
|
+
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
23
|
+
# SOFTWARE.
|
24
|
+
|
25
|
+
# The module for all classes.
|
26
|
+
#
|
27
|
+
# Author:: Yegor Bugayenko (yegor256@gmail.com)
|
28
|
+
# Copyright:: Copyright (c) 2018 Yegor Bugayenko
|
29
|
+
# License:: MIT
|
30
|
+
module RandomPort
|
31
|
+
end
|
data/lib/random-port/pool.rb
CHANGED
@@ -24,121 +24,123 @@
|
|
24
24
|
|
25
25
|
require 'socket'
|
26
26
|
require 'monitor'
|
27
|
+
require_relative 'module'
|
27
28
|
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
29
|
+
# Pool of TPC ports.
|
30
|
+
#
|
31
|
+
# Use it like this:
|
32
|
+
#
|
33
|
+
# RandomPort::Pool.new.acquire do |port|
|
34
|
+
# # Use the TCP port. It will be returned back
|
35
|
+
# # to the pool afterwards.
|
36
|
+
# end
|
37
|
+
#
|
38
|
+
# You can specify the maximum amount of ports to acquire, using +limit+.
|
39
|
+
# If more acquiring requests will arrive, an exception will be raised.
|
40
|
+
#
|
41
|
+
# The class is thread-safe, by default. You can configure it to be
|
42
|
+
# not-thread-safe, using optional +sync+ argument of the constructor,
|
43
|
+
# passing <tt>FALSE</tt>.
|
44
|
+
#
|
45
|
+
# Author:: Yegor Bugayenko (yegor256@gmail.com)
|
46
|
+
# Copyright:: Copyright (c) 2018 Yegor Bugayenko
|
47
|
+
# License:: MIT
|
48
|
+
class RandomPort::Pool
|
49
|
+
# If can't acquire by time out.
|
50
|
+
class Timeout < StandardError; end
|
50
51
|
|
51
|
-
|
52
|
+
attr_reader :limit
|
52
53
|
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
54
|
+
# Ctor.
|
55
|
+
# @param [bool] Set it to FALSE if you want this pool to be NOT thread-safe
|
56
|
+
# @param [int] Set the maximum number of ports in the pool
|
57
|
+
def initialize(sync: true, limit: 65_536)
|
58
|
+
@ports = []
|
59
|
+
@sync = sync
|
60
|
+
@monitor = Monitor.new
|
61
|
+
@limit = limit
|
62
|
+
end
|
60
63
|
|
61
|
-
|
62
|
-
|
64
|
+
# Application wide pool of ports
|
65
|
+
SINGLETON = RandomPort::Pool.new
|
63
66
|
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
67
|
+
# How many ports acquired now?
|
68
|
+
def count
|
69
|
+
@ports.count
|
70
|
+
end
|
71
|
+
alias size count
|
69
72
|
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
73
|
+
# Is it empty?
|
74
|
+
def empty?
|
75
|
+
@ports.empty?
|
76
|
+
end
|
74
77
|
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
78
|
+
# Acquire a new random TCP port.
|
79
|
+
#
|
80
|
+
# You can specify the number of ports to acquire. If it's more than one,
|
81
|
+
# an array will be returned.
|
82
|
+
#
|
83
|
+
# You can specify the amount of seconds to wait until a new port
|
84
|
+
# is available.
|
85
|
+
def acquire(total = 1, timeout: 4)
|
86
|
+
start = Time.now
|
87
|
+
loop do
|
88
|
+
if Time.now > start + timeout
|
89
|
+
raise Timeout, "Can't find a place in the pool of #{@limit} ports \
|
87
90
|
for #{total} port(s), in #{format('%.02f', Time.now - start)}s"
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
begin
|
93
|
-
(0..(total - 1)).each do |i|
|
94
|
-
opts[i] = i.zero? ? take : take(opts[i - 1] + 1)
|
95
|
-
end
|
96
|
-
rescue Errno::EADDRINUSE, SocketError
|
97
|
-
next
|
98
|
-
end
|
99
|
-
next if opts.any? { |p| @ports.include?(p) }
|
100
|
-
d = total * (total - 1) / 2
|
101
|
-
next unless opts.inject(&:+) - total * opts.min == d
|
102
|
-
@ports += opts
|
103
|
-
opts
|
104
|
-
end
|
105
|
-
next if opts.nil?
|
106
|
-
opts = opts[0] if total == 1
|
107
|
-
return opts unless block_given?
|
91
|
+
end
|
92
|
+
opts = safe do
|
93
|
+
next if @ports.count + total > @limit
|
94
|
+
opts = Array.new(0, total)
|
108
95
|
begin
|
109
|
-
|
110
|
-
|
111
|
-
|
96
|
+
(0..(total - 1)).each do |i|
|
97
|
+
opts[i] = i.zero? ? take : take(opts[i - 1] + 1)
|
98
|
+
end
|
99
|
+
rescue Errno::EADDRINUSE, SocketError
|
100
|
+
next
|
112
101
|
end
|
102
|
+
next if opts.any? { |p| @ports.include?(p) }
|
103
|
+
d = total * (total - 1) / 2
|
104
|
+
next unless opts.inject(&:+) - (total * opts.min) == d
|
105
|
+
@ports += opts
|
106
|
+
opts
|
107
|
+
end
|
108
|
+
next if opts.nil?
|
109
|
+
opts = opts[0] if total == 1
|
110
|
+
return opts unless block_given?
|
111
|
+
begin
|
112
|
+
return yield opts
|
113
|
+
ensure
|
114
|
+
release(opts)
|
113
115
|
end
|
114
116
|
end
|
117
|
+
end
|
115
118
|
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
end
|
119
|
+
# Return it/them back to the pool.
|
120
|
+
def release(port)
|
121
|
+
safe do
|
122
|
+
if port.is_a?(Array)
|
123
|
+
port.each { |p| @ports.delete(p) }
|
124
|
+
else
|
125
|
+
@ports.delete(port)
|
124
126
|
end
|
125
127
|
end
|
128
|
+
end
|
126
129
|
|
127
|
-
|
130
|
+
private
|
128
131
|
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
|
132
|
+
def take(opt = 0)
|
133
|
+
server = TCPServer.new('127.0.0.1', opt)
|
134
|
+
p = server.addr[1]
|
135
|
+
server.close
|
136
|
+
p
|
137
|
+
end
|
135
138
|
|
136
|
-
|
137
|
-
|
138
|
-
|
139
|
-
|
140
|
-
|
141
|
-
end
|
139
|
+
def safe(&block)
|
140
|
+
if @sync
|
141
|
+
@monitor.synchronize(&block)
|
142
|
+
else
|
143
|
+
yield
|
142
144
|
end
|
143
145
|
end
|
144
146
|
end
|
data/lib/random-port.rb
CHANGED
data/random-port.gemspec
CHANGED
@@ -24,14 +24,10 @@
|
|
24
24
|
|
25
25
|
require 'English'
|
26
26
|
Gem::Specification.new do |s|
|
27
|
-
s.
|
28
|
-
if s.respond_to? :required_rubygems_version=
|
29
|
-
s.required_rubygems_version = Gem::Requirement.new('>= 0')
|
30
|
-
end
|
31
|
-
s.rubygems_version = '2.3.3'
|
27
|
+
s.required_rubygems_version = Gem::Requirement.new('>= 0') if s.respond_to? :required_rubygems_version=
|
32
28
|
s.required_ruby_version = '>=2.3'
|
33
29
|
s.name = 'random-port'
|
34
|
-
s.version = '0.
|
30
|
+
s.version = '0.6.0'
|
35
31
|
s.license = 'MIT'
|
36
32
|
s.summary = 'Random TCP port'
|
37
33
|
s.description = 'Reserves a random TCP port'
|
@@ -39,13 +35,7 @@ Gem::Specification.new do |s|
|
|
39
35
|
s.email = 'yegor256@gmail.com'
|
40
36
|
s.homepage = 'http://github.com/yegor256/random-port'
|
41
37
|
s.files = `git ls-files`.split($RS)
|
42
|
-
s.test_files = s.files.grep(%r{^(test)/})
|
43
38
|
s.rdoc_options = ['--charset=UTF-8']
|
44
39
|
s.extra_rdoc_files = ['README.md']
|
45
|
-
s.
|
46
|
-
s.add_development_dependency 'minitest', '5.11.3'
|
47
|
-
s.add_development_dependency 'rake', '12.3.1'
|
48
|
-
s.add_development_dependency 'rdoc', '4.3.0'
|
49
|
-
s.add_development_dependency 'rubocop', '0.58.1'
|
50
|
-
s.add_development_dependency 'rubocop-rspec', '1.27.0'
|
40
|
+
s.metadata['rubygems_mfa_required'] = 'true'
|
51
41
|
end
|
data/test/test__helper.rb
CHANGED
@@ -20,13 +20,8 @@
|
|
20
20
|
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
21
21
|
# SOFTWARE.
|
22
22
|
|
23
|
-
|
23
|
+
$stdout.sync = true
|
24
24
|
|
25
25
|
require 'simplecov'
|
26
26
|
SimpleCov.start
|
27
|
-
if ENV['CI'] == 'true'
|
28
|
-
require 'codecov'
|
29
|
-
SimpleCov.formatter = SimpleCov::Formatter::Codecov
|
30
|
-
end
|
31
|
-
|
32
27
|
require 'minitest/autorun'
|
data/test/test_pool.rb
CHANGED
@@ -23,88 +23,109 @@
|
|
23
23
|
# SOFTWARE.
|
24
24
|
|
25
25
|
require 'minitest/autorun'
|
26
|
+
require 'threads'
|
26
27
|
require_relative '../lib/random-port/pool'
|
27
28
|
|
28
29
|
# Pool test.
|
29
30
|
# Author:: Yegor Bugayenko (yegor256@gmail.com)
|
30
31
|
# Copyright:: Copyright (c) 2018 Yegor Bugayenko
|
31
32
|
# License:: MIT
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
33
|
+
class RandomPort::TestPool < Minitest::Test
|
34
|
+
def test_acquires_and_releases
|
35
|
+
pool = RandomPort::Pool.new
|
36
|
+
port = pool.acquire
|
37
|
+
server = TCPServer.new(port)
|
38
|
+
server.close
|
39
|
+
assert(!port.nil?)
|
40
|
+
assert(port.positive?)
|
41
|
+
pool.release(port)
|
42
|
+
end
|
41
43
|
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
assert_equal(0, pool.size)
|
44
|
+
def test_acquires_and_releases_three_ports
|
45
|
+
pool = RandomPort::Pool.new(limit: 3)
|
46
|
+
assert_equal(0, pool.size)
|
47
|
+
ports = pool.acquire(3, timeout: 16)
|
48
|
+
ports.each do |p|
|
49
|
+
server = TCPServer.new(p)
|
50
|
+
server.close
|
50
51
|
end
|
52
|
+
assert_equal(3, pool.size)
|
53
|
+
assert_equal(3, ports.count)
|
54
|
+
pool.release(ports)
|
55
|
+
assert_equal(0, pool.size)
|
56
|
+
end
|
51
57
|
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
58
|
+
def test_acquires_and_releases_three_ports_in_block
|
59
|
+
pool = RandomPort::Pool.new(limit: 3)
|
60
|
+
assert_equal(0, pool.size)
|
61
|
+
pool.acquire(3, timeout: 16) do |ports|
|
62
|
+
assert(ports.is_a?(Array))
|
63
|
+
assert_equal(3, ports.count)
|
64
|
+
assert_equal(3, pool.size)
|
65
|
+
ports.each do |p|
|
66
|
+
server = TCPServer.new(p)
|
67
|
+
server.close
|
59
68
|
end
|
60
|
-
assert_equal(0, pool.size)
|
61
69
|
end
|
70
|
+
assert_equal(0, pool.size)
|
71
|
+
end
|
62
72
|
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
end
|
69
|
-
assert_equal(123, result)
|
73
|
+
def test_acquires_and_releases_in_block
|
74
|
+
result = RandomPort::Pool.new.acquire do |port|
|
75
|
+
assert(!port.nil?)
|
76
|
+
assert(port.positive?)
|
77
|
+
123
|
70
78
|
end
|
79
|
+
assert_equal(123, result)
|
80
|
+
end
|
71
81
|
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
82
|
+
def test_acquires_and_releases_in_threads
|
83
|
+
pool = RandomPort::Pool.new
|
84
|
+
Threads.new(100).assert do
|
85
|
+
pool.acquire(5) do |ports|
|
86
|
+
ports.each do |p|
|
87
|
+
server = TCPServer.new(p)
|
88
|
+
server.close
|
77
89
|
end
|
78
90
|
end
|
79
|
-
assert(pool.count.zero?)
|
80
91
|
end
|
92
|
+
end
|
81
93
|
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
94
|
+
def test_acquires_and_releases_safely
|
95
|
+
pool = RandomPort::Pool.new
|
96
|
+
assert_raises do
|
97
|
+
pool.acquire do
|
98
|
+
raise 'Itended'
|
86
99
|
end
|
87
100
|
end
|
101
|
+
assert(pool.count.zero?)
|
102
|
+
end
|
88
103
|
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
104
|
+
def test_acquires_and_releases_from_singleton
|
105
|
+
RandomPort::Pool::SINGLETON.acquire do |port|
|
106
|
+
assert(!port.nil?)
|
107
|
+
assert(port.positive?)
|
93
108
|
end
|
109
|
+
end
|
94
110
|
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
end
|
101
|
-
end
|
111
|
+
def test_acquires_unique_numbers
|
112
|
+
total = 25
|
113
|
+
numbers = (0..total - 1).map { RandomPort::Pool::SINGLETON.acquire }
|
114
|
+
assert_equal(total, numbers.uniq.count)
|
115
|
+
end
|
102
116
|
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
117
|
+
def test_raises_when_too_many
|
118
|
+
pool = RandomPort::Pool.new(limit: 1)
|
119
|
+
pool.acquire
|
120
|
+
assert_raises RandomPort::Pool::Timeout do
|
121
|
+
pool.acquire(timeout: 0.1)
|
108
122
|
end
|
109
123
|
end
|
124
|
+
|
125
|
+
def test_acquires_unique_numbers_in_no_sync_mode
|
126
|
+
total = 25
|
127
|
+
pool = RandomPort::Pool.new(sync: false)
|
128
|
+
numbers = (0..total - 1).map { pool.acquire }
|
129
|
+
assert_equal(total, numbers.uniq.count)
|
130
|
+
end
|
110
131
|
end
|
metadata
CHANGED
@@ -1,99 +1,15 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: random-port
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.6.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Yegor Bugayenko
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
12
|
-
dependencies:
|
13
|
-
- !ruby/object:Gem::Dependency
|
14
|
-
name: codecov
|
15
|
-
requirement: !ruby/object:Gem::Requirement
|
16
|
-
requirements:
|
17
|
-
- - '='
|
18
|
-
- !ruby/object:Gem::Version
|
19
|
-
version: 0.1.10
|
20
|
-
type: :development
|
21
|
-
prerelease: false
|
22
|
-
version_requirements: !ruby/object:Gem::Requirement
|
23
|
-
requirements:
|
24
|
-
- - '='
|
25
|
-
- !ruby/object:Gem::Version
|
26
|
-
version: 0.1.10
|
27
|
-
- !ruby/object:Gem::Dependency
|
28
|
-
name: minitest
|
29
|
-
requirement: !ruby/object:Gem::Requirement
|
30
|
-
requirements:
|
31
|
-
- - '='
|
32
|
-
- !ruby/object:Gem::Version
|
33
|
-
version: 5.11.3
|
34
|
-
type: :development
|
35
|
-
prerelease: false
|
36
|
-
version_requirements: !ruby/object:Gem::Requirement
|
37
|
-
requirements:
|
38
|
-
- - '='
|
39
|
-
- !ruby/object:Gem::Version
|
40
|
-
version: 5.11.3
|
41
|
-
- !ruby/object:Gem::Dependency
|
42
|
-
name: rake
|
43
|
-
requirement: !ruby/object:Gem::Requirement
|
44
|
-
requirements:
|
45
|
-
- - '='
|
46
|
-
- !ruby/object:Gem::Version
|
47
|
-
version: 12.3.1
|
48
|
-
type: :development
|
49
|
-
prerelease: false
|
50
|
-
version_requirements: !ruby/object:Gem::Requirement
|
51
|
-
requirements:
|
52
|
-
- - '='
|
53
|
-
- !ruby/object:Gem::Version
|
54
|
-
version: 12.3.1
|
55
|
-
- !ruby/object:Gem::Dependency
|
56
|
-
name: rdoc
|
57
|
-
requirement: !ruby/object:Gem::Requirement
|
58
|
-
requirements:
|
59
|
-
- - '='
|
60
|
-
- !ruby/object:Gem::Version
|
61
|
-
version: 4.3.0
|
62
|
-
type: :development
|
63
|
-
prerelease: false
|
64
|
-
version_requirements: !ruby/object:Gem::Requirement
|
65
|
-
requirements:
|
66
|
-
- - '='
|
67
|
-
- !ruby/object:Gem::Version
|
68
|
-
version: 4.3.0
|
69
|
-
- !ruby/object:Gem::Dependency
|
70
|
-
name: rubocop
|
71
|
-
requirement: !ruby/object:Gem::Requirement
|
72
|
-
requirements:
|
73
|
-
- - '='
|
74
|
-
- !ruby/object:Gem::Version
|
75
|
-
version: 0.58.1
|
76
|
-
type: :development
|
77
|
-
prerelease: false
|
78
|
-
version_requirements: !ruby/object:Gem::Requirement
|
79
|
-
requirements:
|
80
|
-
- - '='
|
81
|
-
- !ruby/object:Gem::Version
|
82
|
-
version: 0.58.1
|
83
|
-
- !ruby/object:Gem::Dependency
|
84
|
-
name: rubocop-rspec
|
85
|
-
requirement: !ruby/object:Gem::Requirement
|
86
|
-
requirements:
|
87
|
-
- - '='
|
88
|
-
- !ruby/object:Gem::Version
|
89
|
-
version: 1.27.0
|
90
|
-
type: :development
|
91
|
-
prerelease: false
|
92
|
-
version_requirements: !ruby/object:Gem::Requirement
|
93
|
-
requirements:
|
94
|
-
- - '='
|
95
|
-
- !ruby/object:Gem::Version
|
96
|
-
version: 1.27.0
|
11
|
+
date: 2023-05-26 00:00:00.000000000 Z
|
12
|
+
dependencies: []
|
97
13
|
description: Reserves a random TCP port
|
98
14
|
email: yegor256@gmail.com
|
99
15
|
executables: []
|
@@ -102,6 +18,10 @@ extra_rdoc_files:
|
|
102
18
|
- README.md
|
103
19
|
files:
|
104
20
|
- ".0pdd.yml"
|
21
|
+
- ".github/workflows/codecov.yml"
|
22
|
+
- ".github/workflows/pdd.yml"
|
23
|
+
- ".github/workflows/rake.yml"
|
24
|
+
- ".github/workflows/xcop.yml"
|
105
25
|
- ".gitignore"
|
106
26
|
- ".pdd"
|
107
27
|
- ".rubocop.yml"
|
@@ -112,6 +32,7 @@ files:
|
|
112
32
|
- README.md
|
113
33
|
- Rakefile
|
114
34
|
- lib/random-port.rb
|
35
|
+
- lib/random-port/module.rb
|
115
36
|
- lib/random-port/pool.rb
|
116
37
|
- random-port.gemspec
|
117
38
|
- test/test__helper.rb
|
@@ -119,7 +40,8 @@ files:
|
|
119
40
|
homepage: http://github.com/yegor256/random-port
|
120
41
|
licenses:
|
121
42
|
- MIT
|
122
|
-
metadata:
|
43
|
+
metadata:
|
44
|
+
rubygems_mfa_required: 'true'
|
123
45
|
post_install_message:
|
124
46
|
rdoc_options:
|
125
47
|
- "--charset=UTF-8"
|
@@ -136,10 +58,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
136
58
|
- !ruby/object:Gem::Version
|
137
59
|
version: '0'
|
138
60
|
requirements: []
|
139
|
-
rubygems_version: 3.
|
61
|
+
rubygems_version: 3.2.15
|
140
62
|
signing_key:
|
141
|
-
specification_version:
|
63
|
+
specification_version: 4
|
142
64
|
summary: Random TCP port
|
143
|
-
test_files:
|
144
|
-
- test/test__helper.rb
|
145
|
-
- test/test_pool.rb
|
65
|
+
test_files: []
|