baza.rb 0.9.0 → 0.9.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: 82a8cd1767f0f915a8345f5aa9ad79699b8a5a1d5f102cae9c77dd822d2a4e77
4
- data.tar.gz: 15c9601e95620ccc4904c94e6e813cac13ea3b46aa398797433d03d9c5ccf219
3
+ metadata.gz: cfbf5db87c6e2de8bdbd96bb3be0be9b575682508854db36dc9772dfb6120d36
4
+ data.tar.gz: 3547d2d4f8ac5dabd6cd9d2e170c1e3509ae8f6378bf4ae3f7b6cb613b5a0922
5
5
  SHA512:
6
- metadata.gz: 92e9caded9b39f0194c79920b12a5d81ee3dbc0e21bace3ce8b7368ecea63ab9c7af739e02114f1cdff72337d09926ec3a7b8bbf5b2c60ebc65e88e7a17dd6da
7
- data.tar.gz: e492fc6856487d474b58d869844e51b240f629572d5d4118df20926ba2cbab5ec116e3af4ddfa7b7586a3ba82d03667d240adcc66f319c3b0106d7698ea81c7c
6
+ metadata.gz: 81c87e65deddac4af96f84eb2bbcb8af2504e3ec7117ee9c6699c92154626cefdaec4daa68d0a8a64f5e8152199bc1f677841042ddeed7ee47ad51f3e32dc575
7
+ data.tar.gz: e6303b57c12d710f09308a4729def841b28b97b4411ea8dc63950de49c8c5be8d273a6092bc7e97b24bc2890b2e6df0df4911eef47bead8171390cda682c5565
data/Gemfile CHANGED
@@ -11,7 +11,10 @@ gem 'factbase', '~>0.11', require: false
11
11
  gem 'minitest', '~>5.25', require: false
12
12
  gem 'minitest-reporters', '~>1.7', require: false
13
13
  gem 'os', '~>1.1', require: false
14
+ gem 'puma', '~>6.6', require: false
14
15
  gem 'qbash', '~>0.4', require: false
16
+ gem 'rack', '~>3.1', require: false
17
+ gem 'rackup', '~>2.2', require: false
15
18
  gem 'rake', '~>13.2', require: false
16
19
  gem 'random-port', '~>0.7', require: false
17
20
  gem 'rubocop', '~>1.73', require: false
@@ -20,6 +23,7 @@ gem 'rubocop-performance', '~>1.23', require: false
20
23
  gem 'rubocop-rake', '~>0.7', require: false
21
24
  gem 'simplecov', '~>0.22', require: false
22
25
  gem 'simplecov-cobertura', '~>2.1', require: false
26
+ gem 'sinatra', '~>4.1', require: false
23
27
  gem 'wait_for', '~>0.1', require: false
24
28
  gem 'webmock', '~>3.24', require: false
25
29
  gem 'webrick', '~>1.9', require: false
data/Gemfile.lock CHANGED
@@ -76,8 +76,11 @@ GEM
76
76
  minitest (>= 5.0)
77
77
  ruby-progressbar
78
78
  multipart-post (2.4.1)
79
+ mustermann (3.0.3)
80
+ ruby2_keywords (~> 0.0.1)
79
81
  net-http (0.6.0)
80
82
  uri
83
+ nio4r (2.7.4)
81
84
  nokogiri (1.18.8-arm64-darwin)
82
85
  racc (~> 1.4)
83
86
  nokogiri (1.18.8-x64-mingw-ucrt)
@@ -94,12 +97,24 @@ GEM
94
97
  racc
95
98
  prism (1.4.0)
96
99
  public_suffix (6.0.2)
100
+ puma (6.6.0)
101
+ nio4r (~> 2.0)
97
102
  qbash (0.4.5)
98
103
  backtrace (> 0)
99
104
  elapsed (> 0)
100
105
  loog (> 0)
101
106
  tago (> 0)
102
107
  racc (1.8.1)
108
+ rack (3.1.16)
109
+ rack-protection (4.1.1)
110
+ base64 (>= 0.1.0)
111
+ logger (>= 1.6.0)
112
+ rack (>= 3.0.0, < 4)
113
+ rack-session (2.1.1)
114
+ base64 (>= 0.1.0)
115
+ rack (>= 3.0.0)
116
+ rackup (2.2.1)
117
+ rack (>= 3)
103
118
  rainbow (3.1.1)
104
119
  rake (13.3.0)
105
120
  random-port (0.7.5)
