zold 0.21.4 → 0.22.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 97e75811a1329436f6840794104457cfcc6cf123144fd5a248db333fec67e8f7
4
- data.tar.gz: a7ffabc0edb17a8e59c588ed390c9efbd4f34483631178f995e33dd35c6a2539
3
+ metadata.gz: 396a65bbca7258f8feecc54b1474e49805316f4088bbc7a9a6f1e62ff5a33ac8
4
+ data.tar.gz: 5172b79f8b015f94ad90a4453e110778d7f21a75b2e6643a77e009ecb8244987
5
5
  SHA512:
6
- metadata.gz: 12541b87e91a1597365b86e65a9eafe192c5362b492f54d16c24e244cf667a86168e63991f397cc3af791596e5ebaadf35aea64cb54cf042803768bdec5a5854
7
- data.tar.gz: 9eb0728e374ff5c74e3db2992bf8d3bbcf3644deaa626df556f7a6fe1bcfdce9012d86e1f6a4280ee36b3ad6a4ff84e2ad2d922887b999dacb05a74d9d78cc13
6
+ metadata.gz: f2dfba67609c3021e6f7504a7fbd077d45388f4aad4e0aeca8475f624ee7fa37df8d262efad99250b304d6169ed735e8de739e766869d91fa601be080744db92
7
+ data.tar.gz: a27154e642518f971672bc210aeeb81c5291a307c9ecc04daf1a7e781637033fe25dd1f343994ca1a696bf2c0b43939e1210b1f4c3d6a11aee934c2b9efce2f4
data/.travis.yml CHANGED
@@ -1,6 +1,6 @@
1
1
  language: ruby
2
2
  rvm:
3
- - 2.5.1
3
+ - 2.6.0
4
4
  cache: bundler
5
5
  branches:
6
6
  only:
data/INSTALL.md CHANGED
@@ -18,17 +18,29 @@ It is recommended to have at least 2 CPUs and 2 Gb RAM.
18
18
 
19
19
  ## Debian 9.4
20
20
 
21
+ As a `root` user:
22
+
21
23
  ```bash
22
24
  $ sudo apt update -y
23
25
  $ sudo apt install -y ruby-dev rubygems zlib1g-dev libssl-dev make build-essential libcurl4-openssl-dev
26
+ $ gpg --keyserver hkp://keys.gnupg.net --recv-keys 409B6B1796C275462A1703113804BB82D39DC0E3 7D2BAF1CF37B13E2069D6956105BD0E739499BDB
27
+ $ curl -sSL https://get.rvm.io | bash -s stable
28
+ $ source /etc/profile.d/rvm.sh
29
+ $ rvm install --default 2.5.1
24
30
  $ gem install --no-ri --no-rdoc zold
25
31
  ```
26
32
 
27
33
  ## Ubuntu 16.04
28
34
 
35
+ As a `root` user:
36
+
29
37
  ```bash
30
38
  $ sudo apt-get update -y
31
- $ sudo apt-get install -y ruby-dev rubygems zlib1g-dev libssl-dev build-essential libcurl4-openssl-dev
39
+ $ sudo apt-get install -y curl ruby-dev rubygems zlib1g-dev libssl-dev build-essential libcurl4-openssl-dev
40
+ $ gpg --keyserver hkp://keys.gnupg.net --recv-keys 409B6B1796C275462A1703113804BB82D39DC0E3 7D2BAF1CF37B13E2069D6956105BD0E739499BDB
41
+ $ curl -sSL https://get.rvm.io | bash -s stable
42
+ $ source /etc/profile.d/rvm.sh
43
+ $ rvm install --default 2.5.1
32
44
  $ gem install --no-ri --no-rdoc zold
33
45
  ```
34
46
 
@@ -64,7 +76,7 @@ $ sudo yum install zlib-devel gcc gcc-c++ ruby-devel rubygems ruby curl-devel
64
76
  $ gpg --keyserver hkp://keys.gnupg.net --recv-keys 409B6B1796C275462A1703113804BB82D39DC0E3 7D2BAF1CF37B13E2069D6956105BD0E739499BDB
