zold 0.14.33 → 0.14.34

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 6df0097af1313fb51d104da4479e2d2791cc128f
4
- data.tar.gz: ac6bec37a2bf2c7c258398d4659c75cf2ee1b4b6
3
+ metadata.gz: 2c127e60442516b5480ef0eb7716adbec286a691
4
+ data.tar.gz: 3af1c25664de1a26bbedb54ee7bd165b62aec1c6
5
5
  SHA512:
6
- metadata.gz: d4c6cd31dba6057e1b01ed56315a255799758097920cdad06267f522668cc44c250bb6cb63b8db9d6ed3661e07ca926d94c7bf2b9e75ff9c6bdbb5d51cc4b56d
7
- data.tar.gz: 2497f81f693ed1e07f7815c24762b5b4c50e260fb5e0e30cf53278be925c48cd67e68b49cab2b2f4a4b4e0162e91f7d999b7488928dc07daa5e71751cc71cdc5
6
+ metadata.gz: f85512c025adf7afe4cd4fc211dbccaadab88ca69f300b1f52ac3c0ebbe471e9b567603ab927ff99e3c58ed74425a966d7fc65240cf4657b1477934f23bec726
7
+ data.tar.gz: 1508517a2892afd7c6a25cac27dd02e71a2173158bc949f4a6479085165a1bb29ad42464e6088b78802aae4b8631dca78a87d35dd66987d79038e0ed11227980
data/README.md CHANGED
@@ -247,8 +247,9 @@ Then, you need to create three objects:
247
247
 
248
248
  ```ruby
249
249
  require 'zold/wallets'
250
+ require 'zold/sync_wallets'
250
251
  require 'zold/remotes'
251
- wallets = Zold::Wallets.new(home)
252
+ wallets = Zold::SyncWallets.new(Zold::Wallets.new(home))
252
253
  remotes = Zold::Remotes.new(File.join(home, 'remotes'))
253
254
  copies = File.join(home, 'copies')
254
255
  ```
data/bin/zold CHANGED
@@ -83,6 +83,8 @@ Available commands:
83
83
  Propagate transactions to receiving wallets
84
84
  #{Rainbow('pull').green} [ID...] [options]
85
85
  Fetch and then merge
86
+ #{Rainbow('remove').green} [ID...] [options]
87
+ Remove the wallet(s) from the local storage
86
88
  #{Rainbow('show').green} [ID...] [options]
87
89
  Show all available information about the wallet
88
90
  #{Rainbow('pay').green} from to amount details [options]
@@ -172,7 +174,7 @@ Available options:"
172
174
  Zold::Remote.new(remotes: remotes, log: log).run(args)
173
175
  when 'invoice'
174
176
  require_relative '../lib/zold/commands/invoice'
175
- Zold::Invoice.new(wallets: wallets, log: log).run(args)
177
+ Zold::Invoice.new(wallets: wallets, remotes: remotes, copies: copies, log: log).run(args)
176
178
  when 'pay'
177
179
  require_relative '../lib/zold/commands/pay'
178
180
  Zold::Pay.new(wallets: wallets, remotes: remotes, log: log).run(args)
@@ -185,6 +187,9 @@ Available options:"
185
187
  when 'clean'
186
188
  require_relative '../lib/zold/commands/clean'
187
189
  Zold::Clean.new(wallets: wallets, copies: copies, log: log).run(args)
190
+ when 'remove'
191
+ require_relative '../lib/zold/commands/remove'
192
+ Zold::Remove.new(wallets: wallets, log: log).run(args)
188
193
  when 'diff'
189
194
  require_relative '../lib/zold/commands/diff'
190
195
  Zold::Diff.new(wallets: wallets, copies: copies, log: log).run(args)
