vnstat-ruby 1.0.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 +7 -0
- data/.codeclimate.yml +14 -0
- data/.document +5 -0
- data/.rspec +3 -0
- data/.rubocop.yml +1171 -0
- data/.travis.yml +14 -0
- data/Gemfile +11 -0
- data/Gemfile.lock +84 -0
- data/LICENSE.txt +20 -0
- data/README.md +81 -0
- data/Rakefile +28 -0
- data/VERSION +1 -0
- data/lib/vnstat-ruby.rb +1 -0
- data/lib/vnstat.rb +65 -0
- data/lib/vnstat/configuration.rb +35 -0
- data/lib/vnstat/document.rb +56 -0
- data/lib/vnstat/error.rb +6 -0
- data/lib/vnstat/errors/executable_not_found.rb +7 -0
- data/lib/vnstat/errors/unknown_interface.rb +12 -0
- data/lib/vnstat/interface.rb +161 -0
- data/lib/vnstat/interface_collection.rb +106 -0
- data/lib/vnstat/parser.rb +54 -0
- data/lib/vnstat/result.rb +55 -0
- data/lib/vnstat/result/date_delegation.rb +31 -0
- data/lib/vnstat/result/day.rb +45 -0
- data/lib/vnstat/result/hour.rb +56 -0
- data/lib/vnstat/result/minute.rb +62 -0
- data/lib/vnstat/result/month.rb +47 -0
- data/lib/vnstat/result/time_comparable.rb +16 -0
- data/lib/vnstat/system_call.rb +90 -0
- data/lib/vnstat/traffic.rb +11 -0
- data/lib/vnstat/traffic/base.rb +46 -0
- data/lib/vnstat/traffic/daily.rb +40 -0
- data/lib/vnstat/traffic/hourly.rb +44 -0
- data/lib/vnstat/traffic/monthly.rb +27 -0
- data/lib/vnstat/traffic/tops.rb +39 -0
- data/lib/vnstat/utils.rb +68 -0
- data/spec/lib/vnstat/configuration_spec.rb +72 -0
- data/spec/lib/vnstat/document_spec.rb +54 -0
- data/spec/lib/vnstat/errors/executable_not_found_spec.rb +5 -0
- data/spec/lib/vnstat/errors/unknown_interface_spec.rb +5 -0
- data/spec/lib/vnstat/interface_collection_spec.rb +124 -0
- data/spec/lib/vnstat/interface_spec.rb +213 -0
- data/spec/lib/vnstat/result/day_spec.rb +39 -0
- data/spec/lib/vnstat/result/hour_spec.rb +43 -0
- data/spec/lib/vnstat/result/minute_spec.rb +52 -0
- data/spec/lib/vnstat/result/month_spec.rb +39 -0
- data/spec/lib/vnstat/result_spec.rb +86 -0
- data/spec/lib/vnstat/system_call_spec.rb +209 -0
- data/spec/lib/vnstat/traffic/daily_spec.rb +109 -0
- data/spec/lib/vnstat/traffic/hourly_spec.rb +153 -0
- data/spec/lib/vnstat/traffic/monthly_spec.rb +46 -0
- data/spec/lib/vnstat/traffic/tops_spec.rb +48 -0
- data/spec/lib/vnstat/utils_spec.rb +128 -0
- data/spec/lib/vnstat_spec.rb +61 -0
- data/spec/spec_helper.rb +98 -0
- data/spec/support/shared_examples/shared_examples_for_date_delegation.rb +19 -0
- data/spec/support/shared_examples/shared_examples_for_traffic_collection.rb +19 -0
- data/vnstat-ruby.gemspec +113 -0
- metadata +187 -0
@@ -0,0 +1,39 @@
|
|
1
|
+
describe Vnstat::Result::Day do
|
2
|
+
it 'includes Comparable' do
|
3
|
+
expect(described_class).to include Comparable
|
4
|
+
end
|
5
|
+
|
6
|
+
describe '.extract_from_xml_element' do
|
7
|
+
let :element do
|
8
|
+
data = <<-XML
|
9
|
+
<day id="0">
|
10
|
+
<date><year>2015</year><month>7</month><day>14</day></date>
|
11
|
+
<rx>1000</rx><tx>2000</tx>
|
12
|
+
</day>
|
13
|
+
XML
|
14
|
+
Nokogiri::XML.parse(data).xpath('day')
|
15
|
+
end
|
16
|
+
|
17
|
+
subject do
|
18
|
+
described_class.extract_from_xml_element(element)
|
19
|
+
end
|
20
|
+
|
21
|
+
it { is_expected.to be_a described_class }
|
22
|
+
|
23
|
+
it 'initializes with the correct #date' do
|
24
|
+
expect(subject.date).to eq Date.new(2015, 7, 14)
|
25
|
+
end
|
26
|
+
|
27
|
+
it 'initializes with the correct #bytes_received' do
|
28
|
+
expect(subject.bytes_received).to eq 1000 * 1024
|
29
|
+
end
|
30
|
+
|
31
|
+
it 'initializes with the correct #bytes_sent' do
|
32
|
+
expect(subject.bytes_sent).to eq 2000 * 1024
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
include_examples 'date delegation' do
|
37
|
+
subject { described_class.new(Date.today, 0, 0) }
|
38
|
+
end
|
39
|
+
end
|
@@ -0,0 +1,43 @@
|
|
1
|
+
describe Vnstat::Result::Hour do
|
2
|
+
it 'includes Comparable' do
|
3
|
+
expect(described_class).to include Comparable
|
4
|
+
end
|
5
|
+
|
6
|
+
describe '.extract_from_xml_element' do
|
7
|
+
let :element do
|
8
|
+
data = <<-XML
|
9
|
+
<hour id="19">
|
10
|
+
<date><year>2015</year><month>10</month><day>21</day></date>
|
11
|
+
<rx>1000</rx><tx>2000</tx>
|
12
|
+
</hour>
|
13
|
+
XML
|
14
|
+
Nokogiri::XML.parse(data).xpath('hour')
|
15
|
+
end
|
16
|
+
|
17
|
+
subject do
|
18
|
+
described_class.extract_from_xml_element(element)
|
19
|
+
end
|
20
|
+
|
21
|
+
it { is_expected.to be_a described_class }
|
22
|
+
|
23
|
+
it 'initializes with the correct #date' do
|
24
|
+
expect(subject.date).to eq Date.new(2015, 10, 21)
|
25
|
+
end
|
26
|
+
|
27
|
+
it 'initializes with the correct #hour' do
|
28
|
+
expect(subject.hour).to eq 19
|
29
|
+
end
|
30
|
+
|
31
|
+
it 'initializes with the correct #bytes_received' do
|
32
|
+
expect(subject.bytes_received).to eq 1000 * 1024
|
33
|
+
end
|
34
|
+
|
35
|
+
it 'initializes with the correct #bytes_sent' do
|
36
|
+
expect(subject.bytes_sent).to eq 2000 * 1024
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
include_examples 'date delegation' do
|
41
|
+
subject { described_class.new(Date.today, 12, 0, 0) }
|
42
|
+
end
|
43
|
+
end
|
@@ -0,0 +1,52 @@
|
|
1
|
+
describe Vnstat::Result::Minute do
|
2
|
+
it 'includes Comparable' do
|
3
|
+
expect(described_class).to include Comparable
|
4
|
+
end
|
5
|
+
|
6
|
+
describe '.extract_from_xml_element' do
|
7
|
+
let :element do
|
8
|
+
data = <<-XML
|
9
|
+
<top id="0">
|
10
|
+
<date><year>2015</year><month>2</month><day>3</day></date>
|
11
|
+
<time><hour>12</hour><minute>34</minute></time>
|
12
|
+
<rx>1000</rx><tx>2000</tx>
|
13
|
+
</top>
|
14
|
+
XML
|
15
|
+
Nokogiri::XML.parse(data).xpath('top')
|
16
|
+
end
|
17
|
+
|
18
|
+
subject do
|
19
|
+
described_class.extract_from_xml_element(element)
|
20
|
+
end
|
21
|
+
|
22
|
+
it { is_expected.to be_a described_class }
|
23
|
+
|
24
|
+
it 'initializes with the correct #time' do
|
25
|
+
expect(subject.time).to eq DateTime.new(2015, 2, 3, 12, 34)
|
26
|
+
end
|
27
|
+
|
28
|
+
it 'initializes with the correct #date' do
|
29
|
+
expect(subject.date).to eq Date.new(2015, 2, 3)
|
30
|
+
end
|
31
|
+
|
32
|
+
it 'initializes with the correct #hour' do
|
33
|
+
expect(subject.hour).to eq 12
|
34
|
+
end
|
35
|
+
|
36
|
+
it 'initialized with the correct #minute' do
|
37
|
+
expect(subject.minute).to eq 34
|
38
|
+
end
|
39
|
+
|
40
|
+
it 'initializes with the correct #bytes_received' do
|
41
|
+
expect(subject.bytes_received).to eq 1000 * 1024
|
42
|
+
end
|
43
|
+
|
44
|
+
it 'initializes with the correct #bytes_sent' do
|
45
|
+
expect(subject.bytes_sent).to eq 2000 * 1024
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
include_examples 'date delegation' do
|
50
|
+
subject { described_class.new(DateTime.now, 0, 0) }
|
51
|
+
end
|
52
|
+
end
|
@@ -0,0 +1,39 @@
|
|
1
|
+
describe Vnstat::Result::Month do
|
2
|
+
it 'includes Comparable' do
|
3
|
+
expect(described_class).to include Comparable
|
4
|
+
end
|
5
|
+
|
6
|
+
describe '.extract_from_xml_element' do
|
7
|
+
let :element do
|
8
|
+
data = <<-XML
|
9
|
+
<month id="0">
|
10
|
+
<date><year>2015</year><month>9</month></date>
|
11
|
+
<rx>1000</rx><tx>2000</tx>
|
12
|
+
</month>
|
13
|
+
XML
|
14
|
+
Nokogiri::XML.parse(data).xpath('month')
|
15
|
+
end
|
16
|
+
|
17
|
+
subject do
|
18
|
+
described_class.extract_from_xml_element(element)
|
19
|
+
end
|
20
|
+
|
21
|
+
it { is_expected.to be_a described_class }
|
22
|
+
|
23
|
+
it 'initializes with the correct #year' do
|
24
|
+
expect(subject.year).to eq 2015
|
25
|
+
end
|
26
|
+
|
27
|
+
it 'initializes with the correct #month' do
|
28
|
+
expect(subject.month).to eq 9
|
29
|
+
end
|
30
|
+
|
31
|
+
it 'initializes with the correct #bytes_received' do
|
32
|
+
expect(subject.bytes_received).to eq 1000 * 1024
|
33
|
+
end
|
34
|
+
|
35
|
+
it 'initializes with the correct #bytes_sent' do
|
36
|
+
expect(subject.bytes_sent).to eq 2000 * 1024
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
@@ -0,0 +1,86 @@
|
|
1
|
+
describe Vnstat::Result do
|
2
|
+
it 'includes Comparable' do
|
3
|
+
expect(described_class).to include Comparable
|
4
|
+
end
|
5
|
+
|
6
|
+
describe '.extract_from_xml_element' do
|
7
|
+
let :element do
|
8
|
+
data = <<-XML
|
9
|
+
<total>
|
10
|
+
<rx>1000</rx><tx>2000</tx>
|
11
|
+
</total>
|
12
|
+
XML
|
13
|
+
Nokogiri::XML.parse(data).xpath('total')
|
14
|
+
end
|
15
|
+
|
16
|
+
subject { described_class.extract_from_xml_element(element) }
|
17
|
+
|
18
|
+
it { is_expected.to be_a described_class }
|
19
|
+
|
20
|
+
it 'initializes with the correct #bytes_received' do
|
21
|
+
expect(subject.bytes_received).to eq 1000 * 1024
|
22
|
+
end
|
23
|
+
|
24
|
+
it 'initializes with the correct #bytes_sent' do
|
25
|
+
expect(subject.bytes_sent).to eq 2000 * 1024
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
describe '#initialize' do
|
30
|
+
subject { described_class.new(1000, 2000) }
|
31
|
+
|
32
|
+
it 'stores the first argument in #bytes_received' do
|
33
|
+
expect(subject.bytes_received).to eq 1000
|
34
|
+
end
|
35
|
+
|
36
|
+
it 'stores the second argument in #bytes_sent' do
|
37
|
+
expect(subject.bytes_sent).to eq 2000
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
describe '#bytes_transmitted' do
|
42
|
+
subject { described_class.new(1000, 2000) }
|
43
|
+
|
44
|
+
it 'returns sum of #bytes_received and #bytes_sent' do
|
45
|
+
expect(subject.bytes_transmitted).to eq 3000
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
describe '#<=>' do
|
50
|
+
subject { described_class.new(1000, 2000) }
|
51
|
+
|
52
|
+
context 'when argument does not respond to :bytes_transmitted' do
|
53
|
+
let(:other) { double }
|
54
|
+
|
55
|
+
it 'returns nil' do
|
56
|
+
expect(subject <=> other).to be nil
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
context 'when argument responds to :bytes_transmitted' do
|
61
|
+
context 'with other value being greater' do
|
62
|
+
let(:other) { double(bytes_transmitted: 4000) }
|
63
|
+
|
64
|
+
it 'returns -1' do
|
65
|
+
expect(subject <=> other).to eq -1
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
context 'with other value being equal' do
|
70
|
+
let(:other) { double(bytes_transmitted: 3000) }
|
71
|
+
|
72
|
+
it 'returns 0' do
|
73
|
+
expect(subject <=> other).to eq 0
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
77
|
+
context 'with other value being lower' do
|
78
|
+
let(:other) { double(bytes_transmitted: 2000) }
|
79
|
+
|
80
|
+
it 'returns 1' do
|
81
|
+
expect(subject <=> other).to eq 1
|
82
|
+
end
|
83
|
+
end
|
84
|
+
end
|
85
|
+
end
|
86
|
+
end
|
@@ -0,0 +1,209 @@
|
|
1
|
+
describe Vnstat::SystemCall do
|
2
|
+
let(:args) { ['test', 'test2', 'test3'] }
|
3
|
+
|
4
|
+
describe '#initialize' do
|
5
|
+
context 'when arguments are anything' do
|
6
|
+
subject { described_class.new(*args) }
|
7
|
+
|
8
|
+
it 'stores args in #args' do
|
9
|
+
expect(subject.args).to eq args
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
context 'when first argument is an Array' do
|
14
|
+
subject { described_class.new(args) }
|
15
|
+
|
16
|
+
it 'stores args in #args' do
|
17
|
+
expect(subject.args).to eq args
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
describe '.call' do
|
23
|
+
it 'forwards args to .new' do
|
24
|
+
expect(described_class).to receive(:new).with('test').and_call_original
|
25
|
+
|
26
|
+
described_class.call('test')
|
27
|
+
end
|
28
|
+
|
29
|
+
it 'delegates to #call with no args' do
|
30
|
+
expect_any_instance_of(described_class).to receive(:call).with(no_args)
|
31
|
+
|
32
|
+
described_class.call('test')
|
33
|
+
end
|
34
|
+
|
35
|
+
it "returns result of #call" do
|
36
|
+
allow_any_instance_of(described_class)
|
37
|
+
.to receive(:call).and_return('test')
|
38
|
+
|
39
|
+
expect(described_class.call).to eq 'test'
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
describe '#call' do
|
44
|
+
subject { described_class.new(*args) }
|
45
|
+
|
46
|
+
it 'returns self' do
|
47
|
+
expect(subject.call).to eq subject
|
48
|
+
end
|
49
|
+
|
50
|
+
it 'calls Open3.popen with #args as arguments' do
|
51
|
+
expect(Open3).to receive(:popen3).with(*args)
|
52
|
+
|
53
|
+
subject.call
|
54
|
+
end
|
55
|
+
|
56
|
+
context 'when called' do
|
57
|
+
let(:success_result) { "success 1\nsuccess 2" }
|
58
|
+
let(:error_result) { "error 1\nerror 2" }
|
59
|
+
let(:exit_status) { double(value: 'test') }
|
60
|
+
|
61
|
+
before :each do
|
62
|
+
success_io = build_mock_io(success_result)
|
63
|
+
error_io = build_mock_io(error_result)
|
64
|
+
|
65
|
+
allow(Open3).to receive(:popen3)
|
66
|
+
.and_yield(nil, success_io, error_io, exit_status)
|
67
|
+
|
68
|
+
subject.call
|
69
|
+
end
|
70
|
+
|
71
|
+
it 'sets #exit_status' do
|
72
|
+
expect(subject.exit_status).to eq exit_status.value
|
73
|
+
end
|
74
|
+
|
75
|
+
it 'sets #success_result' do
|
76
|
+
expect(subject.success_result).to eq success_result
|
77
|
+
end
|
78
|
+
|
79
|
+
it 'sets #error_result' do
|
80
|
+
expect(subject.error_result).to eq error_result
|
81
|
+
end
|
82
|
+
|
83
|
+
def build_mock_io(*lines)
|
84
|
+
io = StringIO.new
|
85
|
+
lines.flatten.each { |line| io.puts(line) }
|
86
|
+
io.tap(&:rewind)
|
87
|
+
end
|
88
|
+
end
|
89
|
+
end
|
90
|
+
|
91
|
+
describe '#called?' do
|
92
|
+
context 'when #exit_status is nil' do
|
93
|
+
before :each do
|
94
|
+
allow(subject).to receive(:exit_status).and_return('something')
|
95
|
+
end
|
96
|
+
|
97
|
+
it 'returns true' do
|
98
|
+
expect(subject.called?).to be true
|
99
|
+
end
|
100
|
+
end
|
101
|
+
|
102
|
+
context 'when #exit_status is not nil' do
|
103
|
+
before :each do
|
104
|
+
allow(subject).to receive(:exit_status).and_return(nil)
|
105
|
+
end
|
106
|
+
|
107
|
+
it 'returns false' do
|
108
|
+
expect(subject.called?).to be false
|
109
|
+
end
|
110
|
+
end
|
111
|
+
end
|
112
|
+
|
113
|
+
describe '#success?' do
|
114
|
+
context 'when #called? is true' do
|
115
|
+
before :each do
|
116
|
+
allow(subject).to receive(:called?).and_return(true)
|
117
|
+
end
|
118
|
+
|
119
|
+
context 'when exited successfully' do
|
120
|
+
before :each do
|
121
|
+
allow(subject).to receive(:exit_status) do
|
122
|
+
double(success?: true)
|
123
|
+
end
|
124
|
+
end
|
125
|
+
|
126
|
+
it 'returns true' do
|
127
|
+
expect(subject.success?).to be true
|
128
|
+
end
|
129
|
+
end
|
130
|
+
|
131
|
+
context 'when not exited successfully' do
|
132
|
+
before :each do
|
133
|
+
allow(subject).to receive(:exit_status) do
|
134
|
+
double(success?: false)
|
135
|
+
end
|
136
|
+
end
|
137
|
+
|
138
|
+
it 'returns false' do
|
139
|
+
expect(subject.success?).to be false
|
140
|
+
end
|
141
|
+
end
|
142
|
+
end
|
143
|
+
|
144
|
+
context 'when #called? is false' do
|
145
|
+
before :each do
|
146
|
+
allow(subject).to receive(:called?).and_return(false)
|
147
|
+
end
|
148
|
+
|
149
|
+
it 'raises' do
|
150
|
+
expect { subject.success? }.to raise_error('Command not invoked')
|
151
|
+
end
|
152
|
+
end
|
153
|
+
end
|
154
|
+
|
155
|
+
describe '#error?' do
|
156
|
+
it 'calls #success?' do
|
157
|
+
expect(subject).to receive(:success?)
|
158
|
+
|
159
|
+
subject.error?
|
160
|
+
end
|
161
|
+
|
162
|
+
context 'when #success? is true' do
|
163
|
+
before :each do
|
164
|
+
allow(subject).to receive(:success?).and_return(true)
|
165
|
+
end
|
166
|
+
|
167
|
+
it 'returns false' do
|
168
|
+
expect(subject.error?).to be false
|
169
|
+
end
|
170
|
+
end
|
171
|
+
|
172
|
+
context 'when #success? is false' do
|
173
|
+
before :each do
|
174
|
+
allow(subject).to receive(:success?).and_return(false)
|
175
|
+
end
|
176
|
+
|
177
|
+
it 'returns true' do
|
178
|
+
expect(subject.error?).to be true
|
179
|
+
end
|
180
|
+
end
|
181
|
+
end
|
182
|
+
|
183
|
+
describe '#result' do
|
184
|
+
before :each do
|
185
|
+
allow(subject).to receive(:success_result).and_return('success')
|
186
|
+
allow(subject).to receive(:error_result).and_return('error')
|
187
|
+
end
|
188
|
+
|
189
|
+
context 'when #success? is true' do
|
190
|
+
before :each do
|
191
|
+
allow(subject).to receive(:success?).and_return(true)
|
192
|
+
end
|
193
|
+
|
194
|
+
it 'returns #success_result' do
|
195
|
+
expect(subject.result).to eq subject.success_result
|
196
|
+
end
|
197
|
+
end
|
198
|
+
|
199
|
+
context 'when #success? is false' do
|
200
|
+
before :each do
|
201
|
+
allow(subject).to receive(:success?).and_return(false)
|
202
|
+
end
|
203
|
+
|
204
|
+
it 'returns #error_result' do
|
205
|
+
expect(subject.result).to eq subject.error_result
|
206
|
+
end
|
207
|
+
end
|
208
|
+
end
|
209
|
+
end
|