zold 0.16.30 → 0.17.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 290d87dc57f2e51e44dffc3f55ca05fbcb9903988070583a5c074bd8482ee261
4
- data.tar.gz: 59842e6f21d7c959b1e03900d971d7f1d193e2e16cb6eddb0e58d909bef06e9b
3
+ metadata.gz: e102a5d92bc1bde5c3751cf9c7737f64b751b7240596028b5e3488c59fbd6e9f
4
+ data.tar.gz: 65ea0826b5dfe6a693142356174dd808525f1ba23668f643beb341add7edb2c1
5
5
  SHA512:
6
- metadata.gz: '086dcfc48660670347ae67d832b3a915e96c67dc870abea06589e0d4a5156aca5adcf5abd028a123500ad6962a410abbd489fac6674c21b9de942fa292b4921c'
7
- data.tar.gz: 48eeebe1591746a0d48f9ba65c644c83f5a621a6426500544e80f789bca0ac33895f67ae62d97e28ae117618956c24aa29971111c0daa86133c5485547811a58
6
+ metadata.gz: ffe60b65ba93cb1dd80c3257d7dabd9d808019b57b32fa51ebf97deca31d5f3ecfe6d5fd1a3af31a8ae64a39e3c90611c03d2f530e951951bcf2bb9629cc8826
7
+ data.tar.gz: d19ae042b08b72c357d23438f65fabebe4a46ee3fcf536a79e231f739809fb2c0589b885621473e4b53eee68c33b703df81a64e0882a19447d3b1ee0762a66b8
@@ -3,7 +3,7 @@ AllCops:
3
3
  - 'bin/**/*'
4
4
  - 'assets/**/*'
5
5
  DisplayCopNames: true
6
- TargetRubyVersion: 2.3.3
6
+ TargetRubyVersion: 2.5.1
7
7
 
8
8
  Layout/EmptyLineAfterGuardClause:
9
9
  Enabled: false
@@ -1 +1 @@
1
- 2.3.3
1
+ 2.5.1
@@ -12,7 +12,10 @@ release:
12
12
  script: |-
13
13
  export RUBYOPT="-W0"
14
14
  [[ "${tag}" =~ ^[0-9]+\.[0-9]+\.[0-9]+$ ]] || exit -1
15
- rm -rf *.gem
15
+ # gem build zold.gemspec
16
+ # gem install --local zold-0.0.0.gem
17
+ # zold --version | grep -vq '0.0.0' && exit 1
18
+ # zold remote update
16
19
  sed -i "s/0\.0\.0/${tag}/g" lib/zold/version.rb
17
20
  bundle install --no-color
18
21
  rake --quiet
@@ -1,7 +1,5 @@
1
1
  language: ruby
2
2
  rvm:
3
- - 2.3.1
4
- - 2.3.3
5
3
  - 2.5.1
6
4
  cache: bundler
7
5
  branches:
