baza.rb 0.8.0 → 0.9.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 +4 -4
- data/lib/baza-rb/version.rb +1 -1
- data/lib/baza-rb.rb +262 -337
- data/test/test_baza-rb.rb +51 -36
- metadata +1 -1
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 82a8cd1767f0f915a8345f5aa9ad79699b8a5a1d5f102cae9c77dd822d2a4e77
|
4
|
+
data.tar.gz: 15c9601e95620ccc4904c94e6e813cac13ea3b46aa398797433d03d9c5ccf219
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 92e9caded9b39f0194c79920b12a5d81ee3dbc0e21bace3ce8b7368ecea63ab9c7af739e02114f1cdff72337d09926ec3a7b8bbf5b2c60ebc65e88e7a17dd6da
|
7
|
+
data.tar.gz: e492fc6856487d474b58d869844e51b240f629572d5d4118df20926ba2cbab5ec116e3af4ddfa7b7586a3ba82d03667d240adcc66f319c3b0106d7698ea81c7c
|
data/lib/baza-rb/version.rb
CHANGED
data/lib/baza-rb.rb
CHANGED
@@ -68,15 +68,7 @@ class BazaRb
|
|
68
68
|
def whoami
|
69
69
|
nick = nil
|
70
70
|
elapsed(@loog) do
|
71
|
-
ret =
|
72
|
-
retry_it do
|
73
|
-
checked(
|
74
|
-
Typhoeus::Request.get(
|
75
|
-
home.append('whoami').to_s,
|
76
|
-
headers:
|
77
|
-
)
|
78
|
-
)
|
79
|
-
end
|
71
|
+
ret = get(home.append('whoami'))
|
80
72
|
nick = ret.body
|
81
73
|
throw :"I know that I am @#{nick}, at #{@host}"
|
82
74
|
end
|
@@ -90,15 +82,7 @@ class BazaRb
|
|
90
82
|
def balance
|
91
83
|
z = nil
|
92
84
|
elapsed(@loog) do
|
93
|
-
ret =
|
94
|
-
retry_it do
|
95
|
-
checked(
|
96
|
-
Typhoeus::Request.get(
|
97
|
-
home.append('account').append('balance').to_s,
|
98
|
-
headers:
|
99
|
-
)
|
100
|
-
)
|
101
|
-
end
|
85
|
+
ret = get(home.append('account').append('balance'))
|
102
86
|
z = ret.body.to_f
|
103
87
|
throw :"The balance is Ƶ#{z}, at #{@host}"
|
104
88
|
end
|
@@ -110,41 +94,27 @@ class BazaRb
|
|
110
94
|
# @param [String] name The unique name of the job on the server
|
111
95
|
# @param [String] data The binary data to push to the server (factbase content)
|
112
96
|
# @param [Array<String>] meta List of metadata strings to attach to the job
|
113
|
-
# @
|
97
|
+
# @param [Integer] chunk_size Maximum size of one chunk
|
114
98
|
# @raise [ServerFailure] If the push operation fails
|
115
|
-
def push(name, data, meta)
|
99
|
+
def push(name, data, meta, chunk_size: 1_000_000)
|
116
100
|
raise 'The "name" of the job is nil' if name.nil?
|
117
101
|
raise 'The "name" of the job may not be empty' if name.empty?
|
118
102
|
raise 'The "data" of the job is nil' if data.nil?
|
119
103
|
raise 'The "meta" of the job is nil' if meta.nil?
|
120
|
-
id = 0
|
121
|
-
hdrs = headers.merge(
|
122
|
-
'Content-Type' => 'application/octet-stream',
|
123
|
-
'Content-Length' => data.bytesize
|
124
|
-
)
|
125
|
-
unless meta.empty?
|
126
|
-
hdrs = hdrs.merge('X-Zerocracy-Meta' => meta.map { |v| Base64.encode64(v).delete("\n") }.join(' '))
|
127
|
-
end
|
128
|
-
params = {
|
129
|
-
connecttimeout: @timeout,
|
130
|
-
timeout: @timeout,
|
131
|
-
body: data,
|
132
|
-
headers: hdrs
|
133
|
-
}
|
134
104
|
elapsed(@loog) do
|
135
|
-
|
136
|
-
|
137
|
-
|
138
|
-
|
139
|
-
|
140
|
-
|
141
|
-
)
|
142
|
-
)
|
143
|
-
|
144
|
-
|
145
|
-
|
105
|
+
Tempfile.open do |file|
|
106
|
+
File.binwrite(file.path, data)
|
107
|
+
upload(
|
108
|
+
home.append('push').append(name),
|
109
|
+
file.path,
|
110
|
+
headers.merge(
|
111
|
+
'X-Zerocracy-Meta' => meta.map { |v| Base64.encode64(v).delete("\n") }.join(' ')
|
112
|
+
),
|
113
|
+
chunk_size:
|
114
|
+
)
|
115
|
+
end
|
116
|
+
throw :"Pushed #{data.bytesize} bytes to #{@host}"
|
146
117
|
end
|
147
|
-
id
|
148
118
|
end
|
149
119
|
|
150
120
|
# Pull factbase from the server for a specific job.
|
@@ -158,7 +128,7 @@ class BazaRb
|
|
158
128
|
data = ''
|
159
129
|
elapsed(@loog) do
|
160
130
|
Tempfile.open do |file|
|
161
|
-
download(home.append('pull').append("#{id}.fb")
|
131
|
+
download(home.append('pull').append("#{id}.fb"), file.path)
|
162
132
|
data = File.binread(file)
|
163
133
|
throw :"Pulled #{data.bytesize} bytes of job ##{id} factbase at #{@host}"
|
164
134
|
end
|
@@ -176,15 +146,7 @@ class BazaRb
|
|
176
146
|
raise 'The ID of the job must be a positive integer' unless id.positive?
|
177
147
|
fin = false
|
178
148
|
elapsed(@loog) do
|
179
|
-
ret =
|
180
|
-
retry_it do
|
181
|
-
checked(
|
182
|
-
Typhoeus::Request.get(
|
183
|
-
home.append('finished').append(id).to_s,
|
184
|
-
headers:
|
185
|
-
)
|
186
|
-
)
|
187
|
-
end
|
149
|
+
ret = get(home.append('finished').append(id))
|
188
150
|
fin = ret.body == 'yes'
|
189
151
|
throw :"The job ##{id} is #{'not yet ' unless fin}finished at #{@host}#{" (#{ret.body.inspect})" unless fin}"
|
190
152
|
end
|
@@ -195,20 +157,13 @@ class BazaRb
|
|
195
157
|
#
|
196
158
|
# @param [Integer] id The ID of the job on the server
|
197
159
|
# @return [String] The stdout, as a text
|
160
|
+
# @raise [ServerFailure] If the job doesn't exist or retrieval fails
|
198
161
|
def stdout(id)
|
199
162
|
raise 'The ID of the job is nil' if id.nil?
|
200
163
|
raise 'The ID of the job must be a positive integer' unless id.positive?
|
201
164
|
stdout = ''
|
202
165
|
elapsed(@loog) do
|
203
|
-
ret =
|
204
|
-
retry_it do
|
205
|
-
checked(
|
206
|
-
Typhoeus::Request.get(
|
207
|
-
home.append('stdout').append("#{id}.txt").to_s,
|
208
|
-
headers:
|
209
|
-
)
|
210
|
-
)
|
211
|
-
end
|
166
|
+
ret = get(home.append('stdout').append("#{id}.txt"))
|
212
167
|
stdout = ret.body
|
213
168
|
throw :"The stdout of the job ##{id} has #{stdout.split("\n").count} lines"
|
214
169
|
end
|
@@ -219,20 +174,13 @@ class BazaRb
|
|
219
174
|
#
|
220
175
|
# @param [Integer] id The ID of the job on the server
|
221
176
|
# @return [Integer] The exit code
|
177
|
+
# @raise [ServerFailure] If the job doesn't exist or retrieval fails
|
222
178
|
def exit_code(id)
|
223
179
|
raise 'The ID of the job is nil' if id.nil?
|
224
180
|
raise 'The ID of the job must be a positive integer' unless id.positive?
|
225
181
|
code = 0
|
226
182
|
elapsed(@loog) do
|
227
|
-
ret =
|
228
|
-
retry_it do
|
229
|
-
checked(
|
230
|
-
Typhoeus::Request.get(
|
231
|
-
home.append('exit').append("#{id}.txt").to_s,
|
232
|
-
headers:
|
233
|
-
)
|
234
|
-
)
|
235
|
-
end
|
183
|
+
ret = get(home.append('exit').append("#{id}.txt"))
|
236
184
|
code = ret.body.to_i
|
237
185
|
throw :"The exit code of the job ##{id} is #{code}"
|
238
186
|
end
|
@@ -243,20 +191,13 @@ class BazaRb
|
|
243
191
|
#
|
244
192
|
# @param [Integer] id The ID of the job on the server
|
245
193
|
# @return [String] The verdict
|
194
|
+
# @raise [ServerFailure] If the job doesn't exist or retrieval fails
|
246
195
|
def verified(id)
|
247
196
|
raise 'The ID of the job is nil' if id.nil?
|
248
197
|
raise 'The ID of the job must be a positive integer' unless id.positive?
|
249
198
|
verdict = ''
|
250
199
|
elapsed(@loog) do
|
251
|
-
ret =
|
252
|
-
retry_it do
|
253
|
-
checked(
|
254
|
-
Typhoeus::Request.get(
|
255
|
-
home.append('jobs').append(id).append('verified.txt').to_s,
|
256
|
-
headers:
|
257
|
-
)
|
258
|
-
)
|
259
|
-
end
|
200
|
+
ret = get(home.append('jobs').append(id).append('verified.txt'))
|
260
201
|
verdict = ret.body
|
261
202
|
throw :"The verdict of the job ##{id} is #{verdict.inspect}"
|
262
203
|
end
|
@@ -267,21 +208,18 @@ class BazaRb
|
|
267
208
|
#
|
268
209
|
# @param [String] name The name of the job on the server
|
269
210
|
# @param [String] owner The owner of the lock (any string)
|
211
|
+
# @raise [RuntimeError] If the name is already locked
|
212
|
+
# @raise [ServerFailure] If the lock operation fails
|
270
213
|
def lock(name, owner)
|
271
214
|
raise 'The "name" of the job is nil' if name.nil?
|
272
215
|
raise 'The "name" of the job may not be empty' if name.empty?
|
273
216
|
raise 'The "owner" of the lock is nil' if owner.nil?
|
274
217
|
elapsed(@loog) do
|
275
|
-
ret =
|
276
|
-
|
277
|
-
|
278
|
-
|
279
|
-
|
280
|
-
headers:
|
281
|
-
),
|
282
|
-
[302, 409]
|
283
|
-
)
|
284
|
-
end
|
218
|
+
ret = post(
|
219
|
+
home.append('lock').append(name),
|
220
|
+
{ 'owner' => owner },
|
221
|
+
[302, 409]
|
222
|
+
)
|
285
223
|
throw :"Job name '#{name}' locked at #{@host}" if ret.code == 302
|
286
224
|
raise "Failed to lock '#{name}' job at #{@host}, it's already locked"
|
287
225
|
end
|
@@ -291,21 +229,17 @@ class BazaRb
|
|
291
229
|
#
|
292
230
|
# @param [String] name The name of the job on the server
|
293
231
|
# @param [String] owner The owner of the lock (any string)
|
232
|
+
# @raise [ServerFailure] If the unlock operation fails
|
294
233
|
def unlock(name, owner)
|
295
234
|
raise 'The "name" of the job is nil' if name.nil?
|
296
235
|
raise 'The "name" of the job may not be empty' if name.empty?
|
297
236
|
raise 'The "owner" of the lock is nil' if owner.nil?
|
298
237
|
raise 'The "owner" of the lock may not be empty' if owner.empty?
|
299
238
|
elapsed(@loog) do
|
300
|
-
|
301
|
-
|
302
|
-
|
303
|
-
|
304
|
-
headers:
|
305
|
-
),
|
306
|
-
302
|
307
|
-
)
|
308
|
-
end
|
239
|
+
post(
|
240
|
+
home.append('unlock').append(name),
|
241
|
+
{ 'owner' => owner }
|
242
|
+
)
|
309
243
|
throw :"Job name '#{name}' unlocked at #{@host}"
|
310
244
|
end
|
311
245
|
end
|
@@ -314,20 +248,13 @@ class BazaRb
|
|
314
248
|
#
|
315
249
|
# @param [String] name The name of the job on the server
|
316
250
|
# @return [Integer] The ID of the job on the server
|
251
|
+
# @raise [ServerFailure] If the job doesn't exist or retrieval fails
|
317
252
|
def recent(name)
|
318
253
|
raise 'The "name" of the job is nil' if name.nil?
|
319
254
|
raise 'The "name" of the job may not be empty' if name.empty?
|
320
255
|
job = nil
|
321
256
|
elapsed(@loog) do
|
322
|
-
ret =
|
323
|
-
retry_it do
|
324
|
-
checked(
|
325
|
-
Typhoeus::Request.get(
|
326
|
-
home.append('recent').append("#{name}.txt").to_s,
|
327
|
-
headers:
|
328
|
-
)
|
329
|
-
)
|
330
|
-
end
|
257
|
+
ret = get(home.append('recent').append("#{name}.txt"))
|
331
258
|
job = ret.body.to_i
|
332
259
|
throw :"The recent \"#{name}\" job's ID is ##{job} at #{@host}"
|
333
260
|
end
|
@@ -343,15 +270,7 @@ class BazaRb
|
|
343
270
|
raise 'The "name" of the job may not be empty' if name.empty?
|
344
271
|
exists = false
|
345
272
|
elapsed(@loog) do
|
346
|
-
ret =
|
347
|
-
retry_it do
|
348
|
-
checked(
|
349
|
-
Typhoeus::Request.get(
|
350
|
-
home.append('exists').append(name).to_s,
|
351
|
-
headers:
|
352
|
-
)
|
353
|
-
)
|
354
|
-
end
|
273
|
+
ret = get(home.append('exists').append(name))
|
355
274
|
exists = ret.body == 'yes'
|
356
275
|
throw :"The name \"#{name}\" #{exists ? 'exists' : "doesn't exist"} at #{@host}"
|
357
276
|
end
|
@@ -362,9 +281,10 @@ class BazaRb
|
|
362
281
|
#
|
363
282
|
# @param [String] jname The name of the job on the server
|
364
283
|
# @param [String] file The path to the file to upload
|
284
|
+
# @param [Integer] chunk_size Maximum size of one chunk
|
365
285
|
# @return [Integer] The ID of the created durable
|
366
286
|
# @raise [ServerFailure] If the upload fails
|
367
|
-
def durable_place(jname, file)
|
287
|
+
def durable_place(jname, file, chunk_size: 1_000_000)
|
368
288
|
raise 'The "jname" of the durable is nil' if jname.nil?
|
369
289
|
raise 'The "jname" of the durable may not be empty' if jname.empty?
|
370
290
|
raise 'The "file" of the durable is nil' if file.nil?
|
@@ -373,30 +293,20 @@ class BazaRb
|
|
373
293
|
Tempfile.open do |f|
|
374
294
|
File.write(f.path, 'placeholder')
|
375
295
|
elapsed(@loog) do
|
376
|
-
ret =
|
377
|
-
|
378
|
-
|
379
|
-
|
380
|
-
|
381
|
-
|
382
|
-
|
383
|
-
|
384
|
-
'file' => File.basename(file),
|
385
|
-
'zip' => File.open(f, 'rb')
|
386
|
-
},
|
387
|
-
headers:,
|
388
|
-
connecttimeout: @timeout,
|
389
|
-
timeout: @timeout
|
390
|
-
),
|
391
|
-
302
|
392
|
-
)
|
393
|
-
end
|
296
|
+
ret = post(
|
297
|
+
home.append('durables').append('place'),
|
298
|
+
{
|
299
|
+
'jname' => jname,
|
300
|
+
'file' => File.basename(file),
|
301
|
+
'zip' => File.open(f, 'rb')
|
302
|
+
}
|
303
|
+
)
|
394
304
|
id = ret.headers['X-Zerocracy-DurableId'].to_i
|
395
|
-
throw :"Durable ##{id} (#{file}) placed for job \"#{jname}\" at #{@host}"
|
305
|
+
throw :"Durable ##{id} (#{file}, #{File.size(file)} bytes) placed for job \"#{jname}\" at #{@host}"
|
396
306
|
end
|
397
307
|
end
|
398
308
|
durable_lock(id, user_agent)
|
399
|
-
durable_save(id, file)
|
309
|
+
durable_save(id, file, chunk_size:)
|
400
310
|
durable_unlock(id, user_agent)
|
401
311
|
id
|
402
312
|
end
|
@@ -405,23 +315,15 @@ class BazaRb
|
|
405
315
|
#
|
406
316
|
# @param [Integer] id The ID of the durable
|
407
317
|
# @param [String] file The file to upload
|
408
|
-
|
318
|
+
# @param [Integer] chunk_size Maximum size of one chunk
|
319
|
+
# @raise [ServerFailure] If the save operation fails
|
320
|
+
def durable_save(id, file, chunk_size: 1_000_000)
|
409
321
|
raise 'The ID of the durable is nil' if id.nil?
|
410
322
|
raise 'The ID of the durable must be a positive integer' unless id.positive?
|
411
323
|
raise 'The "file" of the durable is nil' if file.nil?
|
412
324
|
raise "The file '#{file}' is absent" unless File.exist?(file)
|
413
325
|
elapsed(@loog) do
|
414
|
-
|
415
|
-
checked(
|
416
|
-
Typhoeus::Request.put(
|
417
|
-
home.append('durables').append(id).to_s,
|
418
|
-
body: File.binread(file),
|
419
|
-
headers:,
|
420
|
-
connecttimeout: @timeout,
|
421
|
-
timeout: @timeout
|
422
|
-
)
|
423
|
-
)
|
424
|
-
end
|
326
|
+
upload(home.append('durables').append(id), file, chunk_size:)
|
425
327
|
throw :"Durable ##{id} saved #{File.size(file)} bytes to #{@host}"
|
426
328
|
end
|
427
329
|
end
|
@@ -429,13 +331,14 @@ class BazaRb
|
|
429
331
|
# Load a single durable from server to local file.
|
430
332
|
#
|
431
333
|
# @param [Integer] id The ID of the durable
|
432
|
-
# @param [String] file The file to
|
334
|
+
# @param [String] file The local file path to save the downloaded durable
|
335
|
+
# @raise [ServerFailure] If the load operation fails
|
433
336
|
def durable_load(id, file)
|
434
337
|
raise 'The ID of the durable is nil' if id.nil?
|
435
338
|
raise 'The ID of the durable must be a positive integer' unless id.positive?
|
436
339
|
raise 'The "file" of the durable is nil' if file.nil?
|
437
340
|
elapsed(@loog) do
|
438
|
-
download(home.append('durables').append(id)
|
341
|
+
download(home.append('durables').append(id), file)
|
439
342
|
throw :"Durable ##{id} loaded #{File.size(file)} bytes from #{@host}"
|
440
343
|
end
|
441
344
|
end
|
@@ -444,21 +347,17 @@ class BazaRb
|
|
444
347
|
#
|
445
348
|
# @param [Integer] id The ID of the durable
|
446
349
|
# @param [String] owner The owner of the lock
|
350
|
+
# @raise [ServerFailure] If the lock operation fails
|
447
351
|
def durable_lock(id, owner)
|
448
352
|
raise 'The ID of the durable is nil' if id.nil?
|
449
353
|
raise 'The ID of the durable must be a positive integer' unless id.positive?
|
450
354
|
raise 'The "owner" of the lock is nil' if owner.nil?
|
451
355
|
raise 'The "owner" of the lock may not be empty' if owner.empty?
|
452
356
|
elapsed(@loog) do
|
453
|
-
|
454
|
-
|
455
|
-
|
456
|
-
|
457
|
-
headers:
|
458
|
-
),
|
459
|
-
302
|
460
|
-
)
|
461
|
-
end
|
357
|
+
post(
|
358
|
+
home.append('durables').append(id).append('lock'),
|
359
|
+
{ 'owner' => owner }
|
360
|
+
)
|
462
361
|
throw :"Durable ##{id} locked at #{@host}"
|
463
362
|
end
|
464
363
|
end
|
@@ -467,21 +366,17 @@ class BazaRb
|
|
467
366
|
#
|
468
367
|
# @param [Integer] id The ID of the durable
|
469
368
|
# @param [String] owner The owner of the lock
|
369
|
+
# @raise [ServerFailure] If the unlock operation fails
|
470
370
|
def durable_unlock(id, owner)
|
471
371
|
raise 'The ID of the durable is nil' if id.nil?
|
472
372
|
raise 'The ID of the durable must be a positive integer' unless id.positive?
|
473
373
|
raise 'The "owner" of the lock is nil' if owner.nil?
|
474
374
|
raise 'The "owner" of the lock may not be empty' if owner.empty?
|
475
375
|
elapsed(@loog) do
|
476
|
-
|
477
|
-
|
478
|
-
|
479
|
-
|
480
|
-
headers:
|
481
|
-
),
|
482
|
-
302
|
483
|
-
)
|
484
|
-
end
|
376
|
+
post(
|
377
|
+
home.append('durables').append(id).append('unlock'),
|
378
|
+
{ 'owner' => owner }
|
379
|
+
)
|
485
380
|
throw :"Durable ##{id} unlocked at #{@host}"
|
486
381
|
end
|
487
382
|
end
|
@@ -498,16 +393,7 @@ class BazaRb
|
|
498
393
|
raise 'The "file" may not be empty' if file.empty?
|
499
394
|
id = nil
|
500
395
|
elapsed(@loog) do
|
501
|
-
ret =
|
502
|
-
retry_it do
|
503
|
-
checked(
|
504
|
-
Typhoeus::Request.get(
|
505
|
-
home.append('durables').append('find').add(jname:, file:).to_s,
|
506
|
-
headers:
|
507
|
-
),
|
508
|
-
[200, 404]
|
509
|
-
)
|
510
|
-
end
|
396
|
+
ret = get(home.append('durables').append('find').add(jname:, file:), [200, 404])
|
511
397
|
if ret.code == 200
|
512
398
|
id = ret.body.to_i
|
513
399
|
throw :"Found durable ##{id} for job \"#{jname}\" file \"#{file}\" at #{@host}"
|
@@ -533,26 +419,16 @@ class BazaRb
|
|
533
419
|
raise 'The "summary" is nil' if summary.nil?
|
534
420
|
id = nil
|
535
421
|
body = {
|
536
|
-
'_csrf' => csrf,
|
537
422
|
'human' => recipient,
|
538
423
|
'amount' => format('%0.6f', amount),
|
539
424
|
'summary' => summary
|
540
425
|
}
|
541
426
|
body['job'] = job unless job.nil?
|
542
427
|
elapsed(@loog) do
|
543
|
-
ret =
|
544
|
-
|
545
|
-
|
546
|
-
|
547
|
-
home.append('account').append('transfer').to_s,
|
548
|
-
body:,
|
549
|
-
headers:,
|
550
|
-
connecttimeout: @timeout,
|
551
|
-
timeout: @timeout
|
552
|
-
),
|
553
|
-
302
|
554
|
-
)
|
555
|
-
end
|
428
|
+
ret = post(
|
429
|
+
home.append('account').append('transfer'),
|
430
|
+
body
|
431
|
+
)
|
556
432
|
id = ret.headers['X-Zerocracy-ReceiptId'].to_i
|
557
433
|
throw :"Transferred Ƶ#{format('%0.6f', amount)} to @#{recipient} at #{@host}"
|
558
434
|
end
|
@@ -575,27 +451,16 @@ class BazaRb
|
|
575
451
|
raise 'The "job" must be Integer' unless job.is_a?(Integer)
|
576
452
|
raise 'The "summary" is nil' if summary.nil?
|
577
453
|
id = nil
|
578
|
-
body = {
|
579
|
-
'_csrf' => csrf,
|
580
|
-
'tab' => tab,
|
581
|
-
'amount' => format('%0.6f', amount),
|
582
|
-
'summary' => summary,
|
583
|
-
'job' => job.to_s
|
584
|
-
}
|
585
454
|
elapsed(@loog) do
|
586
|
-
ret =
|
587
|
-
|
588
|
-
|
589
|
-
|
590
|
-
|
591
|
-
|
592
|
-
|
593
|
-
|
594
|
-
|
595
|
-
),
|
596
|
-
302
|
597
|
-
)
|
598
|
-
end
|
455
|
+
ret = post(
|
456
|
+
home.append('account').append('fee'),
|
457
|
+
{
|
458
|
+
'tab' => tab,
|
459
|
+
'amount' => format('%0.6f', amount),
|
460
|
+
'summary' => summary,
|
461
|
+
'job' => job.to_s
|
462
|
+
}
|
463
|
+
)
|
599
464
|
id = ret.headers['X-Zerocracy-ReceiptId'].to_i
|
600
465
|
throw :"Fee Ƶ#{format('%0.6f', amount)} paid at #{@host}"
|
601
466
|
end
|
@@ -612,16 +477,7 @@ class BazaRb
|
|
612
477
|
success = false
|
613
478
|
elapsed(@loog) do
|
614
479
|
uri = home.append('pop').add(owner:)
|
615
|
-
ret =
|
616
|
-
retry_it do
|
617
|
-
checked(
|
618
|
-
Typhoeus::Request.get(
|
619
|
-
uri.to_s,
|
620
|
-
headers:
|
621
|
-
),
|
622
|
-
[204, 302]
|
623
|
-
)
|
624
|
-
end
|
480
|
+
ret = get(uri, [204, 302])
|
625
481
|
if ret.code == 204
|
626
482
|
FileUtils.rm_f(zip)
|
627
483
|
throw :"Nothing to pop at #{uri}"
|
@@ -647,20 +503,7 @@ class BazaRb
|
|
647
503
|
raise 'The "zip" of the job is nil' if zip.nil?
|
648
504
|
raise "The 'zip' file is absent: #{zip}" unless File.exist?(zip)
|
649
505
|
elapsed(@loog) do
|
650
|
-
|
651
|
-
checked(
|
652
|
-
Typhoeus::Request.put(
|
653
|
-
home.append('finish').add(id:).to_s,
|
654
|
-
connecttimeout: @timeout,
|
655
|
-
timeout: @timeout,
|
656
|
-
body: File.binread(zip),
|
657
|
-
headers: headers.merge(
|
658
|
-
'Content-Type' => 'application/octet-stream',
|
659
|
-
'Content-Length' => File.size(zip)
|
660
|
-
)
|
661
|
-
)
|
662
|
-
)
|
663
|
-
end
|
506
|
+
upload(home.append('finish').add(id:), zip)
|
664
507
|
throw :"Pushed #{File.size(zip)} bytes to #{@host}, finished job ##{id}"
|
665
508
|
end
|
666
509
|
end
|
@@ -681,30 +524,19 @@ class BazaRb
|
|
681
524
|
def enter(name, badge, why, job)
|
682
525
|
elapsed(@loog, intro: "Entered valve #{badge} to #{name}") do
|
683
526
|
retry_it do
|
684
|
-
ret =
|
685
|
-
Typhoeus::Request.get(
|
686
|
-
home.append('valves').append('result').add(badge:).to_s,
|
687
|
-
headers:
|
688
|
-
),
|
689
|
-
[200, 204]
|
690
|
-
)
|
527
|
+
ret = get(home.append('valves').append('result').add(badge:), [200, 204])
|
691
528
|
return ret.body if ret.code == 200
|
692
529
|
r = yield
|
693
530
|
uri = home.append('valves').append('add')
|
694
531
|
uri = uri.add(job:) unless job.nil?
|
695
|
-
|
696
|
-
|
697
|
-
|
698
|
-
|
699
|
-
|
700
|
-
|
701
|
-
|
702
|
-
|
703
|
-
'result' => r.to_s
|
704
|
-
},
|
705
|
-
headers:
|
706
|
-
),
|
707
|
-
302
|
532
|
+
post(
|
533
|
+
uri,
|
534
|
+
{
|
535
|
+
'name' => name,
|
536
|
+
'badge' => badge,
|
537
|
+
'why' => why,
|
538
|
+
'result' => r.to_s
|
539
|
+
}
|
708
540
|
)
|
709
541
|
r
|
710
542
|
end
|
@@ -721,15 +553,7 @@ class BazaRb
|
|
721
553
|
def csrf
|
722
554
|
token = nil
|
723
555
|
elapsed(@loog) do
|
724
|
-
|
725
|
-
token = checked(
|
726
|
-
Typhoeus::Request.get(
|
727
|
-
home.append('csrf').to_s,
|
728
|
-
headers:
|
729
|
-
),
|
730
|
-
200
|
731
|
-
).body
|
732
|
-
end
|
556
|
+
token = get(home.append('csrf')).body
|
733
557
|
throw :"CSRF token retrieved (#{token.length} chars)"
|
734
558
|
end
|
735
559
|
token
|
@@ -737,10 +561,16 @@ class BazaRb
|
|
737
561
|
|
738
562
|
private
|
739
563
|
|
564
|
+
# Get the user agent string for HTTP requests.
|
565
|
+
#
|
566
|
+
# @return [String] The user agent string
|
740
567
|
def user_agent
|
741
568
|
"baza.rb #{BazaRb::VERSION}"
|
742
569
|
end
|
743
570
|
|
571
|
+
# Get default headers for HTTP requests.
|
572
|
+
#
|
573
|
+
# @return [Hash] The default headers including User-Agent, Connection, and authentication token
|
744
574
|
def headers
|
745
575
|
{
|
746
576
|
'User-Agent' => user_agent,
|
@@ -749,8 +579,26 @@ class BazaRb
|
|
749
579
|
}
|
750
580
|
end
|
751
581
|
|
582
|
+
# Decompress gzipped data.
|
583
|
+
#
|
584
|
+
# @param [String] data The gzipped data to decompress
|
585
|
+
# @return [String] The decompressed data
|
586
|
+
def unzip(data)
|
587
|
+
io = StringIO.new(data)
|
588
|
+
gz = Zlib::GzipReader.new(io)
|
589
|
+
gz.read
|
590
|
+
end
|
591
|
+
|
592
|
+
# Compress request parameters with gzip.
|
593
|
+
#
|
594
|
+
# @param [Hash] params The request parameters with :body and :headers keys
|
595
|
+
# @return [Hash] The modified parameters with compressed body and updated headers
|
752
596
|
def zipped(params)
|
753
|
-
|
597
|
+
io = StringIO.new
|
598
|
+
gz = Zlib::GzipWriter.new(io)
|
599
|
+
gz.write(params.fetch(:body))
|
600
|
+
gz.close
|
601
|
+
body = io.string
|
754
602
|
headers = params
|
755
603
|
.fetch(:headers)
|
756
604
|
.merge(
|
@@ -763,15 +611,9 @@ class BazaRb
|
|
763
611
|
params.merge(body:, headers:)
|
764
612
|
end
|
765
613
|
|
766
|
-
|
767
|
-
|
768
|
-
|
769
|
-
gz = Zlib::GzipWriter.new(io)
|
770
|
-
gz.write(data)
|
771
|
-
gz.close
|
772
|
-
end
|
773
|
-
end
|
774
|
-
|
614
|
+
# Build the base URI for API requests.
|
615
|
+
#
|
616
|
+
# @return [Iri] The base URI object
|
775
617
|
def home
|
776
618
|
Iri.new('')
|
777
619
|
.host(@host)
|
@@ -779,6 +621,10 @@ class BazaRb
|
|
779
621
|
.scheme(@ssl ? 'https' : 'http')
|
780
622
|
end
|
781
623
|
|
624
|
+
# Execute a block with retries on timeout.
|
625
|
+
#
|
626
|
+
# @yield The block to execute with retries
|
627
|
+
# @return [Object] The result of the block execution
|
782
628
|
def retry_it(&)
|
783
629
|
with_retries(max_tries: @retries, rescue: TimedOut, &)
|
784
630
|
end
|
@@ -831,89 +677,168 @@ class BazaRb
|
|
831
677
|
raise ServerFailure, msg
|
832
678
|
end
|
833
679
|
|
834
|
-
#
|
835
|
-
#
|
836
|
-
# @param [
|
680
|
+
# Make a GET request.
|
681
|
+
#
|
682
|
+
# @param [Iri] uri The URI to send the request to
|
683
|
+
# @param [Array<Integer>] allowed List of allowed HTTP response codes
|
684
|
+
# @return [Typhoeus::Response] The HTTP response
|
685
|
+
# @raise [ServerFailure] If the response code is not in the allowed list
|
686
|
+
def get(uri, allowed = [200])
|
687
|
+
retry_it do
|
688
|
+
checked(
|
689
|
+
Typhoeus::Request.get(
|
690
|
+
uri.to_s,
|
691
|
+
headers:,
|
692
|
+
connecttimeout: @timeout,
|
693
|
+
timeout: @timeout
|
694
|
+
),
|
695
|
+
allowed
|
696
|
+
)
|
697
|
+
end
|
698
|
+
end
|
699
|
+
|
700
|
+
# Make a POST request.
|
701
|
+
#
|
702
|
+
# @param [Iri] uri The URI to send the request to
|
703
|
+
# @param [Hash] params The request parameters to send in the body
|
704
|
+
# @param [Array<Integer>] allowed List of allowed HTTP response codes
|
705
|
+
# @return [Typhoeus::Response] The HTTP response
|
706
|
+
# @raise [ServerFailure] If the response code is not in the allowed list
|
707
|
+
def post(uri, params, allowed = [302])
|
708
|
+
retry_it do
|
709
|
+
checked(
|
710
|
+
Typhoeus::Request.post(
|
711
|
+
uri.to_s,
|
712
|
+
body: params.merge('_csrf' => csrf),
|
713
|
+
headers:,
|
714
|
+
connecttimeout: @timeout,
|
715
|
+
timeout: @timeout
|
716
|
+
),
|
717
|
+
allowed
|
718
|
+
)
|
719
|
+
end
|
720
|
+
end
|
721
|
+
|
722
|
+
# Download file via GET, using range requests for large files.
|
723
|
+
#
|
724
|
+
# @param [Iri] uri The URI to download from
|
725
|
+
# @param [String] file The local file path to save to
|
726
|
+
# @raise [ServerFailure] If the download fails
|
837
727
|
def download(uri, file)
|
838
|
-
raise 'The "file" is nil' if file.nil?
|
839
728
|
FileUtils.mkdir_p(File.dirname(file))
|
729
|
+
FileUtils.rm_f(file)
|
730
|
+
chunk = 0
|
840
731
|
elapsed(@loog) do
|
841
|
-
|
842
|
-
|
843
|
-
|
844
|
-
|
845
|
-
|
846
|
-
|
847
|
-
|
848
|
-
|
849
|
-
|
850
|
-
|
851
|
-
|
852
|
-
|
853
|
-
|
854
|
-
|
855
|
-
|
856
|
-
|
857
|
-
|
858
|
-
|
859
|
-
|
860
|
-
|
861
|
-
|
862
|
-
|
863
|
-
|
864
|
-
|
865
|
-
|
866
|
-
|
867
|
-
|
868
|
-
|
869
|
-
|
870
|
-
|
871
|
-
|
872
|
-
|
732
|
+
pos = 0
|
733
|
+
loop do
|
734
|
+
request = Typhoeus::Request.new(
|
735
|
+
uri.to_s,
|
736
|
+
method: :get,
|
737
|
+
headers: headers.merge(
|
738
|
+
'Accept' => 'application/octet-stream',
|
739
|
+
'Accept-Encoding' => 'gzip',
|
740
|
+
'Range' => "bytes=#{pos}-"
|
741
|
+
),
|
742
|
+
connecttimeout: @timeout,
|
743
|
+
timeout: @timeout
|
744
|
+
)
|
745
|
+
slice = ''
|
746
|
+
request.on_body do |data|
|
747
|
+
slice = data
|
748
|
+
end
|
749
|
+
retry_it do
|
750
|
+
request.run
|
751
|
+
end
|
752
|
+
ret = request.response
|
753
|
+
msg = [
|
754
|
+
"GET #{uri.to_uri.path} #{ret.code}",
|
755
|
+
"#{slice.bytesize} bytes",
|
756
|
+
('in gzip' if ret.headers['Content-Encoding'] == 'gzip'),
|
757
|
+
("ranged as #{ret.headers['Content-Range'].inspect}" if ret.headers['Content-Range'])
|
758
|
+
]
|
759
|
+
checked(ret, [200, 206])
|
760
|
+
if ret.headers['Content-Encoding'] == 'gzip'
|
761
|
+
slice = unzip(slice)
|
762
|
+
msg << "unzipped to #{slice.bytesize} bytes"
|
763
|
+
end
|
764
|
+
File.open(file, 'ab') do |f|
|
765
|
+
f.write(slice)
|
873
766
|
end
|
767
|
+
@loog.debug(msg.compact.join(', '))
|
768
|
+
break if ret.code == 200
|
769
|
+
_, v = ret.headers['Content-Range'].split
|
770
|
+
range, total = v.split('/')
|
771
|
+
raise "Total size is not valid (#{total.inspect})" unless total.match?(/^\*|[0-9]+$/)
|
772
|
+
_b, e = range.split('-')
|
773
|
+
raise "Range is not valid (#{range.inspect})" unless e.match?(/^[0-9]+$/)
|
774
|
+
len = ret.headers['Content-Length'].to_i
|
775
|
+
pos = e.to_i
|
776
|
+
pos += 1 unless len.zero?
|
777
|
+
break if e.to_i == total.to_i - 1
|
778
|
+
chunk += 1
|
779
|
+
sleep(1) if len.zero?
|
874
780
|
end
|
875
|
-
throw :"Downloaded #{File.size(file)} bytes from #{uri}"
|
781
|
+
throw :"Downloaded #{File.size(file)} bytes in #{chunk + 1} chunks from #{uri}"
|
876
782
|
end
|
877
783
|
end
|
878
784
|
|
879
|
-
# Upload file via PUT,
|
880
|
-
#
|
881
|
-
# @param [
|
882
|
-
# @param [
|
883
|
-
|
884
|
-
|
885
|
-
|
785
|
+
# Upload file via PUT, using chunked uploads for large files.
|
786
|
+
#
|
787
|
+
# @param [Iri] uri The URI to upload to
|
788
|
+
# @param [String] file The local file path to upload from
|
789
|
+
# @param [Hash] extra Hash of extra HTTP headers to include
|
790
|
+
# @param [Integer] chunk_size Maximum size of each chunk in bytes
|
791
|
+
# @raise [ServerFailure] If the upload fails
|
792
|
+
def upload(uri, file, extra = {}, chunk_size: 1_000_000)
|
886
793
|
params = {
|
887
794
|
connecttimeout: @timeout,
|
888
795
|
timeout: @timeout,
|
889
|
-
|
890
|
-
headers: headers.merge(
|
796
|
+
headers: headers.merge(extra).merge(
|
891
797
|
'Content-Type' => 'application/octet-stream'
|
892
798
|
)
|
893
799
|
}
|
894
|
-
|
800
|
+
total = File.size(file)
|
895
801
|
chunk = 0
|
802
|
+
sent = 0
|
896
803
|
elapsed(@loog) do
|
897
|
-
params[:headers]['X-Zerocracy-Chunk'] = chunk.to_s
|
898
804
|
loop do
|
899
|
-
|
900
|
-
|
901
|
-
|
902
|
-
|
903
|
-
|
805
|
+
slice =
|
806
|
+
if total > chunk_size
|
807
|
+
File.open(file, 'rb') do |f|
|
808
|
+
params[:headers]['X-Zerocracy-Chunk'] = chunk.to_s
|
809
|
+
f.seek(chunk_size * chunk)
|
810
|
+
f.read(chunk_size) || ''
|
811
|
+
end
|
812
|
+
else
|
813
|
+
File.binread(file)
|
814
|
+
end
|
815
|
+
params[:body] = slice
|
816
|
+
params[:headers]['Content-Length'] = slice.bytesize
|
817
|
+
params = zipped(params) if @compress
|
818
|
+
ret =
|
904
819
|
retry_it do
|
905
820
|
checked(
|
906
821
|
Typhoeus::Request.put(
|
907
822
|
uri.to_s,
|
908
|
-
|
823
|
+
params
|
909
824
|
)
|
910
825
|
)
|
911
826
|
end
|
912
|
-
|
913
|
-
|
827
|
+
sent += params[:body].bytesize
|
828
|
+
@loog.debug(
|
829
|
+
[
|
830
|
+
"PUT #{uri.to_uri.path} #{ret.code}",
|
831
|
+
("gzipped #{slice.bytesize} bytes" if params[:headers]['Content-Encoding'] == 'gzip'),
|
832
|
+
"sent #{params[:body].bytesize} bytes",
|
833
|
+
("chunk ##{chunk}" if params[:headers]['X-Zerocracy-Chunk']),
|
834
|
+
('no chunks' unless params[:headers]['X-Zerocracy-Chunk'])
|
835
|
+
].compact.join(', ')
|
836
|
+
)
|
837
|
+
break if slice.empty?
|
838
|
+
break if total <= chunk_size
|
914
839
|
chunk += 1
|
915
840
|
end
|
916
|
-
throw :"Uploaded #{
|
841
|
+
throw :"Uploaded #{sent} bytes to #{uri}#{" in #{chunk + 1} chunks" if chunk.positive?}"
|
917
842
|
end
|
918
843
|
end
|
919
844
|
end
|
data/test/test_baza-rb.rb
CHANGED
@@ -40,7 +40,7 @@ class TestBazaRb < Minitest::Test
|
|
40
40
|
fb.insert.foo = 'test-' * 10_000
|
41
41
|
fb.insert
|
42
42
|
n = fake_name
|
43
|
-
|
43
|
+
LIVE.push(n, fb.export, [])
|
44
44
|
assert(LIVE.name_exists?(n))
|
45
45
|
assert_predicate(LIVE.recent(n), :positive?)
|
46
46
|
id = LIVE.recent(n)
|
@@ -86,15 +86,16 @@ class TestBazaRb < Minitest::Test
|
|
86
86
|
fb.insert.foo = 'test-' * 10_000
|
87
87
|
fb.insert
|
88
88
|
baza = BazaRb.new(HOST, PORT, TOKEN, compress: false)
|
89
|
-
|
89
|
+
baza.push(fake_name, fb.export, [])
|
90
90
|
end
|
91
91
|
|
92
92
|
def test_live_durable_lock_unlock
|
93
93
|
WebMock.enable_net_connect!
|
94
94
|
skip('We are offline') unless we_are_online
|
95
95
|
Dir.mktmpdir do |dir|
|
96
|
-
file = File.join(dir,
|
97
|
-
|
96
|
+
file = File.join(dir, 'before.bin')
|
97
|
+
before = 'hello, Джеф!' * 10
|
98
|
+
File.binwrite(file, before)
|
98
99
|
jname = fake_name
|
99
100
|
refute(LIVE.durable_find(jname, File.basename(file)))
|
100
101
|
id = LIVE.durable_place(jname, file)
|
@@ -102,7 +103,12 @@ class TestBazaRb < Minitest::Test
|
|
102
103
|
owner = fake_name
|
103
104
|
LIVE.durable_lock(id, owner)
|
104
105
|
LIVE.durable_load(id, file)
|
106
|
+
assert_equal(before, File.binread(file).force_encoding('UTF-8'))
|
107
|
+
after = 'привет, друг!'
|
108
|
+
File.binwrite(file, after)
|
105
109
|
LIVE.durable_save(id, file)
|
110
|
+
LIVE.durable_load(id, file)
|
111
|
+
assert_equal(after, File.binread(file).force_encoding('UTF-8'))
|
106
112
|
LIVE.durable_unlock(id, owner)
|
107
113
|
end
|
108
114
|
end
|
@@ -169,25 +175,36 @@ class TestBazaRb < Minitest::Test
|
|
169
175
|
|
170
176
|
def test_unlocks_job_by_name
|
171
177
|
WebMock.disable_net_connect!
|
172
|
-
stub_request(:get, 'https://example.org/
|
178
|
+
stub_request(:get, 'https://example.org/csrf').to_return(body: 'token')
|
179
|
+
stub_request(:post, %r{https://example.org/unlock/foo}).to_return(status: 302)
|
173
180
|
assert(fake_baza.unlock('foo', 'x'))
|
174
181
|
end
|
175
182
|
|
176
183
|
def test_durable_place
|
177
184
|
WebMock.disable_net_connect!
|
178
|
-
|
179
|
-
|
180
|
-
|
181
|
-
|
182
|
-
|
183
|
-
|
184
|
-
|
185
|
-
|
186
|
-
|
187
|
-
|
188
|
-
|
189
|
-
|
190
|
-
|
185
|
+
[fake_baza(compress: true), fake_baza(compress: false)].each do |baza|
|
186
|
+
stub_request(:get, 'https://example.org/csrf').to_return(body: 'token')
|
187
|
+
stub_request(:post, 'https://example.org/durables/place').to_return(
|
188
|
+
status: 302, headers: { 'X-Zerocracy-DurableId' => '42' }
|
189
|
+
)
|
190
|
+
stub_request(:post, %r{https://example\.org/durables/42/lock})
|
191
|
+
.to_return(status: 302)
|
192
|
+
stub_request(:post, %r{https://example\.org/durables/42/unlock})
|
193
|
+
.to_return(status: 302)
|
194
|
+
stub_request(:put, 'https://example.org/durables/42')
|
195
|
+
.with(headers: { 'X-Zerocracy-Chunk' => '0' })
|
196
|
+
.to_return(status: 200)
|
197
|
+
stub_request(:put, 'https://example.org/durables/42')
|
198
|
+
.with(headers: { 'X-Zerocracy-Chunk' => '1' })
|
199
|
+
.to_return(status: 200)
|
200
|
+
stub_request(:put, 'https://example.org/durables/42')
|
201
|
+
.with(headers: { 'X-Zerocracy-Chunk' => '2' })
|
202
|
+
.to_return(status: 200)
|
203
|
+
Dir.mktmpdir do |dir|
|
204
|
+
file = File.join(dir, 'test.bin')
|
205
|
+
File.binwrite(file, 'hello, world!')
|
206
|
+
assert_equal(42, baza.durable_place('simple', file, chunk_size: 8))
|
207
|
+
end
|
191
208
|
end
|
192
209
|
end
|
193
210
|
|
@@ -196,10 +213,7 @@ class TestBazaRb < Minitest::Test
|
|
196
213
|
stub_request(:put, 'https://example.org/push/simple').to_return(
|
197
214
|
status: 200, body: '42'
|
198
215
|
)
|
199
|
-
|
200
|
-
42,
|
201
|
-
fake_baza.push('simple', 'hello, world!', [])
|
202
|
-
)
|
216
|
+
fake_baza.push('simple', 'hello, world!', [])
|
203
217
|
end
|
204
218
|
|
205
219
|
def test_simple_pop_with_no_job_found
|
@@ -226,7 +240,7 @@ class TestBazaRb < Minitest::Test
|
|
226
240
|
.with(query: { job: })
|
227
241
|
.to_return(
|
228
242
|
status: 206,
|
229
|
-
headers: { 'Content-Range' => 'bytes 0-0/*', '
|
243
|
+
headers: { 'Content-Range' => 'bytes 0-0/*', 'Content-Length' => 0 },
|
230
244
|
body: ''
|
231
245
|
)
|
232
246
|
bin = nil
|
@@ -240,7 +254,6 @@ class TestBazaRb < Minitest::Test
|
|
240
254
|
status: 206,
|
241
255
|
headers: {
|
242
256
|
'Content-Range' => "bytes 0-7/#{bin.size}",
|
243
|
-
'X-Zerocracy-JobId' => job,
|
244
257
|
'Content-Length' => 8
|
245
258
|
},
|
246
259
|
body: bin[0..7]
|
@@ -252,7 +265,6 @@ class TestBazaRb < Minitest::Test
|
|
252
265
|
status: 206,
|
253
266
|
headers: {
|
254
267
|
'Content-Range' => "bytes 8-#{bin.size - 1}/#{bin.size}",
|
255
|
-
'X-Zerocracy-JobId' => job,
|
256
268
|
'Content-Length' => bin.size - 8
|
257
269
|
},
|
258
270
|
body: bin[8..]
|
@@ -317,7 +329,7 @@ class TestBazaRb < Minitest::Test
|
|
317
329
|
def test_simple_pull
|
318
330
|
WebMock.disable_net_connect!
|
319
331
|
stub_request(:get, 'https://example.org/pull/333.fb').to_return(
|
320
|
-
status: 200, body: 'hello, world!'
|
332
|
+
status: 200, body: 'hello, world!', headers: {}
|
321
333
|
)
|
322
334
|
assert(
|
323
335
|
fake_baza.pull(333).start_with?('hello')
|
@@ -326,13 +338,15 @@ class TestBazaRb < Minitest::Test
|
|
326
338
|
|
327
339
|
def test_simple_lock_success
|
328
340
|
WebMock.disable_net_connect!
|
329
|
-
stub_request(:get, 'https://example.org/
|
341
|
+
stub_request(:get, 'https://example.org/csrf').to_return(body: 'token')
|
342
|
+
stub_request(:post, %r{https://example.org/lock/name}).to_return(status: 302)
|
330
343
|
fake_baza.lock('name', 'owner')
|
331
344
|
end
|
332
345
|
|
333
346
|
def test_simple_lock_failure
|
334
347
|
WebMock.disable_net_connect!
|
335
|
-
stub_request(:get, 'https://example.org/
|
348
|
+
stub_request(:get, 'https://example.org/csrf').to_return(body: 'token')
|
349
|
+
stub_request(:post, %r{https://example.org/lock/name}).to_return(status: 409)
|
336
350
|
assert_raises(StandardError) do
|
337
351
|
fake_baza.lock('name', 'owner')
|
338
352
|
end
|
@@ -446,7 +460,7 @@ class TestBazaRb < Minitest::Test
|
|
446
460
|
file = File.join(dir, 'test.txt')
|
447
461
|
File.write(file, 'test content')
|
448
462
|
stub_request(:put, 'https://example.org:443/durables/42')
|
449
|
-
.with(headers: { 'X-Zerocracy-Token' => '000' }
|
463
|
+
.with(headers: { 'X-Zerocracy-Token' => '000' })
|
450
464
|
.to_return(status: 200)
|
451
465
|
fake_baza.durable_save(42, file)
|
452
466
|
end
|
@@ -458,7 +472,7 @@ class TestBazaRb < Minitest::Test
|
|
458
472
|
file = File.join(dir, 'loaded.txt')
|
459
473
|
stub_request(:get, 'https://example.org:443/durables/42')
|
460
474
|
.with(headers: { 'X-Zerocracy-Token' => '000' })
|
461
|
-
.to_return(status: 200, body: 'loaded content')
|
475
|
+
.to_return(status: 200, body: 'loaded content', headers: {})
|
462
476
|
fake_baza.durable_load(42, file)
|
463
477
|
assert_equal('loaded content', File.read(file))
|
464
478
|
end
|
@@ -466,7 +480,8 @@ class TestBazaRb < Minitest::Test
|
|
466
480
|
|
467
481
|
def test_durable_lock
|
468
482
|
WebMock.disable_net_connect!
|
469
|
-
stub_request(:get, 'https://example.org
|
483
|
+
stub_request(:get, 'https://example.org/csrf').to_return(body: 'token')
|
484
|
+
stub_request(:post, %r{https://example.org:443/durables/42/lock})
|
470
485
|
.with(headers: { 'X-Zerocracy-Token' => '000' })
|
471
486
|
.to_return(status: 302)
|
472
487
|
fake_baza.durable_lock(42, 'test-owner')
|
@@ -474,7 +489,8 @@ class TestBazaRb < Minitest::Test
|
|
474
489
|
|
475
490
|
def test_durable_unlock
|
476
491
|
WebMock.disable_net_connect!
|
477
|
-
stub_request(:get, 'https://example.org
|
492
|
+
stub_request(:get, 'https://example.org/csrf').to_return(body: 'token')
|
493
|
+
stub_request(:post, %r{https://example.org:443/durables/42/unlock})
|
478
494
|
.with(headers: { 'X-Zerocracy-Token' => '000' })
|
479
495
|
.to_return(status: 302)
|
480
496
|
fake_baza.durable_unlock(42, 'test-owner')
|
@@ -630,8 +646,7 @@ class TestBazaRb < Minitest::Test
|
|
630
646
|
body: 'data'
|
631
647
|
)
|
632
648
|
.to_return(status: 200, body: '123')
|
633
|
-
|
634
|
-
assert_equal(123, id)
|
649
|
+
baza.push('test', 'data', [])
|
635
650
|
end
|
636
651
|
|
637
652
|
private
|
@@ -663,8 +678,8 @@ class TestBazaRb < Minitest::Test
|
|
663
678
|
req
|
664
679
|
end
|
665
680
|
|
666
|
-
def fake_baza
|
667
|
-
BazaRb.new('example.org', 443, '000', loog: Loog::NULL)
|
681
|
+
def fake_baza(compress: true)
|
682
|
+
BazaRb.new('example.org', 443, '000', loog: Loog::NULL, compress:)
|
668
683
|
end
|
669
684
|
|
670
685
|
def fake_name
|