influxdb-api 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.gitignore +17 -0
- data/.rspec +3 -0
- data/.travis.yml +6 -0
- data/Gemfile +12 -0
- data/LICENSE.txt +22 -0
- data/README.md +208 -0
- data/Rakefile +6 -0
- data/influxdb-api.gemspec +27 -0
- data/lib/influxdb-api.rb +2 -0
- data/lib/influxdb.rb +4 -0
- data/lib/influxdb/api.rb +38 -0
- data/lib/influxdb/api/client.rb +99 -0
- data/lib/influxdb/api/client/connection.rb +55 -0
- data/lib/influxdb/api/client/connection_pool.rb +52 -0
- data/lib/influxdb/api/client/errors.rb +62 -0
- data/lib/influxdb/api/client/response.rb +14 -0
- data/lib/influxdb/api/client/selector.rb +27 -0
- data/lib/influxdb/api/configuration.rb +116 -0
- data/lib/influxdb/api/database.rb +29 -0
- data/lib/influxdb/api/extensions.rb +15 -0
- data/lib/influxdb/api/namespaces.rb +50 -0
- data/lib/influxdb/api/namespaces/base.rb +61 -0
- data/lib/influxdb/api/namespaces/cluster_admins.rb +14 -0
- data/lib/influxdb/api/namespaces/continuous_queries.rb +13 -0
- data/lib/influxdb/api/namespaces/databases.rb +13 -0
- data/lib/influxdb/api/namespaces/series.rb +52 -0
- data/lib/influxdb/api/namespaces/servers.rb +12 -0
- data/lib/influxdb/api/namespaces/shard_spaces.rb +33 -0
- data/lib/influxdb/api/namespaces/shards.rb +10 -0
- data/lib/influxdb/api/namespaces/users.rb +18 -0
- data/lib/influxdb/api/namespaces/with_database.rb +20 -0
- data/lib/influxdb/api/server_version.rb +62 -0
- data/lib/influxdb/api/version.rb +5 -0
- data/spec/lib/influxdb/api/client/connection_pool_spec.rb +61 -0
- data/spec/lib/influxdb/api/client/connection_spec.rb +72 -0
- data/spec/lib/influxdb/api/client/response_spec.rb +11 -0
- data/spec/lib/influxdb/api/client/selector_spec.rb +24 -0
- data/spec/lib/influxdb/api/client_spec.rb +110 -0
- data/spec/lib/influxdb/api/configuration_spec.rb +54 -0
- data/spec/lib/influxdb/api/database_spec.rb +32 -0
- data/spec/lib/influxdb/api/namespaces/cluster_admins_spec.rb +46 -0
- data/spec/lib/influxdb/api/namespaces/continuous_queries_spec.rb +42 -0
- data/spec/lib/influxdb/api/namespaces/databases_spec.rb +36 -0
- data/spec/lib/influxdb/api/namespaces/series_spec.rb +119 -0
- data/spec/lib/influxdb/api/namespaces/servers_spec.rb +30 -0
- data/spec/lib/influxdb/api/namespaces/shard_spaces_spec.rb +55 -0
- data/spec/lib/influxdb/api/namespaces/shards_spec.rb +52 -0
- data/spec/lib/influxdb/api/namespaces/users_spec.rb +55 -0
- data/spec/lib/influxdb/api/namespaces_spec.rb +65 -0
- data/spec/lib/influxdb/api/server_version_spec.rb +51 -0
- data/spec/spec_helper.rb +28 -0
- metadata +183 -0
@@ -0,0 +1,52 @@
|
|
1
|
+
module Influxdb
|
2
|
+
module Api
|
3
|
+
module Namespaces
|
4
|
+
class Series < WithDatabase
|
5
|
+
resource_path '/series'
|
6
|
+
|
7
|
+
undef_method(:create) if method_defined?(:create)
|
8
|
+
|
9
|
+
def all
|
10
|
+
raw_execute('list series').map{|s| s['name']}
|
11
|
+
end
|
12
|
+
|
13
|
+
def write(*series)
|
14
|
+
series = if series.first.is_a?(String) || series.first.is_a?(Symbol)
|
15
|
+
{ series.shift => series.shift }
|
16
|
+
else
|
17
|
+
series.shift
|
18
|
+
end
|
19
|
+
|
20
|
+
series = series.map{|name, points| writing_block(name, Array.wrap(points)) }
|
21
|
+
perform_writing(series)
|
22
|
+
end
|
23
|
+
|
24
|
+
def execute(*args)
|
25
|
+
raw_execute(*args).each_with_object({}) do |block_of_series, result|
|
26
|
+
result[block_of_series['name']] = block_of_series['points'].map do |point|
|
27
|
+
Hash[block_of_series['columns'].zip(point)]
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
def raw_execute(query_string, time_precision = nil)
|
33
|
+
params = { q: query_string }
|
34
|
+
params[:time_precision] = time_precision if time_precision
|
35
|
+
perform_get(resource_path, params)
|
36
|
+
end
|
37
|
+
|
38
|
+
private
|
39
|
+
|
40
|
+
def perform_writing(series, time_precision = nil)
|
41
|
+
params = { time_precision: time_precision } if time_precision
|
42
|
+
perform_post(resource_path, params, series)
|
43
|
+
true
|
44
|
+
end
|
45
|
+
|
46
|
+
def writing_block(name, points)
|
47
|
+
{ name: name, columns: points.first.keys, points: points.map(&:values) }
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
@@ -0,0 +1,33 @@
|
|
1
|
+
module Influxdb
|
2
|
+
module Api
|
3
|
+
module Namespaces
|
4
|
+
class ShardSpaces < WithDatabase
|
5
|
+
resource_path '/cluster/shard_spaces'
|
6
|
+
|
7
|
+
def all
|
8
|
+
perform_get(resource_path)
|
9
|
+
end
|
10
|
+
|
11
|
+
def create(attributes)
|
12
|
+
perform_post(resource_path(database_name), {}, attributes)
|
13
|
+
true
|
14
|
+
end
|
15
|
+
|
16
|
+
def update(name, attributes)
|
17
|
+
perform_post(resource_path(database_name, name), {}, attributes)
|
18
|
+
true
|
19
|
+
end
|
20
|
+
|
21
|
+
def delete(name)
|
22
|
+
perform_delete(resource_path(database_name, name))
|
23
|
+
true
|
24
|
+
end
|
25
|
+
|
26
|
+
protected
|
27
|
+
|
28
|
+
def path_prefix
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
module Influxdb
|
2
|
+
module Api
|
3
|
+
module Namespaces
|
4
|
+
class Users < WithDatabase
|
5
|
+
resource_path '/users'
|
6
|
+
|
7
|
+
def find(name)
|
8
|
+
perform_get(resource_path(name))
|
9
|
+
end
|
10
|
+
|
11
|
+
def update(name, attributes)
|
12
|
+
perform_post(resource_path(name), {}, attributes)
|
13
|
+
true
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
module Influxdb
|
2
|
+
module Api
|
3
|
+
module Namespaces
|
4
|
+
class WithDatabase < Base
|
5
|
+
attr_reader :database_name
|
6
|
+
|
7
|
+
def initialize(client, database_name)
|
8
|
+
@client = client
|
9
|
+
@database_name = database_name
|
10
|
+
end
|
11
|
+
|
12
|
+
protected
|
13
|
+
|
14
|
+
def path_prefix
|
15
|
+
"/db/#{database_name}"
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
@@ -0,0 +1,62 @@
|
|
1
|
+
module Influxdb
|
2
|
+
module Api
|
3
|
+
class ServerVersion
|
4
|
+
include Comparable
|
5
|
+
|
6
|
+
class Engine
|
7
|
+
attr_reader :name, :major, :minor, :patch
|
8
|
+
|
9
|
+
def initialize(name, major, minor, patch)
|
10
|
+
@name, @major, @minor, @patch = name, major, minor, patch
|
11
|
+
end
|
12
|
+
|
13
|
+
def to_s
|
14
|
+
"%s: %s.%s.%s" % [name, major, minor, patch]
|
15
|
+
end
|
16
|
+
|
17
|
+
def inspect
|
18
|
+
to_s.inspect
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
# InfluxDB v0.7.3 (git: 023abcdef) (leveldb: 1.7)
|
23
|
+
REGEXP = /^InfluxDB\sv(\d+)\.(\d+)\.(\d+)\s\(git:\s([0-9abcdef]+)\)\s\((\w+):\s(\d+)\.(\d+)\)$/
|
24
|
+
|
25
|
+
attr_reader :source, :git, :engine, :major, :minor, :patch
|
26
|
+
|
27
|
+
def initialize(source)
|
28
|
+
@source = source
|
29
|
+
parse!
|
30
|
+
end
|
31
|
+
|
32
|
+
def <=>(other)
|
33
|
+
other_major, other_minor, other_patch = (other.to_s.split('.', 3) + [0] * 3).first(3).map(&:to_i)
|
34
|
+
[major <=> other_major, minor <=> other_minor, patch <=> other_patch].detect{|c| c != 0 } || 0
|
35
|
+
end
|
36
|
+
|
37
|
+
def to_s
|
38
|
+
source
|
39
|
+
end
|
40
|
+
|
41
|
+
def inspect
|
42
|
+
to_s.inspect
|
43
|
+
end
|
44
|
+
|
45
|
+
private
|
46
|
+
|
47
|
+
def parse!
|
48
|
+
matched = REGEXP.match(source)
|
49
|
+
|
50
|
+
@major = matched[1].to_i
|
51
|
+
@minor = matched[2].to_i
|
52
|
+
@patch = matched[3].to_i
|
53
|
+
@git = matched[4]
|
54
|
+
@engine = build_engine(matched)
|
55
|
+
end
|
56
|
+
|
57
|
+
def build_engine(matched)
|
58
|
+
Engine.new(matched[5], matched[6].to_i, matched[7].to_i, matched[8].to_i)
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
@@ -0,0 +1,61 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Influxdb::Api::Client::ConnectionPool do
|
4
|
+
let(:config){ Influxdb::Api::Configuration.new }
|
5
|
+
|
6
|
+
subject{ Influxdb::Api::Client::ConnectionPool.new(config) }
|
7
|
+
|
8
|
+
describe '#initialize' do
|
9
|
+
before do
|
10
|
+
config.hosts = ['localhost', 'influxdb.server.com']
|
11
|
+
config.connection_block{|conn| }
|
12
|
+
config.connection_options = { key: :value }
|
13
|
+
end
|
14
|
+
|
15
|
+
let(:conn){ double(:conn) }
|
16
|
+
|
17
|
+
specify do
|
18
|
+
expect(::Faraday::Connection).to receive(:new).with(
|
19
|
+
'http://localhost:8086', { key: :value }, &config.connection_block
|
20
|
+
).and_return(conn)
|
21
|
+
|
22
|
+
expect(Influxdb::Api::Client::Connection).to receive(:new).with('http://localhost:8086', conn, config).
|
23
|
+
and_return(conn)
|
24
|
+
|
25
|
+
expect(::Faraday::Connection).to receive(:new).with(
|
26
|
+
'http://influxdb.server.com:8086', { key: :value }, &config.connection_block
|
27
|
+
).and_return(conn)
|
28
|
+
|
29
|
+
expect(Influxdb::Api::Client::Connection).to receive(:new).with('http://influxdb.server.com:8086', conn, config).
|
30
|
+
and_return(conn)
|
31
|
+
|
32
|
+
expect(subject.all).to eq([conn, conn])
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
describe '#get_connection' do
|
37
|
+
let(:conn){ double(:conn) }
|
38
|
+
|
39
|
+
before{ allow(config.selector).to receive(:select_from).and_return(conn) }
|
40
|
+
|
41
|
+
specify{ expect(subject.get_connection).to eq(conn) }
|
42
|
+
end
|
43
|
+
|
44
|
+
describe '#connections' do
|
45
|
+
before do
|
46
|
+
config.hosts = ['localhost', 'influxdb01.server.com', 'influxdb02.server.com']
|
47
|
+
subject.all.first.dead!
|
48
|
+
end
|
49
|
+
|
50
|
+
specify{ expect(subject.connections.size).to eq(2) }
|
51
|
+
end
|
52
|
+
|
53
|
+
describe '#dead' do
|
54
|
+
before do
|
55
|
+
config.hosts = ['localhost', 'influxdb01.server.com', 'influxdb02.server.com']
|
56
|
+
subject.all.first.dead!
|
57
|
+
end
|
58
|
+
|
59
|
+
specify{ expect(subject.dead.size).to eq(1) }
|
60
|
+
end
|
61
|
+
end
|
@@ -0,0 +1,72 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Influxdb::Api::Client::Connection do
|
4
|
+
let(:config){ Influxdb::Api::Configuration.new }
|
5
|
+
|
6
|
+
subject{ Influxdb::Api::Client::Connection.new('http://localhost:8086', nil, config) }
|
7
|
+
|
8
|
+
describe '#full_path' do
|
9
|
+
let(:path){ '/some/path' }
|
10
|
+
let(:params){ { key1: 'value1', key2: 'value2' } }
|
11
|
+
let(:result){ '/some/path?key1=value1&key2=value2' }
|
12
|
+
|
13
|
+
specify{ expect(subject.full_path(path, params)).to eq(result) }
|
14
|
+
end
|
15
|
+
|
16
|
+
describe '#dead?' do
|
17
|
+
specify{ expect(subject.dead?).to be_falsy }
|
18
|
+
|
19
|
+
context do
|
20
|
+
before{ subject.dead! }
|
21
|
+
specify{ expect(subject.dead?).to be_truthy }
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
describe '#dead!', time_freeze: '16.9.2014 00:00:00 +0700' do
|
26
|
+
let(:now){ Time.parse('16.9.2014 00:00:00 +0700') }
|
27
|
+
|
28
|
+
specify{ expect{ subject.dead! }.to change{ subject.failures }.from(0).to(1) }
|
29
|
+
specify{ expect{ subject.dead! }.to change{ subject.dead? }.from(false).to(true) }
|
30
|
+
specify{ expect{ subject.dead! }.to change{ subject.dead_since }.from(nil).to(now) }
|
31
|
+
specify{ expect(subject.dead!).to eq(subject) }
|
32
|
+
end
|
33
|
+
|
34
|
+
describe '#alive!' do
|
35
|
+
before{ subject.dead! }
|
36
|
+
|
37
|
+
specify{ expect{ subject.alive! }.to change{ subject.dead? }.from(true).to(false) }
|
38
|
+
specify{ expect{ subject.alive! }.not_to change{ subject.failures } }
|
39
|
+
specify{ expect(subject.alive!).to eq(subject) }
|
40
|
+
end
|
41
|
+
|
42
|
+
describe '#healthy!' do
|
43
|
+
before{ subject.dead! }
|
44
|
+
|
45
|
+
specify{ expect{ subject.healthy! }.to change{ subject.dead? }.from(true).to(false) }
|
46
|
+
specify{ expect{ subject.healthy! }.to change{ subject.failures }.from(1).to(0) }
|
47
|
+
specify{ expect(subject.healthy!).to eq(subject) }
|
48
|
+
end
|
49
|
+
|
50
|
+
describe '#resurrect!' do
|
51
|
+
before{ subject.dead! }
|
52
|
+
|
53
|
+
context 'when connection is resurrectable' do
|
54
|
+
before{ allow(subject).to receive(:resurrectable?).and_return(true) }
|
55
|
+
|
56
|
+
specify{ expect{ subject.resurrect! }.to change{ subject.dead? }.from(true).to(false) }
|
57
|
+
specify{ expect(subject.resurrect!).to eq(subject) }
|
58
|
+
end
|
59
|
+
|
60
|
+
context 'when connection is not resurrectable' do
|
61
|
+
before{ allow(subject).to receive(:resurrectable?).and_return(false) }
|
62
|
+
|
63
|
+
specify{ expect{ subject.resurrect! }.not_to change{ subject.dead? } }
|
64
|
+
specify{ expect(subject.resurrect!).to eq(subject) }
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
describe '#resurrectable?' do
|
69
|
+
|
70
|
+
|
71
|
+
end
|
72
|
+
end
|
@@ -0,0 +1,11 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Influxdb::Api::Client::Response do
|
4
|
+
describe '#initialize' do
|
5
|
+
let(:iso_8859){ 'Hello Encoding!'.encode(Encoding::ISO_8859_1) }
|
6
|
+
|
7
|
+
subject{ Influxdb::Api::Client::Response.new(200, iso_8859, {}) }
|
8
|
+
|
9
|
+
specify{ expect(subject.body.encoding.name).to eq('UTF-8') }
|
10
|
+
end
|
11
|
+
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Influxdb::Api::Client::Selector do
|
4
|
+
describe 'Random' do
|
5
|
+
subject{ Influxdb::Api::Client::Selector::Random.new }
|
6
|
+
|
7
|
+
describe '#select_from' do
|
8
|
+
specify{ expect(subject.select_from([1, 2, 3])).not_to be_nil }
|
9
|
+
end
|
10
|
+
end
|
11
|
+
|
12
|
+
describe 'RoundRobin' do
|
13
|
+
subject{ Influxdb::Api::Client::Selector::RoundRobin.new }
|
14
|
+
|
15
|
+
describe '#select_from' do
|
16
|
+
specify do
|
17
|
+
expect(subject.select_from([1, 2, 3])).to eq(1)
|
18
|
+
expect(subject.select_from([1, 2, 3])).to eq(2)
|
19
|
+
expect(subject.select_from([1, 2, 3])).to eq(3)
|
20
|
+
expect(subject.select_from([1, 2, 3])).to eq(1)
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
@@ -0,0 +1,110 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Influxdb::Api::Client do
|
4
|
+
let(:config){ Influxdb::Api::Configuration.new }
|
5
|
+
let(:client){ Influxdb::Api::Client.new(config) }
|
6
|
+
|
7
|
+
describe '#perform_request' do
|
8
|
+
let(:pool){ client.send(:connection_pool) }
|
9
|
+
|
10
|
+
context 'perform GET request without params' do
|
11
|
+
before do
|
12
|
+
stub_request(:get, 'http://root:root@localhost:8086/path').
|
13
|
+
to_return(status: 200, body: '{}', headers: { 'Content-Type' => 'application/json' })
|
14
|
+
end
|
15
|
+
|
16
|
+
subject{ client.perform_request('GET', '/path') }
|
17
|
+
|
18
|
+
specify{ expect(subject.status).to eq(200) }
|
19
|
+
specify{ expect(subject.body).to eq({}) }
|
20
|
+
specify{ expect(subject.headers).to include('content-type' => 'application/json') }
|
21
|
+
end
|
22
|
+
|
23
|
+
context 'perform GET request with params' do
|
24
|
+
before do
|
25
|
+
stub_request(:get, 'http://root:root@localhost:8086/path?key1=value1').
|
26
|
+
to_return(status: 200, body: '{}', headers: { 'Content-Type' => 'application/json' })
|
27
|
+
end
|
28
|
+
|
29
|
+
subject{ client.perform_request('GET', '/path', key1: 'value1') }
|
30
|
+
|
31
|
+
specify{ expect(subject.status).to eq(200) }
|
32
|
+
specify{ expect(subject.body).to eq({}) }
|
33
|
+
specify{ expect(subject.headers).to include('content-type' => 'application/json') }
|
34
|
+
end
|
35
|
+
|
36
|
+
context 'perform GET request with HTTP error' do
|
37
|
+
before do
|
38
|
+
stub_request(:get, 'http://root:root@localhost:8086/path').
|
39
|
+
to_return(status: 404, body: '', headers: { 'Content-Type' => 'application/json' })
|
40
|
+
end
|
41
|
+
|
42
|
+
subject{ client.perform_request('GET', '/path') }
|
43
|
+
|
44
|
+
specify{ expect{ subject }.to raise_error(Influxdb::Api::Client::Errors::NotFound) }
|
45
|
+
end
|
46
|
+
|
47
|
+
context 'perform GET request with transport error if connection pool more then retry number' do
|
48
|
+
before do
|
49
|
+
config.hosts = ['localhost', 'influxdb1.server.com', 'influxdb2.server.com']
|
50
|
+
config.retry_on_failure = 2
|
51
|
+
|
52
|
+
stub_request(:get, 'http://root:root@localhost:8086/path').
|
53
|
+
to_raise(::Faraday::Error::ConnectionFailed)
|
54
|
+
stub_request(:get, 'http://root:root@influxdb1.server.com:8086/path').
|
55
|
+
to_raise(::Faraday::Error::ConnectionFailed)
|
56
|
+
stub_request(:get, 'http://root:root@influxdb2.server.com:8086/path').
|
57
|
+
to_raise(::Faraday::Error::ConnectionFailed)
|
58
|
+
end
|
59
|
+
|
60
|
+
subject{ client.perform_request('GET', '/path') }
|
61
|
+
|
62
|
+
specify do
|
63
|
+
expect{ subject }.to raise_error(Faraday::Error::ConnectionFailed)
|
64
|
+
expect(pool.alive.size).to eq(1)
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
context 'perform GET request with transport error if connection pool less then retry number' do
|
69
|
+
before do
|
70
|
+
config.hosts = ['localhost', 'influxdb1.server.com', 'influxdb2.server.com']
|
71
|
+
config.retry_on_failure = 4
|
72
|
+
|
73
|
+
stub_request(:get, 'http://root:root@localhost:8086/path').
|
74
|
+
to_raise(::Faraday::Error::ConnectionFailed)
|
75
|
+
stub_request(:get, 'http://root:root@influxdb1.server.com:8086/path').
|
76
|
+
to_raise(::Faraday::Error::ConnectionFailed)
|
77
|
+
stub_request(:get, 'http://root:root@influxdb2.server.com:8086/path').
|
78
|
+
to_raise(::Faraday::Error::ConnectionFailed)
|
79
|
+
end
|
80
|
+
|
81
|
+
subject{ client.perform_request('GET', '/path') }
|
82
|
+
|
83
|
+
specify do
|
84
|
+
expect{ subject }.to raise_error(Faraday::Error::ConnectionFailed)
|
85
|
+
expect(pool.alive.size).to eq(0)
|
86
|
+
end
|
87
|
+
end
|
88
|
+
|
89
|
+
context 'perform GET request with 2 transport errors and success' do
|
90
|
+
before do
|
91
|
+
config.hosts = ['localhost', 'influxdb1.server.com', 'influxdb2.server.com']
|
92
|
+
config.retry_on_failure = 4
|
93
|
+
|
94
|
+
stub_request(:get, 'http://root:root@localhost:8086/path').
|
95
|
+
to_raise(::Faraday::Error::ConnectionFailed)
|
96
|
+
stub_request(:get, 'http://root:root@influxdb2.server.com:8086/path').
|
97
|
+
to_raise(::Faraday::Error::ConnectionFailed)
|
98
|
+
stub_request(:get, 'http://root:root@influxdb1.server.com:8086/path').
|
99
|
+
to_return(status: 200, body: '{}', headers: { 'Content-Type' => 'application/json' })
|
100
|
+
end
|
101
|
+
|
102
|
+
subject{ client.perform_request('GET', '/path') }
|
103
|
+
|
104
|
+
specify{ expect(subject.status).to eq(200) }
|
105
|
+
specify{ expect(subject.body).to eq({}) }
|
106
|
+
specify{ expect(subject.headers).to include('content-type' => 'application/json') }
|
107
|
+
specify{ expect{ subject }.to change{ pool.alive.size }.from(3).to(1) }
|
108
|
+
end
|
109
|
+
end
|
110
|
+
end
|