Skip to content
This repository

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse code

Adopting scopes-n-groups

  • Loading branch information...
commit f87d6c070c5a0c8a9f9696bf05c3319a68587691 1 parent a573a10
DanielVartanov authored
4 init.rb
... ... @@ -1,4 +1,8 @@
1 1 require 'rubygems'
2 2 require 'active_support'
  3 +
3 4 __DIR__ = File.dirname(__FILE__)
  5 +
  6 +require File.join(__DIR__, 'vendor', 'scopes-n-groups', 'lib', 'scope')
  7 +
4 8 Dir.glob(File.join(__DIR__, 'lib', '**', '*.rb')).each { |file| require file }
16 lib/host.rb
... ... @@ -1,9 +1,9 @@
1 1 class Host < Struct.new(:address, :records)
2   - def amount_of_traffic
3   - summ = 0
4   - records.each do |record|
5   - summ += record.bytes
6   - end
7   - summ
8   - end
9   -end
  2 + def amount_of_traffic
  3 + summ = 0
  4 + records.each do |record|
  5 + summ += record.bytes
  6 + end
  7 + summ
  8 + end
  9 +end
77 lib/traffic.rb
... ... @@ -1,44 +1,41 @@
1   -class Traffic
2   - attr_accessor :local_address
3   - attr_reader :records
4   -
5   - def initialize(records, local_address)
6   - @records = records
7   - @local_address = local_address
8   - end
  1 +class Traffic < Scope
  2 + attr_accessor :local_address
  3 +
  4 + define_scope :internal, proc { |record| record.internal? }
  5 + define_scope :world, proc { |record| record.world? }
  6 + define_scope :daily, proc { |record| record.daily? }
  7 + define_scope :nightly, proc { |record| record.nightly? }
  8 + define_scope :outcoming, proc { |record| record.source_address == local_address }
  9 + define_scope :incoming, proc { |record| record.destination_address == local_address }
9 10
10   - def incoming
11   - @incoming ||= self.records.select { |record| record.destination_address == self.local_address }
12   - self.class.new(@incoming, self.local_address)
13   - end
  11 + def highest_ten_hosts
  12 + highest_hosts(10)
  13 + end
14 14
15   - def outcoming
16   - @outcoming ||= self.records.select { |record| record.source_address == self.local_address }
17   - self.class.new(@outcoming, self.local_address)
18   - end
19   -
20   - def hosts
21   - @hosts ||= grouped_by_host.map { |host_address, records| Host.new(host_address, records) }
22   - end
23   -
24   - def highest_hosts(limit=nil)
25   - sorted_hosts = hosts.sort { |left, right| right.amount_of_traffic <=> left.amount_of_traffic }
26   - limit.nil? ? sorted_hosts : sorted_hosts[0..limit-1]
27   - end
28   -
29   - def grouped_by_host
30   - return @grouped_by_host if @grouped_by_host
31   -
32   - @grouped_by_host = {}
33   -
34   - incoming.records.each do |record|
35   - (@grouped_by_host[record.source_address] ||= []) << record
36   - end
  15 +protected
37 16
38   - outcoming.records.each do |record|
39   - (@grouped_by_host[record.destination_address] ||= []) << record
40   - end
41   -
42   - @grouped_by_host
43   - end
  17 + def hosts
  18 + @hosts ||= grouped_by_host.map { |host_address, records| Host.new(host_address, records) }
  19 + end
  20 +
  21 + def highest_hosts(limit=0)
  22 + sorted_hosts = hosts.sort { |left, right| right.amount_of_traffic <=> left.amount_of_traffic }
  23 + limit.nil? ? sorted_hosts : sorted_hosts[0..limit-1]
  24 + end
  25 +
  26 + def grouped_by_host
  27 + return @grouped_by_host if @grouped_by_host
  28 +
  29 + @grouped_by_host = {}
  30 +
  31 + incoming.records.each do |record|
  32 + (@grouped_by_host[record.source_address] ||= []) << record
  33 + end
  34 +
  35 + outcoming.records.each do |record|
  36 + (@grouped_by_host[record.destination_address] ||= []) << record
  37 + end
  38 +
  39 + @grouped_by_host
  40 + end
