wavefront-client 3.2.0 → 3.3.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 +8 -8
- data/.travis.yml +1 -0
- data/README-cli.md +108 -1
- data/bin/wavefront +49 -11
- data/lib/wavefront/batch_writer.rb +247 -0
- data/lib/wavefront/cli/alerts.rb +50 -27
- data/lib/wavefront/cli/batch_write.rb +227 -0
- data/lib/wavefront/cli/events.rb +1 -1
- data/lib/wavefront/cli/ts.rb +2 -2
- data/lib/wavefront/cli/write.rb +89 -0
- data/lib/wavefront/cli.rb +19 -13
- data/lib/wavefront/client/version.rb +1 -1
- data/lib/wavefront/constants.rb +3 -0
- data/lib/wavefront/events.rb +39 -18
- data/lib/wavefront/exception.rb +8 -1
- data/lib/wavefront/mixins.rb +9 -2
- data/lib/wavefront/writer.rb +7 -2
- data/spec/spec_helper.rb +52 -1
- data/spec/wavefront/batch_writer_spec.rb +523 -0
- data/spec/wavefront/cli/alerts_spec.rb +153 -0
- data/spec/wavefront/cli/batch_write_spec.rb +251 -0
- data/spec/wavefront/cli/events_spec.rb +43 -0
- data/spec/wavefront/cli/resources/alert.human.erb +14 -0
- data/spec/wavefront/cli/resources/alert.human2 +14 -0
- data/spec/wavefront/cli/resources/alert.json +38 -0
- data/spec/wavefront/cli/resources/alert.raw +1 -0
- data/spec/wavefront/cli/resources/alert.ruby +1 -0
- data/spec/wavefront/cli/resources/write.parabola +49 -0
- data/spec/wavefront/cli/write_spec.rb +112 -0
- data/spec/wavefront/cli_spec.rb +68 -0
- data/spec/wavefront/events_spec.rb +111 -0
- data/spec/wavefront/mixins_spec.rb +16 -1
- data/spec/wavefront/writer_spec.rb +0 -7
- data/wavefront-client.gemspec +1 -1
- metadata +35 -6
@@ -0,0 +1,14 @@
|
|
1
|
+
name Test Alert
|
2
|
+
created 2016-07-29 16:54:22 +0100
|
3
|
+
severity WARN
|
4
|
+
condition ts("dev.cli.test_metric") > 0
|
5
|
+
displayExpression ts("dev.cli.test_metric")
|
6
|
+
minutes 5
|
7
|
+
resolveAfterMinutes
|
8
|
+
updated 2016-07-29 16:55:35 +0100
|
9
|
+
alertStates CHECKING
|
10
|
+
metricsUsed
|
11
|
+
hostsUsed
|
12
|
+
additionalInformation This alert has been made up to feed into the test
|
13
|
+
framework for the Ruby CLI. It is not real. Even this
|
14
|
+
text is just placeholder text.
|
@@ -0,0 +1,38 @@
|
|
1
|
+
[
|
2
|
+
{
|
3
|
+
"customerTagsWithCounts": {
|
4
|
+
"test": 1
|
5
|
+
},
|
6
|
+
"userTagsWithCounts": {
|
7
|
+
},
|
8
|
+
"created": 1469807662271,
|
9
|
+
"name": "Test Alert",
|
10
|
+
"conditionQBEnabled": false,
|
11
|
+
"displayExpressionQBEnabled": false,
|
12
|
+
"condition": "ts(\"dev.cli.test_metric\") > 0",
|
13
|
+
"displayExpression": "ts(\"dev.cli.test_metric\")",
|
14
|
+
"minutes": 5,
|
15
|
+
"target": "someone@example.com",
|
16
|
+
"failingHostLabelPairs": [
|
17
|
+
|
18
|
+
],
|
19
|
+
"updated": 1469807735018,
|
20
|
+
"severity": "WARN",
|
21
|
+
"additionalInformation": "This alert has been made up to feed into the test framework for the Ruby CLI. It is not real. Even this text is just placeholder text.",
|
22
|
+
"activeMaintenanceWindows": [
|
23
|
+
|
24
|
+
],
|
25
|
+
"inMaintenanceHostLabelPairs": [
|
26
|
+
|
27
|
+
],
|
28
|
+
"prefiringHostLabelPairs": [
|
29
|
+
|
30
|
+
],
|
31
|
+
"alertStates": [
|
32
|
+
"CHECKING"
|
33
|
+
],
|
34
|
+
"inTrash": false,
|
35
|
+
"numMetricsUsed": 0,
|
36
|
+
"numHostsUsed": 0
|
37
|
+
}
|
38
|
+
]
|
@@ -0,0 +1 @@
|
|
1
|
+
[{"customerTagsWithCounts":{"test":1},"userTagsWithCounts":{},"created":1469807662271,"name":"Test Alert","conditionQBEnabled":false,"displayExpressionQBEnabled":false,"condition":"ts(\"dev.cli.test_metric\") > 0","displayExpression":"ts(\"dev.cli.test_metric\")","minutes":5,"target":"someone@example.com","failingHostLabelPairs":[],"updated":1469807735018,"severity":"WARN","additionalInformation":"This alert has been made up to feed into the test framework for the Ruby CLI. It is not real. Even this text is just placeholder text.","activeMaintenanceWindows":[],"inMaintenanceHostLabelPairs":[],"prefiringHostLabelPairs":[],"alertStates":["CHECKING"],"inTrash":false,"numMetricsUsed":0,"numHostsUsed":0}]
|
@@ -0,0 +1 @@
|
|
1
|
+
"[{\"customerTagsWithCounts\":{\"test\":1},\"userTagsWithCounts\":{},\"created\":1469807662271,\"name\":\"Test Alert\",\"conditionQBEnabled\":false,\"displayExpressionQBEnabled\":false,\"condition\":\"ts(\\\"dev.cli.test_metric\\\") > 0\",\"displayExpression\":\"ts(\\\"dev.cli.test_metric\\\")\",\"minutes\":5,\"target\":\"someone@example.com\",\"failingHostLabelPairs\":[],\"updated\":1469807735018,\"severity\":\"WARN\",\"additionalInformation\":\"This alert has been made up to feed into the test framework for the Ruby CLI. It is not real. Even this text is just placeholder text.\",\"activeMaintenanceWindows\":[],\"inMaintenanceHostLabelPairs\":[],\"prefiringHostLabelPairs\":[],\"alertStates\":[\"CHECKING\"],\"inTrash\":false,\"numMetricsUsed\":0,\"numHostsUsed\":0}]"
|
@@ -0,0 +1,49 @@
|
|
1
|
+
1470075208 6760
|
2
|
+
1470075209 6290
|
3
|
+
1470075210 5840
|
4
|
+
1470075211 5410
|
5
|
+
1470075212 5000
|
6
|
+
1470075213 4610
|
7
|
+
1470075214 4240
|
8
|
+
1470075215 3890
|
9
|
+
1470075216 3560
|
10
|
+
1470075217 3250
|
11
|
+
1470075218 2960
|
12
|
+
1470075219 2690
|
13
|
+
1470075220 2440
|
14
|
+
1470075221 2210
|
15
|
+
1470075222 2000
|
16
|
+
1470075223 1810
|
17
|
+
1470075224 1640
|
18
|
+
1470075225 1490
|
19
|
+
1470075226 1360
|
20
|
+
1470075227 1250
|
21
|
+
1470075228 1160
|
22
|
+
1470075229 1090
|
23
|
+
1470075230 1040
|
24
|
+
1470075231 1010
|
25
|
+
1470075232 1000
|
26
|
+
1470075233 1010
|
27
|
+
1470075234 1040
|
28
|
+
1470075235 1090
|
29
|
+
1470075236 1160
|
30
|
+
1470075237 1250
|
31
|
+
1470075238 1360
|
32
|
+
1470075239 1490
|
33
|
+
1470075240 1640
|
34
|
+
1470075241 1810
|
35
|
+
1470075242 2000
|
36
|
+
1470075243 2210
|
37
|
+
1470075244 2440
|
38
|
+
1470075245 2690
|
39
|
+
1470075246 2960
|
40
|
+
1470075247 3250
|
41
|
+
1470075248 3560
|
42
|
+
1470075249 3890
|
43
|
+
1470075250 4240
|
44
|
+
1470075251 4610
|
45
|
+
1470075252 5000
|
46
|
+
1470075253 5410
|
47
|
+
1470075254 5840
|
48
|
+
1470075255 6290
|
49
|
+
1470075256 6760
|
@@ -0,0 +1,112 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'socket'
|
3
|
+
|
4
|
+
opts = {}
|
5
|
+
args = 'write'
|
6
|
+
k = Wavefront::Cli::Write.new(opts, args)
|
7
|
+
|
8
|
+
describe '#write_metric' do
|
9
|
+
it 'writes a point to a socket' do
|
10
|
+
socket = Mocket.new
|
11
|
+
allow(TCPSocket).to receive(:new).and_return(socket)
|
12
|
+
now = Time.now
|
13
|
+
expect(socket).to receive(:puts).with(
|
14
|
+
"1234 test.metric #{now.to_i} host=testhost")
|
15
|
+
k.write_metric('test.metric', '1234', {
|
16
|
+
timestamp: now, host_name: 'testhost'})
|
17
|
+
end
|
18
|
+
|
19
|
+
it 'writes a point with tags to a socket' do
|
20
|
+
socket = Mocket.new
|
21
|
+
allow(TCPSocket).to receive(:new).and_return(socket)
|
22
|
+
now = Time.now
|
23
|
+
expect(socket).to receive(:puts).with(
|
24
|
+
"5678 test.metric2 #{now.to_i} host=testhost t1=\"v1\" t2=\"v2\"")
|
25
|
+
k.write_metric('test.metric2', '5678', {
|
26
|
+
timestamp: now, host_name: 'testhost', point_tags:
|
27
|
+
{t1: 'v1', t2: 'v2'}})
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
describe '#valid_host?' do
|
32
|
+
|
33
|
+
it 'accepts valid hostnames' do
|
34
|
+
expect(k.valid_host?('valid-host')).to be_truthy
|
35
|
+
end
|
36
|
+
|
37
|
+
it 'rejects invalid hostnames' do
|
38
|
+
expect(k.valid_host?('!nval!d_HOST')).to be_falsey
|
39
|
+
expect(k.valid_host?('a' * 1025)).to be_falsey
|
40
|
+
end
|
41
|
+
|
42
|
+
end
|
43
|
+
|
44
|
+
describe '#valid_value?' do
|
45
|
+
|
46
|
+
it 'accepts real numbers' do
|
47
|
+
expect(k.valid_value?(123)).to be true
|
48
|
+
expect(k.valid_value?(-123)).to be true
|
49
|
+
expect(k.valid_value?(1.23)).to be true
|
50
|
+
expect(k.valid_value?(1.5e07)).to be true
|
51
|
+
end
|
52
|
+
|
53
|
+
it 'accepts integer-type strings' do
|
54
|
+
expect(k.valid_value?('123')).to be true
|
55
|
+
expect(k.valid_value?('-123')).to be true
|
56
|
+
end
|
57
|
+
|
58
|
+
it 'accepts exponential-type strings' do
|
59
|
+
expect(k.valid_value?('1.23e06')).to be true
|
60
|
+
expect(k.valid_value?('-1.23e06')).to be true
|
61
|
+
end
|
62
|
+
|
63
|
+
it 'rejects random strings' do
|
64
|
+
%w(abc 1.2.3 1.2e2e3 6e).each do |str|
|
65
|
+
expect{k.valid_value?(str)}.to raise_exception(
|
66
|
+
Wavefront::Exception::InvalidMetricValue)
|
67
|
+
end
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
describe '#valid_metric?' do
|
72
|
+
it 'accepts some valid metrics' do
|
73
|
+
expect(k.valid_metric?('valid.metric.path')).to be true
|
74
|
+
expect(k.valid_metric?('valid.metric-path')).to be true
|
75
|
+
expect(k.valid_metric?('valid.metric_path')).to be true
|
76
|
+
end
|
77
|
+
|
78
|
+
it 'rejects non-strings' do
|
79
|
+
[123, {k: 'v'}, []].each do |el|
|
80
|
+
expect{k.valid_metric?(el)}.to raise_exception(
|
81
|
+
Wavefront::Exception::InvalidMetricName)
|
82
|
+
end
|
83
|
+
end
|
84
|
+
|
85
|
+
it 'rejects too-long paths' do
|
86
|
+
expect{k.valid_metric?('aaaa.' * 300 )}.to raise_exception(
|
87
|
+
Wavefront::Exception::InvalidMetricName)
|
88
|
+
end
|
89
|
+
|
90
|
+
it 'rejects single-element paths' do
|
91
|
+
expect{k.valid_metric?('metric')}.to raise_exception(
|
92
|
+
Wavefront::Exception::InvalidMetricName)
|
93
|
+
end
|
94
|
+
|
95
|
+
it 'rejects invalid characters' do
|
96
|
+
expect{k.valid_metric?('!nval!d.metric')}.to raise_exception(
|
97
|
+
Wavefront::Exception::InvalidMetricName)
|
98
|
+
end
|
99
|
+
end
|
100
|
+
|
101
|
+
describe '#prep_tags' do
|
102
|
+
it 'handles invalid input' do
|
103
|
+
expect(k.prep_tags('string')).to eq([])
|
104
|
+
expect(k.prep_tags({key: 'val'})).to eq([])
|
105
|
+
expect(k.prep_tags(['badtag1', 'badtag2'])).to eq([])
|
106
|
+
end
|
107
|
+
|
108
|
+
it 'handles sample valid input' do
|
109
|
+
expect(k.prep_tags(['key1=val1', 'key2=val2'])).to eq(
|
110
|
+
[['key1', 'val1'], ['key2', 'val2']])
|
111
|
+
end
|
112
|
+
end
|
@@ -0,0 +1,68 @@
|
|
1
|
+
=begin
|
2
|
+
Copyright 2015 Wavefront Inc.
|
3
|
+
Licensed under the Apache License, Version 2.0 (the "License");
|
4
|
+
you may not use this file except in compliance with the License.
|
5
|
+
You may obtain a copy of the License at
|
6
|
+
|
7
|
+
http://www.apache.org/licenses/LICENSE-2.0
|
8
|
+
|
9
|
+
Unless required by applicable law or agreed to in writing, software
|
10
|
+
distributed under the License is distributed on an "AS IS" BASIS,
|
11
|
+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
12
|
+
See the License for the specific language governing permissions and
|
13
|
+
limitations under the License.
|
14
|
+
|
15
|
+
=end
|
16
|
+
|
17
|
+
require 'spec_helper'
|
18
|
+
require 'pathname'
|
19
|
+
require 'tempfile'
|
20
|
+
|
21
|
+
# A sample config file with two profiles.
|
22
|
+
#
|
23
|
+
pf_src = %Q(
|
24
|
+
[default]
|
25
|
+
token = 12345678-abcd-1234-abcd-123456789012
|
26
|
+
endpoint = metrics.wavefront.com
|
27
|
+
format = human
|
28
|
+
proxy = wavefront.localnet
|
29
|
+
|
30
|
+
[other]
|
31
|
+
token = abcdefab-0123-abcd-0123-abcdefabcdef
|
32
|
+
endpoint = test.wavefront.com
|
33
|
+
format = human
|
34
|
+
)
|
35
|
+
|
36
|
+
describe Wavefront::Cli do
|
37
|
+
|
38
|
+
profile = Tempfile.new('wf_test_profile')
|
39
|
+
cf = profile.path
|
40
|
+
profile.write(pf_src)
|
41
|
+
profile.close
|
42
|
+
|
43
|
+
it 'does not complain when there is no config file' do
|
44
|
+
k = Wavefront::Cli.new({config: '/no/file', profile: 'default'}, false)
|
45
|
+
expect(k.load_profile).to be_kind_of(NilClass)
|
46
|
+
end
|
47
|
+
|
48
|
+
it 'loads the specified profile' do
|
49
|
+
k = Wavefront::Cli.new({config: cf, profile: 'other'}, false)
|
50
|
+
pf = k.load_profile
|
51
|
+
expect(pf).not_to include('proxy')
|
52
|
+
expect(pf[:token]).to eq('abcdefab-0123-abcd-0123-abcdefabcdef')
|
53
|
+
end
|
54
|
+
|
55
|
+
it 'loads the default when no profile is specified' do
|
56
|
+
k = Wavefront::Cli.new({config: cf}, false)
|
57
|
+
pf = k.load_profile
|
58
|
+
expect(pf[:proxy]).to eq('wavefront.localnet')
|
59
|
+
expect(pf[:token]).to eq('12345678-abcd-1234-abcd-123456789012')
|
60
|
+
end
|
61
|
+
|
62
|
+
it 'prefers command-line options to config file values' do
|
63
|
+
k = Wavefront::Cli.new({config: cf, format: 'graphite'}, false)
|
64
|
+
pf = k.load_profile
|
65
|
+
expect(pf[:format]).to eq('graphite')
|
66
|
+
expect(pf[:token]).to eq('12345678-abcd-1234-abcd-123456789012')
|
67
|
+
end
|
68
|
+
end
|
@@ -0,0 +1,111 @@
|
|
1
|
+
=begin
|
2
|
+
Copyright 2016 Wavefront Inc.
|
3
|
+
Licensed under the Apache License, Version 2.0 (the "License");
|
4
|
+
you may not use this file except in compliance with the License.
|
5
|
+
You may obtain a copy of the License at
|
6
|
+
|
7
|
+
http://www.apache.org/licenses/LICENSE-2.0
|
8
|
+
|
9
|
+
Unless required by applicable law or agreed to in writing, software
|
10
|
+
distributed under the License is distributed on an "AS IS" BASIS,
|
11
|
+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
12
|
+
See the License for the specific language governing permissions and
|
13
|
+
limitations under the License.
|
14
|
+
|
15
|
+
=end
|
16
|
+
|
17
|
+
require 'spec_helper'
|
18
|
+
|
19
|
+
describe Wavefront::Events do
|
20
|
+
|
21
|
+
describe "#initialize" do
|
22
|
+
it 'puts the token in a suitable header' do
|
23
|
+
k = Wavefront::Events.new(TEST_TOKEN)
|
24
|
+
expect(k.headers).to eq({ :'X-AUTH-TOKEN' => TEST_TOKEN })
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
describe '#create_uri' do
|
29
|
+
it 'generates a correct URI if host and path are supplied' do
|
30
|
+
k = Wavefront::Events.new(TEST_TOKEN)
|
31
|
+
res = k.create_uri({
|
32
|
+
host: 'test.wavefront.com', path: '/alternate/api/'
|
33
|
+
})
|
34
|
+
|
35
|
+
expect(res).to be_kind_of(URI)
|
36
|
+
expect(res.port).to be(443)
|
37
|
+
expect(res.host).to eq('test.wavefront.com')
|
38
|
+
expect(res.path).to eq('/alternate/api/')
|
39
|
+
expect(res.query).to be(nil)
|
40
|
+
end
|
41
|
+
|
42
|
+
it 'generates a correct URI if no host or path are supplied' do
|
43
|
+
k = Wavefront::Events.new(TEST_TOKEN)
|
44
|
+
res = k.create_uri
|
45
|
+
|
46
|
+
expect(res).to be_kind_of(URI)
|
47
|
+
expect(res.port).to be(443)
|
48
|
+
expect(res.host).to eq('metrics.wavefront.com')
|
49
|
+
expect(res.path).to eq('/api/events/')
|
50
|
+
expect(res.query).to be(nil)
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
describe '#close_uri' do
|
55
|
+
it 'generates a correct URI if host and path are supplied' do
|
56
|
+
k = Wavefront::Events.new(TEST_TOKEN)
|
57
|
+
res = k.close_uri({
|
58
|
+
host: 'test.wavefront.com', path: '/alternate/api/'
|
59
|
+
})
|
60
|
+
|
61
|
+
expect(res).to be_kind_of(URI)
|
62
|
+
expect(res.port).to be(443)
|
63
|
+
expect(res.host).to eq('test.wavefront.com')
|
64
|
+
expect(res.path).to eq('/alternate/api/close')
|
65
|
+
expect(res.query).to be(nil)
|
66
|
+
end
|
67
|
+
|
68
|
+
it 'generates a correct URI if no host or path are supplied' do
|
69
|
+
k = Wavefront::Events.new(TEST_TOKEN)
|
70
|
+
res = k.close_uri
|
71
|
+
|
72
|
+
expect(res).to be_kind_of(URI)
|
73
|
+
expect(res.port).to be(443)
|
74
|
+
expect(res.host).to eq('metrics.wavefront.com')
|
75
|
+
expect(res.path).to eq('/api/events/close')
|
76
|
+
expect(res.query).to be(nil)
|
77
|
+
end
|
78
|
+
end
|
79
|
+
|
80
|
+
describe '#create_qs' do
|
81
|
+
payload = { key1: 'val1', key2: 'val2' }
|
82
|
+
|
83
|
+
it 'generates a query string with no hosts' do
|
84
|
+
k = Wavefront::Events.new(TEST_TOKEN)
|
85
|
+
expect(k.create_qs(payload)).to eq('key1=val1&key2=val2')
|
86
|
+
end
|
87
|
+
|
88
|
+
it 'generates a query string with single host as a string' do
|
89
|
+
payload[:h] = ['host1']
|
90
|
+
k = Wavefront::Events.new(TEST_TOKEN)
|
91
|
+
expect(k.create_qs(payload)).to eq('key1=val1&key2=val2&h=host1')
|
92
|
+
end
|
93
|
+
|
94
|
+
it 'generates a query string with multiple hosts' do
|
95
|
+
payload[:h] = ['host1', 'host2', 'host3']
|
96
|
+
k = Wavefront::Events.new(TEST_TOKEN)
|
97
|
+
expect(k.create_qs(payload)).to eq(
|
98
|
+
'key1=val1&key2=val2&h=host1&h=host2&h=host3')
|
99
|
+
end
|
100
|
+
end
|
101
|
+
|
102
|
+
describe '#hash_to_qs' do
|
103
|
+
it 'makes a proper query string' do
|
104
|
+
k = Wavefront::Events.new(TEST_TOKEN)
|
105
|
+
expect(k.hash_to_qs({
|
106
|
+
key1: 'val1',
|
107
|
+
key2: 'value 2'
|
108
|
+
})).to eq('key1=val1&key2=value%202')
|
109
|
+
end
|
110
|
+
end
|
111
|
+
end
|
@@ -1,4 +1,4 @@
|
|
1
|
-
=begin
|
1
|
+
=begin
|
2
2
|
Copyright 2015 Wavefront Inc.
|
3
3
|
Licensed under the Apache License, Version 2.0 (the "License");
|
4
4
|
you may not use this file except in compliance with the License.
|
@@ -26,4 +26,19 @@ describe Wavefront::Mixins do
|
|
26
26
|
expect(interpolate_schema(wavefront_schema, HOST, 1)).to eq("a.#{HOST}.b.c.d.e")
|
27
27
|
expect(interpolate_schema(wavefront_schema, HOST, 2)).to eq("a.b.#{HOST}.c.d.e")
|
28
28
|
end
|
29
|
+
|
30
|
+
it 'provides a method to parse times' do
|
31
|
+
expect(parse_time(1469711187)).to eq(1469711187)
|
32
|
+
expect(parse_time('1469711187')).to eq(1469711187)
|
33
|
+
expect(parse_time('2016-07-28 14:25:36 +0100')).to eq(1469712336)
|
34
|
+
expect(parse_time('2016-07-28')).to eq(1469664000)
|
35
|
+
expect(parse_time(Time.now)).to be_kind_of(Integer)
|
36
|
+
expect{parse_time('nonsense')}.to raise_exception(RuntimeError,
|
37
|
+
"cannot parse timestamp 'nonsense'.")
|
38
|
+
end
|
39
|
+
|
40
|
+
it 'provides a method to convert epoch times to milliseconds' do
|
41
|
+
expect(time_to_ms(1469711187)).to eq(1469711187000)
|
42
|
+
expect(time_to_ms('1469711187')).to be(false)
|
43
|
+
end
|
29
44
|
end
|
@@ -15,15 +15,8 @@ See the License for the specific language governing permissions and
|
|
15
15
|
=end
|
16
16
|
|
17
17
|
require 'spec_helper'
|
18
|
-
require 'pathname'
|
19
18
|
require 'socket'
|
20
19
|
|
21
|
-
class Mocket
|
22
|
-
def puts(str)
|
23
|
-
return true
|
24
|
-
end
|
25
|
-
end
|
26
|
-
|
27
20
|
describe Wavefront::Writer do
|
28
21
|
|
29
22
|
it 'has some defaults' do
|