@@ -133,6 +148,7 @@ GEM
133
148
  lint_roller (~> 1.1)
134
149
  rubocop (>= 1.72.1)
135
150
  ruby-progressbar (1.13.0)
151
+ ruby2_keywords (0.0.5)
136
152
  simplecov (0.22.0)
137
153
  docile (~> 1.1)
138
154
  simplecov-html (~> 0.11)
@@ -142,7 +158,15 @@ GEM
142
158
  simplecov (~> 0.19)
143
159
  simplecov-html (0.13.1)
144
160
  simplecov_json_formatter (0.1.4)
161
+ sinatra (4.1.1)
162
+ logger (>= 1.6.0)
163
+ mustermann (~> 3.0)
164
+ rack (>= 3.0.0, < 4)
165
+ rack-protection (= 4.1.1)
166
+ rack-session (>= 2.0.0, < 3)
167
+ tilt (~> 2.0)
145
168
  tago (0.1.0)
169
+ tilt (2.6.0)
146
170
  typhoeus (1.4.1)
147
171
  ethon (>= 0.9.0)
148
172
  unicode-display_width (3.1.4)
@@ -174,7 +198,10 @@ DEPENDENCIES
174
198
  minitest (~> 5.25)
175
199
  minitest-reporters (~> 1.7)
176
200
  os (~> 1.1)
201
+ puma (~> 6.6)
177
202
  qbash (~> 0.4)
203
+ rack (~> 3.1)
204
+ rackup (~> 2.2)
178
205
  rake (~> 13.2)
179
206
  random-port (~> 0.7)
180
207
  rubocop (~> 1.73)
@@ -183,6 +210,7 @@ DEPENDENCIES
183
210
  rubocop-rake (~> 0.7)
184
211
  simplecov (~> 0.22)
185
212
  simplecov-cobertura (~> 2.1)
213
+ sinatra (~> 4.1)
186
214
  wait_for (~> 0.1)
187
215
  webmock (~> 3.24)
188
216
  webrick (~> 1.9)
@@ -13,5 +13,5 @@
13
13
  # Copyright:: Copyright (c) 2024-2025 Yegor Bugayenko
14
14
  # License:: MIT
15
15
  class BazaRb
16
- VERSION = '0.9.0'
16
+ VERSION = '0.9.2'
17
17
  end
data/lib/baza-rb.rb CHANGED
@@ -40,6 +40,9 @@ class BazaRb
40
40
  # Unexpected response arrived from the server.
41
41
  class BadResponse < StandardError; end
42
42
 
43
+ # When server sent incorrectly compressed data.
44
+ class BadCompression < StandardError; end
45
+
43
46
  # Initialize a new Zerocracy API client.
44
47
  #
45
48
  # @param [String] host The API host name (e.g., 'api.zerocracy.com')
@@ -587,6 +590,8 @@ class BazaRb
587
590
  io = StringIO.new(data)
588
591
  gz = Zlib::GzipReader.new(io)
589
592
  gz.read
593
+ rescue Zlib::GzipFile::Error => e
594
+ raise BadCompression, "Failed to unzip #{data.bytesize} bytes: #{e.message}"
590
595
  end
591
596
 
592
597
  # Compress request parameters with gzip.
@@ -735,7 +740,7 @@ class BazaRb
735
740
  uri.to_s,
736
741
  method: :get,
737
742
  headers: headers.merge(
738
- 'Accept' => 'application/octet-stream',
743
+ 'Accept' => '*',
739
744
  'Accept-Encoding' => 'gzip',
740
745
  'Range' => "bytes=#{pos}-"
741
746
  ),
@@ -744,7 +749,7 @@ class BazaRb
744
749
  )
745
750
  slice = ''
746
751
  request.on_body do |data|
747
- slice = data
752
+ slice += data
748
753
  end
749
754
  retry_it do
750
755
  request.run
@@ -756,12 +761,17 @@ class BazaRb
756
761
  ('in gzip' if ret.headers['Content-Encoding'] == 'gzip'),
757
762
  ("ranged as #{ret.headers['Content-Range'].inspect}" if ret.headers['Content-Range'])
758
763
  ]
759
- checked(ret, [200, 206])
764
+ ret = checked(ret, [200, 206])
760
765
  if ret.headers['Content-Encoding'] == 'gzip'
