zold 0.14.17 → 0.14.18
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.gitignore +2 -0
- data/.rubocop.yml +1 -1
- data/bin/zold +6 -1
- data/fixtures/scripts/_head.sh +33 -13
- data/fixtures/scripts/calculate-scores.sh +1 -1
- data/fixtures/scripts/distribute-wallet.sh +2 -2
- data/fixtures/scripts/push-and-pull.sh +2 -2
- data/fixtures/scripts/redeploy-on-upgrade.sh +3 -3
- data/fixtures/scripts/sigdump.sh +1 -1
- data/fixtures/scripts/spread-wallets.sh +2 -2
- data/lib/zold/commands/next.rb +57 -0
- data/lib/zold/commands/node.rb +23 -8
- data/lib/zold/commands/remote.rb +7 -4
- data/lib/zold/metronome.rb +0 -1
- data/lib/zold/node/farm.rb +3 -2
- data/lib/zold/node/front.rb +11 -0
- data/lib/zold/node/spread_entrance.rb +0 -1
- data/lib/zold/remotes.rb +68 -75
- data/lib/zold/type.rb +5 -4
- data/lib/zold/version.rb +1 -1
- data/test/commands/routines/test_reconnect.rb +2 -2
- data/test/commands/test_create.rb +1 -1
- data/test/commands/test_invoice.rb +1 -1
- data/test/commands/test_list.rb +1 -1
- data/test/commands/test_merge.rb +1 -1
- data/test/commands/test_pull.rb +49 -0
- data/test/commands/test_remote.rb +11 -12
- data/test/commands/test_show.rb +1 -1
- data/test/fake_home.rb +26 -4
- data/test/node/fake_node.rb +1 -0
- data/test/node/test_farm.rb +10 -10
- data/test/test_atomic_file.rb +2 -2
- data/test/test_copies.rb +8 -8
- data/test/test_key.rb +1 -1
- data/test/test_remotes.rb +60 -21
- data/test/test_zold.rb +3 -2
- metadata +5 -4
- data/.zoldata/remotes +0 -1
- data/farm +0 -1
data/lib/zold/remotes.rb
CHANGED
@@ -28,6 +28,7 @@ require 'fileutils'
|
|
28
28
|
require_relative 'backtrace'
|
29
29
|
require_relative 'node/farm'
|
30
30
|
require_relative 'atomic_file'
|
31
|
+
require_relative 'type'
|
31
32
|
|
32
33
|
# The list of remotes.
|
33
34
|
# Author:: Yegor Bugayenko (yegor256@gmail.com)
|
@@ -42,18 +43,11 @@ module Zold
|
|
42
43
|
# At what amount of errors we delete the remote automatically
|
43
44
|
TOLERANCE = 8
|
44
45
|
|
45
|
-
# After this limit, the remote runtime must be recorded
|
46
|
-
RUNTIME_LIMIT = 16
|
47
|
-
|
48
46
|
# Default number of nodes to fetch.
|
49
47
|
MAX_NODES = 16
|
50
48
|
|
51
49
|
# Empty, for standalone mode
|
52
50
|
class Empty < Remotes
|
53
|
-
def initialize
|
54
|
-
# Nothing here
|
55
|
-
end
|
56
|
-
|
57
51
|
def all
|
58
52
|
[]
|
59
53
|
end
|
@@ -64,33 +58,28 @@ module Zold
|
|
64
58
|
end
|
65
59
|
|
66
60
|
# One remote.
|
67
|
-
class Remote
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
@idx = idx
|
77
|
-
raise 'Network can\'t be nil' if network.nil?
|
78
|
-
@network = network
|
79
|
-
@log = log
|
80
|
-
end
|
61
|
+
class Remote < Dry::Struct
|
62
|
+
attribute :host, Types::Strict::String
|
63
|
+
attribute :port, Types::Strict::Integer.constrained(gteq: 0, lt: 65_535)
|
64
|
+
attribute :score, Score
|
65
|
+
attribute :idx, Types::Strict::Integer
|
66
|
+
attribute :network, Types::Strict::String.optional.default('test')
|
67
|
+
attribute :log, (Types::Class.constructor do |value|
|
68
|
+
value.nil? ? Log::Quiet.new : value
|
69
|
+
end)
|
81
70
|
|
82
71
|
def http(path = '/')
|
83
|
-
Http.new(uri: "http://#{
|
72
|
+
Http.new(uri: "http://#{host}:#{port}#{path}", score: score, network: network)
|
84
73
|
end
|
85
74
|
|
86
75
|
def to_s
|
87
|
-
"#{
|
76
|
+
"#{host}:#{port}/#{idx}"
|
88
77
|
end
|
89
78
|
|
90
79
|
def assert_code(code, response)
|
91
80
|
msg = response.message.strip
|
92
81
|
return if response.code.to_i == code
|
93
|
-
|
82
|
+
log.debug("#{response.code} \"#{response.message}\" at \"#{response.body}\"")
|
94
83
|
raise "Unexpected HTTP code #{response.code}, instead of #{code}" if msg.empty?
|
95
84
|
raise "#{msg} (HTTP code #{response.code}, instead of #{code})"
|
96
85
|
end
|
@@ -101,8 +90,8 @@ module Zold
|
|
101
90
|
end
|
102
91
|
|
103
92
|
def assert_score_ownership(score)
|
104
|
-
raise "Masqueraded host #{
|
105
|
-
raise "Masqueraded port #{
|
93
|
+
raise "Masqueraded host #{host} as #{score.host}: #{score}" if host != score.host
|
94
|
+
raise "Masqueraded port #{port} as #{score.port}: #{score}" if port != score.port
|
106
95
|
end
|
107
96
|
|
108
97
|
def assert_score_strength(score)
|
@@ -114,12 +103,11 @@ module Zold
|
|
114
103
|
end
|
115
104
|
end
|
116
105
|
|
117
|
-
def initialize(file
|
118
|
-
raise 'File can\'t be nil' if file.nil?
|
106
|
+
def initialize(file:, network: 'test', mutex: Mutex.new, timeout: 16)
|
119
107
|
@file = file
|
120
|
-
raise 'Network can\'t be nil' if network.nil?
|
121
108
|
@network = network
|
122
|
-
@mutex =
|
109
|
+
@mutex = mutex
|
110
|
+
@timeout = timeout
|
123
111
|
end
|
124
112
|
|
125
113
|
def all
|
@@ -134,7 +122,7 @@ module Zold
|
|
134
122
|
end
|
135
123
|
|
136
124
|
def clean
|
137
|
-
|
125
|
+
modify { [] }
|
138
126
|
end
|
139
127
|
|
140
128
|
def reset
|
@@ -161,18 +149,18 @@ module Zold
|
|
161
149
|
raise 'Port can\'t be negative' if port.negative?
|
162
150
|
raise 'Port can\'t be over 65536' if port > 0xffff
|
163
151
|
raise "#{host}:#{port} already exists" if exists?(host, port)
|
164
|
-
|
165
|
-
|
166
|
-
|
152
|
+
modify do |list|
|
153
|
+
list + [{ host: host.downcase, port: port, score: 0 }]
|
154
|
+
end
|
167
155
|
end
|
168
156
|
|
169
157
|
def remove(host, port = Remotes::PORT)
|
170
158
|
raise 'Port has to be of type Integer' unless port.is_a?(Integer)
|
171
159
|
raise 'Host can\'t be nil' if host.nil?
|
172
160
|
raise 'Port can\'t be nil' if port.nil?
|
173
|
-
|
174
|
-
|
175
|
-
|
161
|
+
modify do |list|
|
162
|
+
list.reject { |r| r[:host] == host.downcase && r[:port] == port }
|
163
|
+
end
|
176
164
|
end
|
177
165
|
|
178
166
|
def iterate(log, farm: Farm::Empty.new)
|
@@ -188,12 +176,18 @@ module Zold
|
|
188
176
|
pool.post do
|
189
177
|
Thread.current.abort_on_exception = true
|
190
178
|
Thread.current.name = 'remotes'
|
191
|
-
Thread.current.priority = -100
|
192
179
|
start = Time.now
|
193
180
|
begin
|
194
|
-
yield Remotes::Remote.new(
|
181
|
+
yield Remotes::Remote.new(
|
182
|
+
host: r[:host],
|
183
|
+
port: r[:port],
|
184
|
+
score: score,
|
185
|
+
idx: idx,
|
186
|
+
log: log,
|
187
|
+
network: @network
|
188
|
+
)
|
195
189
|
idx += 1
|
196
|
-
raise 'Took too long to execute' if (Time.now - start).round >
|
190
|
+
raise 'Took too long to execute' if (Time.now - start).round > @timeout
|
197
191
|
rescue StandardError => e
|
198
192
|
error(r[:host], r[:port])
|
199
193
|
errors = errors(r[:host], r[:port])
|
@@ -234,49 +228,48 @@ in #{(Time.now - start).round}s; errors=#{errors}")
|
|
234
228
|
|
235
229
|
private
|
236
230
|
|
237
|
-
def
|
238
|
-
list = load
|
239
|
-
remote = list.find { |r| r[:host] == host.downcase && r[:port] == port }
|
240
|
-
return unless remote
|
241
|
-
yield remote
|
242
|
-
save(list)
|
243
|
-
end
|
244
|
-
|
245
|
-
def load
|
231
|
+
def modify
|
246
232
|
@mutex.synchronize do
|
247
|
-
|
248
|
-
{
|
249
|
-
host: r[0],
|
250
|
-
port: r[1].to_i,
|
251
|
-
score: r[2].to_i,
|
252
|
-
errors: r[3].to_i
|
253
|
-
}
|
254
|
-
end
|
255
|
-
raw.reject { |r| !r[:host] || r[:port].zero? }.map do |r|
|
256
|
-
r[:home] = URI("http://#{r[:host]}:#{r[:port]}/")
|
257
|
-
r
|
258
|
-
end
|
233
|
+
save(yield(load))
|
259
234
|
end
|
260
235
|
end
|
261
236
|
|
262
|
-
def
|
263
|
-
|
264
|
-
|
265
|
-
|
266
|
-
|
267
|
-
|
268
|
-
r[:port],
|
269
|
-
r[:score],
|
270
|
-
r[:errors]
|
271
|
-
].join(',')
|
272
|
-
end.join("\n")
|
273
|
-
)
|
237
|
+
def if_present(host, port)
|
238
|
+
modify do |list|
|
239
|
+
remote = list.find { |r| r[:host] == host.downcase && r[:port] == port }
|
240
|
+
return unless remote
|
241
|
+
yield remote
|
242
|
+
list
|
274
243
|
end
|
275
244
|
end
|
276
245
|
|
277
|
-
def
|
246
|
+
def load
|
278
247
|
reset unless File.exist?(@file)
|
279
|
-
@file
|
248
|
+
raw = CSV.read(@file).map do |r|
|
249
|
+
{
|
250
|
+
host: r[0],
|
251
|
+
port: r[1].to_i,
|
252
|
+
score: r[2].to_i,
|
253
|
+
errors: r[3].to_i
|
254
|
+
}
|
255
|
+
end
|
256
|
+
raw.reject { |r| !r[:host] || r[:port].zero? }.map do |r|
|
257
|
+
r[:home] = URI("http://#{r[:host]}:#{r[:port]}/")
|
258
|
+
r
|
259
|
+
end
|
260
|
+
end
|
261
|
+
|
262
|
+
def save(list)
|
263
|
+
AtomicFile.new(@file).write(
|
264
|
+
list.uniq { |r| "#{r[:host]}:#{r[:port]}" }.map do |r|
|
265
|
+
[
|
266
|
+
r[:host],
|
267
|
+
r[:port],
|
268
|
+
r[:score],
|
269
|
+
r[:errors]
|
270
|
+
].join(',')
|
271
|
+
end.join("\n")
|
272
|
+
)
|
280
273
|
end
|
281
274
|
end
|
282
275
|
end
|
data/lib/zold/type.rb
CHANGED
@@ -20,10 +20,11 @@
|
|
20
20
|
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
21
21
|
# SOFTWARE.
|
22
22
|
|
23
|
-
# @todo #
|
24
|
-
# dry-types, even tough the issue has
|
25
|
-
# is very cumbersome. Please refer
|
26
|
-
# the changes for the project to
|
23
|
+
# @todo #394:30m/DEV Right now only Score, Http, Zold::Remotes and Zold::Remote
|
24
|
+
# classes have been refactored for using dry-types, even tough the issue has
|
25
|
+
# been boosted refactoring the whole project is very cumbersome. Please refer
|
26
|
+
# to Score and Http class on how to perform all the changes for the project to
|
27
|
+
# adopt dry-types
|
27
28
|
require 'dry-types'
|
28
29
|
require 'dry-struct'
|
29
30
|
|
data/lib/zold/version.rb
CHANGED
@@ -33,8 +33,8 @@ require_relative '../../../lib/zold/commands/routines/reconnect.rb'
|
|
33
33
|
# License:: MIT
|
34
34
|
class TestReconnect < Minitest::Test
|
35
35
|
def test_reconnects
|
36
|
-
Dir.mktmpdir
|
37
|
-
remotes = Zold::Remotes.new(File.join(dir, 'remotes.csv'))
|
36
|
+
Dir.mktmpdir do |dir|
|
37
|
+
remotes = Zold::Remotes.new(file: File.join(dir, 'remotes.csv'))
|
38
38
|
remotes.clean
|
39
39
|
stub_request(:get, 'http://b1.zold.io:80/remotes').to_return(status: 404)
|
40
40
|
opts = { 'never-reboot' => true, 'routine-immediately' => true }
|
@@ -33,7 +33,7 @@ require_relative '../../lib/zold/commands/create'
|
|
33
33
|
# License:: MIT
|
34
34
|
class TestCreate < Minitest::Test
|
35
35
|
def test_creates_wallet
|
36
|
-
Dir.mktmpdir
|
36
|
+
Dir.mktmpdir do |dir|
|
37
37
|
wallet = Zold::Create.new(wallets: Zold::Wallets.new(dir), log: test_log).run(
|
38
38
|
['create', '--public-key=fixtures/id_rsa.pub']
|
39
39
|
)
|
@@ -35,7 +35,7 @@ require_relative '../../lib/zold/commands/invoice'
|
|
35
35
|
# License:: MIT
|
36
36
|
class TestInvoice < Minitest::Test
|
37
37
|
def test_generates_invoice
|
38
|
-
Dir.mktmpdir
|
38
|
+
Dir.mktmpdir do |dir|
|
39
39
|
id = Zold::Id.new
|
40
40
|
wallets = Zold::Wallets.new(dir)
|
41
41
|
source = wallets.find(id)
|
data/test/commands/test_list.rb
CHANGED
@@ -34,7 +34,7 @@ require_relative '../../lib/zold/commands/list'
|
|
34
34
|
# License:: MIT
|
35
35
|
class TestList < Minitest::Test
|
36
36
|
def test_lists_wallets_with_balances
|
37
|
-
Dir.mktmpdir
|
37
|
+
Dir.mktmpdir do |dir|
|
38
38
|
id = Zold::Id.new
|
39
39
|
wallets = Zold::Wallets.new(dir)
|
40
40
|
wallet = wallets.find(id)
|
data/test/commands/test_merge.rb
CHANGED
@@ -140,7 +140,7 @@ class TestMerge < Minitest::Test
|
|
140
140
|
def test_merges_scenarios
|
141
141
|
base = 'fixtures/merge'
|
142
142
|
Dir.new(base).select { |f| File.directory?(File.join(base, f)) && !f.start_with?('.') }.each do |f|
|
143
|
-
Dir.mktmpdir
|
143
|
+
Dir.mktmpdir do |dir|
|
144
144
|
FileUtils.cp_r(File.join('fixtures/merge', "#{f}/."), dir)
|
145
145
|
scores = File.join(dir, 'copies/0123456789abcdef/scores.z')
|
146
146
|
File.write(scores, File.read(scores).gsub(/NOW/, Time.now.utc.iso8601))
|
@@ -0,0 +1,49 @@
|
|
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 'minitest/autorun'
|
24
|
+
require 'webmock/minitest'
|
25
|
+
require_relative '../fake_home'
|
26
|
+
require_relative '../test__helper'
|
27
|
+
require_relative '../../lib/zold/id'
|
28
|
+
require_relative '../../lib/zold/json_page'
|
29
|
+
require_relative '../../lib/zold/commands/pull'
|
30
|
+
|
31
|
+
# PUSH test.
|
32
|
+
# Author:: Yegor Bugayenko (yegor256@gmail.com)
|
33
|
+
# Copyright:: Copyright (c) 2018 Yegor Bugayenko
|
34
|
+
# License:: MIT
|
35
|
+
class TestPull < Minitest::Test
|
36
|
+
def test_pull_wallet
|
37
|
+
FakeHome.new.run do |home|
|
38
|
+
remotes = home.remotes
|
39
|
+
remotes.add('localhost', 80)
|
40
|
+
json = home.create_wallet_json
|
41
|
+
id = Zold::JsonPage.new(json).to_hash['id']
|
42
|
+
stub_request(:get, "http://localhost:80/wallet/#{id}").to_return(status: 200, body: json)
|
43
|
+
Zold::Pull.new(wallets: home.wallets, remotes: remotes, copies: home.copies.root.to_s, log: test_log).run(
|
44
|
+
['--ignore-this-stupid-option', 'pull', id.to_s]
|
45
|
+
)
|
46
|
+
assert(home.wallets.find(Zold::Id.new(id)).exists?)
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
@@ -38,8 +38,8 @@ require_relative '../../lib/zold/commands/remote'
|
|
38
38
|
# License:: MIT
|
39
39
|
class TestRemote < Minitest::Test
|
40
40
|
def test_updates_remote
|
41
|
-
Dir.mktmpdir
|
42
|
-
remotes = Zold::Remotes.new(File.join(dir, 'a/b/c/remotes'))
|
41
|
+
Dir.mktmpdir do |dir|
|
42
|
+
remotes = Zold::Remotes.new(file: File.join(dir, 'a/b/c/remotes'))
|
43
43
|
zero = Zold::Score::ZERO
|
44
44
|
stub_request(:get, "http://#{zero.host}:#{zero.port}/remotes").to_return(
|
45
45
|
status: 200,
|
@@ -73,9 +73,9 @@ class TestRemote < Minitest::Test
|
|
73
73
|
end
|
74
74
|
|
75
75
|
def test_elects_a_remote
|
76
|
-
Dir.mktmpdir
|
76
|
+
Dir.mktmpdir do |dir|
|
77
77
|
zero = Zold::Score::ZERO
|
78
|
-
remotes = Zold::Remotes.new(File.join(dir, 'remotes.txt'))
|
78
|
+
remotes = Zold::Remotes.new(file: File.join(dir, 'remotes.txt'))
|
79
79
|
remotes.clean
|
80
80
|
remotes.add(zero.host, zero.port)
|
81
81
|
stub_request(:get, "http://#{zero.host}:#{zero.port}/").to_return(
|
@@ -92,8 +92,8 @@ class TestRemote < Minitest::Test
|
|
92
92
|
end
|
93
93
|
|
94
94
|
def test_remote_trim_with_tolerate
|
95
|
-
Dir.mktmpdir
|
96
|
-
remotes = Zold::Remotes.new(File.join(dir, 'remotes.txt'))
|
95
|
+
Dir.mktmpdir do |dir|
|
96
|
+
remotes = Zold::Remotes.new(file: File.join(dir, 'remotes.txt'))
|
97
97
|
zero = Zold::Score::ZERO
|
98
98
|
stub_request(:get, "http://#{zero.host}:#{zero.port}/remotes").to_return(
|
99
99
|
status: 200,
|
@@ -105,14 +105,13 @@ class TestRemote < Minitest::Test
|
|
105
105
|
]
|
106
106
|
}.to_json
|
107
107
|
)
|
108
|
-
stub_request(:get, 'http://localhost:888/remotes').to_return(
|
109
|
-
status: 404
|
110
|
-
)
|
108
|
+
stub_request(:get, 'http://localhost:888/remotes').to_return(status: 404)
|
111
109
|
cmd = Zold::Remote.new(remotes: remotes, log: test_log)
|
112
110
|
cmd.run(%w[remote clean])
|
113
111
|
assert(remotes.all.empty?)
|
114
112
|
cmd.run(['remote', 'add', zero.host, zero.port.to_s, '--skip-ping'])
|
115
|
-
cmd.run(
|
113
|
+
cmd.run(['remote', 'update', '--ignore-score-weakness', '--skip-ping'])
|
114
|
+
assert_equal(2, remotes.all.count)
|
116
115
|
cmd.run(['remote', 'update', '--ignore-score-weakness'])
|
117
116
|
cmd.run(['remote', 'trim', '--tolerate=0'])
|
118
117
|
assert_equal(1, remotes.all.count)
|
@@ -127,8 +126,8 @@ class TestRemote < Minitest::Test
|
|
127
126
|
end
|
128
127
|
|
129
128
|
def test_select_respects_max_nodes_option
|
130
|
-
Dir.mktmpdir
|
131
|
-
remotes = Zold::Remotes.new(File.join(dir, 'remotes.txt'))
|
129
|
+
Dir.mktmpdir do |dir|
|
130
|
+
remotes = Zold::Remotes.new(file: File.join(dir, 'remotes.txt'))
|
132
131
|
zero = Zold::Score::ZERO
|
133
132
|
cmd = Zold::Remote.new(remotes: remotes, log: test_log)
|
134
133
|
(5000..5010).each do |port|
|
data/test/commands/test_show.rb
CHANGED
@@ -35,7 +35,7 @@ require_relative '../../lib/zold/commands/show'
|
|
35
35
|
# License:: MIT
|
36
36
|
class TestShow < Minitest::Test
|
37
37
|
def test_checks_wallet_balance
|
38
|
-
Dir.mktmpdir
|
38
|
+
Dir.mktmpdir do |dir|
|
39
39
|
id = Zold::Id.new
|
40
40
|
wallets = Zold::Wallets.new(dir)
|
41
41
|
wallet = wallets.find(id)
|
data/test/fake_home.rb
CHANGED
@@ -25,6 +25,9 @@ require_relative '../lib/zold/id'
|
|
25
25
|
require_relative '../lib/zold/wallet'
|
26
26
|
require_relative '../lib/zold/wallets'
|
27
27
|
require_relative '../lib/zold/key'
|
28
|
+
require_relative '../lib/zold/version'
|
29
|
+
require_relative '../lib/zold/remotes'
|
30
|
+
require_relative '../lib/zold/atomic_file'
|
28
31
|
|
29
32
|
# Fake home dir.
|
30
33
|
# Author:: Yegor Bugayenko (yegor256@gmail.com)
|
@@ -37,7 +40,7 @@ class FakeHome
|
|
37
40
|
end
|
38
41
|
|
39
42
|
def run
|
40
|
-
Dir.mktmpdir
|
43
|
+
Dir.mktmpdir do |dir|
|
41
44
|
FileUtils.copy(File.join(__dir__, '../fixtures/id_rsa'), File.join(dir, 'id_rsa'))
|
42
45
|
yield FakeHome.new(dir)
|
43
46
|
end
|
@@ -47,18 +50,37 @@ class FakeHome
|
|
47
50
|
Zold::Wallets.new(@dir)
|
48
51
|
end
|
49
52
|
|
50
|
-
def create_wallet(id = Zold::Id.new)
|
51
|
-
wallet = Zold::Wallet.new(File.join(
|
53
|
+
def create_wallet(id = Zold::Id.new, dir = @dir)
|
54
|
+
wallet = Zold::Wallet.new(File.join(dir, id.to_s))
|
52
55
|
wallet.init(id, Zold::Key.new(file: File.join(__dir__, '../fixtures/id_rsa.pub')))
|
53
56
|
wallet
|
54
57
|
end
|
55
58
|
|
59
|
+
def create_wallet_json(id = Zold::Id.new)
|
60
|
+
require_relative '../lib/zold/score'
|
61
|
+
score = Zold::Score::ZERO
|
62
|
+
Dir.mktmpdir 'wallets' do |external_dir|
|
63
|
+
wallet = create_wallet(id, external_dir)
|
64
|
+
{
|
65
|
+
version: Zold::VERSION,
|
66
|
+
protocol: Zold::PROTOCOL,
|
67
|
+
id: wallet.id.to_s,
|
68
|
+
score: score.to_h,
|
69
|
+
wallets: 1,
|
70
|
+
mtime: wallet.mtime.utc.iso8601,
|
71
|
+
digest: wallet.digest,
|
72
|
+
balance: wallet.balance.to_i,
|
73
|
+
body: Zold::AtomicFile.new(wallet.path).read
|
74
|
+
}.to_json
|
75
|
+
end
|
76
|
+
end
|
77
|
+
|
56
78
|
def copies(wallet = create_wallet)
|
57
79
|
Zold::Copies.new(File.join(@dir, "copies/#{wallet.id}"))
|
58
80
|
end
|
59
81
|
|
60
82
|
def remotes
|
61
|
-
remotes = Zold::Remotes.new(File.join(@dir, 'secrets/remotes'))
|
83
|
+
remotes = Zold::Remotes.new(file: File.join(@dir, 'secrets/remotes'))
|
62
84
|
remotes.clean
|
63
85
|
remotes
|
64
86
|
end
|