44 41 end
52 lib/traffic_calculator.rb
... ... @@ -1,52 +0,0 @@
1   -class TrafficCalculator < Struct.new(:log_file_name, :user_address)
2   - def calculate!
3   - parser = Parser.new
4   - parser.parse_file!(self.log_file_name)
5   -
6   - @traffic = Traffic.new(parser.records, self.user_address)
7   - end
8   -
9   - def get_results
10   - res = Hash.new
11   - res[:intraffic] = Array.new()
12   - res[:outtraffic] = Array.new()
13   -
14   - @traffic.incoming.highest_hosts(10).each do |host|
15   - res[:intraffic].push(Hash["IP" => host.address , "size" => nice_bytes(host.amount_of_traffic)])
16   - end
17   -
18   - @traffic.outcoming.highest_hosts(10).each do |host|
19   - res[:outtraffic].push(Hash["IP" => host.address , "size" => nice_bytes(host.amount_of_traffic)])
20   - end
21   -
22   - res
23   - end
24   -
25   - def print_results
26   - puts results_string
27   - end
28   -
29   - def results_string
30   - result = ''
31   -
32   - result << "\n=== Incoming traffic ===\n"
33   - @traffic.incoming.highest_hosts(10).each do |host|
34   - result << "#{self.user_address} <- #{host.address} [#{nice_bytes(host.amount_of_traffic)}]\n"
35   - end
36   -
37   - result << "\n=== Outcoming traffic ===\n"
38   - @traffic.outcoming.highest_hosts(10).each do |host|
39   - result << "#{self.user_address} -> #{host.address} [#{nice_bytes(host.amount_of_traffic)}]\n"
40   - end
41   -
42   - result
43   - end
44   -
45   -protected
46   -
47   - def print_first_ten_hosts(traffic)
48   - traffic.highest_hosts(10).each do |host|
49   - puts "#{self.user_address} <- #{host.address} [#{nice_bytes(host.amount_of_traffic)}]"
50   - end
51   - end
52   -end
15 lib/traffic_splitter.rb
... ... @@ -0,0 +1,15 @@
  1 +class TrafficSplitter < Struct.new(:local_address)
  2 + def split_traffic!(records)
  3 + {
  4 + :internal => {
  5 + :daily => traffic.internal.daily.highest_ten_hosts,
  6 + :nightly => traffic.internal.nightly.highest_ten_hosts,
  7 + },
  8 +
  9 + :world => {
  10 + :daily => traffic.world.daily.highest_ten_hosts,
  11 + :nightly => traffic.world.nightly.highest_ten_hosts,
  12 + }
  13 + }
  14 + end
  15 +end
32 parse!.rb
@@ -3,9 +3,33 @@
3 3 __DIR__ = File.dirname(__FILE__)
4 4 require File.join(__DIR__, 'init')
5 5
  6 +def print_results(split_traffic)
  7 +
  8 +end
  9 +
  10 +def results_string
  11 + result = ''
  12 +
  13 + result << "\n=== Incoming traffic ===\n"
  14 + @traffic.incoming.highest_hosts(10).each do |host|
  15 + result << "#{self.user_address} <- #{host.address} [#{nice_bytes(host.amount_of_traffic)}]\n"
  16 + end
  17 +
  18 + result << "\n=== Outcoming traffic ===\n"
  19 + @traffic.outcoming.highest_hosts(10).each do |host|
  20 + result << "#{self.user_address} -> #{host.address} [#{nice_bytes(host.amount_of_traffic)}]\n"
  21 + end
  22 +
  23 + result
  24 +end
  25 +
6 26 user_address = '77.235.9.36'
7   -file_name = 'sample.log'
  27 +log_file_name = 'sample.log'
  28 +
  29 +parser = Parser.new
  30 +parser.parse_file!(log_file_name)
  31 +
  32 +traffic_calculator = TrafficCalculator.new local_address, records
  33 +split_traffic = traffic_calculator.split_traffic!
8 34
9   -traffic_calculator = TrafficCalculator.new file_name, user_address
10   -traffic_calculator.calculate!
11   -traffic_calculator.print_results
  35 +print_results(spit_traffic)
96 spec/traffic/scopes_spec.rb
... ... @@ -1,54 +1,54 @@
1 1 require File.join(File.dirname(__FILE__), '..', 'spec_helper')
2 2
3 3 describe Traffic do
4   - describe "given a bunch of records" do
5   - before :each do
6   - @local_address = '192.168.0.1'
7   - @facebook = '77.235.14.9'
8   - @gmail = '77.235.14.10'
9   -
10   - @records = [
11   - Record.new(@local_address, @facebook),
12   - Record.new(@local_address, @gmail),
13   - Record.new(@facebook, @local_address),
14   - Record.new(@gmail, @local_address)
15   - ]
16   - end
17   -
18   -
19   - describe "given a Traffic instance loaded with records" do
20   - before :each do
21   - @traffic = Traffic.new(@records, @local_address)
22   - end
23   -
24   - describe "when #incoming is called" do
25   - before :each do
26   - @return_value = @traffic.incoming
27   - end
28   -
29   - it "should return a Traffic instance" do
30   - @return_value.should be_kind_of(Traffic)
31   - end
32   -
33   - it "should narrow records to incoming traffic only" do
34   - @return_value.records.to_set.should == [Record.new(@facebook, @local_address), Record.new(@gmail, @local_address)].to_set
35   - end
36   - end
37   -
38   - describe "when #outcoming is called" do
39   - before :each do
40   - @return_value = @traffic.outcoming
41   - end
42   -
43   - it "should return a Traffic instance" do
44   - @return_value.should be_kind_of(Traffic)
45   - end
46   -
47   - it "should narrow records to outcoming traffic only" do
48   - @return_value.records.to_set.should == [Record.new(@local_address, @facebook), Record.new(@local_address, @gmail)].to_set
49   - end
50   - end
51   - end
  4 + describe "given a bunch of records" do
  5 + before :each do
  6 + @local_address = '192.168.0.1'
  7 + @facebook = '77.235.14.9'
  8 + @gmail = '77.235.14.10'
  9 +
  10 + @records = [
  11 + Record.new(@local_address, @facebook),
  12 + Record.new(@local_address, @gmail),
  13 + Record.new(@facebook, @local_address),
  14 + Record.new(@gmail, @local_address)
  15 + ]
  16 + end
  17 +
  18 + describe "given a Traffic instance loaded with records" do
  19 + before :each do
  20 + @traffic = Traffic.new @records
  21 + @traffic.local_address = @local_address
  22 + end
  23 +
  24 + describe "when #incoming is called" do
  25 + before :each do
  26 + @return_value = @traffic.incoming
  27 + end
  28 +
  29 + it "should return a Traffic instance" do
  30 + @return_value.should be_kind_of(Traffic)
  31 + end
  32 +
  33 + it "should narrow records to incoming traffic only" do
  34 + @return_value.to_set.should == [Record.new(@facebook, @local_address), Record.new(@gmail, @local_address)].to_set
  35 + end
  36 + end
  37 +
  38 + describe "when #outcoming is called" do
  39 + before :each do
  40 + @return_value = @traffic.outcoming
  41 + end
  42 +
  43 + it "should return a Traffic instance" do
  44 + @return_value.should be_kind_of(Traffic)
  45 + end
  46 +
  47 + it "should narrow records to outcoming traffic only" do
  48 + @return_value.to_set.should == [Record.new(@local_address, @facebook), Record.new(@local_address, @gmail)].to_set
