vnstat-ruby 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (60) hide show
  1. checksums.yaml +7 -0
  2. data/.codeclimate.yml +14 -0
  3. data/.document +5 -0
  4. data/.rspec +3 -0
  5. data/.rubocop.yml +1171 -0
  6. data/.travis.yml +14 -0
  7. data/Gemfile +11 -0
  8. data/Gemfile.lock +84 -0
  9. data/LICENSE.txt +20 -0
  10. data/README.md +81 -0
  11. data/Rakefile +28 -0
  12. data/VERSION +1 -0
  13. data/lib/vnstat-ruby.rb +1 -0
  14. data/lib/vnstat.rb +65 -0
  15. data/lib/vnstat/configuration.rb +35 -0
  16. data/lib/vnstat/document.rb +56 -0
  17. data/lib/vnstat/error.rb +6 -0
  18. data/lib/vnstat/errors/executable_not_found.rb +7 -0
  19. data/lib/vnstat/errors/unknown_interface.rb +12 -0
  20. data/lib/vnstat/interface.rb +161 -0
  21. data/lib/vnstat/interface_collection.rb +106 -0
  22. data/lib/vnstat/parser.rb +54 -0
  23. data/lib/vnstat/result.rb +55 -0
  24. data/lib/vnstat/result/date_delegation.rb +31 -0
  25. data/lib/vnstat/result/day.rb +45 -0
  26. data/lib/vnstat/result/hour.rb +56 -0
  27. data/lib/vnstat/result/minute.rb +62 -0
  28. data/lib/vnstat/result/month.rb +47 -0
  29. data/lib/vnstat/result/time_comparable.rb +16 -0
  30. data/lib/vnstat/system_call.rb +90 -0
  31. data/lib/vnstat/traffic.rb +11 -0
  32. data/lib/vnstat/traffic/base.rb +46 -0
  33. data/lib/vnstat/traffic/daily.rb +40 -0
  34. data/lib/vnstat/traffic/hourly.rb +44 -0
  35. data/lib/vnstat/traffic/monthly.rb +27 -0
  36. data/lib/vnstat/traffic/tops.rb +39 -0
  37. data/lib/vnstat/utils.rb +68 -0
  38. data/spec/lib/vnstat/configuration_spec.rb +72 -0
  39. data/spec/lib/vnstat/document_spec.rb +54 -0
  40. data/spec/lib/vnstat/errors/executable_not_found_spec.rb +5 -0
  41. data/spec/lib/vnstat/errors/unknown_interface_spec.rb +5 -0
  42. data/spec/lib/vnstat/interface_collection_spec.rb +124 -0
  43. data/spec/lib/vnstat/interface_spec.rb +213 -0
  44. data/spec/lib/vnstat/result/day_spec.rb +39 -0
  45. data/spec/lib/vnstat/result/hour_spec.rb +43 -0
  46. data/spec/lib/vnstat/result/minute_spec.rb +52 -0
  47. data/spec/lib/vnstat/result/month_spec.rb +39 -0
  48. data/spec/lib/vnstat/result_spec.rb +86 -0
  49. data/spec/lib/vnstat/system_call_spec.rb +209 -0
  50. data/spec/lib/vnstat/traffic/daily_spec.rb +109 -0
  51. data/spec/lib/vnstat/traffic/hourly_spec.rb +153 -0
  52. data/spec/lib/vnstat/traffic/monthly_spec.rb +46 -0
  53. data/spec/lib/vnstat/traffic/tops_spec.rb +48 -0
  54. data/spec/lib/vnstat/utils_spec.rb +128 -0
  55. data/spec/lib/vnstat_spec.rb +61 -0
  56. data/spec/spec_helper.rb +98 -0
  57. data/spec/support/shared_examples/shared_examples_for_date_delegation.rb +19 -0
  58. data/spec/support/shared_examples/shared_examples_for_traffic_collection.rb +19 -0
  59. data/vnstat-ruby.gemspec +113 -0
  60. metadata +187 -0
