zold-stress 0.5.1 → 0.5.2

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
  SHA256:
3
- metadata.gz: 6ab86a1ae25c81f4ac5fb1c98279b618dbfaa977e926a3c760b13d06b53ad2fb
4
- data.tar.gz: a20be8604c929d4b371db76655a176c3a3973941e9e79e7f2fed9defdc260a2a
3
+ metadata.gz: 298a325cf8b0b4dc1f0158e8295111a2564f91cf90734f7b8d3ff9e2bf19efe0
4
+ data.tar.gz: 463737afba3299a6333e18f2f527f140d338dc73b223b4c49f58aaf044c9aafe
5
5
  SHA512:
6
- metadata.gz: 706d9e39efaac93346011db9869cbb83c45dc9c2ef8d22dee3382faa2dd7f790e8cd917ed0b9793ff21ddfd996d5f429cab9915d6ef69a058d4274736165592e
7
- data.tar.gz: 3debbc344aaaa1d5a3841bc407c9d7bb323df226c8bb94c25be04e39bab22e9acdaf6ac1946e4c7ac3d30ba626cdc4fd7ea6f347408a5aeb524199569f541d8f
6
+ metadata.gz: abada0b527309a1f116fe74de753c96365b092675533608bcf9afbafedf2ae190e9727f3241399c4d6f5552d54f630f19c2830616bb53243daf478243bd64249
7
+ data.tar.gz: f3466ba90fc620c5340bbb621cd2ba52bd09f23d84451b8c771009f56444b7c025277801df7db4a91ba0c58437ffd39f7f5db4b25927acccbd2d47f531219f88
@@ -2,7 +2,7 @@ AllCops:
2
2
  DisplayCopNames: true
3
3
  TargetRubyVersion: 2.3.3
4
4
 
5
- Style/EndOfLine:
5
+ Layout/EndOfLine:
6
6
  EnforcedStyle: lf
7
7
  Metrics/LineLength:
8
8
  Max: 120
@@ -44,8 +44,8 @@ Thread.current.name = 'main'
44
44
  Encoding.default_external = Encoding::UTF_8
45
45
  Encoding.default_internal = Encoding::UTF_8
46
46
 
47
- log = Zold::Log::Regular.new
48
- vlog = Zold::Log::Quiet.new
47
+ log = Zold::Log::REGULAR
48
+ vlog = Zold::Log::ERRORS
49
49
 
50
50
  begin
51
51
  opts = Slop.parse(ARGV, strict: false, suppress_errors: true) do |o|
@@ -74,22 +74,19 @@ Available options:"
74
74
  "Home directory (default: #{Dir.pwd})",
75
75
  default: Dir.pwd
76
76
  o.string '--network',
77
- "The name of the network we work in (default: #{Zold::Wallet::MAIN_NETWORK}",
77
+ "The name of the network we work in (default: #{Zold::Wallet::MAINET}",
78
78
  required: true,
79
- default: Zold::Wallet::MAIN_NETWORK
79
+ default: Zold::Wallet::MAINET
80
80
  o.bool '-h', '--help', 'Show these instructions'
81
81
  o.on '--verbose', 'Enable extra logging information' do
82
- log = Zold::Log::Verbose.new
83
- vlog = Zold::Log::Regular.new
82
+ log = Zold::Log::VERBOSE
83
+ vlog = Zold::Log::REGULAR
84
84
  end
85
85
  o.on '--no-colors', 'Disable colors in the ouput' do
86
86
  Rainbow.enabled = false
87
87
  end
88
88
  end
89
89
 
90
- log = Zold::Log::Sync.new(log)
91
- vlog = Zold::Log::Sync.new(vlog)
92
-
93
90
  if opts.help?
94
91
  log.info(opts.to_s)
95
92
  exit
@@ -112,7 +109,7 @@ Available options:"
112
109
  end
113
110
  copies = File.join(zoldata, 'copies')
114
111
 
115
- stats = Zold::Stress::Stats.new
112
+ stats = Zold::Stress::Stats.new(log: vlog)
116
113
  summary = Zold::Stress::Summary.new(stats, opts['batch'])
117
114
  air = Zold::Stress::Air.new