data/README.md CHANGED
@@ -7,7 +7,7 @@
7
7
  [![DevOps By Rultor.com](http://www.rultor.com/b/yegor256/zold)](http://www.rultor.com/p/yegor256/zold)
8
8
  [![We recommend RubyMine](http://www.elegantobjects.org/rubymine.svg)](https://www.jetbrains.com/ruby/)
9
9
 
10
- [![Build Status](https://travis-ci.org/zold-io/zold.svg)](https://travis-ci.org/zold-io/zold)
10
+ [![Build Status](https://travis-ci.org/zold-io/zold.svg?branch=master)](https://travis-ci.org/zold-io/zold)
11
11
  [![Build status](https://ci.appveyor.com/api/projects/status/15ola3lb03opv14m?svg=true)](https://ci.appveyor.com/project/yegor256/zold-wcn4o)
12
12
  [![PDD status](http://www.0pdd.com/svg?name=zold-io/zold)](http://www.0pdd.com/p?name=zold-io/zold)
13
13
  [![Gem Version](https://badge.fury.io/rb/zold.svg)](http://badge.fury.io/rb/zold)
@@ -9,8 +9,6 @@ branches:
9
9
  os: Windows Server 2012
10
10
  environment:
11
11
  matrix:
12
- - ruby_version: "23-x64"
13
- - ruby_version: "24-x64"
14
12
  - ruby_version: "25-x64"
15
13
  install:
16
14
  - ps: |
@@ -26,10 +24,25 @@ install:
26
24
  $Env:openssl_dir = "C:\msys64\mingw64"
27
25
  }
28
26
  - bundle config --local path vendor/bundle
27
+
28
+ # Download & extract libcurl
29
+ # Copy libcurl.{dll,lib} and add to PATH, so that libcurl.dll is found during the tests
30
+ - ps: |
31
+ appveyor DownloadFile "https://dl.dropboxusercontent.com/s/jxwohqax4e2avyt/libcurl-7.48.0-WinSSL-zlib-x86-x64.zip?dl=0" -FileName libcurl.zip
32
+ 7z x libcurl.zip
33
+ cp dmd2\windows\bin64\libcurl.dll C:\Ruby${Env:ruby_version}\bin
34
+ cp dmd2\windows\lib64\curl.lib C:\Ruby${Env:ruby_version}\bin
35
+
29
36
  - bundle config build.openssl --with-openssl-dir=%openssl_dir%
37
+ - bundle config build.eventmachine --use-system-libraries --with-ssl-dir=%openssl_dir%
30
38
  - ruby -v
31
39
  - bundle -v
32
40
  build_script:
41
+ # Support pure ruby eventmachine for windows
42
+ # https://github.com/eventmachine/eventmachine/issues/820
43
+ # https://github.com/eventmachine/eventmachine/issues/800
44
+ #
45
+ - gem install eventmachine --platform ruby
33
46
  - bundle update
34
47
  - bundle install
35
48
  test_script:
data/bin/zold CHANGED
@@ -181,7 +181,8 @@ wallets = Zold::SyncWallets.new(
181
181
  Zold::CachedWallets.new(
182
182
  command == 'node' ? Zold::TreeWallets.new(home) : Zold::Wallets.new(home)
183
183
  ),
184
- log: log
184
+ log: log,
185
+ dir: File.join(zoldata, 'locks')
185
186
  )
186
187
  fremotes = File.join(zoldata, 'remotes')
187
188
  remotes = Zold::Remotes.new(file: fremotes, network: opts['network'])
@@ -7,7 +7,7 @@ function start_node {
7
7
  zold node $3 --nohup --nohup-command='touch restarted' --nohup-log=log --nohup-max-cycles=0 --nohup-log-truncate=10240 \
8
8
  --expose-version=$2 --save-pid=pid --routine-immediately \
9
9
  --verbose --trace --invoice=REDEPLOY@ffffffffffffffff \
10
- --host=127.0.0.1 --port=$1 --bind-port=$1 --threads=1 --strength=20 --memory-dump > /dev/null 2>&1
10
+ --host=127.0.0.1 --port=$1 --bind-port=$1 --threads=1 --strength=20 > /dev/null 2>&1
11
11
  wait_for_port $1
12
12
  cat pid
13
13
  cd ..
@@ -28,6 +28,8 @@ require 'slop'
28
28
  require 'rainbow'
29
29
  require 'concurrent/atomics'
30
30
  require 'zold/score'
31
+ require 'concurrent'
32
+ require 'parallel'
31
33
  require_relative 'thread_badge'
32
34
  require_relative 'args'
33
35
  require_relative '../log'
@@ -69,11 +71,15 @@ Available options:"
69
71
  o.string '--network',
70
72
  'The name of the network we work in',
71
73
  default: 'test'
74
+ o.integer '--threads',
75
+ "How many threads to use for fetching wallets (default: #{[Concurrent.processor_count / 2, 2].max})",
76
+ default: [Concurrent.processor_count / 2, 2].max
72
77
  o.bool '--help', 'Print instructions'
73
78
  end
74
79
  mine = Args.new(opts, @log).take || return
75
- (mine.empty? ? @wallets.all : mine.map { |i| Id.new(i) }).each do |id|
80
+ Parallel.map((mine.empty? ? @wallets.all : mine.map { |i| Id.new(i) }), in_threads: opts[:threads]) do |id|
76
81
  fetch(id, Copies.new(File.join(@copies, id)), opts)
82
+ @log.debug("Worker: #{Parallel.worker_number} has fetched wallet #{id}")
77
83
  end
78
84
  end
79
85
 
@@ -247,7 +247,7 @@ module Zold
247
247
  network: opts['network']
248
248
  ).start do |entrance|
249
249
  Front.set(:entrance, entrance)
250
- farmer = opts['no-spawn'] ? Farmers::Plain.new : Farmers::Spawn.new(log: @log)
250
+ farmer = opts['no-spawn'] ? Farmers::Plain.new : Farmers::Fork.new(log: @log)
251
251
  Farm.new(invoice, File.join(home, 'farm'), log: @log, farmer: farmer)
252
252
  .start(host, opts[:port], threads: opts[:threads], strength: opts[:strength]) do |farm|
253
253
  Front.set(:farm, farm)
@@ -24,6 +24,8 @@ require 'rainbow'
24
24
  require 'slop'
25
25
  require 'json'
26
26
  require 'net/http'
27
+ require 'concurrent'
28
+ require 'parallel'
27
29
  require_relative 'thread_badge'
28
30
  require_relative 'args'
29
31
  require_relative '../age'
@@ -58,11 +60,15 @@ Available options:"
58
60
  o.array '--ignore-node',
59
61
  'Ignore this node and don\'t push to it',
60
62
  default: []
63
+ o.integer '--threads',
64
+ "How many threads to use for pushing wallets (default: #{[Concurrent.processor_count / 2, 2].max})",
65
+ default: [Concurrent.processor_count / 2, 2].max
61
66
  o.bool '--help', 'Print instructions'
62
67
  end
63
68
  mine = Args.new(opts, @log).take || return
64
- (mine.empty? ? @wallets.all : mine.map { |i| Id.new(i) }).each do |id|
69
+ Parallel.map((mine.empty? ? @wallets.all : mine.map { |i| Id.new(i) }), in_threads: opts[:threads]) do |id|
65
70
  push(id, opts)
71
+ @log.debug("Worker: #{Parallel.worker_number} has pushed wallet #{id}")
66
72
  end
67
73
  end
68
74
 
@@ -137,7 +137,7 @@ Available options:"
137
137
  when 'reset'
138
138
  reset
139
139
  when 'defaults'
140
- defaults
140
+ defaults(opts)
141
141
  when 'add'
142
142
  add(mine[1], mine[2] ? mine[2].to_i : Remotes::PORT, opts)
143
143
  when 'remove'
@@ -175,7 +175,7 @@ Available options:"
175
175
  defaults
176
176
  end
177
177
 
178
- def defaults
178
+ def defaults(opts)
179
179
  @remotes.defaults do |host, port|
180
180
  !opts['ignore-node'].include?("#{host}:#{port}")
181
181
  end
@@ -42,7 +42,7 @@ module Zold
42
42
  def fetch(recursive: true)
43
43
  spawn = POSIX::Spawn::Child.new(
44
44
  'find',
45
- *([Shellwords.escape(@dir), '-type', 'f', '-print'] + (recursive ? [] : ['-maxdepth', '1']))
45
+ *([@dir, '-type', 'f', '-print'] + (recursive ? [] : ['-maxdepth', '1']))
46
46
  )
47
47
  raise spawn.err unless spawn.status.success?
48
48
  spawn.out
@@ -23,8 +23,8 @@
23
23
  require 'rainbow'
24
24
  require 'uri'
25
25
  require 'backtrace'
26
- require 'patron'
27
26
  require 'zold/score'
27
+ require 'typhoeus'
28
28
  require_relative 'version'
29
29
 
30
30
  # HTTP page.
@@ -68,49 +68,56 @@ module Zold
68
68
  end
69
69
 
70
70
  def get(timeout: READ_TIMEOUT)
71
- base_url = "#{@uri.scheme}://#{@uri.host}:#{@uri.port}"
72
- session = Patron::Session.new(
73
- timeout: timeout,
74
- connect_timeout: CONNECT_TIMEOUT,
75
- base_url: base_url,
76
- headers: headers
71
+ Response.new(
72
+ Typhoeus::Request.get(
73
+ @uri,
74
+ accept_encoding: 'gzip',
75
+ headers: headers,
76
+ connecttimeout: CONNECT_TIMEOUT,
77
+ timeout: timeout
78
+ )
77
79
  )
78
- path = @uri.path
79
- path += '?' + @uri.query if @uri.query
80
- session.get(path)
81
80
  rescue StandardError => e
82
81
  Error.new(e)
83
82
  end
84
83
 
85
84
  def put(body, timeout: READ_TIMEOUT)
86
- base_url = "#{@uri.scheme}://#{@uri.host}:#{@uri.port}"
87
- session = Patron::Session.new(
88
- timeout: timeout,
89
- connect_timeout: CONNECT_TIMEOUT,
90
- base_url: base_url,
91
- headers: headers.merge(
92
- 'Content-Type': 'text/plain',
93
- 'Content-Length': body.length.to_s
85
+ Response.new(
86
+ Typhoeus::Request.put(
87
+ @uri,
88
+ accept_encoding: 'gzip',
89
+ body: body,
90
+ headers: headers.merge('Content-Type': 'text/plain'),
91
+ connecttimeout: CONNECT_TIMEOUT,
92
+ timeout: timeout
94
93
  )
95
94
  )
96
- path = @uri.path
97
- path += '?' + @uri.query if @uri.query
98
- session.put(path, body)
99
95
  rescue StandardError => e
100
96
  Error.new(e)
101
97
  end
102
98
 
103
99
  private
104
100
 
105
- # The error, if connection fails
106
- class Error
107
- def initialize(ex)
108
- @ex = ex
101
+ # Some clients waits for status method in respons
102
+ class Response < SimpleDelegator
103
+ def status
104
+ code.zero? ? 599 : code
105
+ end
106
+
107
+ def status_line
108
+ status_message
109
109
  end
110
110
 
111
111
  def to_s
112
112
  "#{status}: #{status_line}\n#{body}"
113
113
  end
114
+ end
115
+
116
+ # The error, if connection fails
117
+ class Error < Response
118
+ def initialize(ex)
119
+ @ex = ex
120
+ end
114
121
 
115
122
  def body
116
123
  Backtrace.new(@ex).to_s
@@ -40,7 +40,7 @@ module Zold
40
40
  raise 'JSON is empty, can\'t parse' + (@uri.empty? ? '' : " at #{@uri}") if @text.empty?
41
41
  JSON.parse(@text)
42
42
  rescue JSON::ParserError => e
43
- raise "Failed to parse JSON #{@uri.empty? ? '' : "at #{@uri}"} (#{e.message}): #{@text}"
43
+ raise "Failed to parse JSON #{@uri.empty? ? '' : "at #{@uri}"} (#{e.message}): #{@text.inspect}"
44
44
  end
45
45
  end
46
46
  end
@@ -215,12 +215,10 @@ at #{host}:#{port}, strength is #{strength}")
215
215
  return [] unless File.exist?(@cache)
216
216
  Futex.new(@cache).open do |f|
217
217
  IO.read(f).split(/\n/).map do |t|
218
- begin
219
- Score.parse(t)
220
- rescue StandardError => e
221
- @log.error(Backtrace.new(e).to_s)
222
- nil
223
- end
218
+ Score.parse(t)
219
+ rescue StandardError => e
220
+ @log.error(Backtrace.new(e).to_s)
221
+ nil
224
222
  end.compact
225
223
  end
226
224
  end
@@ -37,6 +37,10 @@ module Zold
37
37
  module Farmers
38
38
  # Plain and simple
39
39
  class Plain
40
+ def initialize(log: Log::NULL)
41
+ @log = log
42
+ end
43
+
40
44
  def up(score)
41
45
  score.next
42
46
  end
@@ -49,9 +53,8 @@ module Zold
49
53
  end
50
54
 
51
55
  def up(score)
52
- if POSIX::Spawn::Child.new('ps', 'ax').out.include?(score.to_s.split(' ').take(4).join(' '))
53
- raise "We are farming the score already: #{score}"
54
- end
56
+ raise "We are farming the score already: #{score}" if
57
+ POSIX::Spawn::Child.new('ps', 'ax').out.include?(score.to_s.split(' ').take(4).join(' '))
55
58
  start = Time.now
56
59
  bin = File.expand_path(File.join(File.dirname(__FILE__), '../../../bin/zold'))
57
60
  raise "Zold binary not found at #{bin}" unless File.exist?(bin)
@@ -112,5 +115,28 @@ for #{after.host}:#{after.port} in #{Age.new(start)}: #{after.suffixes}")
112
115
  @log.debug("No need to kill process ##{pid} since it's dead already: #{e.message}")
113
116
  end
114
117
  end
118
+
119
+ # In a child process using fork
120
+ class Fork
121
+ def initialize(log: Log::NULL)
122
+ @log = log
123
+ end
124
+
125
+ def up(score)
126
+ start = Time.now
127
+ stdin, stdout = IO.pipe
128
+ pid = Process.fork do
129
+ stdout.puts(score.next)
130
+ end
131
+ at_exit { Process.kill('KILL', pid) }
132
+ Process.wait
133
+ stdout.close
134
+ after = Score.parse(stdin.read.strip)
135
+ stdin.close
136
+ @log.debug("Next score #{after.value}/#{after.strength} found in proc ##{pid} \
137
+ for #{after.host}:#{after.port} in #{Age.new(start)}: #{after.suffixes}")
138
+ after
139
+ end
140
+ end
115
141
  end
116
142
  end
@@ -30,10 +30,11 @@ require_relative 'log'
30
30
  module Zold
31
31
  # Synchronized collection of wallets
32
32
  class SyncWallets
33
- def initialize(wallets, timeout: 30, log: Log::NULL)
33
+ def initialize(wallets, timeout: 30, log: Log::NULL, dir: wallets.path)
34
34
  @wallets = wallets
35
35
  @log = log
36
36
  @timeout = timeout
37
+ @dir = dir
37
38
  end
38
39
 
39
40
  def to_s
@@ -50,7 +51,7 @@ module Zold
50
51
 
51
52
  def acq(id, exclusive: false)
52
53
  @wallets.acq(id, exclusive: exclusive) do |wallet|
53
- Futex.new(wallet.path, log: @log).open(exclusive) do
54
+ Futex.new(wallet.path, log: @log, lock: File.join(@dir, "#{id}.lock")).open(exclusive) do
54
55
  yield wallet
55
56
  end
56
57
  end
@@ -25,6 +25,6 @@
25
25
  # Copyright:: Copyright (c) 2018 Yegor Bugayenko
26
26
  # License:: MIT
27
27
  module Zold
28
- VERSION = '0.16.30'
28
+ VERSION = '0.17.0'
29
29
  PROTOCOL = 2
30
30
  end
@@ -73,4 +73,51 @@ class TestFetch < Zold::Test
73
73
  assert_equal(0, copies.all[0][:score])
74
74
  end
75
75
  end
76
+
77
+ def test_fetches_multiple_wallets
78
+ log = TestLogger.new(test_log)
79
+ FakeHome.new(log: log).run do |home|
80
+ wallet_a = home.create_wallet
81
+ stub_request(:get, "http://localhost:4096/wallet/#{wallet_a.id}/size")
82
+ .to_return(status: 200, body: wallet_a.size.to_s)
83
+ stub_request(:get, "http://localhost:4096/wallet/#{wallet_a.id}").to_return(
84
+ status: 200,
85
+ body: {
86
+ 'score': Zold::Score::ZERO.to_h,
87
+ 'body': IO.read(wallet_a.path),
88
+ 'mtime': Time.now.utc.iso8601
89
+ }.to_json
90
+ )
91
+ wallet_b = home.create_wallet
92
+ stub_request(:get, "http://localhost:4096/wallet/#{wallet_b.id}/size")
93
+ .to_return(status: 200, body: wallet_b.size.to_s)
94
+ stub_request(:get, "http://localhost:4096/wallet/#{wallet_b.id}").to_return(
95
+ status: 200,
96
+ body: {
97
+ 'score': Zold::Score::ZERO.to_h,
98
+ 'body': IO.read(wallet_b.path),
99
+ 'mtime': Time.now.utc.iso8601
100
+ }.to_json
101
+ )
102
+ remotes = home.remotes
103
+ remotes.add('localhost', 4096)
104
+ copies_a = home.copies(wallet_a)
105
+ copies_b = home.copies(wallet_b)
106
+ begin
107
+ retries ||= 0
108
+ Zold::Fetch.new(wallets: home.wallets, copies: copies_a.root, remotes: remotes, log: log).run(
109
+ ['fetch', '--ignore-score-weakness', '--threads 2', wallet_a.id.to_s, wallet_b.id.to_s]
110
+ )
111
+ rescue StandardError => _
112
+ sleep 1
113
+ retry if (retries += 1) < 3
114
+ end
115
+ assert_equal(1, copies_a.all.count)
116
+ assert_equal('1', copies_a.all[0][:name])
117
+ assert_equal(0, copies_a.all[0][:score])
118
+ assert_equal(1, copies_b.all.count)
119
+ assert_equal('1', copies_b.all[0][:name])
120
+ assert_equal(0, copies_b.all[0][:score])
121
+ end
122
+ end
76
123
  end
@@ -47,4 +47,19 @@ class TestPush < Zold::Test
47
47
  )
48
48
  end
49
49
  end
50
+
51
+ def test_pushes_multiple_wallets
52
+ log = TestLogger.new(test_log)
53
+ FakeHome.new(log: log).run do |home|
54
+ wallet_a = home.create_wallet
55
+ wallet_b = home.create_wallet
56
+ remotes = home.remotes
57
+ remotes.add('localhost', 80)
58
+ stub_request(:put, "http://localhost:80/wallet/#{wallet_a.id}").to_return(status: 304)
59
+ stub_request(:put, "http://localhost:80/wallet/#{wallet_b.id}").to_return(status: 304)
60
+ Zold::Push.new(wallets: home.wallets, remotes: remotes, log: log).run(
61
+ ['--ignore-this-stupid-option --threads 2', 'push', wallet_a.id.to_s, wallet_b.id.to_s]
62
+ )
63
+ end
64
+ end
50
65
  end
@@ -234,4 +234,13 @@ class TestRemote < Zold::Test
234
234
  assert_equal(5, remotes.all.count)
235
235
  end
236
236
  end
237
+
238
+ def test_sets_defaults
239
+ Dir.mktmpdir do |dir|
240
+ remotes = Zold::Remotes.new(file: File.join(dir, 'remotes.txt'))
241
+ cmd = Zold::Remote.new(remotes: remotes, log: test_log)
242
+ cmd.run(%w[remote defaults])
243
+ assert(!remotes.all.empty?)
244
+ end
245
+ end
237
246
  end
@@ -58,7 +58,7 @@ class TestAsyncEntrance < Zold::Test
58
58
  def test_sends_through
59
59
  FakeHome.new(log: test_log).run do |home|
60
60
  basic = CountingEntrance.new
61
- Zold::AsyncEntrance.new(basic, File.join(home.dir, 'a/b/c'), log: test_log).start do |e|
61
+ Zold::AsyncEntrance.new(basic, File.join(home.dir, 'a/b/c'), log: test_log, queue_limit: 1000).start do |e|
62
62
  Threads.new(20).assert do
63
63
  wallet = home.create_wallet
64
64
  amount = Zold::Amount.new(zld: 39.99)
@@ -25,23 +25,28 @@ require 'time'
25
25
  require 'zold/score'
26
26
  require_relative '../test__helper'
27
27
  require_relative '../../lib/zold/node/farmers'
28
+ require_relative '../../lib/zold/verbose_thread'
28
29
 
29
30
  class FarmersTest < Zold::Test
30
31
  def test_calculates_next_score
31
32
  before = Zold::Score.new(host: 'some-host', port: 9999, invoice: 'NOPREFIX4@ffffffffffffffff', strength: 3)
32
- farmer = Zold::Farmers::Spawn.new(log: test_log)
33
- after = farmer.up(before)
34
- assert_equal(1, after.value)
35
- assert(!after.expired?)
36
- assert_equal('some-host', after.host)
37
- assert_equal(9999, after.port)
33
+ [Zold::Farmers::Plain, Zold::Farmers::Spawn, Zold::Farmers::Fork].each do |farmer_class|
34
+ farmer = farmer_class.new(log: test_log)
35
+ after = farmer.up(before)
36
+ assert_equal(1, after.value)
37
+ assert(!after.expired?)
38
+ assert_equal('some-host', after.host)
39
+ assert_equal(9999, after.port)
40
+ end
38
41
  end
39
42
 
40
43
  def test_calculates_large_score
41
44
  log = TestLogger.new(test_log)
42
45
  thread = Thread.start do
43
- farmer = Zold::Farmers::Spawn.new(log: log)
44
- farmer.up(Zold::Score.new(host: 'a', port: 1, invoice: 'NOPREFIX4@ffffffffffffffff', strength: 20))
46
+ [Zold::Farmers::Spawn, Zold::Farmers::Fork].each do |farmer_class|
47
+ farmer = farmer_class.new(log: log)
48
+ farmer.up(Zold::Score.new(host: 'a', port: 1, invoice: 'NOPREFIX4@ffffffffffffffff', strength: 20))
49
+ end
45
50
  end
46
51
  assert_wait { !log.msgs.find { |m| m.include?('Scoring started') }.nil? }
47
52
  thread.kill
@@ -49,28 +54,36 @@ class FarmersTest < Zold::Test
49
54
  assert(log.msgs.find { |m| m.include?('killed') })
50
55
  end
51
56
 
52
- def test_calculates_next_score_plain
53
- before = Zold::Score.new(host: 'some-host', port: 9999, invoice: 'NOPREFIX4@ffffffffffffffff', strength: 1)
54
- farmer = Zold::Farmers::Plain.new
55
- after = farmer.up(before)
56
- assert_equal(1, after.value)
57
- assert(!after.expired?)
58
- assert_equal('some-host', after.host)
59
- assert_equal(9999, after.port)
57
+ def test_kills_farmer
58
+ [Zold::Farmers::Plain, Zold::Farmers::Spawn, Zold::Farmers::Fork].each do |type|
59
+ farmer = type.new(log: test_log)
60
+ thread = Thread.start do
61
+ Zold::VerboseThread.new(test_log).run do
62
+ farmer.up(Zold::Score.new(host: 'some-host', invoice: 'NOPREFIX4@ffffffffffffffff', strength: 32))
63
+ end
64
+ end
65
+ sleep(1)
66
+ thread.kill
67
+ thread.join
68
+ end
60
69
  end
61
70
 
62
71
  def test_avoid_duplicate_processes
63
72
  log = TestLogger.new(test_log)
64
73
  time = Time.now
65
74
  thread = Thread.start do
66
- farmer = Zold::Farmers::Spawn.new(log: log)
67
- farmer.up(Zold::Score.new(time: time, host: 'a', port: 1, invoice: 'prefixone@ffffffffffffffff', strength: 20))
75
+ [Zold::Farmers::Spawn, Zold::Farmers::Fork].each do |farmer_class|
76
+ farmer = farmer_class.new(log: log)
77
+ farmer.up(Zold::Score.new(time: time, host: 'a', port: 1, invoice: 'prefixone@ffffffffffffffff', strength: 20))
78
+ end
68
79
  end
69
80
  assert_wait { !log.msgs.find { |m| m.include?('Scoring started') }.nil? }
70
81
  assert_raises do
71
- Zold::Farmers::Spawn.new(log: log).up(
72
- Zold::Score.new(time: time, host: 'a', port: 1, invoice: 'prefixtwo@ffffffffffffffff', strength: 20)
73
- )
82
+ [Zold::Farmers::Spawn, Zold::Farmers::Fork].each do |farmer_class|
83
+ farmer_class.new(log: log).up(
84
+ Zold::Score.new(time: time, host: 'a', port: 1, invoice: 'prefixtwo@ffffffffffffffff', strength: 20)
85
+ )
86
+ end
74
87
  end
75
88
  thread.kill
76
89
  thread.join
@@ -61,13 +61,13 @@ class FrontTest < Zold::Test
61
61
  assert_equal(Zold::VERSION, json['version'])
62
62
  assert_equal(Zold::PROTOCOL, json['protocol'])
63
63
  assert_equal('foo', json['network'])
64
- assert(json['pid'].positive?)
65
- assert(json['cpus'].positive?)
66
- assert(json['memory'].positive?)
67
- assert(json['load'].positive?)
68
- assert(json['wallets'].positive?)
69
- assert(json['remotes'].zero?)
70
- assert(json['nscore'].zero?)
64
+ assert(json['pid'].positive?, json)
65
+ assert(json['cpus'].positive?, json)
66
+ assert(json['memory'].positive?, json)
67
+ assert(!json['load'].negative?, json)
68
+ assert(json['wallets'].positive?, json)
69
+ assert(json['remotes'].zero?, json)
70
+ assert(json['nscore'].zero?, json)
71
71
  end
72
72
  end
73
73
 
@@ -53,11 +53,7 @@ class TestDirItems < Zold::Test
53
53
  end
54
54
  end
55
55
 
56
- # @todo #507:30min I don't understand why this test doesn't work. It's not
57
- # mission critical, since we don't have spaces in our paths, mostly. But
58
- # still, would be great to fix it.
59
56
  def test_lists_empty_dir
60
- skip
61
57
  Dir.mktmpdir do |dir|
62
58
  d = File.join(dir, 'path с пробелами')
63
59
  FileUtils.mkdir_p(d)
@@ -20,6 +20,7 @@
20
20
  # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
21
  # SOFTWARE.
22
22
 
23
+ require 'rainbow'
23
24
  require_relative '../lib/zold/version'
24
25
  require_relative '../lib/zold/wallet'
25
26
 
@@ -38,7 +39,8 @@ module Zold
38
39
  f = File.join(@home, path)
39
40
  wallet = Wallet.new(f)
40
41
  next if wallet.network == @network
41
- @log.info("Wallet #{wallet.id} renamed, since it's in #{wallet.network}, while we are in #{@network} network")
42
+ @log.info("Wallet #{wallet.id} #{Rainbow(renamed).red}, \
43
+ since it's in \"#{wallet.network}\", while we are in \"#{@network}\" network")
42
44
  File.rename(f, f + '-old')
43
45
  end
44
46
  end
@@ -30,7 +30,7 @@ Gem::Specification.new do |s|
30
30
  s.specification_version = 2 if s.respond_to? :specification_version=
31
31
  s.required_rubygems_version = Gem::Requirement.new('>= 0') if s.respond_to? :required_rubygems_version=
32
32
  s.rubygems_version = '2.2'
33
- s.required_ruby_version = '>=2.3'
33
+ s.required_ruby_version = '>=2.5'
34
34
  s.name = 'zold'
35
35
  s.version = Zold::VERSION
36
36
  s.license = 'MIT'
@@ -70,7 +70,7 @@ and suggests a different architecture for digital wallet maintenance.'
70
70
  s.add_runtime_dependency 'json', '2.1.0'
71
71
  s.add_runtime_dependency 'memory_profiler', '0.9.12'
72
72
  s.add_runtime_dependency 'openssl', '2.1.2'
73
- s.add_runtime_dependency 'patron', '0.13.1'
73
+ s.add_runtime_dependency 'parallel', '1.12.1'
74
74
  s.add_runtime_dependency 'posix-spawn', '0.3.13'
75
75
  s.add_runtime_dependency 'rainbow', '3.0.0'
76
76
  s.add_runtime_dependency 'rake', '12.3.1' # has to stay here for Heroku
@@ -82,10 +82,11 @@ and suggests a different architecture for digital wallet maintenance.'
82
82
  s.add_runtime_dependency 'sys-proctable', '1.2.1'
83
83
  s.add_runtime_dependency 'thin', '1.7.2'
84
84
  s.add_runtime_dependency 'threads', '0.3.0'
85
+ s.add_runtime_dependency 'typhoeus', '1.3.1'
85
86
  s.add_runtime_dependency 'usagewatch_ext', '0.2.1'
86
87
  s.add_runtime_dependency 'xcop', '0.6'
87
88
  s.add_runtime_dependency 'zache', '0.3.1'
88
- s.add_runtime_dependency 'zold-score', '0.2.2'
89
+ s.add_runtime_dependency 'zold-score', '0.3.3'
89
90
  s.add_development_dependency 'codecov', '0.1.13'
90
91
  s.add_development_dependency 'minitest', '5.11.3'
91
92
  s.add_development_dependency 'minitest-fail-fast', '0.1.0'
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.16.30
4
+ version: 0.17.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: 2018-11-22 00:00:00.000000000 Z
11
+ date: 2018-11-28 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: backtrace
@@ -137,19 +137,19 @@ dependencies:
137
137
  - !ruby/object:Gem::Version
138
138
  version: 2.1.2
139
139
  - !ruby/object:Gem::Dependency
140
- name: patron
140
+ name: parallel
141
141
  requirement: !ruby/object:Gem::Requirement
142
142
  requirements:
143
143
  - - '='
144
144
  - !ruby/object:Gem::Version
145
- version: 0.13.1
145
+ version: 1.12.1
146
146
  type: :runtime
147
147
  prerelease: false
148
148
  version_requirements: !ruby/object:Gem::Requirement
149
149
  requirements:
150
150
  - - '='
151
151
  - !ruby/object:Gem::Version
152
- version: 0.13.1
152
+ version: 1.12.1
153
153
  - !ruby/object:Gem::Dependency
154
154
  name: posix-spawn
155
155
  requirement: !ruby/object:Gem::Requirement
@@ -304,6 +304,20 @@ dependencies:
304
304
  - - '='
305
305
  - !ruby/object:Gem::Version
306
306
  version: 0.3.0
307
+ - !ruby/object:Gem::Dependency
308
+ name: typhoeus
309
+ requirement: !ruby/object:Gem::Requirement
310
+ requirements:
311
+ - - '='
312
+ - !ruby/object:Gem::Version
313
+ version: 1.3.1
314
+ type: :runtime
315
+ prerelease: false
316
+ version_requirements: !ruby/object:Gem::Requirement
317
+ requirements:
318
+ - - '='
319
+ - !ruby/object:Gem::Version
320
+ version: 1.3.1
307
321
  - !ruby/object:Gem::Dependency
308
322
  name: usagewatch_ext
309
323
  requirement: !ruby/object:Gem::Requirement
@@ -352,14 +366,14 @@ dependencies:
352
366
  requirements:
353
367
  - - '='
354
368
  - !ruby/object:Gem::Version
355
- version: 0.2.2
369
+ version: 0.3.3
356
370
  type: :runtime
357
371
  prerelease: false
358
372
  version_requirements: !ruby/object:Gem::Requirement
359
373
  requirements:
360
374
  - - '='
361
375
  - !ruby/object:Gem::Version
362
- version: 0.2.2
376
+ version: 0.3.3
363
377
  - !ruby/object:Gem::Dependency
364
378
  name: codecov
365
379
  requirement: !ruby/object:Gem::Requirement
@@ -697,7 +711,7 @@ licenses:
697
711
  - MIT
698
712
  metadata: {}
699
713
  post_install_message: |-
700
- Thanks for installing Zold 0.16.30!
714
+ Thanks for installing Zold 0.17.0!
701
715
  Study our White Paper: https://papers.zold.io/wp.pdf
702
716
  Read our blog posts: https://blog.zold.io
703
717
  Try online wallet at: https://wts.zold.io
@@ -712,7 +726,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
712
726
  requirements:
713
727
  - - ">="
714
728
  - !ruby/object:Gem::Version
715
- version: '2.3'
729
+ version: '2.5'
716
730
  required_rubygems_version: !ruby/object:Gem::Requirement
717
731
  requirements:
718
732
  - - ">="