65
77
  $ curl -sSL https://get.rvm.io | bash -s stable
66
78
  $ source /etc/profile.d/rvm.sh
67
- $ rvm install 2.5.1
79
+ $ rvm install --default 2.5.1
68
80
  $ gem install --no-ri --no-rdoc zold
69
81
  ```
70
82
 
@@ -75,7 +87,7 @@ $ sudo yum install zlib-devel gcc gcc-c++ ruby-devel rubygems ruby libcurl4-open
75
87
  $ gpg --keyserver hkp://keys.gnupg.net --recv-keys 409B6B1796C275462A1703113804BB82D39DC0E3 7D2BAF1CF37B13E2069D6956105BD0E739499BDB
76
88
  $ curl -sSL https://get.rvm.io | bash -s stable
77
89
  $ source $HOME/.rvm/scripts/rvm
78
- $ rvm install 2.5.1
90
+ $ rvm install --default 2.5.1
79
91
  $ gem install --no-ri --no-rdoc zold
80
92
  ```
81
93
 
@@ -87,6 +87,9 @@ Available options:"
87
87
  o.integer '--threads',
88
88
  'How many threads to use for fetching wallets (default: 1)',
89
89
  default: 1
90
+ o.integer '--retry',
91
+ 'How many times to retry each node before reporting a failure (default: 2)',
92
+ default: 2
90
93
  o.bool '--help', 'Print instructions'
91
94
  end
92
95
  mine = Args.new(opts, @log).take || return
@@ -133,48 +136,64 @@ run 'zold remote update' or use --tolerate-quorum=1"
133
136
  end
134
137
 
135
138
  def fetch_one(id, r, cps, opts)
136
- start = Time.now
137
139
  if opts['ignore-node'].include?(r.to_s)
138
140
  @log.debug("#{r} ignored because of --ignore-node")
139
141
  return 0
140
142
  end
