influxdb 0.1.9 → 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.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
|