118
115
  round = Zold::Stress::Round.new(
@@ -137,7 +134,7 @@ Available options:"
137
134
  round.pull
138
135
  round.match
139
136
  log.info(summary)
140
- Zold::List.new(wallets: wallets, log: log).run(['list'] + opts.arguments) if (r % 10).zero?
137
+ round.list if (r % 10).zero?
141
138
  end
142
139
  s = Time.now
143
140
  loop do
@@ -147,7 +144,11 @@ Available options:"
147
144
  round.match
148
145
  log.info(summary)
149
146
  end
147
+ round.list
150
148
  unless air.fetch.empty?
149
+ air.fetch.each do |p|
150
+ log.info(" #{p[:source]} -> #{p[:target]} #{p[:amount]} #{Zold::Age.new(p[:pushed])}")
151
+ end
151
152
  raise "#{air.fetch.count} payments out of #{stats.total('paid')} are still somewhere, we lost them :("
152
153
  end
153
154
  log.info("Successfully sent and received #{Rainbow(stats.total('arrived')).green} transactions \
@@ -8,6 +8,8 @@ export RUBYOPT="-W0"
8
8
  alias zold="zold --network=test"
9
9
  alias zold-stress="$1 --network=test"
10
10
 
11
+ zold --version
12
+
11
13
  function reserve_port {
12
14
  python -c 'import socket; s=socket.socket(); s.bind(("", 0)); print(s.getsockname()[1]); s.close()'
13
15
  }
@@ -1,36 +1,47 @@
1
1
  #!/bin/bash
2
2
 
3
3
  function start_node {
4
- port=$(reserve_port)
4
+ port=$1
5
5
  mkdir ${port}
6
6
  cd ${port}
7
+ zold remote clean
7
8
  zold node --trace --invoice=MULTINODE@ffffffffffffffff \
8
9
  --host=localhost --port=${port} --bind-port=${port} --dump-errors \
9
- --no-metronome --halt-code=test --threads=1 --strength=2 > log.txt &
10
+ --no-metronome --halt-code=test --threads=1 --strength=3 --pretty=full > log.txt 2>&1 &
10
11
  pid=$!
11
12
  echo ${pid} > pid
12
13
  cd ..
13
- wait_for_url http://localhost:${port}/
14
- echo ${port}
14
+ wait_for_url "http://localhost:${port}/"
15
15
  }
16
16
 
17
- nodes=($(start_node) $(start_node) $(start_node) $(start_node))
17
+ nodes=()
18
+ for i in `seq 1 4`; do
19
+ port=$(reserve_port)
20
+ nodes+=($port)
21
+ start_node $port &
22
+ done
23
+ wait
24
+
18
25
  trap "halt_nodes ${nodes[*]}" EXIT
26
+
19
27
  for port in ${nodes[@]}; do
20
- cd ${port}
21
- zold remote clean
22
- for friend in ${nodes[@]}; do
23
- if [ "${port}" != "${friend}" ]; then
24
- zold remote add localhost ${friend}
25
- fi
26
- done
27
- cd ..
28
+ {
29
+ cd ${port}
30
+ for friend in ${nodes[@]}; do
31
+ if [ "${port}" != "${friend}" ]; then
32
+ zold remote add localhost ${friend}
33
+ fi
34
+ done
35
+ cd ..
36
+ } &
28
37
  done
38
+ wait
29
39
 
30
40
  zold remote clean
31
41
  for port in ${nodes[@]}; do
32
- zold remote add localhost ${port}
42
+ zold remote add localhost ${port} &
33
43
  done
44
+ wait
34
45
 
35
46
  zold --public-key=id_rsa.pub create 0000000000000000
36
47
  zold --public-key=id_rsa.pub create abcdabcdabcdabcd
@@ -38,6 +49,5 @@ zold pay --private-key=id_rsa 0000000000000000 abcdabcdabcdabcd 4.95 'To test'
38
49
  zold push 0000000000000000 --ignore-score-weakness
39
50
  zold remove 0000000000000000
40
51
 
41
- zold-stress --rounds=8 --wait=10 --threads=${#nodes[@]} --pool=8 --batch=8 --private-key=id_rsa --ignore-score-weakness
42
-
43
- zold show
52
+ # zold-stress --rounds=32 --wait=10 --threads=8 --pool=8 --batch=16 --private-key=id_rsa --ignore-score-weakness
53
+ zold-stress --rounds=4 --wait=10 --threads=${#nodes[@]} --pool=8 --batch=8 --private-key=id_rsa --ignore-score-weakness
@@ -1,21 +1,21 @@
1
1
  #!/bin/bash
2
2
 
3
3
  function start_node {
4
- port=$(reserve_port)
4
+ port=$1
5
5
  mkdir ${port}
6
6
  cd ${port}
7
7
  zold node --trace --invoice=SPREADWALLETS@ffffffffffffffff \
8
8
  --host=localhost --port=${port} --bind-port=${port} --dump-errors \
9
9
  --standalone --no-metronome --halt-code=test \
10
- --threads=0 > log.txt &
10
+ --threads=0 --verbose --pretty=full 2>&1 &
11
11
  pid=$!
12
12
  echo ${pid} > pid
13
13
  cd ..
14
- wait_for_url http://localhost:${port}/
15
- echo ${port}
14
+ wait_for_url "http://localhost:${port}/"
16
15
  }
17
16
 
18
- port=$(start_node)
17
+ port=$(reserve_port)
18
+ start_node $port
19
19
  trap "halt_nodes ${port}" EXIT
20
20
  zold remote clean
21
21
  zold remote add localhost ${port}
@@ -26,5 +26,5 @@ zold pay --private-key=id_rsa 0000000000000000 abcdabcdabcdabcd 4.95 'To test'
26
26
  zold push 0000000000000000
27
27
  zold remove 0000000000000000
28
28
 
29
- # zold-stress --rounds=1000 --wait=5 --threads=12 --pool=16 --batch=8 --private-key=id_rsa
29
+ # zold-stress --rounds=8 --wait=5 --threads=32 --pool=32 --batch=64 --private-key=id_rsa --verbose
30
30
  zold-stress --rounds=4 --wait=5 --threads=4 --pool=4 --batch=4 --private-key=id_rsa
@@ -32,25 +32,28 @@ module Zold::Stress
32
32
  @all = []
33
33
  end
34
34
 
35
- def fetch
36
- @all
35
+ def fetch(any = false)
36
+ @all.select { |p| any || p[:arrived].nil? }
37
37
  end
38
38
 
39
39
  def add(pmt)
40
40
  @mutex.synchronize do
41
+ raise "Payment already exists (#{@all.size} total): #{pmt}" if @all.find { |p| p[:details] == pmt[:details] }
41
42
  @all << pmt.merge(pushed: Time.now)
42
43
  end
43
44
  end
44
45
 
45
- def delete(pmt)
46
+ def pulled(id)
46
47
  @mutex.synchronize do
47
- @all.delete(pmt)
48
+ @all.select { |a| a[:target] == id }.each { |a| a[:pulled] = Time.now }
48
49
  end
49
50
  end
50
51
 
51
- def pulled(id)
52
+ def arrived(pmt)
52
53
  @mutex.synchronize do
53
- @all.select { |a| a[:target] == id }.each { |a| a[:pulled] = Time.now }
54
+ found = @all.find { |p| p[:details] == pmt[:details] }
55
+ raise "Payment doesn't exist (#{@all.size} total): #{pmt}" if found.nil?
56
+ found[:arrived] = Time.now
54
57
  end
55
58
  end
56
59
  end
@@ -36,7 +36,7 @@ module Zold::Stress
36
36
  # Payments to send in a batch.
37
37
  class Pmnts
38
38
  def initialize(pvt:, wallets:, remotes:, stats:, opts:,
39
- vlog: Zold::Log::Quiet.new, log: Zold::Log::Quiet.new)
39
+ vlog: Zold::Log::NULL, log: Zold::Log::NULL)
40
40
  @pvt = pvt
41
41
  @wallets = wallets
42
42
  @remotes = remotes
@@ -38,7 +38,7 @@ module Zold::Stress
38
38
  # Pool of wallets.
39
39
  class Pool
40
40
  def initialize(wallets:, remotes:, copies:, stats:, opts:,
41
- log: Zold::Log::Quiet.new, vlog: Zold::Log::Quiet.new)
41
+ log: Zold::Log::NULL, vlog: Zold::Log::NULL)
42
42
  @wallets = wallets
43
43
  @remotes = remotes
44
44
  @copies = copies
@@ -26,6 +26,7 @@ require 'zold/key'
26
26
  require 'zold/id'
27
27
  require 'zold/commands/push'
28
28
  require 'zold/commands/remote'
29
+ require 'zold/commands/list'
29
30
  require_relative 'stats'
30
31
  require_relative 'pool'
31
32
  require_relative 'pmnts'
@@ -39,7 +40,7 @@ module Zold::Stress
39
40
  # Full round of stress test
40
41
  class Round
41
42
  def initialize(pvt:, wallets:, remotes:, copies:,
42
- stats:, air:, opts:, log: Zold::Log::Quiet.new, vlog: Zold::Log::Quiet.new)
43
+ stats:, air:, opts:, log: Zold::Log::NULL, vlog: Zold::Log::NULL)
43
44
  @pvt = pvt
44
45
  @wallets = wallets
45
46
  @remotes = remotes
@@ -51,6 +52,10 @@ module Zold::Stress
51
52
  @vlog = vlog
52
53
  end
53
54
 
55
+ def list
56
+ Zold::List.new(wallets: @wallets, copies: @copies, log: @log).run(['list'] + @opts.arguments)
57
+ end
58
+
54
59
  def update
55
60
  start = Time.now
56
61
  cmd = Zold::Remote.new(remotes: @remotes, log: @vlog)
@@ -74,6 +79,7 @@ module Zold::Stress
74
79
  )
