3scale_client 2.3.4 → 2.4.0.pre.1
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/.travis.yml +14 -3
- data/3scale_client.gemspec +1 -0
- data/Rakefile +5 -1
- data/lib/3scale/client/http_client.rb +74 -0
- data/lib/3scale/client/version.rb +1 -1
- data/lib/3scale/client.rb +10 -11
- data/test/benchmark.rb +21 -0
- data/test/client_test.rb +56 -18
- data/test/persistence_test.rb +30 -0
- data/test/remote_test.rb +13 -0
- metadata +24 -5
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: ca13a0b71b091111263b305b227d8384e3648e53
|
4
|
+
data.tar.gz: 204c15465a171d3c181f72e7f7877155ca77933c
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 245f5ad62823a036a60fb6c1209f87053bd084fda544b0be17be338f4dfdde45e88931cd1241071115ddc40ce5c4ed6a3f409616c25681fe8e0544ec8111facc
|
7
|
+
data.tar.gz: 003b18dd48bcc5117169e6326bb9e7a268cf7e6e92f97de2d8d0a9669ec4f80141b8c99d9b8638c566e24b0907bc3053826d84dee30bb84ce051a1cfbf3a679f
|
data/.travis.yml
CHANGED
@@ -1,5 +1,16 @@
|
|
1
1
|
language: ruby
|
2
|
+
cache: bundler
|
2
3
|
rvm:
|
3
|
-
|
4
|
-
|
5
|
-
|
4
|
+
- 1.9.3
|
5
|
+
- 2.0.0
|
6
|
+
- 2.1.1
|
7
|
+
- 2.1.2
|
8
|
+
- jruby
|
9
|
+
matrix:
|
10
|
+
include:
|
11
|
+
- rvm: jruby
|
12
|
+
env: JRUBY_OPTS="--2.0"
|
13
|
+
env:
|
14
|
+
global:
|
15
|
+
- TEST_3SCALE_APP_IDS=4d4b20b9 TEST_3SCALE_APP_KEYS=ecce202ecc2eb8dc7a499c34a34d5987
|
16
|
+
- secure: VSElS0KvnufcZKStV7kj6xHFEiWvQkpxk1IEuhKq5JqywniN/6ScaNUFxbBKrOUrqhzXIRUCteBP2wvYRjlNhLFZSnYskzh7dLkOp/WV+WK6KjrdflTiF6UTxW4pBSsg6YDJ/wWJlmwsPVty1pRvOE3ru6uco+dTWCCLn4BvWqc=
|
data/3scale_client.gemspec
CHANGED
data/Rakefile
CHANGED
@@ -9,7 +9,7 @@ require 'rake/testtask'
|
|
9
9
|
require 'rdoc/task'
|
10
10
|
|
11
11
|
desc 'Default: run unit tests.'
|
12
|
-
task :default =>
|
12
|
+
task :default => %w[test benchmark]
|
13
13
|
|
14
14
|
desc 'Run unit tests.'
|
15
15
|
Rake::TestTask.new(:test) do |t|
|
@@ -17,6 +17,10 @@ Rake::TestTask.new(:test) do |t|
|
|
17
17
|
t.verbose = true
|
18
18
|
end
|
19
19
|
|
20
|
+
task :benchmark do
|
21
|
+
system 'ruby', '-Ilib', 'test/benchmark.rb'
|
22
|
+
end
|
23
|
+
|
20
24
|
desc 'Generate documentation.'
|
21
25
|
Rake::RDocTask.new(:rdoc) do |rdoc|
|
22
26
|
rdoc.rdoc_dir = 'rdoc'
|
@@ -0,0 +1,74 @@
|
|
1
|
+
require 'forwardable'
|
2
|
+
|
3
|
+
module ThreeScale
|
4
|
+
class Client
|
5
|
+
class HTTPClient
|
6
|
+
extend Forwardable
|
7
|
+
def_delegators :@http, :get, :post, :use_ssl?, :active?
|
8
|
+
|
9
|
+
def initialize(options)
|
10
|
+
|
11
|
+
@secure = !!options[:secure]
|
12
|
+
@host = options.fetch(:host)
|
13
|
+
@persistent = options[:persistent]
|
14
|
+
|
15
|
+
backend_class = @persistent ? Persistent : NetHttp
|
16
|
+
|
17
|
+
@http = backend_class.new(@host)
|
18
|
+
@http.ssl! if @secure
|
19
|
+
end
|
20
|
+
|
21
|
+
class Persistent
|
22
|
+
def initialize(host)
|
23
|
+
require 'net/http/persistent'
|
24
|
+
@http = ::Net::HTTP::Persistent.new
|
25
|
+
@host = host
|
26
|
+
@protocol = 'http'
|
27
|
+
end
|
28
|
+
|
29
|
+
def ssl!
|
30
|
+
@protocol = 'https'
|
31
|
+
end
|
32
|
+
|
33
|
+
def get(path)
|
34
|
+
uri = full_uri(path)
|
35
|
+
get = Net::HTTP::Get.new(uri.request_uri)
|
36
|
+
@http.request(uri, get)
|
37
|
+
end
|
38
|
+
|
39
|
+
|
40
|
+
def post(path, payload)
|
41
|
+
uri = full_uri(path)
|
42
|
+
post = Net::HTTP::Post.new uri.path
|
43
|
+
post.set_form_data(payload)
|
44
|
+
|
45
|
+
@http.request(uri, post)
|
46
|
+
end
|
47
|
+
|
48
|
+
def full_uri(path)
|
49
|
+
URI.join "#{@protocol}://#{@host}", path
|
50
|
+
end
|
51
|
+
|
52
|
+
end
|
53
|
+
|
54
|
+
class NetHttp
|
55
|
+
extend Forwardable
|
56
|
+
def_delegators :@http, :get, :post, :use_ssl?, :active?
|
57
|
+
|
58
|
+
def initialize(host)
|
59
|
+
@host = host
|
60
|
+
@http = Net::HTTP.new(@host, 80)
|
61
|
+
end
|
62
|
+
|
63
|
+
def ssl!
|
64
|
+
@http = Net::HTTP.new(@host, 443)
|
65
|
+
@http.use_ssl = true
|
66
|
+
end
|
67
|
+
|
68
|
+
def post(path, payload)
|
69
|
+
@http.post(path, URI.encode_www_form(payload))
|
70
|
+
end
|
71
|
+
end
|
72
|
+
end
|
73
|
+
end
|
74
|
+
end
|
data/lib/3scale/client.rb
CHANGED
@@ -2,6 +2,7 @@ require 'cgi'
|
|
2
2
|
require 'uri'
|
3
3
|
require 'net/http'
|
4
4
|
require 'nokogiri'
|
5
|
+
require '3scale/client/http_client'
|
5
6
|
|
6
7
|
require '3scale/response'
|
7
8
|
require '3scale/authorize_response'
|
@@ -45,11 +46,13 @@ module ThreeScale
|
|
45
46
|
end
|
46
47
|
|
47
48
|
@provider_key = options[:provider_key]
|
48
|
-
|
49
|
+
|
50
|
+
@host = options[:host] ||= DEFAULT_HOST
|
51
|
+
|
52
|
+
@http = ThreeScale::Client::HTTPClient.new(options)
|
49
53
|
end
|
50
54
|
|
51
|
-
attr_reader :provider_key
|
52
|
-
attr_reader :host
|
55
|
+
attr_reader :provider_key, :host, :http
|
53
56
|
|
54
57
|
# Authorize and report an application.
|
55
58
|
# TODO (in the mean time read authorize comments or head over to https://support.3scale.net/reference/activedocs#operation/66 for details
|
@@ -81,8 +84,7 @@ module ThreeScale
|
|
81
84
|
path += "&#{log.join('&')}"
|
82
85
|
end
|
83
86
|
|
84
|
-
|
85
|
-
http_response = Net::HTTP.get_response(uri)
|
87
|
+
http_response = @http.get(path)
|
86
88
|
|
87
89
|
case http_response
|
88
90
|
when Net::HTTPSuccess,Net::HTTPConflict
|
@@ -139,8 +141,7 @@ module ThreeScale
|
|
139
141
|
payload = encode_transactions(transactions)
|
140
142
|
payload['provider_key'] = CGI.escape(provider_key)
|
141
143
|
|
142
|
-
|
143
|
-
http_response = Net::HTTP.post_form(uri, payload)
|
144
|
+
http_response = @http.post('/transactions.xml', payload)
|
144
145
|
|
145
146
|
case http_response
|
146
147
|
when Net::HTTPSuccess
|
@@ -185,8 +186,7 @@ module ThreeScale
|
|
185
186
|
def authorize(options)
|
186
187
|
path = "/transactions/authorize.xml" + options_to_params(options, ALL_PARAMS)
|
187
188
|
|
188
|
-
|
189
|
-
http_response = Net::HTTP.get_response(uri)
|
189
|
+
http_response = @http.get(path)
|
190
190
|
|
191
191
|
case http_response
|
192
192
|
when Net::HTTPSuccess,Net::HTTPConflict
|
@@ -232,8 +232,7 @@ module ThreeScale
|
|
232
232
|
def oauth_authorize(options)
|
233
233
|
path = "/transactions/oauth_authorize.xml" + options_to_params(options, OAUTH_PARAMS)
|
234
234
|
|
235
|
-
|
236
|
-
http_response = Net::HTTP.get_response(uri)
|
235
|
+
http_response = @http.get(path)
|
237
236
|
|
238
237
|
case http_response
|
239
238
|
when Net::HTTPSuccess,Net::HTTPConflict
|
data/test/benchmark.rb
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
require 'benchmark'
|
2
|
+
|
3
|
+
require '3scale/client'
|
4
|
+
|
5
|
+
provider_key = ENV['TEST_3SCALE_PROVIDER_KEY']
|
6
|
+
|
7
|
+
client = ThreeScale::Client.new(:provider_key => provider_key)
|
8
|
+
persistent_client = ThreeScale::Client.new(:provider_key => provider_key, :persistent => true)
|
9
|
+
persistent_ssl_client = ThreeScale::Client.new(:provider_key => provider_key, :secure => true, :persistent => true)
|
10
|
+
ssl_client = ThreeScale::Client.new(:provider_key => provider_key, :secure => true)
|
11
|
+
|
12
|
+
auth = { :app_id => ENV['TEST_3SCALE_APP_IDS'], :app_key => ENV['TEST_3SCALE_APP_KEYS'] }
|
13
|
+
|
14
|
+
N = 10
|
15
|
+
|
16
|
+
Benchmark.bmbm do |x|
|
17
|
+
x.report('http') { N.times{ client.authorize(auth) } }
|
18
|
+
x.report('http+persistent') { N.times{ persistent_client.authorize(auth) } }
|
19
|
+
x.report('https+persistent') { N.times{ persistent_ssl_client.authorize(auth) } }
|
20
|
+
x.report('https') { N.times{ ssl_client.authorize(auth) } }
|
21
|
+
end
|
data/test/client_test.rb
CHANGED
@@ -1,15 +1,20 @@
|
|
1
1
|
require 'test/unit'
|
2
2
|
require 'fakeweb'
|
3
|
-
require 'mocha'
|
3
|
+
require 'mocha/setup'
|
4
4
|
|
5
5
|
require '3scale/client'
|
6
6
|
|
7
7
|
class ThreeScale::ClientTest < Test::Unit::TestCase
|
8
|
+
|
9
|
+
def client(options = {})
|
10
|
+
ThreeScale::Client.new({:provider_key => '1234abcd'}.merge(options))
|
11
|
+
end
|
12
|
+
|
8
13
|
def setup
|
9
14
|
FakeWeb.clean_registry
|
10
15
|
FakeWeb.allow_net_connect = false
|
11
16
|
|
12
|
-
@client =
|
17
|
+
@client = client
|
13
18
|
@host = ThreeScale::Client::DEFAULT_HOST
|
14
19
|
end
|
15
20
|
|
@@ -31,12 +36,32 @@ class ThreeScale::ClientTest < Test::Unit::TestCase
|
|
31
36
|
assert_equal 'example.com', client.host
|
32
37
|
end
|
33
38
|
|
39
|
+
def test_default_protocol
|
40
|
+
client = ThreeScale::Client.new(:provider_key => 'test')
|
41
|
+
assert_equal false, client.http.use_ssl?
|
42
|
+
end
|
43
|
+
|
44
|
+
def test_insecure_protocol
|
45
|
+
client = ThreeScale::Client.new(:provider_key => 'test', :secure => false)
|
46
|
+
assert_equal false, client.http.use_ssl?
|
47
|
+
end
|
48
|
+
|
49
|
+
def test_secure_protocol
|
50
|
+
client = ThreeScale::Client.new(:provider_key => 'test', :secure => true)
|
51
|
+
assert_equal true, client.http.use_ssl?
|
52
|
+
end
|
53
|
+
|
34
54
|
def test_authrep_usage_is_encoded
|
35
55
|
assert_authrep_url_with_params "&%5Busage%5D%5Bmethod%5D=666"
|
36
56
|
|
37
57
|
@client.authrep({:usage => {:method=> 666}})
|
38
58
|
end
|
39
59
|
|
60
|
+
def test_secure_authrep
|
61
|
+
assert_secure_authrep_url_with_params
|
62
|
+
client(:secure => true).authrep({})
|
63
|
+
end
|
64
|
+
|
40
65
|
def test_authrep_usage_values_are_encoded
|
41
66
|
assert_authrep_url_with_params "&%5Busage%5D%5Bhits%5D=%230"
|
42
67
|
|
@@ -62,9 +87,9 @@ class ThreeScale::ClientTest < Test::Unit::TestCase
|
|
62
87
|
end
|
63
88
|
|
64
89
|
#TODO these authrep tests
|
65
|
-
def test_authrep_supports_api_key_auth_mode; end
|
66
|
-
def test_authrep_log_is_encoded;end
|
67
|
-
def test_authrep_passes_all_params_to_backend;end
|
90
|
+
# def test_authrep_supports_api_key_auth_mode; end
|
91
|
+
# def test_authrep_log_is_encoded;end
|
92
|
+
# def test_authrep_passes_all_params_to_backend;end
|
68
93
|
|
69
94
|
def test_successful_authorize
|
70
95
|
body = '<status>
|
@@ -283,7 +308,7 @@ class ThreeScale::ClientTest < Test::Unit::TestCase
|
|
283
308
|
assert_equal 'application with id="foo" was not found', response.error_message
|
284
309
|
end
|
285
310
|
|
286
|
-
def
|
311
|
+
def test_oauth_authorize_with_server_error
|
287
312
|
FakeWeb.register_uri(:get, "http://#{@host}/transactions/oauth_authorize.xml?provider_key=1234abcd&app_id=foo", :status => ['500', 'Internal Server Error'], :body => 'OMG! WTF!')
|
288
313
|
|
289
314
|
assert_raise ThreeScale::ServerError do
|
@@ -312,16 +337,19 @@ class ThreeScale::ClientTest < Test::Unit::TestCase
|
|
312
337
|
http_response = stub
|
313
338
|
Net::HTTPSuccess.stubs(:===).with(http_response).returns(true)
|
314
339
|
|
315
|
-
|
316
|
-
|
317
|
-
|
318
|
-
|
319
|
-
|
320
|
-
|
321
|
-
|
322
|
-
|
323
|
-
|
324
|
-
|
340
|
+
payload = {
|
341
|
+
'transactions[0][app_id]' => 'foo',
|
342
|
+
'transactions[0][timestamp]' => CGI.escape('2010-04-27 15:42:17 0200'),
|
343
|
+
'transactions[0][usage][hits]' => '1',
|
344
|
+
'transactions[1][app_id]' => 'bar',
|
345
|
+
'transactions[1][timestamp]' => CGI.escape('2010-04-27 15:55:12 0200'),
|
346
|
+
'transactions[1][usage][hits]' => '1',
|
347
|
+
'provider_key' => '1234abcd'
|
348
|
+
}
|
349
|
+
|
350
|
+
@client.http.expects(:post)
|
351
|
+
.with('/transactions.xml', payload)
|
352
|
+
.returns(http_response)
|
325
353
|
|
326
354
|
@client.report({:app_id => 'foo',
|
327
355
|
:usage => {'hits' => 1},
|
@@ -362,8 +390,8 @@ class ThreeScale::ClientTest < Test::Unit::TestCase
|
|
362
390
|
#OPTIMIZE this tricky test helper relies on fakeweb catching the urls requested by the client
|
363
391
|
# it is brittle: it depends in the correct order or params in the url
|
364
392
|
#
|
365
|
-
def assert_authrep_url_with_params(str)
|
366
|
-
authrep_url = "
|
393
|
+
def assert_authrep_url_with_params(str, protocol = 'http')
|
394
|
+
authrep_url = "#{protocol}://#{@host}/transactions/authrep.xml?provider_key=#{@client.provider_key}"
|
367
395
|
params = str # unless str.scan(/log/)
|
368
396
|
params << "&%5Busage%5D%5Bhits%5D=1" unless params.scan(/usage.*hits/)
|
369
397
|
parsed_authrep_url = URI.parse(authrep_url + params)
|
@@ -376,4 +404,14 @@ class ThreeScale::ClientTest < Test::Unit::TestCase
|
|
376
404
|
# this is the actual assertion, if fakeweb raises the client is submiting with wrong params
|
377
405
|
FakeWeb.register_uri(:get, parsed_authrep_url, :status => ['200', 'OK'], :body => body)
|
378
406
|
end
|
407
|
+
|
408
|
+
def assert_secure_authrep_url_with_params(str = '&%5Busage%5D%5Bhits%5D=1')
|
409
|
+
assert_authrep_url_with_params(str, 'https')
|
410
|
+
end
|
411
|
+
end
|
412
|
+
|
413
|
+
class ThreeScale::PersistentClientTest < ThreeScale::ClientTest
|
414
|
+
def client(options = {})
|
415
|
+
ThreeScale::Client.new({:provider_key => '1234abcd', :persistent => true}.merge(options))
|
416
|
+
end
|
379
417
|
end
|
@@ -0,0 +1,30 @@
|
|
1
|
+
require '3scale/client'
|
2
|
+
require 'test/unit'
|
3
|
+
|
4
|
+
if ENV['TEST_3SCALE_PROVIDER_KEY'] && ENV['TEST_3SCALE_APP_IDS'] && ENV['TEST_3SCALE_APP_KEYS']
|
5
|
+
class ThreeScale::PersistenceTest < Test::Unit::TestCase
|
6
|
+
def setup
|
7
|
+
provider_key = ENV['TEST_3SCALE_PROVIDER_KEY']
|
8
|
+
|
9
|
+
@app_id = ENV['TEST_3SCALE_APP_IDS']
|
10
|
+
@app_key = ENV['TEST_3SCALE_APP_KEYS']
|
11
|
+
|
12
|
+
@client = ThreeScale::Client.new(:provider_key => provider_key, :persistence => true)
|
13
|
+
|
14
|
+
if defined?(FakeWeb)
|
15
|
+
FakeWeb.allow_net_connect = true
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
def test_authorize
|
20
|
+
assert @client.authorize(:app_id => @app_id, :app_key => @app_key).success?
|
21
|
+
end
|
22
|
+
|
23
|
+
def test_keepalive_disconnect
|
24
|
+
assert @client.authorize(:app_id => @app_id, :app_key => @app_key).success?
|
25
|
+
sleep 70
|
26
|
+
assert @client.authorize(:app_id => @app_id, :app_key => @app_key).success?
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
data/test/remote_test.rb
CHANGED
@@ -21,6 +21,14 @@ if ENV['TEST_3SCALE_PROVIDER_KEY'] &&
|
|
21
21
|
end
|
22
22
|
end
|
23
23
|
|
24
|
+
def test_app_ids_are_passed
|
25
|
+
assert @app_ids.length > 0, 'expected TEST_3SCALE_APP_IDS to contain app ids'
|
26
|
+
end
|
27
|
+
|
28
|
+
def test_app_keys_are_passed
|
29
|
+
assert @app_keys.length > 0, 'expected TEST_3SCALE_APP_KEYS to contain app keys'
|
30
|
+
end
|
31
|
+
|
24
32
|
def test_successful_authrep
|
25
33
|
@app_keys.each do |app_key|
|
26
34
|
response = @client.authrep(:app_id => @app_ids[0], :app_key => app_key,
|
@@ -30,6 +38,11 @@ if ENV['TEST_3SCALE_PROVIDER_KEY'] &&
|
|
30
38
|
end
|
31
39
|
end
|
32
40
|
|
41
|
+
def test_successful_secure_authrep
|
42
|
+
@client = ThreeScale::Client.new(:provider_key => @provider_key, :secure => true)
|
43
|
+
test_successful_authrep
|
44
|
+
end
|
45
|
+
|
33
46
|
|
34
47
|
def test_failed_authrep
|
35
48
|
response = @client.authrep(:app_id => 'invalid-id')
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: 3scale_client
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 2.
|
4
|
+
version: 2.4.0.pre.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Michal Cichra
|
@@ -12,7 +12,7 @@ authors:
|
|
12
12
|
autorequire:
|
13
13
|
bindir: bin
|
14
14
|
cert_chain: []
|
15
|
-
date: 2014-
|
15
|
+
date: 2014-05-20 00:00:00.000000000 Z
|
16
16
|
dependencies:
|
17
17
|
- !ruby/object:Gem::Dependency
|
18
18
|
name: bundler
|
@@ -84,6 +84,20 @@ dependencies:
|
|
84
84
|
- - '>='
|
85
85
|
- !ruby/object:Gem::Version
|
86
86
|
version: '0'
|
87
|
+
- !ruby/object:Gem::Dependency
|
88
|
+
name: net-http-persistent
|
89
|
+
requirement: !ruby/object:Gem::Requirement
|
90
|
+
requirements:
|
91
|
+
- - '>='
|
92
|
+
- !ruby/object:Gem::Version
|
93
|
+
version: '0'
|
94
|
+
type: :development
|
95
|
+
prerelease: false
|
96
|
+
version_requirements: !ruby/object:Gem::Requirement
|
97
|
+
requirements:
|
98
|
+
- - '>='
|
99
|
+
- !ruby/object:Gem::Version
|
100
|
+
version: '0'
|
87
101
|
- !ruby/object:Gem::Dependency
|
88
102
|
name: nokogiri
|
89
103
|
requirement: !ruby/object:Gem::Requirement
|
@@ -117,10 +131,13 @@ files:
|
|
117
131
|
- VERSION
|
118
132
|
- lib/3scale/authorize_response.rb
|
119
133
|
- lib/3scale/client.rb
|
134
|
+
- lib/3scale/client/http_client.rb
|
120
135
|
- lib/3scale/client/version.rb
|
121
136
|
- lib/3scale/response.rb
|
122
137
|
- lib/3scale_client.rb
|
138
|
+
- test/benchmark.rb
|
123
139
|
- test/client_test.rb
|
140
|
+
- test/persistence_test.rb
|
124
141
|
- test/remote_test.rb
|
125
142
|
homepage: http://www.3scale.net
|
126
143
|
licenses:
|
@@ -137,15 +154,17 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
137
154
|
version: '0'
|
138
155
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
139
156
|
requirements:
|
140
|
-
- - '
|
157
|
+
- - '>'
|
141
158
|
- !ruby/object:Gem::Version
|
142
|
-
version:
|
159
|
+
version: 1.3.1
|
143
160
|
requirements: []
|
144
161
|
rubyforge_project:
|
145
|
-
rubygems_version: 2.
|
162
|
+
rubygems_version: 2.2.2
|
146
163
|
signing_key:
|
147
164
|
specification_version: 4
|
148
165
|
summary: Client for 3scale Web Service Management System API
|
149
166
|
test_files:
|
167
|
+
- test/benchmark.rb
|
150
168
|
- test/client_test.rb
|
169
|
+
- test/persistence_test.rb
|
151
170
|
- test/remote_test.rb
|