@@ -0,0 +1,32 @@
1
+ #!/bin/bash
2
+
3
+ port=$(reserve_port)
4
+ mkdir server
5
+ cd server
6
+ zold node --trace --invoice=PULLONSTART@ffffffffffffffff --no-metronome \
7
+ --host=localhost --port=${port} --bind-port=${port} \
8
+ --threads=0 --standalone &
9
+ cd ..
10
+
11
+ wait_for_port ${port}
12
+
13
+ zold remote clean
14
+ zold remote add localhost ${port}
15
+
16
+ zold --public-key=id_rsa.pub create abcdabcdabcdabcd
17
+ zold push abcdabcdabcdabcd
18
+ zold remove abcdabcdabcdabcd
19
+ zold invoice abcdabcdabcdabcd
20
+
21
+ second_port=$(reserve_port)
22
+ mkdir second
23
+ cd second
24
+ zold remote clean
25
+ zold remote add localhost ${port}
26
+ zold node --trace --invoice=abcdabcdabcdabcd --no-metronome \
27
+ --host=localhost --port=${second_port} --bind-port=${second_port} \
28
+ --threads=0 &
29
+
30
+ wait_for_port ${second_port}
31
+
32
+ halt_nodes ${second_port} ${port}
@@ -37,7 +37,7 @@ module Zold
37
37
  ': ',
38
38
  @error.message,
39
39
  "\n\t",
40
- @error.backtrace.select { |t| t.include?('zold/') }.join("\n\t")
40
+ @error.backtrace.reverse.drop_while { |t| !t.include?('zold/') }.reverse.join("\n\t")
41
41
  ].join
42
42
  end
43
43
  end
@@ -32,8 +32,10 @@ require_relative '../prefixes'
32
32
  module Zold
33
33
  # Generate invoice
34
34
  class Invoice
35
- def initialize(wallets:, log: Log::Quiet.new)
35
+ def initialize(wallets:, remotes:, copies:, log: Log::Quiet.new)
36
36
  @wallets = wallets
37
+ @remotes = remotes
38
+ @copies = copies
37
39
  @log = log
38
40
  end
39
41
 
@@ -51,18 +53,23 @@ Available options:"
51
53
  mine = Args.new(opts, @log).take || return
52
54
  raise 'Receiver wallet ID is required' if mine[0].nil?
53
55
  id = Zold::Id.new(mine[0])
54
- @wallets.find(id) do |wallet|
55
- raise "Wallet #{id} doesn\'t exist in #{@wallets}, do 'zold pull' first" unless wallet.exists?
56
- invoice(wallet, opts)
57
- end
56
+ invoice(id, opts)
58
57
  end
59
58
 
60
59
  private
61
60
 
62
- def invoice(wallet, opts)
63
- invoice = "#{Prefixes.new(wallet).create(opts[:length])}@#{wallet.id}"
64
- @log.info(invoice)
65
- invoice
61
+ def invoice(id, opts)
62
+ unless @wallets.find(id, &:exists?)
63
+ require_relative 'pull'
64
+ Pull.new(wallets: @wallets, remotes: @remotes, copies: @copies, log: @log).run(
65
+ ['pull', id.to_s, "--network=#{opts['network']}"]
66
+ )
67
+ end
68
+ inv = @wallets.find(id) do |wallet|
69
+ "#{Prefixes.new(wallet).create(opts[:length])}@#{wallet.id}"
70
+ end
71
+ @log.info(inv)
72
+ inv
66
73
  end
67
74
  end
68
75
  end
@@ -173,7 +173,7 @@ module Zold
173
173
  )
174
174
  if opts['standalone']
175
175
  @remotes = Zold::Remotes::Empty.new(file: '/tmp/standalone')
176
- @log.debug('Running in standalone mode! (will never talk to other remotes)')
176
+ @log.info('Running in standalone mode! (will never talk to other remotes)')
177
177
  elsif @remotes.exists?(host, port)
178
178
  Zold::Remote.new(remotes: @remotes).run(['remote', 'remove', host, port.to_s])
179
179
  @log.info("Removed current node (#{address}) from list of remotes")
@@ -195,19 +195,10 @@ module Zold
195
195
  Front.set(:node_alias, node_alias)
196
196
  invoice = opts[:invoice]
197
197
  unless invoice.include?('@')
198
- @wallets.find(Id.new(invoice)) do |wallet|
199
- if wallet.exists?
200
- @log.info("Wallet #{invoice} already exists locally, won't pull")
201
- else
202
- @log.info("The wallet #{invoice} is not available locally, will pull now...")
203
- require_relative 'pull'
204
- Pull.new(wallets: @wallets, remotes: @remotes, copies: @copies, log: @log).run(
205
- ['pull', invoice, "--network=#{opts['network']}"]
206
- )
207
- end
208
- end
209
198
  require_relative 'invoice'