75
80
  pool.rebuild
76
81
  @wallets.all.peach(@opts['threads']) do |id|
82
+ Thread.current.name = 'prepare-push'
77
83
  @stats.exec('push') do
78
84
  Zold::Push.new(wallets: @wallets, remotes: @remotes, log: @vlog).run(
79
85
  ['push', id.to_s, "--network=#{@opts['network']}"] + @opts.arguments
@@ -95,6 +101,7 @@ in #{Zold::Age.new(start)}")
95
101
  mutex = Mutex.new
96
102
  sources = sent.group_by { |p| p[:source] }
97
103
  sources.peach(@opts['threads']) do |a|
104
+ Thread.current.name = 'send-push'
98
105
  @stats.exec('push') do
99
106
  Zold::Push.new(wallets: @wallets, remotes: @remotes, log: @vlog).run(
100
107
  ['push', a[0].to_s, "--network=#{@opts['network']}"] + @opts.arguments
@@ -109,16 +116,17 @@ in #{Zold::Age.new(start)}")
109
116
  sent from #{sources.count} wallets, \
110
117
  in #{Zold::Age.new(start)}, #{@air.fetch.count} are now in the air, \
111
118
  #{Zold::Age.new(@air.fetch.map { |a| a[:pushed] }.reverse[0] || Time.now)} is the oldest")
112
- @log.debug(" #{sent.map { |p| "#{p[:source]} -> #{p[:target]} #{p[:amount]}" }.join("\n ")}")
119
+ @log.debug(sent.map { |p| "#{p[:source]} -> #{p[:target]} #{p[:amount]}" }.join("\n"))
113
120
  end
114
121
 
115
122
  def pull
116
123
  start = Time.now
117
124
  targets = @air.fetch.group_by { |p| p[:target] }.map { |a| a[0] }
118
125
  targets.peach(@opts['threads']) do |id|
126
+ Thread.current.name = "pull-#{id}"
119
127
  @stats.exec('pull') do
120
128
  Zold::Pull.new(wallets: @wallets, remotes: @remotes, copies: @copies, log: @vlog).run(
121
- ['pull', id.to_s, "--network=#{@opts['network']}"] + @opts.arguments
129
+ ['pull', id.to_s, "--network=#{@opts['network']}", '--skip-propagate'] + @opts.arguments
122
130
  )
123
131
  end
124
132
  @air.pulled(id)
@@ -134,11 +142,11 @@ after the pull of #{targets.count} in #{Zold::Age.new(start)}")
134
142
  next unless @wallets.acq(p[:target], &:exists?)
135
143
  t = @wallets.acq(p[:target], &:txns).find { |x| x.details == p[:details] && x.bnf == p[:source] }
136
144
  next if t.nil?
145
+ @air.arrived(p)
137
146
  @stats.put('arrived', p[:pulled] - p[:pushed])
138
147
  total += 1
139
148
  @log.debug("#{p[:amount]} arrived from #{p[:source]} to #{p[:target]} \
140
149
  in txn ##{t.id} in #{Zold::Age.new(p[:start])}: #{t.details}")
141
- @air.delete(p)
142
150
  end
143
151
  @log.info("#{total} payments just arrived, #{@air.fetch.count} still in the air")
144
152
  end
@@ -33,9 +33,10 @@ require 'zold/age'
33
33
  module Zold::Stress
34
34
  # Stats
35
35
  class Stats
36
- def initialize
36
+ def initialize(log: Zold::Log::NULL)
37
37
  @history = {}
38
38
  @mutex = Mutex.new
39
+ @log = log
39
40
  end
40
41
 
41
42
  def exists?(metric)
@@ -78,6 +79,7 @@ module Zold::Stress
78
79
  put(metric + '_ok', Time.now - start)
79
80
  rescue StandardError => ex
80
81
  put(metric + '_error', Time.now - start)
82
+ @log.error(Backtrace.new(ex))
81
83
  raise ex unless swallow
82
84
  ensure
83
85
  put(metric, Time.now - start)
@@ -44,6 +44,7 @@ module Zold::Stress
44
44
  RandomPort::Pool::SINGLETON.acquire do |port|
45
45
  Dir.mktmpdir do |home|
46
46
  thread = Thread.start do
47
+ Thread.current.name = 'fake_node'
47
48
  Zold::VerboseThread.new(@log).run do
48
49
  node = Zold::Node.new(
49
50
  wallets: Zold::Wallets.new(home),
@@ -36,7 +36,22 @@ class AirTest < Minitest::Test
36
36
  air.fetch.each do |p|
37
37
  assert_equal(pmt[:details], p[:details])
38
38
  end
39
- air.delete(air.fetch[0])
39
+ air.pulled(air.fetch[0][:target])
40
+ assert_equal(1, air.fetch.count)
41
+ air.arrived(air.fetch[0])
40
42
  assert_equal(0, air.fetch.count)
41
43
  end
44
+
45
+ def test_adds_and_removes_many
46
+ air = Zold::Stress::Air.new
47
+ 5.times do |i|
48
+ pmt = { start: Time.now, source: Zold::Id::ROOT, target: Zold::Id::ROOT, details: i.to_s }
49
+ air.add(pmt)
50
+ assert_equal(i + 1, air.fetch.count)
51
+ end
52
+ air.pulled(air.fetch[0][:target])
53
+ assert_equal(5, air.fetch.count)
54
+ air.arrived(air.fetch[0])
55
+ assert_equal(4, air.fetch.count)
56
+ end
42
57
  end
@@ -36,7 +36,7 @@ class TestBin < Minitest::Test
36
36
  Dir.new('fixtures/scripts').select { |f| f =~ /\.sh$/ && !f.start_with?('_') }.each do |f|
37
37
  define_method("test_#{f.gsub(/\.sh$/, '').gsub(/[^a-z]/, '_')}") do
38
38
  start = Time.now
39
- test_log.debug("\n\n#{f} running...")
39
+ test_log.info("\n\n#{f} running...")
40
40
  Dir.mktmpdir do |dir|
41
41
  FileUtils.cp('fixtures/id_rsa.pub', dir)
42
42
  FileUtils.cp('fixtures/id_rsa', dir)
@@ -49,7 +49,7 @@ class TestBin < Minitest::Test
49
49
  stdin.close
50
50
  until stdout.eof?
51
51
  line = stdout.gets
52
- test_log.debug(line)
52
+ test_log.info(line)
53
53
  out << line
54
54
  end
55
55
  code = thr.value.to_i
@@ -57,7 +57,7 @@ class TestBin < Minitest::Test
57
57
  end
58
58
  end
59
59
  end
60
- test_log.debug("\n\n#{f} done in #{Zold::Age.new(start)}")
60
+ test_log.info("\n\n#{f} done in #{Zold::Age.new(start)}")
61
61
  end
62
62
  end
63
63
 
@@ -46,7 +46,7 @@ require_relative '../../../lib/zold/stress/air'
46
46
 
47
47
  class StressTest < Minitest::Test
48
48
  def test_runs_a_few_full_cycles
49
- Zold::Stress::FakeNode.new(Zold::Log::Quiet.new).exec do |port|
49
+ Zold::Stress::FakeNode.new(Zold::Log::NULL).exec do |port|
50
50
  Dir.mktmpdir do |home|
51
51
  remotes = Zold::Remotes.new(file: File.join(home, 'remotes'), network: 'test')
52
52
  remotes.clean
@@ -20,8 +20,6 @@
20
20
  # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
21
  # SOFTWARE.
22
22
 
23
- STDOUT.sync = true
24
-
25
23
  ENV['RACK_ENV'] = 'test'
26
24
 
27
25
  # require 'simplecov'
@@ -38,7 +36,7 @@ module Minitest
38
36
  class Test
39
37
  def test_log
40
38
  require 'zold/log'
41
- @test_log ||= Zold::Log::Sync.new(ENV['TEST_QUIET_LOG'] ? Zold::Log::Quiet.new : Zold::Log::Verbose.new)
39
+ @test_log ||= ENV['TEST_QUIET_LOG'] ? Zold::Log::NULL : Zold::Log::VERBOSE
42
40
  end
43
41
 
44
42
  def test_opts(*argv)
@@ -27,7 +27,7 @@ Gem::Specification.new do |s|
27
27
  s.rubygems_version = '2.2'
28
28
  s.required_ruby_version = '>=2.3'
29
29
  s.name = 'zold-stress'
30
- s.version = '0.5.1'
30
+ s.version = '0.5.2'
31
31
  s.license = 'MIT'
32
32
  s.summary = 'Zold stress test'
33
33
  s.description = 'Stress testing toolkit for Zold network'
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: zold-stress
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.5.1
4
+ version: 0.5.2
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-11-15 00:00:00.000000000 Z
11
+ date: 2018-11-22 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: backtrace