@@ -0,0 +1,109 @@
1
+ describe Vnstat::Traffic::Daily do
2
+ let :interface do
3
+ data = <<-XML
4
+ <vnstat version="1.12" xmlversion="1">
5
+ <interface id="eth0">
6
+ <traffic>
7
+ <days>
8
+ <day id="0">
9
+ <date><year>2015</year><month>01</month><day>01</day></date>
10
+ <rx>1000</rx><tx>2000</tx>
11
+ </day>
12
+ <day id="1">
13
+ <date><year>2015</year><month>01</month><day>02</day></date>
14
+ <rx>3000</rx><tx>4000</tx>
15
+ </day>
16
+ </days>
17
+ </traffic>
18
+ </interface>
19
+ </vnstat>
20
+ XML
21
+ Vnstat::Interface.new('eth0', data)
22
+ end
23
+
24
+ subject { described_class.new(interface) }
25
+
26
+ include_examples 'traffic collection'
27
+
28
+ describe '#[]' do
29
+ context 'with 1 argument' do
30
+ context 'for existing entry' do
31
+ let(:date) { Date.new(2015, 1, 1) }
32
+
33
+ it 'returns a Vnstat::Result::Day' do
34
+ expect(subject[date]).to be_a Vnstat::Result::Day
35
+ end
36
+
37
+ it 'returns an object with the expected #date' do
38
+ expect(subject[date].date).to eq date
39
+ end
40
+
41
+ it 'returns an object with the expected #bytes_received' do
42
+ expect(subject[date].bytes_received).to eq 1000 * 1024
43
+ end
44
+
45
+ it 'returns an object with the expected #bytes_sent' do
46
+ expect(subject[date].bytes_sent).to eq 2000 * 1024
47
+ end
48
+ end
49
+
50
+ context 'for not-existing entry' do
51
+ it 'returns nil' do
52
+ expect(subject[Date.new(2015, 1, 3)]).to be nil
53
+ end
54
+ end
55
+ end
56
+
57
+ context 'with 2 arguments' do
58
+ it 'fails' do
59
+ expect { subject[nil, nil] }.to(
60
+ raise_error(ArgumentError, 'wrong number of arguments (2 for 1 or 3)')
61
+ )
62
+ end
63
+ end
64
+
65
+ context 'with 3 arguments' do
66
+ context 'for existing entry' do
67
+ it 'returns a Vnstat::Result::Day' do
68
+ expect(subject[2015, 1, 1]).to be_a Vnstat::Result::Day
69
+ end
70
+
71
+ it 'returns an object with the expected #date' do
72
+ expect(subject[2015, 1, 1].date).to eq Date.new(2015, 1, 1)
73
+ end
74
+
75
+ it 'returns an object with the expected #bytes_received' do
76
+ expect(subject[2015, 1, 1].bytes_received).to eq 1000 * 1024
77
+ end
78
+
79
+ it 'returns an object with the expected #bytes_sent' do
80
+ expect(subject[2015, 1, 1].bytes_sent).to eq 2000 * 1024
81
+ end
82
+ end
83
+
84
+ context 'for not-existing entry' do
85
+ it 'returns nil' do
86
+ expect(subject[2015, 1, 3]).to be nil
87
+ end
88
+ end
89
+ end
90
+
91
+ context 'with more than 3 arguments' do
92
+ it 'fails' do
93
+ expect { subject[nil, nil, nil, nil] }.to(
94
+ raise_error(ArgumentError, 'wrong number of arguments (4 for 1 or 3)')
95
+ )
96
+ end
97
+ end
98
+ end
99
+
100
+ describe '#each' do
101
+ it 'yields successively with Vnstat::Result::Day as argument' do
102
+ first_result = subject[2015, 1, 1]
103
+ second_result = subject[2015, 1, 2]
104
+
105
+ expect { |block| subject.each(&block) }
106
+ .to yield_successive_args(first_result, second_result)
107
+ end
108
+ end
109
+ end
@@ -0,0 +1,153 @@
1
+ describe Vnstat::Traffic::Hourly do
2
+ let :interface do
3
+ data = <<-XML
4
+ <vnstat version="1.12" xmlversion="1">
5
+ <interface id="eth0">
6
+ <traffic>
7
+ <hours>
8
+ <hour id="19">
9
+ <date><year>2015</year><month>10</month><day>21</day></date>
10
+ <rx>1000</rx><tx>2000</tx>
11
+ </hour>
12
+ <hour id="20">
13
+ <date><year>2015</year><month>10</month><day>21</day></date>
14
+ <rx>3000</rx><tx>4000</tx>
15
+ </hour>
16
+ </hours>
17
+ </traffic>
18
+ </interface>
19
+ </vnstat>
20
+ XML
21
+ Vnstat::Interface.new('eth0', data)
22
+ end
23
+
24
+ subject { described_class.new(interface) }
25
+
26
+ include_examples 'traffic collection'
27
+
28
+ describe '#[]' do
29
+ context 'with 1 argument' do
30
+ it 'fails' do
31
+ expect { subject[nil] }.to(
32
+ raise_error(ArgumentError, 'wrong number of arguments (1 for 2 or 4)')
33
+ )
34
+ end
35
+ end
36
+
37
+ context 'with 2 arguments' do
38
+ let(:date) { Date.new(2015, 10, 21) }
39
+ let(:hour) { 20 }
40
+
41
+ context 'for existing entry' do
42
+ it 'returns a Vnstat::Result::Day' do
43
+ expect(subject[date, hour]).to be_a Vnstat::Result::Hour
44
+ end
45
+
46
+ it 'returns an object with the expected #date' do
47
+ expect(subject[date, hour].date).to eq date
48
+ end
49
+
50
+ it 'returns an object with the expected #hour' do
51
+ expect(subject[date, hour].hour).to eq hour
52
+ end
53
+
54
+ it 'returns an object with the expected #bytes_received' do
55
+ expect(subject[date, hour].bytes_received).to eq 3000 * 1024
56
+ end
57
+
58
+ it 'returns an object with the expected #bytes_sent' do
59
+ expect(subject[date, hour].bytes_sent).to eq 4000 * 1024
60
+ end
61
+ end
62
+
63
+ context 'for entry with non-existing date' do
64
+ it 'returns nil' do
65
+ expect(subject[Date.new(2015, 10, 20), 19]).to be nil
66
+ end
67
+ end
68
+
69
+ context 'for entry with non-existing hour' do
70
+ it 'returns nil' do
71
+ expect(subject[date, 0]).to be nil
72
+ end
73
+ end
74
+
75
+ context 'for entry with non-existing date and hour' do
76
+ it 'returns nil' do
77
+ expect(subject[Date.new(2015, 10, 20), 0]).to be nil
78
+ end
79
+ end
80
+ end
81
+
82
+ context 'with 3 arguments' do
83
+ it 'fails' do
84
+ expect { subject[nil, nil, nil] }.to(
85
+ raise_error(ArgumentError, 'wrong number of arguments (3 for 2 or 4)')
86
+ )
87
+ end
88
+ end
89
+
90
+ context 'with 4 arguments' do
91
+ let(:date_args) { [2015, 10, 21] }
92
+ let(:hour) { 20 }
93
+
94
+ context 'for existing entry' do
95
+ it 'returns a Vnstat::Result::Day' do
96
+ expect(subject[*date_args, hour]).to be_a Vnstat::Result::Hour
97
+ end
98
+
99
+ it 'returns an object with the expected #date' do
100
+ expect(subject[*date_args, hour].date).to eq Date.new(*date_args)
101
+ end
102
+
103
+ it 'returns an object with the expected #hour' do
104
+ expect(subject[*date_args, hour].hour).to eq hour
105
+ end
106
+
107
+ it 'returns an object with the expected #bytes_received' do
108
+ expect(subject[*date_args, hour].bytes_received).to eq 3000 * 1024
109
+ end
110
+
111
+ it 'returns an object with the expected #bytes_sent' do
112
+ expect(subject[*date_args, hour].bytes_sent).to eq 4000 * 1024
113
+ end
114
+ end
115
+
116
+ context 'for entry with non-existing date' do
117
+ it 'returns nil' do
118
+ expect(subject[2015, 10, 20, 19]).to be nil
119
+ end
120
+ end
121
+
122
+ context 'for entry with non-existing hour' do
123
+ it 'returns nil' do
124
+ expect(subject[*date_args, 0]).to be nil
125
+ end
126
+ end
127
+
128
+ context 'for entry with non-existing date and hour' do
129
+ it 'returns nil' do
130
+ expect(subject[2015, 10, 20, 0]).to be nil
131
+ end
132
+ end
133
+ end
134
+
135
+ context 'with 5 or more arguments' do
136
+ it 'fails' do
137
+ expect { subject[nil, nil, nil, nil, nil] }.to(
138
+ raise_error(ArgumentError, 'wrong number of arguments (5 for 2 or 4)')
139
+ )
140
+ end
141
+ end
142
+ end
143
+
144
+ describe '#each' do
145
+ it 'yields successively with Vnstat::Result::Hour as argument' do
146
+ first_result = subject[2015, 10, 21, 19]
147
+ second_result = subject[2015, 10, 21, 20]
148
+
149
+ expect { |block| subject.each(&block) }
150
+ .to yield_successive_args(first_result, second_result)
151
+ end
152
+ end
153
+ end
@@ -0,0 +1,46 @@
1
+ describe Vnstat::Traffic::Monthly do
2
+ let :interface do
3
+ data = <<-XML
4
+ <vnstat version="1.12" xmlversion="1">
5
+ <interface id="eth0">
6
+ <traffic>
7
+ <months>
8
+ <month id="0">
9
+ <date><year>2015</year><month>01</month></date>
10
+ <rx>1000</rx><tx>2000</tx>
11
+ </month>
12
+ <month id="1">
13
+ <date><year>2015</year><month>02</month></date>
14
+ <rx>3000</rx><tx>4000</tx>
15
+ </month>
16
+ </months>
17
+ </traffic>
18
+ </interface>
19
+ </vnstat>
20
+ XML
21
+ Vnstat::Interface.new('eth0', data)
22
+ end
23
+
24
+ subject { described_class.new(interface) }
25
+
26
+ include_examples 'traffic collection'
27
+
28
+ describe '#[]' do
29
+ it 'returns a Vntat::Result::Month' do
30
+ expect(subject[2015, 2]).to be_a Vnstat::Result::Month
31
+ end
32
+ end
33
+
34
+ describe '#each' do
35
+ it 'yields successively with Vnstat::Result::Month for all months' do
36
+ expect { |block| subject.each(&block) }
37
+ .to yield_successive_args(subject[2015, 1], subject[2015, 2])
38
+ end
39
+ end
40
+
41
+ describe '#to_a' do
42
+ it 'contains Vnstat::Result::Month for all months' do
43
+ expect(subject.to_a).to match_array [subject[2015, 1], subject[2015, 2]]
44
+ end
45
+ end
46
+ end
@@ -0,0 +1,48 @@
1
+ describe Vnstat::Traffic::Tops do
2
+ let :interface do
3
+ data = <<-XML
4
+ <vnstat version="1.12" xmlversion="1">
5
+ <interface id="eth0">
6
+ <traffic>
7
+ <tops>
8
+ <top id="0">
9
+ <date><year>2015</year><month>01</month><day>01</day></date>
10
+ <time><hour>12</hour><minute>34</minute></time>
11
+ <rx>1000</rx><tx>2000</tx>
12
+ </top>
13
+ <top id="1">
14
+ <date><year>2015</year><month>02</month><day>02</day></date>
15
+ <time><hour>23</hour><minute>45</minute></time>
16
+ <rx>3000</rx><tx>4000</tx>
17
+ </top>
18
+ </tops>
19
+ </traffic>
20
+ </interface>
21
+ </vnstat>
22
+ XML
23
+ Vnstat::Interface.new('eth0', data)
24
+ end
25
+
26
+ subject { described_class.new(interface) }
27
+
28
+ include_examples 'traffic collection'
29
+
30
+ describe '#[]' do
31
+ it 'returns the Vnstat::Result::Minute at the specified index' do
32
+ expect(subject[0]).to be_a Vnstat::Result::Minute
33
+ end
34
+ end
35
+
36
+ describe '#each' do
37
+ it 'yields successively with Vnstat::Result::Minute for all top entries' do
38
+ expect { |block| subject.each(&block) }
39
+ .to yield_successive_args(subject[0], subject[1])
40
+ end
41
+ end
42
+
43
+ describe '#to_a' do
44
+ it 'contains Vnstat::Result::Month for all months' do
45
+ expect(subject.to_a).to match_array [subject[0], subject[1]]
46
+ end
47
+ end
48
+ end
@@ -0,0 +1,128 @@
1
+ describe Vnstat::Utils do
2
+ let(:executable_path) { '/any/path' }
3
+
4
+ before :each do
5
+ allow(Vnstat.config).to receive(:executable_path).and_return(executable_path)
6
+ end
7
+
8
+ describe '.system_call' do
9
+ it 'calls Vnstat::SystemCall.call' do
10
+ expect(Vnstat::SystemCall).to receive(:call).with('test', 'test2') do
11
+ double(success?: true, success_result: 'success')
12
+ end
13
+
14
+ described_class.system_call('test', 'test2')
15
+ end
16
+
17
+ context 'when Vnstat::SystemCall#success? is true' do
18
+ let(:system_call) { Vnstat::SystemCall.new('test') }
19
+
20
+ before :each do
21
+ allow(system_call).to receive(:success?).and_return(true)
22
+ allow(system_call).to receive(:success_result).and_return('success')
23
+
24
+ allow(Vnstat::SystemCall).to receive(:call).with('test')
25
+ .and_return(system_call)
26
+ end
27
+
28
+ it 'returns Vnstat::SystemCall#success_result' do
29
+ expect(described_class.system_call('test')).to eq 'success'
30
+ end
31
+ end
32
+
33
+ context 'when Vnstat::SystemCall#success? is false' do
34
+ let(:system_call) { Vnstat::SystemCall.new('test') }
35
+
36
+ before :each do
37
+ allow(system_call).to receive(:success?).and_return(false)
38
+ allow(system_call).to receive(:error_result).and_return('error')
39
+
40
+ allow(Vnstat::SystemCall).to receive(:call).with('test')
41
+ .and_return(system_call)
42
+ end
43
+
44
+ context 'without block given' do
45
+ it 'returns Vnstat::SystemCall#error_result' do
46
+ expect(described_class.system_call('test')).to eq 'error'
47
+ end
48
+ end
49
+
50
+ context 'with block given' do
51
+ it 'yields with Vnstat::SystemCall#error_result' do
52
+ expect { |block| described_class.system_call('test', &block) }
53
+ .to yield_with_args(system_call.error_result)
54
+ end
55
+
56
+ it 'returns block result' do
57
+ expect(described_class.system_call('test') { 'failed' })
58
+ .to eq 'failed'
59
+ end
60
+ end
61
+ end
62
+ end
63
+
64
+ describe '.system_call_returning_status' do
65
+ it 'calls Vnstat::SystemCall.call' do
66
+ expect(Vnstat::SystemCall).to receive(:call).with('test')
67
+ .and_return(double(success?: true))
68
+
69
+ described_class.system_call_returning_status('test')
70
+ end
71
+
72
+ context 'when Vnstat::SystemCall#success? is true' do
73
+ before :each do
74
+ allow_any_instance_of(Vnstat::SystemCall)
75
+ .to receive(:success?).and_return(true)
76
+ end
77
+
78
+ it 'returns true' do
79
+ expect(described_class.system_call_returning_status('test')).to be true
80
+ end
81
+ end
82
+
83
+ context 'when vnstat::SystemCall#success? is false' do
84
+ before :each do
85
+ allow_any_instance_of(Vnstat::SystemCall)
86
+ .to receive(:success?).and_return(false)
87
+ end
88
+
89
+ it 'returns false' do
90
+ expect(described_class.system_call_returning_status('test')).to be false
91
+ end
92
+ end
93
+ end
94
+
95
+ describe '.call_executable' do
96
+ let(:block) { Proc.new {} }
97
+
98
+ it 'calls .system_call using vnstat executable' do
99
+ expect(described_class).to receive(:system_call)
100
+ .with(executable_path, 'test', &block)
101
+
102
+ described_class.call_executable('test', &block)
103
+ end
104
+
105
+ it 'returns the result returned by .system_call' do
106
+ allow(described_class).to receive(:system_call).and_return('result')
107
+
108
+ expect(described_class.call_executable('test')).to eq 'result'
109
+ end
110
+ end
111
+
112
+ describe '.call_executable_returning_status' do
113
+ it 'calls .system_call_returning_status using vnstat executable' do
114
+ expect(described_class).to receive(:system_call_returning_status)
115
+ .with(executable_path, 'test')
116
+
117
+ described_class.call_executable_returning_status('test')
118
+ end
119
+
120
+ it 'returns the result returned by .system_call_returning_status' do
121
+ allow(described_class).to receive(:system_call_returning_status)
122
+ .and_return(true)
123
+
124
+ expect(described_class.call_executable_returning_status('test'))
125
+ .to be true
126
+ end
127
+ end
128
+ end