761
- slice = unzip(slice)
762
- msg << "unzipped to #{slice.bytesize} bytes"
766
+ begin
767
+ slice = unzip(slice)
768
+ msg << "unzipped to #{slice.bytesize} bytes"
769
+ rescue BazaRb::BadCompression => e
770
+ raise BazaRb::BadCompression, "#{msg.compact.join(', ')} (#{e.message})"
771
+ end
763
772
  end
764
773
  File.open(file, 'ab') do |f|
774
+ msg << "added to existed #{File.size(file)} bytes"
765
775
  f.write(slice)
766
776
  end
767
777
  @loog.debug(msg.compact.join(', '))
data/test/test_baza-rb.rb CHANGED
@@ -6,6 +6,7 @@
6
6
  require 'factbase'
7
7
  require 'loog'
8
8
  require 'net/http'
9
+ require 'qbash'
9
10
  require 'random-port'
10
11
  require 'securerandom'
11
12
  require 'socket'
@@ -478,6 +479,31 @@ class TestBazaRb < Minitest::Test
478
479
  end
479
480
  end
480
481
 
482
+ def test_durable_load_in_chunks
483
+ WebMock.disable_net_connect!
484
+ Dir.mktmpdir do |dir|
485
+ file = File.join(dir, 'loaded.txt')
486
+ stub_request(:get, 'https://example.org:443/durables/42').to_return(
487
+ { status: 206, body: '', headers: { 'Content-Range' => 'bytes 0-0/*', 'Content-Length' => '0' } },
488
+ { status: 206, body: 'привет', headers: { 'Content-Range' => 'bytes 0-5/11', 'Content-Length' => '5' } },
489
+ { status: 206, body: ' друг', headers: { 'Content-Range' => 'bytes 6-10/11', 'Content-Length' => '5' } }
490
+ )
491
+ fake_baza.durable_load(42, file)
492
+ assert_equal('привет друг', File.read(file))
493
+ end
494
+ end
495
+
496
+ def test_durable_load_with_broken_compression
497
+ WebMock.disable_net_connect!
498
+ Dir.mktmpdir do |dir|
499
+ file = File.join(dir, 'loaded.txt')
500
+ stub_request(:get, 'https://example.org:443/durables/42').to_return(
501
+ status: 200, body: 'this is not gzip!', headers: { 'Content-Encoding' => 'gzip' }
502
+ )
503
+ assert_raises(BazaRb::BadCompression) { fake_baza.durable_load(42, file) }
504
+ end
505
+ end
506
+
481
507
  def test_durable_lock
482
508
  WebMock.disable_net_connect!
483
509
  stub_request(:get, 'https://example.org/csrf').to_return(body: 'token')
@@ -649,8 +675,49 @@ class TestBazaRb < Minitest::Test
649
675
  baza.push('test', 'data', [])
650
676
  end
651
677
 
678
+ def test_durable_load_from_sinatra
679
+ WebMock.enable_net_connect!
680
+ Dir.mktmpdir do |dir|
681
+ with_sinatra_server do |baza|
682
+ file = File.join(dir, 'x.txt')
683
+ baza.durable_load(42, file)
684
+ assert_equal('Hello, world!', File.read(file))
685
+ end
686
+ end
687
+ end
688
+
652
689
  private
653
690
 
691
+ def with_sinatra_server
692
+ Dir.mktmpdir do |dir|
693
+ app = File.join(dir, 'app.rb')
694
+ File.write(
695
+ app,
696
+ "
697
+ require 'rack'
698
+ require 'sinatra'
699
+ use Rack::Deflater
700
+ get '/' do
701
+ 'I am alive'
702
+ end
703
+ get '/durables/42' do
704
+ 'Hello, world!'
705
+ end
706
+ "
707
+ )
708
+ RandomPort::Pool::SINGLETON.acquire do |port|
709
+ host = '127.0.0.1'
710
+ qbash("bundle exec ruby #{Shellwords.escape(app)} -p #{port}", log: Loog::VERBOSE, accept: nil) do
711
+ loop do
712
+ break if Typhoeus::Request.get("http://#{host}:#{port}").code == 200
713
+ sleep(0.1)
714
+ end
715
+ yield BazaRb.new(host, port, '0000-0000-0000', ssl: false)
716
+ end
717
+ end
718
+ end
719
+ end
720
+
654
721
  def with_http_server(code, response, opts = {})
655
722
  opts = { ssl: false, timeout: 1 }.merge(opts)
656
723
  WebMock.enable_net_connect!
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: baza.rb
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.9.0
4
+ version: 0.9.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Yegor Bugayenko