141
- uri = "/wallet/#{id}"
142
- head = r.http(uri).get
143
- r.assert_code(200, head)
144
- json = JsonPage.new(head.body, uri).to_hash
145
- score = Score.parse_json(json['score'])
146
- r.assert_valid_score(score)
147
- r.assert_score_ownership(score)
148
- r.assert_score_strength(score) unless opts['ignore-score-weakness']
149
- copy = nil
150
- cps.all.each do |c|
151
- next unless json['digest'] == OpenSSL::Digest::SHA256.file(c[:path]).hexdigest &&
152
- json['size'] == File.size(c[:path])
153
- copy = cps.add(IO.read(c[:path]), score.host, score.port, score.value, master: r.master?)
154
- @log.debug("No need to fetch #{id} from #{r}, it's the same content as copy ##{copy}")
155
- break
156
- end
157
- if copy.nil?
158
- Tempfile.open(['', Wallet::EXT]) do |f|
159
- r.http(uri + '.bin').get_file(f)
160
- wallet = Wallet.new(f.path)
161
- wallet.refurbish
162
- if wallet.protocol != Zold::PROTOCOL
163
- raise "Protocol #{wallet.protocol} doesn't match #{Zold::PROTOCOL} in #{id}"
164
- end
165
- if wallet.network != opts['network']
166
- raise "The wallet #{id} is in network '#{wallet.network}', while we are in '#{opts['network']}'"
167
- end
168
- if wallet.balance.negative? && !wallet.root?
169
- raise "The balance of #{id} is #{wallet.balance} and it's not a root wallet"
143
+ start = Time.now
144
+ read_one(id, r, opts) do |json, score|
145
+ r.assert_valid_score(score)
146
+ r.assert_score_ownership(score)
147
+ r.assert_score_strength(score) unless opts['ignore-score-weakness']
148
+ copy = nil
149
+ cps.all.each do |c|
150
+ next unless json['digest'] == OpenSSL::Digest::SHA256.file(c[:path]).hexdigest &&
151
+ json['size'] == File.size(c[:path])
152
+ copy = cps.add(IO.read(c[:path]), score.host, score.port, score.value, master: r.master?)
153
+ @log.debug("No need to fetch #{id} from #{r}, it's the same content as copy ##{copy}")
154
+ break
155
+ end
156
+ if copy.nil?
157
+ Tempfile.open(['', Wallet::EXT]) do |f|
158
+ r.http("/wallet/#{id}.bin").get_file(f)
159
+ wallet = Wallet.new(f.path)
160
+ wallet.refurbish
161
+ if wallet.protocol != Zold::PROTOCOL
162
+ raise "Protocol #{wallet.protocol} doesn't match #{Zold::PROTOCOL} in #{id}"
163
+ end
164
+ if wallet.network != opts['network']
165
+ raise "The wallet #{id} is in network '#{wallet.network}', while we are in '#{opts['network']}'"
166
+ end
167
+ if wallet.balance.negative? && !wallet.root?
168
+ raise "The balance of #{id} is #{wallet.balance} and it's not a root wallet"
169
+ end
170
+ copy = cps.add(IO.read(f), score.host, score.port, score.value, master: r.master?)
171
+ @log.info("#{r} returned #{wallet.mnemo} #{Age.new(json['mtime'])}/#{json['copies']}c \
172
+ as copy ##{copy}/#{cps.all.count} in #{Age.new(start, limit: 4)}: \
173
+ #{Rainbow(score.value).green} (#{json['version']})")
170
174
  end
171
- copy = cps.add(IO.read(f), score.host, score.port, score.value, master: r.master?)
172
- @log.info("#{r} returned #{wallet.mnemo} #{Age.new(json['mtime'])}/#{json['copies']}c \
173
- as copy ##{copy}/#{cps.all.count} in #{Age.new(start, limit: 4)}: \
174
- #{Rainbow(score.value).green} (#{json['version']})")
175
175
  end
176
+ score.value
177
+ end
178
+ end
179
+
180
+ def read_one(id, r, opts)
181
+ attempt = 0
182
+ begin
183
+ uri = "/wallet/#{id}"
184
+ head = r.http(uri).get
185
+ r.assert_code(200, head)
186
+ json = JsonPage.new(head.body, uri).to_hash
187
+ score = Score.parse_json(json['score'])
188
+ yield json, score
189
+ rescue JsonPage::CantParse, Score::CantParse, RemoteNode::CantAssert => e
190
+ attempt += 1
191
+ if attempt < opts['retry']
192
+ @log.error("#{r} failed to fetch #{id}, trying again (attempt no.#{attempt}): #{e.message}")
193
+ retry
194
+ end
195
+ raise e
176
196
  end
177
- score.value
178
197
  end
179
198
 
180
199
  def digest(json)
@@ -78,6 +78,9 @@ Available options:"
78
78
  o.integer '--threads',
79
79
  'How many threads to use for pushing wallets (default: 1)',
80
80
  default: 1
81
+ o.integer '--retry',
82
+ 'How many times to retry each node before reporting a failure (default: 2)',
83
+ default: 2
81
84
  o.bool '--help', 'Print instructions'
82
85
  end
83
86
  mine = Args.new(opts, @log).take || return
@@ -127,27 +130,41 @@ out of #{nodes.value} in #{Age.new(start)}, total score for #{id} is #{total.val
127
130
  return 0
128
131
  end
129
132
  start = Time.now
130
- uri = "/wallet/#{id}"
131
- response = Tempfile.open do |f|
132
- @wallets.acq(id) { |w| FileUtils.copy_file(w.path, f.path) }
133
- r.http(uri).put(f)
133
+ read_one(id, r, opts) do |json, score|
134
+ r.assert_valid_score(score)
135
+ r.assert_score_ownership(score)
136
+ r.assert_score_strength(score) unless opts['ignore-score-weakness']
137
+ if @log.info?
138
+ @log.info("#{r} accepted #{@wallets.acq(id, &:mnemo)} in #{Age.new(start, limit: 4)}: \
139
+ #{Rainbow(score.value).green} (#{json['version']})")
140
+ end
141
+ score.value
134
142
  end
135
- @wallets.acq(id) do |wallet|
143
+ end
144
+
145
+ def read_one(id, r, opts)
146
+ start = Time.now
147
+ uri = "/wallet/#{id}"
148
+ begin
149
+ response = Tempfile.open do |f|
150
+ @wallets.acq(id) { |w| FileUtils.copy_file(w.path, f.path) }
151
+ r.http(uri).put(f)
152
+ end
136
153
  if response.status == 304
137
- @log.info("#{r}: same version of #{wallet.mnemo} there, in #{Age.new(start, limit: 0.5)}")
154
+ @log.info("#{r}: same version of #{@wallets.acq(id, &:mnemo)} there, in #{Age.new(start, limit: 0.5)}")
138
155
  return 0
139
156
  end
140
157
  r.assert_code(200, response)
141
158
  json = JsonPage.new(response.body, uri).to_hash
142
159
  score = Score.parse_json(json['score'])
143
- r.assert_valid_score(score)
144
- r.assert_score_ownership(score)
145
- r.assert_score_strength(score) unless opts['ignore-score-weakness']
146
- if @log.info?
147
- @log.info("#{r} accepted #{wallet.mnemo} in #{Age.new(start, limit: 4)}: \
148
- #{Rainbow(score.value).green} (#{json['version']})")
160
+ yield json, score
161
+ rescue JsonPage::CantParse, Score::CantParse, RemoteNode::CantAssert => e
162
+ attempt += 1
163
+ if attempt < opts['retry']
164
+ @log.error("#{r} failed to push #{id}, trying again (attempt no.#{attempt}): #{e.message}")
165
+ retry
149
166
  end
150
- score.value
167
+ raise e
151
168
  end
152
169
  end
153
170
  end
@@ -93,12 +93,18 @@ Available options:"
93
93
  o.bool '--ignore-if-exists',
94
94
  'Ignore the node while adding if it already exists in the list',
95
95
  default: false
96
+ o.bool '--ignore-masters',
97
+ 'Don\'t elect master nodes, only edges',
98
+ default: false
96
99
  o.integer '--min-score',
97
100
  "The minimum score required for winning the election (default: #{Tax::EXACT_SCORE})",
98
101
  default: Tax::EXACT_SCORE
99
102
  o.integer '--max-winners',
100
103
  'The maximum amount of election winners the election (default: 1)',
101
104
  default: 1
105
+ o.integer '--retry',
106
+ 'How many times to retry each node before reporting a failure (default: 2)',
107
+ default: 2
102
108
  o.bool '--skip-ping',
103
109
  'Don\'t ping back the node when adding it (not recommended)',
104
110
  default: false
@@ -227,6 +233,10 @@ Available options:"
227
233
  r.assert_score_ownership(score)
228
234
  r.assert_score_strength(score) unless opts['ignore-score-weakness']
229
235
  r.assert_score_value(score, opts['min-score']) unless opts['ignore-score-value']
236
+ if r.master? && opts['--ignore-masters']
237
+ @log.debug("#{r} ignored, it's a master node")
238
+ next
239
+ end
230
240
  scores << score
231
241
  end
232
242
  scores = scores.sample(opts['max-winners'])
@@ -254,41 +264,38 @@ Available options:"
254
264
  opts['depth'].times do |cycle|
255
265
  @remotes.iterate(@log, farm: @farm) do |r|
256
266
  start = Time.now
257
- uri = '/remotes'
258
- res = r.http(uri).get
259
- r.assert_code(200, res)
260
- json = JsonPage.new(res.body, uri).to_hash
261
- score = Score.parse_json(json['score'])
262
- r.assert_valid_score(score)
263
- r.assert_score_ownership(score)
264
- r.assert_score_strength(score) unless opts['ignore-score-weakness']
265
- @remotes.rescore(score.host, score.port, score.value)
266
- if Semantic::Version.new(VERSION) < Semantic::Version.new(json['version'])
267
- if opts['reboot']
268
- @log.info("#{r}: their version #{json['version']} is higher than mine #{VERSION}, reboot! \
269
- (use --never-reboot to avoid this from happening)")
270
- terminate
267
+ update_one(r, opts) do |json, score|
268
+ r.assert_valid_score(score)
269
+ r.assert_score_ownership(score)
270
+ r.assert_score_strength(score) unless opts['ignore-score-weakness']
271
+ @remotes.rescore(score.host, score.port, score.value)
272
+ if Semantic::Version.new(VERSION) < Semantic::Version.new(json['version'])
273
+ if opts['reboot']
274
+ @log.info("#{r}: their version #{json['version']} is higher than mine #{VERSION}, reboot! \
275
+ (use --never-reboot to avoid this from happening)")
276
+ terminate
277
+ end
278
+ @log.debug("#{r}: their version #{json['version']} is higher than mine #{VERSION}, \
279
+ it's recommended to reboot, but I don't do it because of --never-reboot")
271
280
  end
272
- @log.debug("#{r}: their version #{json['version']} is higher than mine #{VERSION}, \
273
- it's recommended to reboot, but I don't do it because of --never-reboot")
274
- end
275
- if Semantic::Version.new(VERSION) < Semantic::Version.new(Zold::Gem.new.last_version)
276
- if opts['reboot']
277
- @log.info("#{r}: the version of the gem is higher than mine #{VERSION}, reboot! \
278
- (use --never-reboot to avoid this from happening)")
279
- terminate
281
+ if Semantic::Version.new(VERSION) < Semantic::Version.new(Zold::Gem.new.last_version)
282
+ if opts['reboot']
283
+ @log.info("#{r}: the version of the gem is higher than mine #{VERSION}, reboot! \
284
+ (use --never-reboot to avoid this from happening)")
285
+ terminate
286
+ end
287
+ @log.debug("#{r}: gem version is higher than mine #{VERSION}, \
288
+ it's recommended to reboot, but I don't do it because of --never-reboot")
280
289
  end
281
- @log.debug("#{r}: gem version is higher than mine #{VERSION}, \
282
- it's recommended to reboot, but I don't do it because of --never-reboot")
283
- end
284
- if cycle.positive?
285
- json['all'].each do |s|
286
- next if @remotes.exists?(s['host'], s['port'])
287
- add(s['host'], s['port'], opts)
290
+ if cycle.positive?
291
+ json['all'].each do |s|
292
+ next if @remotes.exists?(s['host'], s['port'])
293
+ add(s['host'], s['port'], opts)
294
+ end
288
295
  end
296
+ capacity << { host: score.host, port: score.port, count: json['all'].count }
297
+ @log.info("#{r}: the score is #{Rainbow(score.value).green} (#{json['version']}) in #{Age.new(start)}")
289
298
  end
290
- capacity << { host: score.host, port: score.port, count: json['all'].count }
291
- @log.info("#{r}: the score is #{Rainbow(score.value).green} (#{json['version']}) in #{Age.new(start)}")
292
299
  end
293
300
  end
294
301
  max_capacity = capacity.map { |c| c[:count] }.max || 0
@@ -304,6 +311,25 @@ it's recommended to reboot, but I don't do it because of --never-reboot")
304
311
  end
305
312
  end
306
313
 
314
+ def update_one(r, opts)
315
+ attempt = 0
316
+ begin
317
+ uri = '/remotes'
318
+ res = r.http(uri).get
319
+ r.assert_code(200, res)
320
+ json = JsonPage.new(res.body, uri).to_hash
321
+ score = Score.parse_json(json['score'])
322
+ yield json, score
323
+ rescue JsonPage::CantParse, Score::CantParse, RemoteNode::CantAssert => e
324
+ attempt += 1
325
+ if attempt < opts['retry']
326
+ @log.error("#{r} failed to read #{id}, trying again (attempt no.#{attempt}): #{e.message}")
327
+ retry
328
+ end
329
+ raise e
330
+ end
331
+ end
332
+
307
333
  def select(opts)
308
334
  selected = @remotes.all.sort_by { |r| r[:score] }.reverse.first(opts['max-nodes'])
309
335
  (@remotes.all - selected).each do |r|
data/lib/zold/remotes.rb CHANGED
@@ -41,6 +41,9 @@ require_relative 'node/farm'
41
41
  module Zold
42
42
  # One remote.
43
43
  class RemoteNode
44
+ # When something is wrong with the assertion
45
+ class CantAssert < StandardError; end
46
+
44
47
  def initialize(host:, port:, score:, idx:, master:, network: 'test', log: Log::NULL)
45
48
  @host = host
46
49
  @port = port
@@ -67,30 +70,30 @@ module Zold
67
70
  msg = response.status_line.strip
68
71
  return if response.status.to_i == code
69
72
  if response.headers && response.headers['X-Zold-Error']
70
- raise "Error ##{response.status} \"#{response.headers['X-Zold-Error']}\"
73
+ raise CantAssert, "Error ##{response.status} \"#{response.headers['X-Zold-Error']}\"
71
74
  at #{response.headers['X-Zold-Path']}"
72
75
  end
73
- raise "Unexpected HTTP code #{response.status}, instead of #{code}" if msg.empty?
74
- raise "#{msg} (HTTP code #{response.status}, instead of #{code})"
76
+ raise CantAssert, "Unexpected HTTP code #{response.status}, instead of #{code}" if msg.empty?
77
+ raise CantAssert, "#{msg} (HTTP code #{response.status}, instead of #{code})"
75
78
  end
76
79
 
77
80
  def assert_valid_score(score)
78
- raise "Invalid score #{score.reduced(4)}" unless score.valid?
79
- raise "Expired score (#{Age.new(score.time)}) #{score.reduced(4)}" if score.expired?
81
+ raise CantAssert, "Invalid score #{score.reduced(4)}" unless score.valid?
82
+ raise CantAssert, "Expired score (#{Age.new(score.time)}) #{score.reduced(4)}" if score.expired?
80
83
  end
81
84
 
82
85
  def assert_score_ownership(score)
83
- raise "Masqueraded host #{@host} as #{score.host}: #{score.reduced(4)}" if @host != score.host
84
- raise "Masqueraded port #{@port} as #{score.port}: #{score.reduced(4)}" if @port != score.port
86
+ raise CantAssert, "Masqueraded host #{@host} as #{score.host}: #{score.reduced(4)}" if @host != score.host
87
+ raise CantAssert, "Masqueraded port #{@port} as #{score.port}: #{score.reduced(4)}" if @port != score.port
85
88
  end
86
89
 
87
90
  def assert_score_strength(score)
88
91
  return if score.strength >= Score::STRENGTH
89
- raise "Score #{score.strength} is too weak (<#{Score::STRENGTH}): #{score.reduced(4)}"
92
+ raise CantAssert, "Score #{score.strength} is too weak (<#{Score::STRENGTH}): #{score.reduced(4)}"
90
93
  end
91
94
 
92
95
  def assert_score_value(score, min)
93
- raise "Score #{score.value} is too small (<#{min}): #{score.reduced(4)}" if score.value < min
96
+ raise CantAssert, "Score #{score.value} is too small (<#{min}): #{score.reduced(4)}" if score.value < min
94
97
  end
95
98
  end
96
99
 
data/lib/zold/version.rb CHANGED
@@ -25,7 +25,7 @@
25
25
  # Copyright:: Copyright (c) 2018 Yegor Bugayenko
26
26
  # License:: MIT
27
27
  module Zold
28
- VERSION = '0.21.4'
28
+ VERSION = '0.22.0'
29
29
  PROTOCOL = 2
30
30
  REPO = 'zold-io/zold'
31
31
  end
data/test/test_http.rb CHANGED
@@ -116,9 +116,11 @@ class TestHttp < Zold::Test
116
116
  WebMock.allow_net_connect!
117
117
  body = ''
118
118
  RandomPort::Pool::SINGLETON.acquire do |port|
119
+ latch = Concurrent::CountDownLatch.new(1)
119
120
  thread = Thread.start do
120
121
  Zold::VerboseThread.new(test_log).run do
121
122
  server = TCPServer.new('127.0.0.1', port)
123
+ latch.count_down
122
124
  socket = server.accept
123
125
  loop do
124
126
  line = socket.gets
@@ -133,6 +135,7 @@ class TestHttp < Zold::Test
133
135
  socket.close
134
136
  end
135
137
  end
138
+ latch.wait
136
139
  res = Tempfile.open do |f|
137
140
  IO.write(f, 'How are you?')
138
141
  Zold::Http.new(uri: "http://127.0.0.1:#{port}/").put(f)
@@ -158,9 +161,11 @@ class TestHttp < Zold::Test
158
161
  def test_uploads_file
159
162
  WebMock.allow_net_connect!
160
163
  RandomPort::Pool::SINGLETON.acquire do |port|
164
+ latch = Concurrent::CountDownLatch.new(1)
161
165
  thread = Thread.start do
162
166
  Zold::VerboseThread.new(test_log).run do
163
167
  server = TCPServer.new(port)
168
+ latch.count_down
164
169
  socket = server.accept
165
170
  body = ''
166
171
  stops = 0
@@ -180,6 +185,7 @@ class TestHttp < Zold::Test
180
185
  socket.close_write
181
186
  end
182
187
  end
188
+ latch.wait
183
189
  content = "how are you\nmy friend"
184
190
  res = Tempfile.open do |f|
185
191
  IO.write(f, content)
@@ -196,14 +202,17 @@ class TestHttp < Zold::Test
196
202
  WebMock.allow_net_connect!
197
203
  RandomPort::Pool::SINGLETON.acquire do |port|
198
204
  content = "how are you\nmy friend" * 1000
205
+ latch = Concurrent::CountDownLatch.new(1)
199
206
  thread = Thread.start do
200
207
  Zold::VerboseThread.new(test_log).run do
201
208
  server = TCPServer.new(port)
209
+ latch.count_down
202
210
  socket = server.accept
203
211
  socket.print("HTTP/1.1 200 OK\nContent-Length: #{content.length}\n\n#{content}")
204
212
  socket.close_write
205
213
  end
206
214
  end
215
+ latch.wait
207
216
  body = Tempfile.open do |f|
208
217
  Zold::Http.new(uri: "http://localhost:#{port}/").get_file(f)
209
218
  IO.read(f)
@@ -47,7 +47,7 @@ class TestHungryWallets < Zold::Test
47
47
  )
48
48
  wallets.acq(id) { |w| assert(!w.exists?) }
49
49
  pool.join(2)
50
- assert_requested(get)
50
+ assert_requested(get, times: 2)
51
51
  end
52
52
  end
53
53
  end
@@ -81,6 +81,7 @@ class TestMetronome < Zold::Test
81
81
 
82
82
  def exec(i)
83
83
  @count = i
84
+ sleep 0.1
84
85
  raise
85
86
  end
86
87
  end
data/test/test_wallet.rb CHANGED
@@ -296,9 +296,10 @@ class TestWallet < Zold::Test
296
296
  end
297
297
 
298
298
  def test_collects_memory_garbage
299
- skip
299
+ # skip
300
300
  require 'get_process_mem'
301
301
  start = GetProcessMem.new.bytes.to_i
302
+
302
303
  40.times do |i|
303
304
  wallet = Zold::Wallet.new('fixtures/448b451bc62e8e16.z')
304
305
  GC.start
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: zold
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.21.4
4
+ version: 0.22.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: 2019-01-08 00:00:00.000000000 Z
11
+ date: 2019-01-16 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: backtrace
@@ -744,7 +744,7 @@ licenses:
744
744
  - MIT
745
745
  metadata: {}
746
746
  post_install_message: |-
747
- Thanks for installing Zold 0.21.4!
747
+ Thanks for installing Zold 0.22.0!
748
748
  Study our White Paper: https://papers.zold.io/wp.pdf
749
749
  Read our blog posts: https://blog.zold.io
750
750
  Try ZLD online wallet at: https://wts.zold.io