52 49 end
  50 + end
  51 + end
  52 + end
53 53 end
54 54
91 spec/traffic_splitter_spec.rb
... ... @@ -0,0 +1,91 @@
  1 +require File.join(File.dirname(__FILE__), 'spec_helper')
  2 +
  3 +module TrafficSpecHelper
  4 + def internal_daily_traffic
  5 + Record.new @local_address, @internal_address,
  6 + end
  7 +
  8 + def internal_nightly_traffic
  9 + end
  10 +
  11 + def world_daily_traffic
  12 + end
  13 +
  14 + def world_nightly_traffic
  15 + end
  16 +end
  17 +
  18 +describe TrafficSplitter do
  19 + before :each do
  20 + @local_address = '212.112.96.1'
  21 + @internal_address = '212.112.1.1'
  22 + @world_address = '8.8.8.8'
  23 +
  24 + @traffic_splitter = TrafficSplitter.new(@local_address)
  25 + end
  26 +
  27 + include TrafficSpecHelper
  28 +
  29 + describe "given a bunch of records of all types" do
  30 + before :each do
  31 + @records = []
  32 +
  33 + # TODO: 15 записей нужны только для проверки одного теста
  34 + # Для остальных нужно сузить и проверять нормально, тестовыми данными, а не выполняя алгоритмы реализации
  35 +
  36 + 15.times { |number| @record << internal_daily_traffic }
  37 + 15.times { |number| @record << internal_nightly_traffic }
  38 + 15.times { |number| @record << world_daily_traffic }
  39 + 15.times { |number| @record << world_nightly_traffic }
  40 + end
  41 +
  42 + describe "when #split_traffic! is called" do
  43 + before :each do
  44 + @results = @traffic_splitter.split_traffic!(@records)
  45 + end
  46 +
  47 + it "should create a two-dimensional hash" do
  48 + @results.keys.should == [:internal, :world]
  49 + @results[:internal].keys.should == [:daily, :nightly]
  50 + @results[:world].keys.should == [:daily, :nightly]
  51 + end
  52 +
  53 + it "should put array of Host in each cell" do
  54 + @results.each_value do |split_results|
  55 + split_results.each_value do |hosts|
  56 + hosts.should be_kind_of(Array)
  57 + hosts.first.should be_kind_of(Host)
  58 + end
  59 + end
  60 + end
  61 +
  62 + it "should spit records by type correctly" do
  63 + @results[:internal][:daily].each do |host|
  64 + host.records.each do |record|
  65 + record.should be_internal_relatively_to(@local_address)
  66 + record.should be_daily
  67 + end
  68 + end
  69 + end
  70 +
  71 + it "should sort hosts by amount of bytes" do
  72 + hosts = @results[:internal][:daily]
  73 + previous_host = hosts.first
  74 + hosts[1..-1].each do |host|
  75 + (host.amount_of_traffic < previous_host.amount_of_traffic).should be_true
  76 + previous_host = host
  77 + end
  78 + end
  79 +
  80 + it "should leave only 10 highest hosts" do
  81 + @results.each_value do |split_results|
  82 + split_results.each_value do |hosts|
  83 + hosts.size.should == 10
  84 + end
  85 + end
  86 + end
  87 + end
  88 + end
  89 +end
  90 +
  91 +# Record #incoming? #daily? #local?
1  vendor/scopes-n-groups
... ... @@ -0,0 +1 @@
  1 +Subproject commit a9ce5e038d9d3cd569d81d9c340df69a950db013

0 comments on commit f87d6c0

Please sign in to comment.
Something went wrong with that request. Please try again.