influxdb 0.1.9 → 0.2.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.gitignore +1 -0
- data/.rubocop.yml +41 -0
- data/.travis.yml +3 -2
- data/Gemfile +7 -1
- data/README.md +218 -102
- data/Rakefile +2 -6
- data/lib/influxdb.rb +15 -5
- data/lib/influxdb/client.rb +38 -433
- data/lib/influxdb/client/http.rb +123 -0
- data/lib/influxdb/config.rb +66 -0
- data/lib/influxdb/errors.rb +8 -2
- data/lib/influxdb/{logger.rb → logging.rb} +6 -5
- data/lib/influxdb/max_queue.rb +2 -1
- data/lib/influxdb/point_value.rb +27 -25
- data/lib/influxdb/query/cluster.rb +17 -0
- data/lib/influxdb/query/continuous_query.rb +22 -0
- data/lib/influxdb/query/core.rb +110 -0
- data/lib/influxdb/query/database.rb +21 -0
- data/lib/influxdb/query/retention_policy.rb +26 -0
- data/lib/influxdb/query/user.rb +41 -0
- data/lib/influxdb/version.rb +2 -2
- data/lib/influxdb/writer/async.rb +115 -0
- data/lib/influxdb/writer/udp.rb +21 -0
- data/spec/influxdb/cases/async_client_spec.rb +33 -0
- data/spec/influxdb/cases/query_cluster_spec.rb +65 -0
- data/spec/influxdb/cases/query_continuous_query_spec.rb +82 -0
- data/spec/influxdb/cases/query_core.rb +34 -0
- data/spec/influxdb/cases/query_database_spec.rb +58 -0
- data/spec/influxdb/cases/query_retention_policy_spec.rb +84 -0
- data/spec/influxdb/cases/query_series_spec.rb +50 -0
- data/spec/influxdb/cases/query_shard_space_spec.rb +105 -0
- data/spec/influxdb/cases/query_shard_spec.rb +43 -0
- data/spec/influxdb/cases/query_user_spec.rb +127 -0
- data/spec/influxdb/cases/querying_spec.rb +149 -0
- data/spec/influxdb/cases/retry_requests_spec.rb +102 -0
- data/spec/influxdb/cases/udp_client_spec.rb +21 -0
- data/spec/influxdb/cases/write_points_spec.rb +140 -0
- data/spec/influxdb/client_spec.rb +37 -810
- data/spec/influxdb/config_spec.rb +118 -0
- data/spec/influxdb/{logger_spec.rb → logging_spec.rb} +4 -8
- data/spec/influxdb/max_queue_spec.rb +29 -0
- data/spec/influxdb/point_value_spec.rb +81 -14
- data/spec/influxdb/worker_spec.rb +8 -11
- data/spec/spec_helper.rb +7 -10
- metadata +65 -30
- data/lib/influxdb/udp_client.rb +0 -16
- data/lib/influxdb/worker.rb +0 -80
- data/spec/influxdb/udp_client_spec.rb +0 -33
- data/spec/influxdb_spec.rb +0 -4
- data/spec/max_queue_spec.rb +0 -32
@@ -0,0 +1,149 @@
|
|
1
|
+
require "spec_helper"
|
2
|
+
require "json"
|
3
|
+
|
4
|
+
describe InfluxDB::Client do
|
5
|
+
let(:subject) do
|
6
|
+
described_class.new(
|
7
|
+
"database",
|
8
|
+
{
|
9
|
+
host: "influxdb.test",
|
10
|
+
port: 9999,
|
11
|
+
username: "username",
|
12
|
+
password: "password",
|
13
|
+
time_precision: "s"
|
14
|
+
}.merge(args)
|
15
|
+
)
|
16
|
+
end
|
17
|
+
|
18
|
+
let(:args) { {} }
|
19
|
+
let(:database) { subject.config.database }
|
20
|
+
|
21
|
+
describe "#query" do
|
22
|
+
context "with single series with multiple points" do
|
23
|
+
let(:response) do
|
24
|
+
{ "results" => [{ "series" => [{ "name" => "cpu", "tags" => { "region" => "us" },
|
25
|
+
"columns" => %w(time temp value),
|
26
|
+
"values" => [["2015-07-07T14:58:37Z", 92, 0.3445], ["2015-07-07T14:59:09Z", 68, 0.8787]] }] }] }
|
27
|
+
end
|
28
|
+
let(:expected_result) do
|
29
|
+
[{ "name" => "cpu", "tags" => { "region" => "us" },
|
30
|
+
"values" => [{ "time" => "2015-07-07T14:58:37Z", "temp" => 92, "value" => 0.3445 },
|
31
|
+
{ "time" => "2015-07-07T14:59:09Z", "temp" => 68, "value" => 0.8787 }] }]
|
32
|
+
end
|
33
|
+
let(:query) { 'SELECT * FROM cpu' }
|
34
|
+
|
35
|
+
before do
|
36
|
+
stub_request(:get, "http://influxdb.test:9999/query").with(
|
37
|
+
query: { q: query, u: "username", p: "password", precision: 's', db: database }
|
38
|
+
).to_return(body: JSON.generate(response))
|
39
|
+
end
|
40
|
+
|
41
|
+
it "should return array with single hash containing multiple values" do
|
42
|
+
expect(subject.query(query)).to eq(expected_result)
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
context "with series with different tags" do
|
47
|
+
let(:response) do
|
48
|
+
{ "results" => [{ "series" => [{ "name" => "cpu", "tags" => { "region" => "pl" }, "columns" => %w(time temp value), "values" => [["2015-07-07T15:13:04Z", 34, 0.343443]] },
|
49
|
+
{ "name" => "cpu", "tags" => { "region" => "us" }, "columns" => %w(time temp value), "values" => [["2015-07-07T14:58:37Z", 92, 0.3445], ["2015-07-07T14:59:09Z", 68, 0.8787]] }] }] }
|
50
|
+
end
|
51
|
+
let(:expected_result) do
|
52
|
+
[{ "name" => "cpu", "tags" => { "region" => "pl" },
|
53
|
+
"values" => [{ "time" => "2015-07-07T15:13:04Z", "temp" => 34, "value" => 0.343443 }] },
|
54
|
+
{ "name" => "cpu", "tags" => { "region" => "us" },
|
55
|
+
"values" => [{ "time" => "2015-07-07T14:58:37Z", "temp" => 92, "value" => 0.3445 },
|
56
|
+
{ "time" => "2015-07-07T14:59:09Z", "temp" => 68, "value" => 0.8787 }] }]
|
57
|
+
end
|
58
|
+
let(:query) { 'SELECT * FROM cpu' }
|
59
|
+
|
60
|
+
before do
|
61
|
+
stub_request(:get, "http://influxdb.test:9999/query").with(
|
62
|
+
query: { q: query, u: "username", p: "password", precision: 's', db: database }
|
63
|
+
).to_return(body: JSON.generate(response))
|
64
|
+
end
|
65
|
+
|
66
|
+
it "should return array with 2 elements grouped by tags" do
|
67
|
+
expect(subject.query(query)).to eq(expected_result)
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
context "with multiple series with different tags" do
|
72
|
+
let(:response) do
|
73
|
+
{ "results" => [{ "series" => [{ "name" => "access_times.service_1", "tags" => { "code" => "200", "result" => "failure", "status" => "OK" }, "columns" => %w(time value), "values" => [["2015-07-08T07:15:22Z", 327]] },
|
74
|
+
{ "name" => "access_times.service_1", "tags" => { "code" => "500", "result" => "failure", "status" => "Internal Server Error" }, "columns" => %w(time value), "values" => [["2015-07-08T06:15:22Z", 873]] },
|
75
|
+
{ "name" => "access_times.service_2", "tags" => { "code" => "200", "result" => "failure", "status" => "OK" }, "columns" => %w(time value), "values" => [["2015-07-08T07:15:22Z", 943]] },
|
76
|
+
{ "name" => "access_times.service_2", "tags" => { "code" => "500", "result" => "failure", "status" => "Internal Server Error" }, "columns" => %w(time value), "values" => [["2015-07-08T06:15:22Z", 606]] }] }] }
|
77
|
+
end
|
78
|
+
let(:expected_result) do
|
79
|
+
[{ "name" => "access_times.service_1", "tags" => { "code" => "200", "result" => "failure", "status" => "OK" }, "values" => [{ "time" => "2015-07-08T07:15:22Z", "value" => 327 }] },
|
80
|
+
{ "name" => "access_times.service_1", "tags" => { "code" => "500", "result" => "failure", "status" => "Internal Server Error" }, "values" => [{ "time" => "2015-07-08T06:15:22Z", "value" => 873 }] },
|
81
|
+
{ "name" => "access_times.service_2", "tags" => { "code" => "200", "result" => "failure", "status" => "OK" }, "values" => [{ "time" => "2015-07-08T07:15:22Z", "value" => 943 }] },
|
82
|
+
{ "name" => "access_times.service_2", "tags" => { "code" => "500", "result" => "failure", "status" => "Internal Server Error" }, "values" => [{ "time" => "2015-07-08T06:15:22Z", "value" => 606 }] }]
|
83
|
+
end
|
84
|
+
let(:query) { "SELECT * FROM /access_times.*/" }
|
85
|
+
|
86
|
+
before do
|
87
|
+
stub_request(:get, "http://influxdb.test:9999/query").with(
|
88
|
+
query: { q: query, u: "username", p: "password", precision: 's', db: database }
|
89
|
+
).to_return(body: JSON.generate(response))
|
90
|
+
end
|
91
|
+
|
92
|
+
it "should return array with 4 elements grouped by name and tags" do
|
93
|
+
expect(subject.query(query)).to eq(expected_result)
|
94
|
+
end
|
95
|
+
end
|
96
|
+
|
97
|
+
context "with multiple series for explicit value only" do
|
98
|
+
let(:response) do
|
99
|
+
{ "results" => [{ "series" => [{ "name" => "access_times.service_1", "columns" => %w(time value), "values" => [["2015-07-08T06:15:22Z", 873], ["2015-07-08T07:15:22Z", 327]] },
|
100
|
+
{ "name" => "access_times.service_2", "columns" => %w(time value), "values" => [["2015-07-08T06:15:22Z", 606], ["2015-07-08T07:15:22Z", 943]] }] }] }
|
101
|
+
end
|
102
|
+
let(:expected_result) do
|
103
|
+
[{ "name" => "access_times.service_1", "tags" => nil, "values" => [{ "time" => "2015-07-08T06:15:22Z", "value" => 873 }, { "time" => "2015-07-08T07:15:22Z", "value" => 327 }] },
|
104
|
+
{ "name" => "access_times.service_2", "tags" => nil, "values" => [{ "time" => "2015-07-08T06:15:22Z", "value" => 606 }, { "time" => "2015-07-08T07:15:22Z", "value" => 943 }] }]
|
105
|
+
end
|
106
|
+
let(:query) { "SELECT value FROM /access_times.*/" }
|
107
|
+
|
108
|
+
before do
|
109
|
+
stub_request(:get, "http://influxdb.test:9999/query").with(
|
110
|
+
query: { q: query, u: "username", p: "password", precision: 's', db: database }
|
111
|
+
).to_return(body: JSON.generate(response))
|
112
|
+
end
|
113
|
+
|
114
|
+
it "should return array with 2 elements grouped by name only and no tags" do
|
115
|
+
expect(subject.query(query)).to eq(expected_result)
|
116
|
+
end
|
117
|
+
end
|
118
|
+
|
119
|
+
context "with a block" do
|
120
|
+
let(:response) do
|
121
|
+
{ "results" => [{ "series" => [{ "name" => "cpu", "tags" => { "region" => "pl" }, "columns" => %w(time temp value), "values" => [["2015-07-07T15:13:04Z", 34, 0.343443]] },
|
122
|
+
{ "name" => "cpu", "tags" => { "region" => "us" }, "columns" => %w(time temp value), "values" => [["2015-07-07T14:58:37Z", 92, 0.3445], ["2015-07-07T14:59:09Z", 68, 0.8787]] }] }] }
|
123
|
+
end
|
124
|
+
|
125
|
+
let(:expected_result) do
|
126
|
+
[{ "name" => "cpu", "tags" => { "region" => "pl" },
|
127
|
+
"values" => [{ "time" => "2015-07-07T15:13:04Z", "temp" => 34, "value" => 0.343443 }] },
|
128
|
+
{ "name" => "cpu", "tags" => { "region" => "us" },
|
129
|
+
"values" => [{ "time" => "2015-07-07T14:58:37Z", "temp" => 92, "value" => 0.3445 },
|
130
|
+
{ "time" => "2015-07-07T14:59:09Z", "temp" => 68, "value" => 0.8787 }] }]
|
131
|
+
end
|
132
|
+
let(:query) { 'SELECT * FROM cpu' }
|
133
|
+
|
134
|
+
before do
|
135
|
+
stub_request(:get, "http://influxdb.test:9999/query").with(
|
136
|
+
query: { q: query, u: "username", p: "password", precision: 's', db: database }
|
137
|
+
).to_return(body: JSON.generate(response))
|
138
|
+
end
|
139
|
+
|
140
|
+
it "should accept a block and yield name, tags and points" do
|
141
|
+
results = []
|
142
|
+
subject.query(query) do |name, tags, points|
|
143
|
+
results << { 'name' => name, 'tags' => tags, 'values' => points }
|
144
|
+
end
|
145
|
+
expect(results).to eq(expected_result)
|
146
|
+
end
|
147
|
+
end
|
148
|
+
end
|
149
|
+
end
|
@@ -0,0 +1,102 @@
|
|
1
|
+
require "spec_helper"
|
2
|
+
require "json"
|
3
|
+
|
4
|
+
describe InfluxDB::Client do
|
5
|
+
let(:client) do
|
6
|
+
described_class.new(
|
7
|
+
"database",
|
8
|
+
{
|
9
|
+
host: "influxdb.test",
|
10
|
+
port: 9999,
|
11
|
+
username: "username",
|
12
|
+
password: "password",
|
13
|
+
time_precision: "s"
|
14
|
+
}.merge(args)
|
15
|
+
)
|
16
|
+
end
|
17
|
+
|
18
|
+
let(:args) { {} }
|
19
|
+
|
20
|
+
let(:database) { client.config.database }
|
21
|
+
|
22
|
+
describe "retrying requests" do
|
23
|
+
let(:series) { "cpu" }
|
24
|
+
let(:data) do
|
25
|
+
{ tags: { region: 'us', host: 'server_1' },
|
26
|
+
values: { temp: 88, value: 54 } }
|
27
|
+
end
|
28
|
+
let(:body) do
|
29
|
+
InfluxDB::PointValue.new(data.merge(series: series)).dump
|
30
|
+
end
|
31
|
+
|
32
|
+
subject { client.write_point(series, data) }
|
33
|
+
|
34
|
+
before do
|
35
|
+
allow(client).to receive(:log)
|
36
|
+
stub_request(:post, "http://influxdb.test:9999/write").with(
|
37
|
+
query: { u: "username", p: "password", precision: 's', db: database },
|
38
|
+
headers: { "Content-Type" => "application/octet-stream" },
|
39
|
+
body: body
|
40
|
+
).to_raise(Timeout::Error)
|
41
|
+
end
|
42
|
+
|
43
|
+
it "raises when stopped" do
|
44
|
+
client.stop!
|
45
|
+
expect(client).not_to receive(:sleep)
|
46
|
+
expect { subject }.to raise_error(InfluxDB::ConnectionError) do |e|
|
47
|
+
expect(e.cause).to be_an_instance_of(Timeout::Error)
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
context "when retry is 0" do
|
52
|
+
let(:args) { { retry: 0 } }
|
53
|
+
it "raise error directly" do
|
54
|
+
expect(client).not_to receive(:sleep)
|
55
|
+
expect { subject }.to raise_error(InfluxDB::ConnectionError) do |e|
|
56
|
+
expect(e.cause).to be_an_instance_of(Timeout::Error)
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
context "when retry is 'n'" do
|
62
|
+
let(:args) { { retry: 3 } }
|
63
|
+
|
64
|
+
it "raise error after 'n' attemps" do
|
65
|
+
expect(client).to receive(:sleep).exactly(3).times
|
66
|
+
expect { subject }.to raise_error(InfluxDB::ConnectionError) do |e|
|
67
|
+
expect(e.cause).to be_an_instance_of(Timeout::Error)
|
68
|
+
end
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
72
|
+
context "when retry is -1" do
|
73
|
+
let(:args) { { retry: -1 } }
|
74
|
+
before do
|
75
|
+
stub_request(:post, "http://influxdb.test:9999/write").with(
|
76
|
+
query: { u: "username", p: "password", precision: 's', db: database },
|
77
|
+
headers: { "Content-Type" => "application/octet-stream" },
|
78
|
+
body: body
|
79
|
+
).to_raise(Timeout::Error).then
|
80
|
+
.to_raise(Timeout::Error).then
|
81
|
+
.to_raise(Timeout::Error).then
|
82
|
+
.to_raise(Timeout::Error).then
|
83
|
+
.to_return(status: 200)
|
84
|
+
end
|
85
|
+
|
86
|
+
it "keep trying until get the connection" do
|
87
|
+
expect(client).to receive(:sleep).exactly(4).times
|
88
|
+
expect { subject }.to_not raise_error
|
89
|
+
end
|
90
|
+
end
|
91
|
+
|
92
|
+
it "raise an exception if the server didn't return 200" do
|
93
|
+
stub_request(:post, "http://influxdb.test:9999/write").with(
|
94
|
+
query: { u: "username", p: "password", precision: 's', db: database },
|
95
|
+
headers: { "Content-Type" => "application/octet-stream" },
|
96
|
+
body: body
|
97
|
+
).to_return(status: 401)
|
98
|
+
|
99
|
+
expect { client.write_point(series, data) }.to raise_error(InfluxDB::AuthenticationError)
|
100
|
+
end
|
101
|
+
end
|
102
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
require "spec_helper"
|
2
|
+
|
3
|
+
describe InfluxDB::Client do
|
4
|
+
let(:client) { described_class.new(udp: { host: "localhost", port: 44_444 }) }
|
5
|
+
|
6
|
+
specify { expect(client.writer).to be_a(InfluxDB::Writer::UDP) }
|
7
|
+
|
8
|
+
describe "#write" do
|
9
|
+
let(:message) { 'responses,region="eu" value=5' }
|
10
|
+
|
11
|
+
it "sends a UPD packet" do
|
12
|
+
s = UDPSocket.new
|
13
|
+
s.bind("localhost", 44_444)
|
14
|
+
|
15
|
+
client.write_point("responses", values: { value: 5 }, tags: { region: 'eu' })
|
16
|
+
|
17
|
+
rec_message = s.recvfrom(30).first
|
18
|
+
expect(rec_message).to eq message
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,140 @@
|
|
1
|
+
require "spec_helper"
|
2
|
+
require "json"
|
3
|
+
|
4
|
+
describe InfluxDB::Client do
|
5
|
+
let(:subject) do
|
6
|
+
described_class.new(
|
7
|
+
"database",
|
8
|
+
{
|
9
|
+
host: "influxdb.test",
|
10
|
+
port: 9999,
|
11
|
+
username: "username",
|
12
|
+
password: "password",
|
13
|
+
time_precision: "s"
|
14
|
+
}.merge(args)
|
15
|
+
)
|
16
|
+
end
|
17
|
+
|
18
|
+
let(:args) { {} }
|
19
|
+
|
20
|
+
let(:database) { subject.config.database }
|
21
|
+
|
22
|
+
describe "#write_point" do
|
23
|
+
let(:series) { "cpu" }
|
24
|
+
let(:data) do
|
25
|
+
{ tags: { region: 'us', host: 'server_1' },
|
26
|
+
values: { temp: 88, value: 54 } }
|
27
|
+
end
|
28
|
+
let(:body) do
|
29
|
+
InfluxDB::PointValue.new(data.merge(series: series)).dump
|
30
|
+
end
|
31
|
+
|
32
|
+
before do
|
33
|
+
stub_request(:post, "http://influxdb.test:9999/write").with(
|
34
|
+
query: { u: "username", p: "password", precision: 's', db: database },
|
35
|
+
headers: { "Content-Type" => "application/octet-stream" },
|
36
|
+
body: body
|
37
|
+
)
|
38
|
+
end
|
39
|
+
|
40
|
+
it "should POST to add single point" do
|
41
|
+
expect(subject.write_point(series, data)).to be_a(Net::HTTPOK)
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
describe "#write_points" do
|
46
|
+
context "with multiple series" do
|
47
|
+
let(:data) do
|
48
|
+
[{
|
49
|
+
series: 'cpu',
|
50
|
+
tags: { region: 'us', host: 'server_1' },
|
51
|
+
values: { temp: 88, value: 54 }
|
52
|
+
},
|
53
|
+
{
|
54
|
+
series: 'gpu',
|
55
|
+
tags: { region: 'uk', host: 'server_5' },
|
56
|
+
values: { value: 0.5435345 }
|
57
|
+
}]
|
58
|
+
end
|
59
|
+
let(:body) do
|
60
|
+
data.map do |point|
|
61
|
+
InfluxDB::PointValue.new(point).dump
|
62
|
+
end.join("\n")
|
63
|
+
end
|
64
|
+
|
65
|
+
before do
|
66
|
+
stub_request(:post, "http://influxdb.test:9999/write").with(
|
67
|
+
query: { u: "username", p: "password", precision: 's', db: database },
|
68
|
+
headers: { "Content-Type" => "application/octet-stream" },
|
69
|
+
body: body
|
70
|
+
)
|
71
|
+
end
|
72
|
+
|
73
|
+
it "should POST multiple points" do
|
74
|
+
expect(subject.write_points(data)).to be_a(Net::HTTPOK)
|
75
|
+
end
|
76
|
+
end
|
77
|
+
|
78
|
+
context "with no tags" do
|
79
|
+
let(:data) do
|
80
|
+
[{
|
81
|
+
series: 'cpu',
|
82
|
+
values: { temp: 88, value: 54 }
|
83
|
+
},
|
84
|
+
{
|
85
|
+
series: 'gpu',
|
86
|
+
values: { value: 0.5435345 }
|
87
|
+
}]
|
88
|
+
end
|
89
|
+
let(:body) do
|
90
|
+
data.map do |point|
|
91
|
+
InfluxDB::PointValue.new(point).dump
|
92
|
+
end.join("\n")
|
93
|
+
end
|
94
|
+
|
95
|
+
before do
|
96
|
+
stub_request(:post, "http://influxdb.test:9999/write").with(
|
97
|
+
query: { u: "username", p: "password", precision: 's', db: database },
|
98
|
+
headers: { "Content-Type" => "application/octet-stream" },
|
99
|
+
body: body
|
100
|
+
)
|
101
|
+
end
|
102
|
+
|
103
|
+
it "should POST multiple points" do
|
104
|
+
expect(subject.write_points(data)).to be_a(Net::HTTPOK)
|
105
|
+
end
|
106
|
+
end
|
107
|
+
|
108
|
+
context "with time precision set to milisceconds" do
|
109
|
+
let(:data) do
|
110
|
+
[{
|
111
|
+
series: 'cpu',
|
112
|
+
values: { temp: 88, value: 54 },
|
113
|
+
timestamp: (Time.now.to_f * 1000).to_i
|
114
|
+
},
|
115
|
+
{
|
116
|
+
series: 'gpu',
|
117
|
+
values: { value: 0.5435345 },
|
118
|
+
timestamp: (Time.now.to_f * 1000).to_i
|
119
|
+
}]
|
120
|
+
end
|
121
|
+
|
122
|
+
let(:body) do
|
123
|
+
data.map do |point|
|
124
|
+
InfluxDB::PointValue.new(point).dump
|
125
|
+
end.join("\n")
|
126
|
+
end
|
127
|
+
|
128
|
+
before do
|
129
|
+
stub_request(:post, "http://influxdb.test:9999/write").with(
|
130
|
+
query: { u: "username", p: "password", precision: 'm', db: database },
|
131
|
+
headers: { "Content-Type" => "application/octet-stream" },
|
132
|
+
body: body
|
133
|
+
)
|
134
|
+
end
|
135
|
+
it "should POST multiple points" do
|
136
|
+
expect(subject.write_points(data, 'm')).to be_a(Net::HTTPOK)
|
137
|
+
end
|
138
|
+
end
|
139
|
+
end
|
140
|
+
end
|
@@ -2,838 +2,65 @@ require "spec_helper"
|
|
2
2
|
require "json"
|
3
3
|
|
4
4
|
describe InfluxDB::Client do
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
:password => "password", :time_precision => "s" }.merge(args)
|
9
|
-
end
|
10
|
-
let(:args) { {} }
|
11
|
-
|
12
|
-
describe "#new" do
|
13
|
-
describe "with no parameters specified" do
|
14
|
-
it "should be initialzed with a nil database and the default options" do
|
15
|
-
@influxdb = InfluxDB::Client.new
|
16
|
-
|
17
|
-
@influxdb.should be_a InfluxDB::Client
|
18
|
-
@influxdb.database.should be_nil
|
19
|
-
@influxdb.hosts.should == ["localhost"]
|
20
|
-
@influxdb.port.should == 8086
|
21
|
-
@influxdb.username.should == "root"
|
22
|
-
@influxdb.password.should == "root"
|
23
|
-
@influxdb.use_ssl.should be_falsey
|
24
|
-
@influxdb.time_precision.should == "s"
|
25
|
-
@influxdb.auth_method.should == "params"
|
26
|
-
end
|
27
|
-
end
|
28
|
-
|
29
|
-
describe "with no database specified" do
|
30
|
-
it "should be initialized with a nil database and the specified options" do
|
31
|
-
@influxdb = InfluxDB::Client.new :host => "host",
|
32
|
-
:port => "port",
|
33
|
-
:username => "username",
|
34
|
-
:password => "password",
|
35
|
-
:time_precision => "m"
|
36
|
-
|
37
|
-
@influxdb.should be_a InfluxDB::Client
|
38
|
-
@influxdb.database.should be_nil
|
39
|
-
@influxdb.hosts.should == ["host"]
|
40
|
-
@influxdb.port.should == "port"
|
41
|
-
@influxdb.username.should == "username"
|
42
|
-
@influxdb.password.should == "password"
|
43
|
-
@influxdb.time_precision.should == "m"
|
44
|
-
end
|
45
|
-
end
|
46
|
-
|
47
|
-
describe "with only a database specified" do
|
48
|
-
it "should be initialized with the specified database and the default options" do
|
49
|
-
@influxdb = InfluxDB::Client.new "database"
|
50
|
-
|
51
|
-
@influxdb.should be_a(InfluxDB::Client)
|
52
|
-
@influxdb.database.should == "database"
|
53
|
-
@influxdb.hosts.should == ["localhost"]
|
54
|
-
@influxdb.port.should == 8086
|
55
|
-
@influxdb.username.should == "root"
|
56
|
-
@influxdb.password.should == "root"
|
57
|
-
@influxdb.time_precision.should == "s"
|
58
|
-
end
|
59
|
-
end
|
60
|
-
|
61
|
-
describe "with both a database and options specified" do
|
62
|
-
it "should be initialized with the specified database and options" do
|
63
|
-
@influxdb = InfluxDB::Client.new "database", :host => "host",
|
64
|
-
:port => "port",
|
65
|
-
:username => "username",
|
66
|
-
:password => "password",
|
67
|
-
:time_precision => "m"
|
68
|
-
|
69
|
-
@influxdb.should be_a(InfluxDB::Client)
|
70
|
-
@influxdb.database.should == "database"
|
71
|
-
@influxdb.hosts.should == ["host"]
|
72
|
-
@influxdb.port.should == "port"
|
73
|
-
@influxdb.username.should == "username"
|
74
|
-
@influxdb.password.should == "password"
|
75
|
-
@influxdb.time_precision.should == "m"
|
76
|
-
end
|
77
|
-
end
|
78
|
-
|
79
|
-
describe "with ssl option specified" do
|
80
|
-
it "should be initialized with ssl enabled" do
|
81
|
-
@influxdb = InfluxDB::Client.new :use_ssl => true
|
82
|
-
|
83
|
-
@influxdb.should be_a InfluxDB::Client
|
84
|
-
@influxdb.database.should be_nil
|
85
|
-
@influxdb.hosts.should == ["localhost"]
|
86
|
-
@influxdb.port.should == 8086
|
87
|
-
@influxdb.username.should == "root"
|
88
|
-
@influxdb.password.should == "root"
|
89
|
-
@influxdb.use_ssl.should be_truthy
|
90
|
-
end
|
91
|
-
end
|
92
|
-
|
93
|
-
describe "with multiple hosts specified" do
|
94
|
-
it "should be initialized with ssl enabled" do
|
95
|
-
@influxdb = InfluxDB::Client.new :hosts => ["1.1.1.1", "2.2.2.2"]
|
96
|
-
|
97
|
-
@influxdb.should be_a InfluxDB::Client
|
98
|
-
@influxdb.database.should be_nil
|
99
|
-
@influxdb.hosts.should == ["1.1.1.1", "2.2.2.2"]
|
100
|
-
@influxdb.port.should == 8086
|
101
|
-
@influxdb.username.should == "root"
|
102
|
-
@influxdb.password.should == "root"
|
103
|
-
end
|
104
|
-
end
|
105
|
-
|
106
|
-
describe "with auth_method basic auth specified" do
|
107
|
-
it "should be initialized with basic auth enabled" do
|
108
|
-
@influxdb = InfluxDB::Client.new :auth_method => 'basic_auth'
|
109
|
-
|
110
|
-
@influxdb.should be_a(InfluxDB::Client)
|
111
|
-
@influxdb.auth_method.should == 'basic_auth'
|
112
|
-
@influxdb.username.should == "root"
|
113
|
-
@influxdb.password.should == "root"
|
114
|
-
end
|
115
|
-
end
|
116
|
-
|
117
|
-
describe "with udp specified" do
|
118
|
-
it "should initialize a udp client" do
|
119
|
-
@influxdb = InfluxDB::Client.new :udp => { :host => 'localhost', :port => 4444 }
|
120
|
-
expect(@influxdb.udp_client).to be_a(InfluxDB::UDPClient)
|
121
|
-
end
|
122
|
-
|
123
|
-
context "without udp specfied" do
|
124
|
-
it "does not initialize a udp client" do
|
125
|
-
@influxdb = InfluxDB::Client.new
|
126
|
-
expect(@influxdb.udp_client).to be_nil
|
127
|
-
end
|
128
|
-
end
|
129
|
-
end
|
130
|
-
end
|
131
|
-
|
132
|
-
|
133
|
-
context "with basic auth enabled" do
|
134
|
-
let(:args) { { :auth_method => 'basic_auth' } }
|
135
|
-
it "should use basic authorization for get" do
|
136
|
-
stub_request(:get, "http://username:password@influxdb.test:9999/").to_return(:body => '[]')
|
137
|
-
@influxdb.send(:get , @influxdb.send(:full_url,'/')).should == []
|
138
|
-
end
|
139
|
-
it "should use basic authorization for post" do
|
140
|
-
stub_request(:post, "http://username:password@influxdb.test:9999/")
|
141
|
-
@influxdb.send(:post , @influxdb.send(:full_url,'/'), {}).should be_a(Net::HTTPOK)
|
142
|
-
end
|
143
|
-
it "should use basic authorization for delete" do
|
144
|
-
stub_request(:delete, "http://username:password@influxdb.test:9999/")
|
145
|
-
@influxdb.send(:delete , @influxdb.send(:full_url,'/')).should be_a(Net::HTTPOK)
|
146
|
-
end
|
147
|
-
end
|
148
|
-
|
149
|
-
describe "#ping" do
|
150
|
-
it "should return status ok" do
|
151
|
-
status_ok = {"status" => "ok"}
|
152
|
-
stub_request(:get, "http://influxdb.test:9999/ping"
|
153
|
-
).to_return(:body => JSON.generate(status_ok), :status => 200)
|
154
|
-
|
155
|
-
@influxdb.ping.should == status_ok
|
156
|
-
end
|
157
|
-
end
|
158
|
-
|
159
|
-
describe "#create_database" do
|
160
|
-
it "should POST to create a new database" do
|
161
|
-
stub_request(
|
162
|
-
:post, 'http://influxdb.test:9999/cluster/database_configs/foo'
|
163
|
-
).with(
|
164
|
-
:query => {:u => "username", :p => "password"},
|
165
|
-
:body => {:spaces => []}
|
166
|
-
)
|
167
|
-
|
168
|
-
@influxdb.create_database("foo", {:spaces => []}).should be_a(Net::HTTPOK)
|
169
|
-
end
|
170
|
-
end
|
171
|
-
|
172
|
-
describe "#delete_database" do
|
173
|
-
it "should DELETE to remove a database" do
|
174
|
-
stub_request(:delete, "http://influxdb.test:9999/db/foo").with(
|
175
|
-
:query => {:u => "username", :p => "password"}
|
176
|
-
)
|
177
|
-
|
178
|
-
@influxdb.delete_database("foo").should be_a(Net::HTTPOK)
|
179
|
-
end
|
180
|
-
end
|
181
|
-
|
182
|
-
describe "#get_database_list" do
|
183
|
-
it "should GET a list of databases" do
|
184
|
-
database_list = [{"name" => "foobar"}]
|
185
|
-
stub_request(:get, "http://influxdb.test:9999/db").with(
|
186
|
-
:query => {:u => "username", :p => "password"}
|
187
|
-
).to_return(:body => JSON.generate(database_list), :status => 200)
|
188
|
-
|
189
|
-
@influxdb.get_database_list.should == database_list
|
190
|
-
end
|
191
|
-
end
|
192
|
-
|
193
|
-
describe "#authenticate_cluster_admin" do
|
194
|
-
it "should GET to authenticate a cluster admin" do
|
195
|
-
stub_request(:get, "http://influxdb.test:9999/cluster_admins/authenticate").with(
|
196
|
-
:query => {:u => "username", :p => "password"}
|
197
|
-
)
|
198
|
-
|
199
|
-
@influxdb.authenticate_cluster_admin.should be_a(Net::HTTPOK)
|
200
|
-
end
|
201
|
-
end
|
202
|
-
|
203
|
-
describe "#create_cluster_admin" do
|
204
|
-
it "should POST to create a new cluster admin" do
|
205
|
-
stub_request(:post, "http://influxdb.test:9999/cluster_admins").with(
|
206
|
-
:query => {:u => "username", :p => "password"},
|
207
|
-
:body => {:name => "adminadmin", :password => "passpass"}
|
208
|
-
)
|
209
|
-
|
210
|
-
@influxdb.create_cluster_admin("adminadmin", "passpass").should be_a(Net::HTTPOK)
|
211
|
-
end
|
212
|
-
end
|
213
|
-
|
214
|
-
describe "#update_cluster_admin" do
|
215
|
-
it "should POST to update a cluster admin" do
|
216
|
-
stub_request(:post, "http://influxdb.test:9999/cluster_admins/adminadmin").with(
|
217
|
-
:query => {:u => "username", :p => "password"},
|
218
|
-
:body => {:password => "passpass"}
|
219
|
-
)
|
220
|
-
|
221
|
-
@influxdb.update_cluster_admin("adminadmin", "passpass").should be_a(Net::HTTPOK)
|
222
|
-
end
|
223
|
-
end
|
224
|
-
|
225
|
-
describe "#delete_cluster_admin" do
|
226
|
-
it "should DELETE a cluster admin" do
|
227
|
-
stub_request(:delete, "http://influxdb.test:9999/cluster_admins/adminadmin").with(
|
228
|
-
:query => {:u => "username", :p => "password"}
|
229
|
-
)
|
230
|
-
|
231
|
-
@influxdb.delete_cluster_admin("adminadmin").should be_a(Net::HTTPOK)
|
232
|
-
end
|
233
|
-
end
|
234
|
-
|
235
|
-
describe "#get_cluster_admin_list" do
|
236
|
-
it "should GET a list of cluster admins" do
|
237
|
-
admin_list = [{"username"=>"root"}, {"username"=>"admin"}]
|
238
|
-
stub_request(:get, "http://influxdb.test:9999/cluster_admins").with(
|
239
|
-
:query => {:u => "username", :p => "password"}
|
240
|
-
).to_return(:body => JSON.generate(admin_list), :status => 200)
|
241
|
-
|
242
|
-
@influxdb.get_cluster_admin_list.should == admin_list
|
243
|
-
end
|
244
|
-
end
|
245
|
-
|
246
|
-
describe "#authenticate_database_user" do
|
247
|
-
it "should GET to authenticate a database database" do
|
248
|
-
stub_request(:get, "http://influxdb.test:9999/db/foo/authenticate").with(
|
249
|
-
:query => {:u => "username", :p => "password"}
|
250
|
-
).to_return(:body => '', :status => 200)
|
251
|
-
|
252
|
-
@influxdb.authenticate_database_user("foo").should be_a(Net::HTTPOK)
|
253
|
-
end
|
254
|
-
end
|
255
|
-
|
256
|
-
describe "#create_database_user" do
|
257
|
-
it "should POST to create a new database user" do
|
258
|
-
stub_request(:post, "http://influxdb.test:9999/db/foo/users").with(
|
259
|
-
:query => {:u => "username", :p => "password"},
|
260
|
-
:body => {:name => "useruser", :password => "passpass"}
|
261
|
-
)
|
262
|
-
|
263
|
-
@influxdb.create_database_user("foo", "useruser", "passpass").should be_a(Net::HTTPOK)
|
264
|
-
end
|
265
|
-
|
266
|
-
it "should POST to create a new database user with permissions" do
|
267
|
-
stub_request(:post, "http://influxdb.test:9999/db/foo/users").with(
|
268
|
-
:query => {:u => "username", :p => "password"},
|
269
|
-
:body => {:name => "useruser", :password => "passpass", :readFrom => "/read*/", :writeTo => "/write*/"}
|
270
|
-
)
|
271
|
-
|
272
|
-
@influxdb.create_database_user(
|
273
|
-
"foo",
|
274
|
-
"useruser",
|
275
|
-
"passpass",
|
276
|
-
{:readFrom => "/read*/", :writeTo => "/write*/"}
|
277
|
-
).should be_a(Net::HTTPOK)
|
278
|
-
end
|
279
|
-
end
|
280
|
-
|
281
|
-
describe "#update_database_user" do
|
282
|
-
it "should POST to update a database user" do
|
283
|
-
stub_request(:post, "http://influxdb.test:9999/db/foo/users/useruser").with(
|
284
|
-
:query => {:u => "username", :p => "password"},
|
285
|
-
:body => {:password => "passpass"}
|
286
|
-
)
|
287
|
-
|
288
|
-
@influxdb.update_database_user("foo", "useruser", :password => "passpass").should be_a(Net::HTTPOK)
|
289
|
-
end
|
290
|
-
end
|
291
|
-
|
292
|
-
describe "#alter_database_privilege" do
|
293
|
-
it "should POST to alter privileges for a user on a database" do
|
294
|
-
stub_request(:post, "http://influxdb.test:9999/db/foo/users/useruser").with(
|
295
|
-
:query => {:u => "username", :p => "password"}
|
296
|
-
)
|
297
|
-
|
298
|
-
@influxdb.alter_database_privilege("foo", "useruser", admin=true).should be_a(Net::HTTPOK)
|
299
|
-
@influxdb.alter_database_privilege("foo", "useruser", admin=false).should be_a(Net::HTTPOK)
|
300
|
-
end
|
301
|
-
end
|
302
|
-
|
303
|
-
describe "#delete_database_user" do
|
304
|
-
it "should DELETE a database user" do
|
305
|
-
stub_request(:delete, "http://influxdb.test:9999/db/foo/users/bar").with(
|
306
|
-
:query => {:u => "username", :p => "password"}
|
307
|
-
)
|
308
|
-
|
309
|
-
@influxdb.delete_database_user("foo", "bar").should be_a(Net::HTTPOK)
|
310
|
-
end
|
311
|
-
end
|
312
|
-
|
313
|
-
describe "#get_database_user_list" do
|
314
|
-
it "should GET a list of database users" do
|
315
|
-
user_list = [{"username"=>"user1"}, {"username"=>"user2"}]
|
316
|
-
stub_request(:get, "http://influxdb.test:9999/db/foo/users").with(
|
317
|
-
:query => {:u => "username", :p => "password"}
|
318
|
-
).to_return(:body => JSON.generate(user_list, :status => 200))
|
319
|
-
|
320
|
-
@influxdb.get_database_user_list("foo").should == user_list
|
321
|
-
end
|
322
|
-
end
|
323
|
-
|
324
|
-
describe "#get_database_user_info" do
|
325
|
-
it "should GET information about a database user" do
|
326
|
-
user_info = {"name" => "bar", "isAdmin" => true}
|
327
|
-
stub_request(:get, "http://influxdb.test:9999/db/foo/users/bar").with(
|
328
|
-
:query => {:u => "username", :p => "password"}
|
329
|
-
).to_return(:body => JSON.generate(user_info, :status => 200))
|
330
|
-
|
331
|
-
@influxdb.get_database_user_info("foo", "bar").should == user_info
|
332
|
-
end
|
333
|
-
end
|
334
|
-
|
335
|
-
describe "#get_shard_list" do
|
336
|
-
it "should GET a list of shards" do
|
337
|
-
shard_list = {"longTerm" => [], "shortTerm" => []}
|
338
|
-
stub_request(:get, "http://influxdb.test:9999/cluster/shards").with(
|
339
|
-
:query => {:u => "username", :p => "password"}
|
340
|
-
).to_return(:body => JSON.generate(shard_list, :status => 200))
|
341
|
-
|
342
|
-
@influxdb.get_shard_list.should == shard_list
|
343
|
-
end
|
344
|
-
end
|
345
|
-
|
346
|
-
describe "#delete_shard" do
|
347
|
-
it "should DELETE a shard by id" do
|
348
|
-
shard_id = 1
|
349
|
-
stub_request(:delete, "http://influxdb.test:9999/cluster/shards/#{shard_id}").with(
|
350
|
-
:query => {:u => "username", :p => "password"}
|
351
|
-
)
|
352
|
-
|
353
|
-
@influxdb.delete_shard(shard_id, [1, 2]).should be_a(Net::HTTPOK)
|
354
|
-
end
|
355
|
-
end
|
356
|
-
|
357
|
-
describe "#create_continuous_query" do
|
358
|
-
it "should GET to create a continuous query" do
|
359
|
-
stub_request(:get, "http://influxdb.test:9999/db/database/series").with(
|
360
|
-
:query => { :q => "select sys from cpu into sys", :u => "username", :p => "password", :time_precision => "s"}
|
361
|
-
).to_return(:body => JSON.generate({}))
|
362
|
-
|
363
|
-
@influxdb.create_continuous_query("select sys from cpu", "sys").should == {}
|
364
|
-
end
|
365
|
-
end
|
366
|
-
|
367
|
-
describe "#get_continuous_query_list" do
|
368
|
-
it "should GET to get continuous query list" do
|
369
|
-
body = [{
|
370
|
-
"name"=>"continuous queries",
|
371
|
-
"columns"=>["time", "sequence_number", "id", "query"],
|
372
|
-
"points"=>[
|
373
|
-
[1399, 1, 1, "select sys from cpu into sys"]
|
374
|
-
]
|
375
|
-
}]
|
376
|
-
expected = {
|
377
|
-
"continuous queries" => [
|
378
|
-
{
|
379
|
-
"time" => 1399,
|
380
|
-
"sequence_number" => 1,
|
381
|
-
"id" => 1,
|
382
|
-
"query" => "select sys from cpu into sys"
|
383
|
-
}
|
384
|
-
]
|
385
|
-
}
|
386
|
-
stub_request(:get, "http://influxdb.test:9999/db/database/series").with(
|
387
|
-
:query => { :q => "list continuous queries", :u => "username", :p => "password", :time_precision => "s"}
|
388
|
-
).to_return(:body => JSON.generate(body))
|
389
|
-
|
390
|
-
@influxdb.get_continuous_query_list.should == expected
|
391
|
-
end
|
392
|
-
end
|
393
|
-
|
394
|
-
describe "#delete_continuous_query" do
|
395
|
-
it "should GET to delete continuous query" do
|
396
|
-
id = 1
|
397
|
-
stub_request(:get, "http://influxdb.test:9999/db/database/series").with(
|
398
|
-
:query => { :q => "drop continuous query #{id}", :u => "username", :p => "password", :time_precision => "s"}
|
399
|
-
).to_return(:body => JSON.generate({}))
|
400
|
-
|
401
|
-
@influxdb.delete_continuous_query(id).should == {}
|
402
|
-
end
|
403
|
-
end
|
404
|
-
|
405
|
-
describe "#get_shard_space_list" do
|
406
|
-
let(:url) { "http://influxdb.test:9999/cluster/shard_spaces" }
|
407
|
-
let(:request_params) { {:query => {:u => "username", :p => "password"}} }
|
408
|
-
let(:response) { {:body => JSON.generate(shard_spaces, :status => 200)} }
|
409
|
-
let(:shard_spaces) { [@influxdb.default_shard_space_options.merge(:database => "foo")] }
|
410
|
-
|
411
|
-
it 'should GET a list of shard spaces' do
|
412
|
-
request = stub_request(:get, url).with(request_params).to_return(response)
|
413
|
-
|
414
|
-
@influxdb.get_shard_space_list
|
415
|
-
|
416
|
-
expect(request).to have_been_requested
|
417
|
-
end
|
418
|
-
end
|
419
|
-
|
420
|
-
describe "#get_shard_space" do
|
421
|
-
let(:url) { "http://influxdb.test:9999/cluster/shard_spaces" }
|
422
|
-
let(:request_params) { {:query => {:u => "username", :p => "password"}} }
|
423
|
-
let(:response) { {:body => JSON.generate(shard_spaces, :status => 200)} }
|
424
|
-
|
425
|
-
describe "#get_shard_space_list returns a non-empty list" do
|
426
|
-
let(:shard_spaces) { [@influxdb.default_shard_space_options.merge("database" => "foo")] }
|
427
|
-
|
428
|
-
it "finds the indicated shard space" do
|
429
|
-
request = stub_request(:get, url).with(request_params).to_return(response)
|
430
|
-
|
431
|
-
expect(@influxdb.get_shard_space('foo', 'default')).to eq shard_spaces.first
|
432
|
-
|
433
|
-
expect(request).to have_been_requested
|
434
|
-
end
|
435
|
-
end
|
436
|
-
|
437
|
-
describe "#get_shard_space_list returns an empty list" do
|
438
|
-
let(:shard_spaces) { [] }
|
439
|
-
|
440
|
-
it "finds no shard space" do
|
441
|
-
request = stub_request(:get, url).with(request_params).to_return(response)
|
442
|
-
|
443
|
-
expect(@influxdb.get_shard_space('foo', 'default')).to eq nil
|
444
|
-
|
445
|
-
expect(request).to have_been_requested
|
446
|
-
end
|
447
|
-
end
|
448
|
-
end
|
449
|
-
|
450
|
-
describe "#create_shard_space" do
|
451
|
-
let(:url) { "http://influxdb.test:9999/cluster/shard_spaces/foo" }
|
452
|
-
let(:request_params) do
|
5
|
+
let(:subject) do
|
6
|
+
described_class.new(
|
7
|
+
"database",
|
453
8
|
{
|
454
|
-
:
|
455
|
-
:
|
456
|
-
|
457
|
-
|
458
|
-
|
459
|
-
|
460
|
-
|
461
|
-
|
462
|
-
@influxdb.create_shard_space("foo", @influxdb.default_shard_space_options)
|
463
|
-
|
464
|
-
expect(request).to have_been_requested
|
465
|
-
end
|
466
|
-
end
|
467
|
-
|
468
|
-
describe "#delete_shard_space" do
|
469
|
-
let(:url) { "http://influxdb.test:9999/cluster/shard_spaces/foo/default" }
|
470
|
-
let(:request_params) { {:query => {:u => "username", :p => "password"}} }
|
471
|
-
|
472
|
-
it 'should DELETE to delete the shard space' do
|
473
|
-
request = stub_request(:delete, url).with(request_params)
|
474
|
-
|
475
|
-
@influxdb.delete_shard_space("foo", "default")
|
476
|
-
|
477
|
-
expect(request).to have_been_requested
|
478
|
-
end
|
9
|
+
host: "influxdb.test",
|
10
|
+
port: 9999,
|
11
|
+
username: "username",
|
12
|
+
password: "password",
|
13
|
+
time_precision: "s"
|
14
|
+
}.merge(args)
|
15
|
+
)
|
479
16
|
end
|
480
17
|
|
481
|
-
|
482
|
-
let(:get_url) { "http://influxdb.test:9999/cluster/shard_spaces" }
|
483
|
-
let(:get_request_params) { {:query => {:u => "username", :p => "password"}} }
|
484
|
-
let(:get_response) { {:body => JSON.generate(shard_spaces, :status => 200)} }
|
485
|
-
let(:shard_spaces) { [@influxdb.default_shard_space_options.merge("database" => "foo")] }
|
486
|
-
|
487
|
-
let(:post_url) { "http://influxdb.test:9999/cluster/shard_spaces/foo/default" }
|
488
|
-
let(:post_request_params) do
|
489
|
-
{
|
490
|
-
:query => {:u => "username", :p => "password"},
|
491
|
-
:body => @influxdb.default_shard_space_options.merge("shardDuration" => "30d")
|
492
|
-
}
|
493
|
-
end
|
18
|
+
let(:args) { {} }
|
494
19
|
|
495
|
-
|
496
|
-
get_request = stub_request(:get, get_url).with(get_request_params).to_return(get_response)
|
497
|
-
post_request = stub_request(:post, post_url).with(post_request_params)
|
20
|
+
specify { is_expected.not_to be_stopped }
|
498
21
|
|
499
|
-
|
22
|
+
context "with basic auth" do
|
23
|
+
let(:args) { { auth_method: 'basic_auth' } }
|
500
24
|
|
501
|
-
|
502
|
-
|
503
|
-
end
|
504
|
-
end
|
25
|
+
let(:stub_url) { "http://username:password@influxdb.test:9999/" }
|
26
|
+
let(:url) { subject.send(:full_url, '/') }
|
505
27
|
|
506
|
-
|
507
|
-
|
508
|
-
|
509
|
-
{
|
510
|
-
:query => {:u => "username", :p => "password"},
|
511
|
-
:body => @influxdb.default_database_configuration
|
512
|
-
}
|
28
|
+
it "GET" do
|
29
|
+
stub_request(:get, stub_url).to_return(body: '[]')
|
30
|
+
expect(subject.get(url, parse: true)).to eq []
|
513
31
|
end
|
514
32
|
|
515
|
-
it "
|
516
|
-
|
517
|
-
|
518
|
-
@influxdb.configure_database("foo").should be_a(Net::HTTPOK)
|
519
|
-
|
520
|
-
expect(request).to have_been_requested
|
33
|
+
it "POST" do
|
34
|
+
stub_request(:post, stub_url)
|
35
|
+
expect(subject.post(url, {})).to be_a(Net::HTTPOK)
|
521
36
|
end
|
522
37
|
end
|
523
38
|
|
524
|
-
describe "#
|
525
|
-
it "
|
526
|
-
|
527
|
-
"name" => "seriez",
|
528
|
-
"points" => [[87, "juan"]],
|
529
|
-
"columns" => ["age", "name"]
|
530
|
-
}]
|
531
|
-
|
532
|
-
stub_request(:post, "http://influxdb.test:9999/db/database/series").with(
|
533
|
-
:query => {:u => "username", :p => "password", :time_precision => "s"},
|
534
|
-
:body => body
|
535
|
-
)
|
536
|
-
|
537
|
-
data = {:name => "juan", :age => 87}
|
538
|
-
|
539
|
-
@influxdb.write_point("seriez", data).should be_a(Net::HTTPOK)
|
540
|
-
end
|
541
|
-
|
542
|
-
describe "retrying requests" do
|
543
|
-
let(:body) do
|
544
|
-
[{
|
545
|
-
"name" => "seriez",
|
546
|
-
"points" => [[87, "juan"]],
|
547
|
-
"columns" => ["age", "name"]
|
548
|
-
}]
|
549
|
-
end
|
550
|
-
|
551
|
-
let(:data) { {:name => "juan", :age => 87} }
|
552
|
-
|
553
|
-
subject { @influxdb.write_point("seriez", data) }
|
554
|
-
|
555
|
-
before do
|
556
|
-
allow(@influxdb).to receive(:log)
|
557
|
-
stub_request(:post, "http://influxdb.test:9999/db/database/series").with(
|
558
|
-
:query => {:u => "username", :p => "password", :time_precision => "s"},
|
559
|
-
:body => body
|
560
|
-
).to_raise(Timeout::Error)
|
561
|
-
end
|
562
|
-
|
563
|
-
it "raises when stopped" do
|
564
|
-
@influxdb.stop!
|
565
|
-
@influxdb.should_not_receive :sleep
|
566
|
-
expect { subject }.to raise_error(InfluxDB::ConnectionError) do |e|
|
567
|
-
expect(e.cause).to be_an_instance_of(Timeout::Error)
|
568
|
-
end
|
569
|
-
end
|
570
|
-
|
571
|
-
context "when retry is 0" do
|
572
|
-
let(:args) { { :retry => 0 } }
|
573
|
-
it "raise error directly" do
|
574
|
-
@influxdb.should_not_receive :sleep
|
575
|
-
expect { subject }.to raise_error(InfluxDB::ConnectionError) do |e|
|
576
|
-
expect(e.cause).to be_an_instance_of(Timeout::Error)
|
577
|
-
end
|
578
|
-
end
|
579
|
-
end
|
580
|
-
|
581
|
-
context "when retry is 'n'" do
|
582
|
-
let(:args) { { :retry => 3 } }
|
583
|
-
|
584
|
-
it "raise error after 'n' attemps" do
|
585
|
-
@influxdb.should_receive(:sleep).exactly(3).times
|
586
|
-
expect { subject }.to raise_error(InfluxDB::ConnectionError) do |e|
|
587
|
-
expect(e.cause).to be_an_instance_of(Timeout::Error)
|
588
|
-
end
|
589
|
-
end
|
590
|
-
end
|
591
|
-
|
592
|
-
context "when retry is -1" do
|
593
|
-
let(:args) { { :retry => -1 } }
|
594
|
-
before do
|
595
|
-
stub_request(:post, "http://influxdb.test:9999/db/database/series").with(
|
596
|
-
:query => {:u => "username", :p => "password", :time_precision => "s"},
|
597
|
-
:body => body
|
598
|
-
).to_raise(Timeout::Error).then.to_raise(Timeout::Error).then.to_raise(Timeout::Error).then.to_raise(Timeout::Error).then.to_return(:status => 200)
|
599
|
-
end
|
600
|
-
|
601
|
-
it "keep trying until get the connection" do
|
602
|
-
@influxdb.should_receive(:sleep).at_least(4).times
|
603
|
-
expect { subject }.to_not raise_error
|
604
|
-
end
|
605
|
-
end
|
606
|
-
end
|
607
|
-
|
608
|
-
it "raise an exception if the server didn't return 200" do
|
609
|
-
body = [{
|
610
|
-
"name" => "seriez",
|
611
|
-
"points" => [[87, "juan"]],
|
612
|
-
"columns" => ["age", "name"]
|
613
|
-
}]
|
614
|
-
|
615
|
-
stub_request(:post, "http://influxdb.test:9999/db/database/series").with(
|
616
|
-
:query => {:u => "username", :p => "password", :time_precision => "s"},
|
617
|
-
:body => body
|
618
|
-
).to_return(:status => 401)
|
619
|
-
|
620
|
-
data = {:name => "juan", :age => 87}
|
621
|
-
|
622
|
-
expect { @influxdb.write_point("seriez", data) }.to raise_error
|
623
|
-
end
|
624
|
-
|
625
|
-
it "should POST multiple points" do
|
626
|
-
body = [{
|
627
|
-
"name" => "seriez",
|
628
|
-
"points" => [[87, "juan"], [99, "shahid"]],
|
629
|
-
"columns" => ["age", "name"]
|
630
|
-
}]
|
631
|
-
|
632
|
-
stub_request(:post, "http://influxdb.test:9999/db/database/series").with(
|
633
|
-
:query => {:u => "username", :p => "password", :time_precision => "s"},
|
634
|
-
:body => body
|
635
|
-
).to_return(:status => 200)
|
636
|
-
|
637
|
-
data = [{:name => "juan", :age => 87}, { :name => "shahid", :age => 99}]
|
638
|
-
|
639
|
-
@influxdb.write_point("seriez", data).should be_a(Net::HTTPOK)
|
640
|
-
end
|
641
|
-
|
642
|
-
it "should POST multiple points with missing columns" do
|
643
|
-
body = [{
|
644
|
-
"name" => "seriez",
|
645
|
-
"points" => [[87, "juan"], [nil, "shahid"]],
|
646
|
-
"columns" => ["age", "name"]
|
647
|
-
}]
|
648
|
-
|
649
|
-
stub_request(:post, "http://influxdb.test:9999/db/database/series").with(
|
650
|
-
:query => {:u => "username", :p => "password", :time_precision => "s"},
|
651
|
-
:body => body
|
652
|
-
)
|
653
|
-
|
654
|
-
data = [{:name => "juan", :age => 87}, { :name => "shahid"}]
|
655
|
-
|
656
|
-
@influxdb.write_point("seriez", data).should be_a(Net::HTTPOK)
|
657
|
-
end
|
658
|
-
|
659
|
-
it "should dump a hash point value to json" do
|
660
|
-
prefs = [{'favorite_food' => 'lasagna'}]
|
661
|
-
body = [{
|
662
|
-
"name" => "users",
|
663
|
-
"points" => [[1, prefs.to_json]],
|
664
|
-
"columns" => ["id", "prefs"]
|
665
|
-
}]
|
666
|
-
|
667
|
-
stub_request(:post, "http://influxdb.test:9999/db/database/series").with(
|
668
|
-
:query => {:u => "username", :p => "password", :time_precision => "s"},
|
669
|
-
:body => body
|
670
|
-
)
|
671
|
-
|
672
|
-
data = {:id => 1, :prefs => prefs}
|
673
|
-
|
674
|
-
@influxdb.write_point("users", data).should be_a(Net::HTTPOK)
|
675
|
-
end
|
676
|
-
|
677
|
-
it "should dump an array point value to json" do
|
678
|
-
line_items = [{'id' => 1, 'product_id' => 2, 'quantity' => 1, 'price' => "100.00"}]
|
679
|
-
body = [{
|
680
|
-
"name" => "seriez",
|
681
|
-
"points" => [[1, line_items.to_json]],
|
682
|
-
"columns" => ["id", "line_items"]
|
683
|
-
}]
|
684
|
-
|
685
|
-
stub_request(:post, "http://influxdb.test:9999/db/database/series").with(
|
686
|
-
:query => {:u => "username", :p => "password", :time_precision => "s"},
|
687
|
-
:body => body
|
688
|
-
)
|
689
|
-
|
690
|
-
data = {:id => 1, :line_items => line_items}
|
691
|
-
|
692
|
-
@influxdb.write_point("seriez", data).should be_a(Net::HTTPOK)
|
693
|
-
end
|
694
|
-
|
695
|
-
it "should POST to add points with time field with precision defined in client initialization" do
|
696
|
-
time_in_seconds = Time.now.to_i
|
697
|
-
body = [{
|
698
|
-
"name" => "seriez",
|
699
|
-
"points" => [[87, "juan", time_in_seconds]],
|
700
|
-
"columns" => ["age", "name", "time"]
|
701
|
-
}]
|
702
|
-
|
703
|
-
stub_request(:post, "http://influxdb.test:9999/db/database/series").with(
|
704
|
-
:query => {:u => "username", :p => "password", :time_precision => "s"},
|
705
|
-
:body => body
|
706
|
-
)
|
707
|
-
|
708
|
-
data = {:name => "juan", :age => 87, :time => time_in_seconds}
|
709
|
-
|
710
|
-
@influxdb.write_point("seriez", data).should be_a(Net::HTTPOK)
|
711
|
-
end
|
712
|
-
|
713
|
-
it "should POST to add points with time field with precision defined in call of write function" do
|
714
|
-
time_in_milliseconds = (Time.now.to_f * 1000).to_i
|
715
|
-
body = [{
|
716
|
-
"name" => "seriez",
|
717
|
-
"points" => [[87, "juan", time_in_milliseconds]],
|
718
|
-
"columns" => ["age", "name", "time"]
|
719
|
-
}]
|
720
|
-
|
721
|
-
stub_request(:post, "http://influxdb.test:9999/db/database/series").with(
|
722
|
-
:query => {:u => "username", :p => "password", :time_precision => "m"},
|
723
|
-
:body => body
|
724
|
-
)
|
725
|
-
|
726
|
-
data = {:name => "juan", :age => 87, :time => time_in_milliseconds}
|
727
|
-
|
728
|
-
@influxdb.write_point("seriez", data, false, "m").should be_a(Net::HTTPOK)
|
729
|
-
end
|
730
|
-
|
731
|
-
describe "async" do
|
732
|
-
|
733
|
-
it "should push to the worker with payload if client is async" do
|
734
|
-
@influxdb = InfluxDB::Client.new "database", :host => "influxdb.test", :async => true
|
735
|
-
|
736
|
-
time = Time.now.to_i
|
737
|
-
data = {:name => "juan", :age => 87, :time => time}
|
738
|
-
expected_data = [{:name => 'seriez', :points => [[87, 'juan', time]], :columns => [:age, :name, :time]}]
|
739
|
-
@influxdb.stub_chain(:worker, :push).with(expected_data).and_return(:ok)
|
740
|
-
@influxdb.write_point("seriez", data).should eq(:ok)
|
741
|
-
end
|
742
|
-
|
743
|
-
it "should push to the worker with payload if write_point call is async" do
|
744
|
-
@influxdb = InfluxDB::Client.new "database", :host => "influxdb.test", :async => false
|
745
|
-
|
746
|
-
time = Time.now.to_i
|
747
|
-
data = {:name => "juan", :age => 87, :time => time}
|
748
|
-
expected_data = [{:name => 'seriez', :points => [[87, 'juan', time]], :columns => [:age, :name, :time]}]
|
749
|
-
@influxdb.stub_chain(:worker, :push).with(expected_data).and_return(:ok)
|
750
|
-
@influxdb.write_point("seriez", data, true).should eq(:ok)
|
751
|
-
end
|
752
|
-
|
753
|
-
end
|
754
|
-
|
755
|
-
describe "udp" do
|
756
|
-
let(:udp_client) { double }
|
757
|
-
let(:time) { Time.now.to_i }
|
758
|
-
let(:influxdb) { InfluxDB::Client.new(:udp => { :host => "localhost", :port => 44444 }) }
|
759
|
-
|
760
|
-
before do
|
761
|
-
allow(InfluxDB::UDPClient).to receive(:new).with('localhost', 44444).and_return(udp_client)
|
762
|
-
end
|
763
|
-
|
764
|
-
it "should send payload via udp if udp client is set up" do
|
765
|
-
expect(udp_client).to receive(:send).with([{:name=>"seriez", :points=>[[87, "juan", time]], :columns=>[:age, :name, :time]}])
|
766
|
-
data = {:name => "juan", :age => 87, :time => time}
|
767
|
-
influxdb.write_point("seriez", data)
|
768
|
-
end
|
39
|
+
describe "#full_url" do
|
40
|
+
it "returns String" do
|
41
|
+
expect(subject.send(:full_url, "/unknown")).to be_a String
|
769
42
|
end
|
770
43
|
|
771
|
-
|
772
|
-
|
773
|
-
|
774
|
-
before(:each) do
|
775
|
-
data = [{ :name => "foo", :columns => ["name", "age", "count", "count"], :points => [["shahid", 99, 1, 2],["dix", 50, 3, 4]]}]
|
776
|
-
|
777
|
-
stub_request(:get, "http://influxdb.test:9999/db/database/series").with(
|
778
|
-
:query => { :q => "select * from foo", :u => "username", :p => "password", :time_precision => "s"}
|
779
|
-
).to_return(
|
780
|
-
:body => JSON.generate(data)
|
781
|
-
)
|
44
|
+
it "escapes params" do
|
45
|
+
url = subject.send(:full_url, "/unknown", value: ' !@#$%^&*()/\\_+-=?|`~')
|
46
|
+
expect(url).to include("value=+%21%40%23%24%25%5E%26%2A%28%29%2F%5C_%2B-%3D%3F%7C%60%7E")
|
782
47
|
end
|
783
48
|
|
784
|
-
|
785
|
-
|
786
|
-
it 'can execute a query with a block' do
|
787
|
-
series = { }
|
49
|
+
context "with prefix" do
|
50
|
+
let(:args) { { prefix: '/dev' } }
|
788
51
|
|
789
|
-
|
790
|
-
series
|
52
|
+
it "returns path with prefix" do
|
53
|
+
expect(subject.send(:full_url, "/series")).to start_with("/dev")
|
791
54
|
end
|
792
|
-
|
793
|
-
series.should ==(expected_series)
|
794
|
-
end
|
795
|
-
|
796
|
-
it 'can execute a query without a block' do
|
797
|
-
series = @influxdb.query 'select * from foo'
|
798
|
-
series.should ==(expected_series)
|
799
|
-
end
|
800
|
-
end
|
801
|
-
|
802
|
-
describe "#query" do
|
803
|
-
|
804
|
-
it 'should load JSON point value as an array of hashes' do
|
805
|
-
line_items = [{'id' => 1, 'product_id' => 2, 'quantity' => 1, 'price' => "100.00"}]
|
806
|
-
|
807
|
-
data = [{ :name => "orders", :columns => ["id", "line_items"], :points => [[1, line_items.to_json]]}]
|
808
|
-
|
809
|
-
stub_request(:get, "http://influxdb.test:9999/db/database/series").with(
|
810
|
-
:query => { :q => "select * from orders", :u => "username", :p => "password", :time_precision => "s"}
|
811
|
-
).to_return(
|
812
|
-
:body => JSON.generate(data)
|
813
|
-
)
|
814
|
-
|
815
|
-
@influxdb.query('select * from orders').should == {'orders' => [{'id' => 1, 'line_items' => line_items}]}
|
816
|
-
end
|
817
|
-
end
|
818
|
-
|
819
|
-
describe "#delete_series" do
|
820
|
-
it "should DELETE to remove a series" do
|
821
|
-
stub_request(:delete, "http://influxdb.test:9999/db/database/series/foo").with(
|
822
|
-
:query => {:u => "username", :p => "password"}
|
823
|
-
)
|
824
|
-
|
825
|
-
@influxdb.delete_series("foo").should be_a(Net::HTTPOK)
|
826
55
|
end
|
827
56
|
end
|
828
57
|
|
829
|
-
describe "#
|
830
|
-
it "
|
831
|
-
|
832
|
-
|
58
|
+
describe "GET #ping" do
|
59
|
+
it "returns OK" do
|
60
|
+
stub_request(:get, "http://influxdb.test:9999/ping")
|
61
|
+
.to_return(status: 204)
|
833
62
|
|
834
|
-
|
835
|
-
url = @influxdb.send(:full_url, "/unknown", :value => ' !@#$%^&*()/\\_+-=?|`~')
|
836
|
-
url.should include("value=+%21%40%23%24%25%5E%26%2A%28%29%2F%5C_%2B-%3D%3F%7C%60%7E")
|
63
|
+
expect(subject.ping).to be_a(Net::HTTPNoContent)
|
837
64
|
end
|
838
65
|
end
|
839
66
|
end
|