210
- invoice = Invoice.new(wallets: @wallets, log: @log).run(['invoice', invoice])
199
+ invoice = Invoice.new(
200
+ wallets: @wallets, remotes: @remotes, copies: @copies, log: @log
201
+ ).run(['invoice', invoice])
211
202
  end
212
203
  SafeEntrance.new(
213
204
  NoDupEntrance.new(
@@ -71,7 +71,9 @@ Available options:"
71
71
  invoice = mine[1]
72
72
  unless invoice.include?('@')
73
73
  require_relative 'invoice'
74
- invoice = Invoice.new(wallets: @wallets, log: @log).run(['invoice', invoice])
74
+ invoice = Invoice.new(
75
+ wallets: @wallets, remotes: @remotes, copies: @copies, log: @log
76
+ ).run(['invoice', invoice])
75
77
  end
76
78
  raise 'Amount is required (in ZLD) as the third argument' if mine[2].nil?
77
79
  amount = Amount.new(zld: mine[2].to_f)
@@ -0,0 +1,58 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Copyright (c) 2018 Yegor Bugayenko
4
+ #
5
+ # Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ # of this software and associated documentation files (the 'Software'), to deal
7
+ # in the Software without restriction, including without limitation the rights
8
+ # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ # copies of the Software, and to permit persons to whom the Software is
10
+ # furnished to do so, subject to the following conditions:
11
+ #
12
+ # The above copyright notice and this permission notice shall be included in all
13
+ # copies or substantial portions of the Software.
14
+ #
15
+ # THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ # FITNESS FOR A PARTICULAR PURPOSE AND NONINFINGEMENT. IN NO EVENT SHALL THE
18
+ # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ # SOFTWARE.
22
+
23
+ require 'slop'
24
+ require 'rainbow'
25
+ require_relative 'args'
26
+ require_relative '../log'
27
+
28
+ # REMOVe command.
29
+ # Author:: Yegor Bugayenko (yegor256@gmail.com)
30
+ # Copyright:: Copyright (c) 2018 Yegor Bugayenko
31
+ # License:: MIT
32
+ module Zold
33
+ # REMOVE command
34
+ class Remove
35
+ def initialize(wallets:, log: Log::Quiet.new)
36
+ @wallets = wallets
37
+ @log = log
38
+ end
39
+
40
+ def run(args = [])
41
+ opts = Slop.parse(args, help: true, suppress_errors: true) do |o|
42
+ o.banner = "Usage: zold remove [ID...] [options]
43
+ Available options:"
44
+ o.bool '--help', 'Print instructions'
45
+ end
46
+ mine = Args.new(opts, @log).take || return
47
+ mine = @wallets.all if mine.empty?
48
+ mine.map { |i| Id.new(i) }.each do |id|
49
+ remove(id, opts)
50
+ end
51
+ end
52
+
53
+ def remove(id, _)
54
+ @wallets.find(id) { |w| File.delete(w.path) }
55
+ @log.info("Wallet #{id} removed")
56
+ end
57
+ end
58
+ end
@@ -42,7 +42,11 @@ module Zold
42
42
 
43
43
  def exec(_ = 0)
44
44
  return if @remotes.all.empty?
45
- sleep(60) unless @opts['routine-immediately']
45
+ if @opts['routine-immediately']
46
+ @log.info('Spreading the wallets immediately, because of --routine-immediately')
47
+ else
48
+ sleep(60)
49
+ end
46
50
  ids = @wallets.all.sample(10)
47
51
  Push.new(wallets: @wallets, remotes: @remotes, log: @log).run(
48
52
  ['push', "--network=#{@opts['network']}"] + ids
data/lib/zold/http.rb CHANGED
@@ -123,7 +123,7 @@ module Zold
123
123
  end
124
124
 
125
125
  def header
126
- []
126
+ {}
127
127
  end
128
128
  end
129
129
 
data/lib/zold/remotes.rb CHANGED
@@ -23,10 +23,12 @@
23
23
  require 'concurrent'
24
24
  require 'csv'
25
25
  require 'uri'
26
+ require 'net/http'
26
27
  require 'time'
27
28
  require 'fileutils'
28
29
  require_relative 'backtrace'
29
30
  require_relative 'score'
31
+ require_relative 'http'
30
32
  require_relative 'node/farm'
31
33
  require_relative 'atomic_file'
32
34
  require_relative 'type'
@@ -80,9 +82,8 @@ module Zold
80
82
  def assert_code(code, response)
81
83
  msg = response.message.strip
82
84
  return if response.code.to_i == code
83
- log.debug("#{response.code} \"#{response.message}\" at \"#{response.body}\"")
84
- raise "Unexpected HTTP code #{response.code}, instead of #{code}" if msg.empty?
85
85
  raise "#{response.code}/#{response.header['X-Zold-Error']}" if response.header['X-Zold-Error']
86
+ raise "Unexpected HTTP code #{response.code}, instead of #{code}" if msg.empty?
86
87
  raise "#{msg} (HTTP code #{response.code}, instead of #{code})"
87
88
  end
88
89
 
@@ -29,7 +29,7 @@ require_relative 'log'
29
29
  module Zold
30
30
  # Synchronized collection of wallets
31
31
  class SyncWallets
32
- def initialize(wallets, dir, timeout: 30, log: Log::Quiet.new)
32
+ def initialize(wallets, dir = Dir.tmpdir, timeout: 30, log: Log::Quiet.new)
33
33
  @wallets = wallets
34
34
  @dir = dir
35
35
  @log = log
data/lib/zold/version.rb CHANGED
@@ -25,6 +25,6 @@
25
25
  # Copyright:: Copyright (c) 2018 Yegor Bugayenko
26
26
  # License:: MIT
27
27
  module Zold
28
- VERSION = '0.14.33'
28
+ VERSION = '0.14.34'
29
29
  PROTOCOL = 2
30
30
  end
@@ -40,7 +40,7 @@ class TestInvoice < Minitest::Test
40
40
  wallets = Zold::Wallets.new(dir)
41
41
  wallets.find(id) do |source|
42
42
  source.init(id, Zold::Key.new(file: 'fixtures/id_rsa.pub'))
43
- invoice = Zold::Invoice.new(wallets: wallets, log: test_log).run(
43
+ invoice = Zold::Invoice.new(wallets: wallets, remotes: nil, copies: nil, log: test_log).run(
44
44
  ['invoice', id.to_s, '--length=16']
45
45
  )
46
46
  assert_equal(33, invoice.length)
@@ -49,6 +49,22 @@ class TestPay < Minitest::Test
49
49
  end
50
50
  end
51
51
 
52
+ def test_pay_in_many_threads
53
+ FakeHome.new.run do |home|
54
+ wallet = home.create_wallet
55
+ amount = Zold::Amount.new(zld: 2.0)
56
+ assert_in_threads(threads: 10) do
57
+ Zold::Pay.new(wallets: home.wallets, remotes: home.remotes, log: test_log).run(
58
+ [
59
+ 'pay', '--force', '--private-key=fixtures/id_rsa',
60
+ wallet.id.to_s, 'NOPREFIX@dddd0000dddd0000', amount.to_zld, '-'
61
+ ]
62
+ )
63
+ end
64
+ assert_equal(amount * -10, wallet.balance)
65
+ end
66
+ end
67
+
52
68
  def test_sends_from_root_wallet
53
69
  FakeHome.new.run do |home|
54
70
  source = home.create_wallet(Zold::Id::ROOT)
@@ -121,26 +121,11 @@ class FrontTest < Minitest::Test
121
121
  FakeNode.new(log: test_log).run do |port|
122
122
  base = "http://localhost:#{port}"
123
123
  FakeHome.new.run do |home|
124
- threads = 20
125
- done = Concurrent::AtomicFixnum.new
126
- pool = Concurrent::FixedThreadPool.new(threads)
127
- latch = Concurrent::CountDownLatch.new(1)
128
- threads.times do |i|
129
- pool.post do
130
- Thread.current.name = "thread-#{i}"
131
- Zold::VerboseThread.new(test_log).run(true) do
132
- latch.wait(10)
133
- wallet = home.create_wallet
134
- Zold::Http.new(uri: "#{base}/wallet/#{wallet.id}", score: nil).put(File.read(wallet.path))
135
- assert_equal_wait('200') { Zold::Http.new(uri: "#{base}/wallet/#{wallet.id}", score: nil).get.code }
136
- done.increment
137
- end
138
- end
124
+ assert_in_threads(threads: 20) do
125
+ wallet = home.create_wallet
126
+ Zold::Http.new(uri: "#{base}/wallet/#{wallet.id}", score: nil).put(File.read(wallet.path))
127
+ assert_equal_wait('200') { Zold::Http.new(uri: "#{base}/wallet/#{wallet.id}", score: nil).get.code }
139
128
  end
140
- latch.count_down
141
- pool.shutdown
142
- pool.wait_for_termination
143
- assert_equal(threads, done.value)
144
129
  end
145
130
  end
146
131
  end
data/test/test__helper.rb CHANGED
@@ -23,6 +23,7 @@
23
23
  gem 'openssl'
24
24
  require 'openssl'
25
25
  require 'minitest/autorun'
26
+ require 'concurrent'
26
27
 
27
28
  STDOUT.sync = true
28
29
 
@@ -55,6 +56,31 @@ module Minitest
55
56
  end
56
57
  end
57
58
 
59
+ def assert_in_threads(threads: Concurrent.processor_count * 8, loops: 0)
60
+ done = Concurrent::AtomicFixnum.new
61
+ cycles = Concurrent::AtomicFixnum.new
62
+ pool = Concurrent::FixedThreadPool.new(threads)
63
+ latch = Concurrent::CountDownLatch.new(1)
64
+ threads.times do |t|
65
+ pool.post do
66
+ Thread.current.name = "assert-thread-#{t}"
67
+ latch.wait(10)
68
+ loop do
69
+ Zold::VerboseThread.new(test_log).run(true) do
70
+ yield t
71
+ end
72
+ cycles.increment
73
+ break if cycles.value > loops
74
+ end
75
+ done.increment
76
+ end
77
+ end
78
+ latch.count_down
79
+ pool.shutdown
80
+ pool.kill unless pool.wait_for_termination(10)
81
+ assert_equal(threads, done.value)
82
+ end
83
+
58
84
  def test_log
59
85
  require_relative '../lib/zold/log'
60
86
  @test_log = Zold::Log::Verbose.new
@@ -23,8 +23,6 @@
23
23
  require 'minitest/autorun'
24
24
  require 'tmpdir'
25
25
  require 'securerandom'
26
- require 'concurrent'
27
- require 'concurrent/atomics'
28
26
  require_relative 'test__helper'
29
27
  require_relative '../lib/zold/atomic_file'
30
28
  require_relative '../lib/zold/verbose_thread'
@@ -47,29 +45,11 @@ class TestAtomicFile < Minitest::Test
47
45
  def test_writes_from_many_threads
48
46
  Dir.mktmpdir do |dir|
49
47
  file = Zold::AtomicFile.new(File.join(dir, 'a.txt'))
50
- threads = 10
51
- pool = Concurrent::FixedThreadPool.new(threads)
52
- alive = true
53
- cycles = Concurrent::AtomicFixnum.new
54
- success = Concurrent::AtomicFixnum.new
55
48
  content = SecureRandom.hex(1000)
56
- threads.times do
57
- pool.post do
58
- while alive
59
- Zold::VerboseThread.new(test_log).run(true) do
60
- cycles.increment
61
- file.write(content)
62
- assert_equal(content, file.read, 'Invalid content')
63
- success.increment
64
- end
65
- end
66
- end
49
+ assert_in_threads(loops: 1000) do
50
+ file.write(content)
51
+ assert_equal(content, file.read, 'Invalid content')
67
52
  end
68
- sleep 0.1 while cycles.value < 50
69
- alive = false
70
- pool.shutdown
71
- pool.wait_for_termination
72
- assert_equal(cycles.value, success.value)
73
53
  end
74
54
  end
75
55
  end
data/test/test_http.rb CHANGED
@@ -43,6 +43,7 @@ class TestHttp < Minitest::Test
43
43
  res = Zold::Http.new(uri: 'http://exception/', score: nil).get
44
44
  assert_equal('599', res.code)
45
45
  assert(res.body.include?('Intentionally'))
46
+ assert(!res.header['nothing'])
46
47
  end
47
48
 
48
49
  def test_pings_live_uri
data/test/test_remotes.rb CHANGED
@@ -22,8 +22,7 @@
22
22
 
23
23
  require 'minitest/autorun'
24
24
  require 'tmpdir'
25
- require 'concurrent'
26
- require 'concurrent/atomics'
25
+ require 'webmock/minitest'
27
26
  require_relative 'test__helper'
28
27
  require_relative '../lib/zold/log'
29
28
  require_relative '../lib/zold/remotes'
@@ -165,29 +164,11 @@ class TestRemotes < Minitest::Test
165
164
  Dir.mktmpdir do |dir|
166
165
  remotes = Zold::Remotes.new(file: File.join(dir, 'a.csv'))
167
166
  remotes.clean
168
- threads = 5
169
- pool = Concurrent::FixedThreadPool.new(threads)
170
- alive = true
171
- cycles = Concurrent::AtomicFixnum.new
172
- success = Concurrent::AtomicFixnum.new
173
167
  host = '192.168.0.1'
174
168
  remotes.add(host)
175
- threads.times do
176
- pool.post do
177
- while alive
178
- Zold::VerboseThread.new(test_log).run(true) do
179
- cycles.increment
180
- remotes.error(host)
181
- success.increment
182
- end
183
- end
184
- end
169
+ assert_in_threads(threads: 5) do
170
+ remotes.error(host)
185
171
  end
186
- assert_wait { cycles.value >= 50 }
187
- alive = false
188
- pool.shutdown
189
- pool.wait_for_termination
190
- assert_equal(cycles.value, success.value)
191
172
  assert_equal(0, remotes.all.reject { |r| r[:host] == host }.size)
192
173
  end
193
174
  end
@@ -196,22 +177,10 @@ class TestRemotes < Minitest::Test
196
177
  Dir.mktmpdir do |dir|
197
178
  remotes = Zold::Remotes.new(file: File.join(dir, 'xx.csv'))
198
179
  remotes.clean
199
- threads = 5
200
- pool = Concurrent::FixedThreadPool.new(threads)
201
- done = Concurrent::AtomicFixnum.new
202
- latch = Concurrent::CountDownLatch.new(1)
203
- threads.times do |i|
204
- pool.post do
205
- Zold::VerboseThread.new(test_log).run(true) do
206
- latch.wait(10)
207
- remotes.add('127.0.0.1', 8080 + i)
208
- done.increment
209
- end
210
- end
180
+ assert_in_threads(threads: 5) do |t|
181
+ remotes.add('127.0.0.1', 8080 + t)
211
182
  end
212
- latch.count_down
213
- assert_equal_wait(threads) { done.value }
214
- assert_equal(threads, remotes.all.count)
183
+ assert_equal(5, remotes.all.count)
215
184
  end
216
185
  end
217
186
 
@@ -219,30 +188,15 @@ class TestRemotes < Minitest::Test
219
188
  Dir.mktmpdir do |dir|
220
189
  remotes = Zold::Remotes.new(file: File.join(dir, 'uu-90.csv'))
221
190
  remotes.clean
222
- threads = 20
223
- pool = Concurrent::FixedThreadPool.new(threads)
224
- done = Concurrent::AtomicFixnum.new
225
191
  start = Time.now
226
- alive = true
227
192
  100.times { |i| remotes.add('192.168.0.1', 8080 + i) }
228
- threads.times do |i|
229
- pool.post do
230
- loop do
231
- break unless alive
232
- Zold::VerboseThread.new(test_log).run(true) do
233
- remotes.add('127.0.0.1', 8080 + i)
234
- remotes.error('127.0.0.1', 8080 + i)
235
- remotes.all
236
- remotes.iterate(test_log) { done.increment }
237
- remotes.remove('127.0.0.1', 8080 + i)
238
- end
239
- end
240
- end
193
+ assert_in_threads(threads: 4, loops: 10) do |t|
194
+ remotes.add('127.0.0.1', 8080 + t)
195
+ remotes.error('127.0.0.1', 8080 + t)
196
+ remotes.all
197
+ remotes.iterate(test_log) { remotes.all }
198
+ remotes.remove('127.0.0.1', 8080 + t)
241
199
  end
242
- assert_wait { done.value >= 1000 }
243
- alive = false
244
- pool.shutdown
245
- pool.wait_for_termination(10)
246
200
  test_log.info("Total time: #{Time.now - start}")
247
201
  end
248
202
  end
@@ -251,4 +205,21 @@ class TestRemotes < Minitest::Test
251
205
  remotes = Zold::Remotes::Empty.new(file: '/tmp/empty')
252
206
  assert(remotes.is_a?(Zold::Remotes))
253
207
  end
208
+
209
+ def test_reports_zold_error_header
210
+ Dir.mktmpdir do |dir|
211
+ remotes = Zold::Remotes.new(file: File.join(dir, 'uu-90.csv'))
212
+ remotes.clean
213
+ remotes.add('11a-example.org', 8080)
214
+ stub_request(:get, 'http://11a-example.org:8080/').to_return(
215
+ status: 500,
216
+ headers: {
217
+ 'X-Zold-Error': 'hey you'
218
+ }
219
+ )
220
+ remotes.iterate(test_log) do |r|
221
+ r.assert_code(200, r.http.get)
222
+ end
223
+ end
224
+ end
254
225
  end
@@ -42,25 +42,13 @@ class TestSyncWallets < Minitest::Test
42
42
  home.create_wallet(id)
43
43
  key = Zold::Key.new(file: 'fixtures/id_rsa')
44
44
  amount = Zold::Amount.new(zld: 5.0)
45
- threads = 10
46
- pool = Concurrent::FixedThreadPool.new(threads)
47
- latch = Concurrent::CountDownLatch.new(1)
48
- threads.times do |i|
49
- pool.post do
50
- Thread.current.name = "thread-#{i}"
51
- Zold::VerboseThread.new(test_log).run(true) do
52
- latch.wait(10)
53
- wallets.find(id) do |wallet|
54
- wallet.sub(amount, "NOPREFIX@#{Zold::Id.new}", key)
55
- wallet.refurbish
56
- end
57
- end
45
+ assert_in_threads(threads: 5) do
46
+ wallets.find(id) do |wallet|
47
+ wallet.sub(amount, "NOPREFIX@#{Zold::Id.new}", key)
48
+ wallet.refurbish
58
49
  end
59
50
  end
60
- latch.count_down
61
- pool.shutdown
62
- pool.wait_for_termination
63
- assert_equal_wait(amount * threads * -1, max: 4) do
51
+ assert_equal_wait(amount * -5, max: 4) do
64
52
  wallets.find(id, &:balance)
65
53
  end
66
54
  assert_equal(5, Dir.new(wallets.path).count)
data/test/test_zold.rb CHANGED
@@ -34,7 +34,7 @@ require_relative '../lib/zold/version'
34
34
  class TestZold < Minitest::Test
35
35
  def test_all_scripts
36
36
  Dir.new('fixtures/scripts').select { |f| f =~ /\.sh$/ && !f.start_with?('_') }.each do |f|
37
- # next unless f == 'distribute-wallet.sh'
37
+ # next unless f == 'pull-on-start.sh'
38
38
  Dir.mktmpdir do |dir|
39
39
  FileUtils.cp('fixtures/id_rsa.pub', dir)
40
40
  FileUtils.cp('fixtures/id_rsa', dir)
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.14.33
4
+ version: 0.14.34
5
5
  platform: ruby
6
6
  authors:
7
7
  - Yegor Bugayenko
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2018-08-11 00:00:00.000000000 Z
11
+ date: 2018-08-15 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: concurrent-ruby
@@ -408,6 +408,7 @@ files:
408
408
  - fixtures/scripts/calculate-scores.sh
409
409
  - fixtures/scripts/distribute-wallet.sh
410
410
  - fixtures/scripts/print-helps.sh
411
+ - fixtures/scripts/pull-on-start.sh
411
412
  - fixtures/scripts/push-and-pull.sh
412
413
  - fixtures/scripts/redeploy-on-upgrade.sh
413
414
  - fixtures/scripts/sigdump.sh
@@ -435,6 +436,7 @@ files:
435
436
  - lib/zold/commands/pull.rb
436
437
  - lib/zold/commands/push.rb
437
438
  - lib/zold/commands/remote.rb
439
+ - lib/zold/commands/remove.rb
438
440
  - lib/zold/commands/routines/reconnect.rb
439
441
  - lib/zold/commands/routines/spread.rb
440
442
  - lib/zold/commands/show.rb