request-log-analyzer 1.1.2 → 1.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.
Files changed (58) hide show
  1. data/DESIGN +24 -10
  2. data/README.rdoc +1 -1
  3. data/Rakefile +1 -2
  4. data/bin/request-log-analyzer +4 -27
  5. data/lib/cli/progressbar.rb +2 -19
  6. data/lib/cli/tools.rb +46 -0
  7. data/lib/request_log_analyzer/aggregator/database.rb +33 -8
  8. data/lib/request_log_analyzer/aggregator/echo.rb +1 -0
  9. data/lib/request_log_analyzer/aggregator/summarizer.rb +15 -13
  10. data/lib/request_log_analyzer/controller.rb +8 -4
  11. data/lib/request_log_analyzer/file_format/merb.rb +17 -4
  12. data/lib/request_log_analyzer/file_format/rails.rb +2 -2
  13. data/lib/request_log_analyzer/file_format/rails_development.rb +30 -92
  14. data/lib/request_log_analyzer/file_format.rb +8 -4
  15. data/lib/request_log_analyzer/filter/anonymize.rb +0 -3
  16. data/lib/request_log_analyzer/filter/field.rb +6 -1
  17. data/lib/request_log_analyzer/filter/timespan.rb +7 -1
  18. data/lib/request_log_analyzer/filter.rb +0 -4
  19. data/lib/request_log_analyzer/line_definition.rb +12 -2
  20. data/lib/request_log_analyzer/output/fixed_width.rb +14 -3
  21. data/lib/request_log_analyzer/output/html.rb +1 -0
  22. data/lib/request_log_analyzer/request.rb +6 -0
  23. data/lib/request_log_analyzer/source/database.rb +76 -0
  24. data/lib/request_log_analyzer/source/log_parser.rb +101 -48
  25. data/lib/request_log_analyzer/source.rb +28 -6
  26. data/lib/request_log_analyzer/tracker/duration.rb +90 -15
  27. data/lib/request_log_analyzer/tracker/frequency.rb +22 -10
  28. data/lib/request_log_analyzer/tracker/hourly_spread.rb +20 -9
  29. data/lib/request_log_analyzer/tracker/timespan.rb +15 -8
  30. data/lib/request_log_analyzer.rb +29 -16
  31. data/spec/integration/command_line_usage_spec.rb +71 -0
  32. data/spec/lib/helper.rb +33 -0
  33. data/spec/lib/mocks.rb +47 -0
  34. data/spec/{file_formats/spec_format.rb → lib/testing_format.rb} +6 -1
  35. data/spec/spec_helper.rb +5 -41
  36. data/spec/{database_inserter_spec.rb → unit/aggregator/database_inserter_spec.rb} +40 -37
  37. data/spec/unit/aggregator/summarizer_spec.rb +28 -0
  38. data/spec/unit/controller/controller_spec.rb +43 -0
  39. data/spec/{log_processor_spec.rb → unit/controller/log_processor_spec.rb} +4 -3
  40. data/spec/{file_format_spec.rb → unit/file_format/file_format_api_spec.rb} +16 -4
  41. data/spec/{line_definition_spec.rb → unit/file_format/line_definition_spec.rb} +13 -6
  42. data/spec/{merb_format_spec.rb → unit/file_format/merb_format_spec.rb} +2 -2
  43. data/spec/{rails_format_spec.rb → unit/file_format/rails_format_spec.rb} +19 -11
  44. data/spec/unit/filter/anonymize_filter_spec.rb +22 -0
  45. data/spec/unit/filter/field_filter_spec.rb +69 -0
  46. data/spec/unit/filter/timespan_filter_spec.rb +61 -0
  47. data/spec/{log_parser_spec.rb → unit/source/log_parser_spec.rb} +7 -7
  48. data/spec/{request_spec.rb → unit/source/request_spec.rb} +5 -5
  49. data/spec/unit/tracker/duration_tracker_spec.rb +99 -0
  50. data/spec/unit/tracker/frequency_tracker_spec.rb +83 -0
  51. data/spec/unit/tracker/hourly_spread_spec.rb +75 -0
  52. data/spec/unit/tracker/timespan_tracker_spec.rb +65 -0
  53. data/spec/unit/tracker/tracker_api_test.rb +45 -0
  54. data/tasks/rspec.rake +12 -0
  55. metadata +54 -26
  56. data/spec/controller_spec.rb +0 -64
  57. data/spec/filter_spec.rb +0 -157
  58. data/spec/summarizer_spec.rb +0 -9
@@ -1,4 +1,4 @@
1
- require File.dirname(__FILE__) + '/spec_helper'
1
+ require File.dirname(__FILE__) + '/../../spec_helper'
2
2
 
3
3
  describe RequestLogAnalyzer::FileFormat, :format_definition do
4
4
 
@@ -63,7 +63,18 @@ end
63
63
 
64
64
  describe RequestLogAnalyzer::FileFormat, :load do
65
65
 
66
- include RequestLogAnalyzerSpecHelper
66
+ include RequestLogAnalyzer::Spec::Helper
67
+
68
+ it "should return an instance of a FileFormat class" do
69
+ @file_format = RequestLogAnalyzer::FileFormat.load(TestingFormat)
70
+ @file_format.should be_kind_of(TestingFormat)
71
+ end
72
+
73
+
74
+ it "should return itself if it already is a FileFormat::Base instance" do
75
+ @file_format = RequestLogAnalyzer::FileFormat.load(testing_format)
76
+ @file_format.should be_kind_of(TestingFormat)
77
+ end
67
78
 
68
79
  it "should load a predefined file format from the /file_format dir" do
69
80
  @file_format = RequestLogAnalyzer::FileFormat.load(:rails)
@@ -71,8 +82,9 @@ describe RequestLogAnalyzer::FileFormat, :load do
71
82
  end
72
83
 
73
84
  it "should load a provided format file" do
74
- @file_format = RequestLogAnalyzer::FileFormat.load(format_file(:spec_format))
75
- @file_format.should be_kind_of(SpecFormat)
85
+ format_filename = File.dirname(__FILE__) + '/../../lib/testing_format.rb'
86
+ @file_format = RequestLogAnalyzer::FileFormat.load(format_filename)
87
+ @file_format.should be_kind_of(TestingFormat)
76
88
  end
77
89
 
78
90
  end
@@ -1,4 +1,4 @@
1
- require File.dirname(__FILE__) + '/spec_helper'
1
+ require File.dirname(__FILE__) + '/../../spec_helper'
2
2
 
3
3
  describe RequestLogAnalyzer::LineDefinition, :parsing do
4
4
 
@@ -35,11 +35,11 @@ end
35
35
 
36
36
  describe RequestLogAnalyzer::LineDefinition, :converting do
37
37
 
38
- include RequestLogAnalyzerSpecHelper
38
+ include RequestLogAnalyzer::Spec::Helper
39
39
 
40
40
  before(:each) do
41
- @file_format = spec_format
42
- @request = @file_format.create_request
41
+ @file_format = testing_format
42
+ @request = @file_format.request
43
43
  end
44
44
 
45
45
  it "should convert captures to a hash of converted values" do
@@ -48,10 +48,17 @@ describe RequestLogAnalyzer::LineDefinition, :converting do
48
48
  end
49
49
 
50
50
  it "should convert captures to a hash" do
51
- hash = @file_format.line_definitions[:test].convert_captured_values(["willem", nil], @request)
52
- hash[:test_capture].should == 'Testing is willem'
51
+ hash = @file_format.line_definitions[:test].convert_captured_values(["great", nil], @request)
52
+ hash[:test_capture].should == 'Testing is great'
53
53
  hash[:duration].should be_nil
54
54
  end
55
+
56
+ it "should merge a hash capture into the line hash" do
57
+ hash = @file_format.line_definitions[:eval].convert_captured_values(["{ 'greating' => 'hello', 'what' => 'world'}"], @request)
58
+ hash[:evaluated].should == { :greating => "hello", :what => "world"}
59
+ hash[:greating].should == 'hello'
60
+ hash[:what].should == 'world'
61
+ end
55
62
 
56
63
 
57
64
  end
@@ -1,7 +1,7 @@
1
- require File.dirname(__FILE__) + '/spec_helper'
1
+ require File.dirname(__FILE__) + '/../../spec_helper'
2
2
 
3
3
  describe RequestLogAnalyzer::Source::LogParser, :merb do
4
- include RequestLogAnalyzerSpecHelper
4
+ include RequestLogAnalyzer::Spec::Helper
5
5
 
6
6
  before(:each) do
7
7
  @log_parser = RequestLogAnalyzer::Source::LogParser.new(RequestLogAnalyzer::FileFormat.load(:merb))
@@ -1,10 +1,11 @@
1
- require File.dirname(__FILE__) + '/spec_helper'
1
+ require File.dirname(__FILE__) + '/../../spec_helper'
2
2
 
3
3
  describe RequestLogAnalyzer::Source::LogParser, "Rails" do
4
- include RequestLogAnalyzerSpecHelper
4
+ include RequestLogAnalyzer::Spec::Helper
5
5
 
6
6
  before(:each) do
7
- @log_parser = RequestLogAnalyzer::Source::LogParser.new(RequestLogAnalyzer::FileFormat.load(:rails))
7
+ @log_parser = RequestLogAnalyzer::Source::LogParser.new(
8
+ RequestLogAnalyzer::FileFormat.load(:rails), :parse_strategy => 'cautious')
8
9
  end
9
10
 
10
11
  it "should have a valid language definitions" do
@@ -66,27 +67,34 @@ describe RequestLogAnalyzer::Source::LogParser, "Rails" do
66
67
  end
67
68
 
68
69
  it "should detect unordered requests in the logs" do
70
+ # No valid request should be found in cautious mode
69
71
  @log_parser.should_not_receive(:handle_request)
70
72
  # the first Processing-line will not give a warning, but the next one will
71
73
  @log_parser.should_receive(:warn).with(:unclosed_request, anything).once
72
- # Both Completed ;ines will give a warning
74
+ # Both Completed lines will give a warning
73
75
  @log_parser.should_receive(:warn).with(:no_current_request, anything).twice
76
+
74
77
  @log_parser.parse_file(log_fixture(:rails_unordered))
75
78
  end
76
79
  end
77
80
 
78
- describe "RequestLogAnalyzer::FileFormat::RailsDevelopment - Rails with development details" do
79
- include RequestLogAnalyzerSpecHelper
81
+ describe RequestLogAnalyzer::FileFormat::RailsDevelopment, "Rails with development details" do
82
+ include RequestLogAnalyzer::Spec::Helper
80
83
 
81
84
  before(:each) do
82
85
  @file_format = RequestLogAnalyzer::FileFormat.load(:rails_development)
83
- @request = @file_format.create_request
86
+ @request = @file_format.request
84
87
  end
85
88
 
86
89
  it "should have a valid language definitions" do
87
90
  @file_format.should be_valid
88
91
  end
89
92
 
93
+ it "should have a different line definer than Rails" do
94
+ rails = RequestLogAnalyzer::FileFormat.load(:rails)
95
+ rails.class.line_definer.should_not == @file_format.class.line_definer
96
+ end
97
+
90
98
  it "should parse a rendered line" do
91
99
  info = @file_format.line_definitions[:rendered].match_for("Rendered layouts/_footer (2.9ms)", @request)
92
100
  info[:render_file].should == 'layouts/_footer'
@@ -97,25 +105,25 @@ describe "RequestLogAnalyzer::FileFormat::RailsDevelopment - Rails with developm
97
105
  info = @file_format.line_definitions[:query_executed].match_for(" User Load (0.4ms) SELECT * FROM `users` WHERE (`users`.`id` = 18205844) ", @request)
98
106
  info[:query_class].should == 'User'
99
107
  info[:query_duration].should == 0.0004
100
- info[:query_sql].should == 'SELECT * FROM `users` WHERE (`users`.`id` = 18205844)'
108
+ info[:query_sql].should == 'SELECT * FROM users WHERE (users.id = :int)'
101
109
  end
102
110
 
103
111
  it "should parse a query executed line without colors" do
104
112
  info = @file_format.line_definitions[:query_executed].match_for(" User Load (0.4ms) SELECT * FROM `users` WHERE (`users`.`id` = 18205844) ", @request)
105
113
  info[:query_class].should == 'User'
106
114
  info[:query_duration].should == 0.0004
107
- info[:query_sql].should == 'SELECT * FROM `users` WHERE (`users`.`id` = 18205844)'
115
+ info[:query_sql].should == 'SELECT * FROM users WHERE (users.id = :int)'
108
116
  end
109
117
 
110
118
  it "should parse a cached query line with colors" do
111
119
  info = @file_format.line_definitions[:query_cached].match_for(' CACHE (0.0ms) SELECT * FROM `users` WHERE (`users`.`id` = 0) ', @request)
112
120
  info[:cached_duration].should == 0.0
113
- info[:cached_sql].should == 'SELECT * FROM `users` WHERE (`users`.`id` = 0)'
121
+ info[:cached_sql].should == 'SELECT * FROM users WHERE (users.id = :int)'
114
122
  end
115
123
 
116
124
  it "should parse a cached query line without colors" do
117
125
  info = @file_format.line_definitions[:query_cached].match_for(' CACHE (0.0ms) SELECT * FROM `users` WHERE (`users`.`id` = 0) ', @request)
118
126
  info[:cached_duration].should == 0.0
119
- info[:cached_sql].should == 'SELECT * FROM `users` WHERE (`users`.`id` = 0)'
127
+ info[:cached_sql].should == 'SELECT * FROM users WHERE (users.id = :int)'
120
128
  end
121
129
  end
@@ -0,0 +1,22 @@
1
+ require File.dirname(__FILE__) + '/../../spec_helper'
2
+
3
+ describe RequestLogAnalyzer::Filter::Anonymize, 'anonymize request' do
4
+ include RequestLogAnalyzer::Spec::Helper
5
+
6
+ before(:each) do
7
+ @filter = RequestLogAnalyzer::Filter::Anonymize.new(testing_format)
8
+ end
9
+
10
+ it "should anonimize ip" do
11
+ @filter.filter(request(:ip => '123.123.123.123'))[:ip].should_not eql('123.123.123.123')
12
+ end
13
+
14
+ it "should anonimize url" do
15
+ @filter.filter(request(:url => 'https://test.mysite.com/employees'))[:url].should eql('http://example.com/employees')
16
+ end
17
+
18
+ it "should fuzz durations" do
19
+ @filter.filter(request(:duration => 100))[:duration].should_not eql(100)
20
+ end
21
+
22
+ end
@@ -0,0 +1,69 @@
1
+ require File.dirname(__FILE__) + '/../../spec_helper'
2
+
3
+ describe RequestLogAnalyzer::Filter::Field, 'string in accept mode' do
4
+ include RequestLogAnalyzer::Spec::Helper
5
+
6
+ before(:each) do
7
+ @filter = RequestLogAnalyzer::Filter::Field.new(testing_format, :field => :test, :value => 'test', :mode => :select)
8
+ end
9
+
10
+ it "should reject a request if the field value does not match" do
11
+ @filter.filter(request(:test => 'not test')).should be_nil
12
+ end
13
+
14
+ it "should reject a request if the field name does not match" do
15
+ @filter.filter(request(:testing => 'test')).should be_nil
16
+ end
17
+
18
+ it "should accept a request if the both name and value match" do
19
+ @filter.filter(request(:test => 'test')).should_not be_nil
20
+ end
21
+
22
+ it "should accept a request if the value is not the first value" do
23
+ @filter.filter(request([{:test => 'ignore'}, {:test => 'test'}])).should_not be_nil
24
+ end
25
+ end
26
+
27
+ describe RequestLogAnalyzer::Filter::Field, 'string in reject mode' do
28
+ include RequestLogAnalyzer::Spec::Helper
29
+
30
+ before(:each) do
31
+ @filter = RequestLogAnalyzer::Filter::Field.new(testing_format, :field => :test, :value => 'test', :mode => :reject)
32
+ end
33
+
34
+ it "should accept a request if the field value does not match" do
35
+ @filter.filter(request(:test => 'not test')).should_not be_nil
36
+ end
37
+
38
+ it "should accept a request if the field name does not match" do
39
+ @filter.filter(request(:testing => 'test')).should_not be_nil
40
+ end
41
+
42
+ it "should reject a request if the both name and value match" do
43
+ @filter.filter(request(:test => 'test')).should be_nil
44
+ end
45
+
46
+ it "should reject a request if the value is not the first value" do
47
+ @filter.filter(request([{:test => 'ignore'}, {:test => 'test'}])).should be_nil
48
+ end
49
+ end
50
+
51
+ describe RequestLogAnalyzer::Filter::Field, 'regexp in accept mode' do
52
+ include RequestLogAnalyzer::Spec::Helper
53
+
54
+ before(:each) do
55
+ @filter = RequestLogAnalyzer::Filter::Field.new(testing_format, :field => :test, :value => '/test/', :mode => :select)
56
+ end
57
+
58
+ it "should reject a request if the field value does not match" do
59
+ @filter.filter(request(:test => 'a working test')).should_not be_nil
60
+ end
61
+
62
+ it "should reject a request if the field name does not match" do
63
+ @filter.filter(request(:testing => 'test')).should be_nil
64
+ end
65
+
66
+ it "should accept a request if the value is not the first value" do
67
+ @filter.filter(request([{:test => 'ignore'}, {:test => 'testing 123'}])).should_not be_nil
68
+ end
69
+ end
@@ -0,0 +1,61 @@
1
+ require File.dirname(__FILE__) + '/../../spec_helper'
2
+
3
+ describe RequestLogAnalyzer::Filter::Timespan, 'both before and after' do
4
+ include RequestLogAnalyzer::Spec::Helper
5
+
6
+ before(:each) do
7
+ @filter = RequestLogAnalyzer::Filter::Timespan.new(testing_format, :after => DateTime.parse('2009-01-01'), :before => DateTime.parse('2009-02-02'))
8
+ end
9
+
10
+ it "should reject a request before the after date" do
11
+ @filter.filter(request(:timestamp => 20081212000000)).should be_nil
12
+ end
13
+
14
+ it "should reject a request after the before date" do
15
+ @filter.filter(request(:timestamp => 20090303000000)).should be_nil
16
+ end
17
+
18
+ it "should accept a request between the after and before dates" do
19
+ @filter.filter(request(:timestamp => 20090102000000)).should_not be_nil
20
+ end
21
+ end
22
+
23
+ describe RequestLogAnalyzer::Filter::Timespan, 'only before' do
24
+ include RequestLogAnalyzer::Spec::Helper
25
+
26
+ before(:each) do
27
+ @filter = RequestLogAnalyzer::Filter::Timespan.new(testing_format, :before => DateTime.parse('2009-02-02'))
28
+ end
29
+
30
+ it "should accept a request before the after date" do
31
+ @filter.filter(request(:timestamp => 20081212000000)).should_not be_nil
32
+ end
33
+
34
+ it "should reject a request after the before date" do
35
+ @filter.filter(request(:timestamp => 20090303000000)).should be_nil
36
+ end
37
+
38
+ it "should accept a request between the after and before dates" do
39
+ @filter.filter(request(:timestamp => 20090102000000)).should_not be_nil
40
+ end
41
+ end
42
+
43
+ describe RequestLogAnalyzer::Filter::Timespan, 'only after' do
44
+ include RequestLogAnalyzer::Spec::Helper
45
+
46
+ before(:each) do
47
+ @filter = RequestLogAnalyzer::Filter::Timespan.new(testing_format, :after => DateTime.parse('2009-01-01'))
48
+ end
49
+
50
+ it "should reject a request before the after date" do
51
+ @filter.filter(request(:timestamp => 20081212000000)).should be_nil
52
+ end
53
+
54
+ it "should accept a request after the before date" do
55
+ @filter.filter(request(:timestamp => 20090303000000)).should_not be_nil
56
+ end
57
+
58
+ it "should accept a request between the after and before dates" do
59
+ @filter.filter(request(:timestamp => 20090102000000)).should_not be_nil
60
+ end
61
+ end
@@ -1,10 +1,10 @@
1
- require File.dirname(__FILE__) + '/spec_helper'
1
+ require File.dirname(__FILE__) + '/../../spec_helper'
2
2
 
3
3
  describe RequestLogAnalyzer::Source::LogParser, :requests do
4
- include RequestLogAnalyzerSpecHelper
4
+ include RequestLogAnalyzer::Spec::Helper
5
5
 
6
6
  before(:each) do
7
- @log_parser = RequestLogAnalyzer::Source::LogParser.new(spec_format)
7
+ @log_parser = RequestLogAnalyzer::Source::LogParser.new(testing_format)
8
8
  end
9
9
 
10
10
  it "should have multiple line definitions" do
@@ -16,13 +16,13 @@ describe RequestLogAnalyzer::Source::LogParser, :requests do
16
16
  end
17
17
 
18
18
  it "should parse more lines than requests" do
19
- @log_parser.should_receive(:handle_request).with(an_instance_of(SpecFormat::Request)).twice
19
+ @log_parser.should_receive(:handle_request).with(an_instance_of(TestingFormat::Request)).twice
20
20
  @log_parser.parse_file(log_fixture(:test_language_combined))
21
21
  @log_parser.parsed_lines.should > 2
22
22
  end
23
23
 
24
24
  it "should parse requests spanned over multiple files" do
25
- @log_parser.should_receive(:handle_request).with(an_instance_of(SpecFormat::Request)).once
25
+ @log_parser.should_receive(:handle_request).with(an_instance_of(TestingFormat::Request)).once
26
26
  @log_parser.parse_files([log_fixture(:multiple_files_1), log_fixture(:multiple_files_2)])
27
27
  end
28
28
 
@@ -47,10 +47,10 @@ describe RequestLogAnalyzer::Source::LogParser, :requests do
47
47
  end
48
48
 
49
49
  describe RequestLogAnalyzer::Source::LogParser, :warnings do
50
- include RequestLogAnalyzerSpecHelper
50
+ include RequestLogAnalyzer::Spec::Helper
51
51
 
52
52
  before(:each) do
53
- @log_parser = RequestLogAnalyzer::Source::LogParser.new(spec_format)
53
+ @log_parser = RequestLogAnalyzer::Source::LogParser.new(testing_format, :parse_strategy => 'cautious')
54
54
  end
55
55
 
56
56
  it "should warn about teaser matching problems" do
@@ -1,11 +1,11 @@
1
- require File.dirname(__FILE__) + '/spec_helper'
1
+ require File.dirname(__FILE__) + '/../../spec_helper'
2
2
 
3
3
  describe RequestLogAnalyzer::Request, :incomplete_request do
4
4
 
5
- include RequestLogAnalyzerSpecHelper
5
+ include RequestLogAnalyzer::Spec::Helper
6
6
 
7
7
  before(:each) do
8
- @incomplete_request = spec_format.create_request
8
+ @incomplete_request = testing_format.request
9
9
  @incomplete_request << { :line_type => :test, :lineno => 1, :test_capture => 'awesome!' }
10
10
  end
11
11
 
@@ -34,10 +34,10 @@ end
34
34
 
35
35
  describe RequestLogAnalyzer::Request, :completed_request do
36
36
 
37
- include RequestLogAnalyzerSpecHelper
37
+ include RequestLogAnalyzer::Spec::Helper
38
38
 
39
39
  before(:each) do
40
- @completed_request = spec_format.create_request
40
+ @completed_request = testing_format.request
41
41
  @completed_request << { :line_type => :first, :lineno => 1, :name => 'first line!' }
42
42
  @completed_request << { :line_type => :test, :lineno => 4, :test_capture => 'testing' }
43
43
  @completed_request << { :line_type => :test, :lineno => 7, :test_capture => 'testing some more' }
@@ -0,0 +1,99 @@
1
+ require File.dirname(__FILE__) + '/../../spec_helper'
2
+
3
+ describe RequestLogAnalyzer::Tracker::Duration, 'static category' do
4
+
5
+ include RequestLogAnalyzer::Spec::Helper
6
+
7
+ before(:each) do
8
+ @tracker = RequestLogAnalyzer::Tracker::Duration.new(:duration => :duration, :category => :category)
9
+ @tracker.prepare
10
+ end
11
+
12
+ it "should register a request in the right category" do
13
+ @tracker.update(request(:category => 'a', :duration => 0.2))
14
+ @tracker.categories.keys.should include('a')
15
+ end
16
+
17
+ it "should register a hit in the right category" do
18
+ @tracker.update(request(:category => 'a', :duration => 0.2))
19
+ @tracker.update(request(:category => 'b', :duration => 0.3))
20
+ @tracker.update(request(:category => 'b', :duration => 0.4))
21
+
22
+ @tracker.hits('a').should == 1
23
+ @tracker.hits('b').should == 2
24
+ end
25
+
26
+ it "should sum the durations of the same category as cumulative duration" do
27
+ @tracker.update(request(:category => 'a', :duration => 0.2))
28
+ @tracker.update(request(:category => 'b', :duration => 0.3))
29
+ @tracker.update(request(:category => 'b', :duration => 0.4))
30
+
31
+ @tracker.cumulative_duration('a').should == 0.2
32
+ @tracker.cumulative_duration('b').should == 0.7
33
+ end
34
+
35
+ it "should calculate the average duration correctly" do
36
+ @tracker.update(request(:category => 'a', :duration => 0.2))
37
+ @tracker.update(request(:category => 'b', :duration => 0.3))
38
+ @tracker.update(request(:category => 'b', :duration => 0.4))
39
+
40
+ @tracker.average_duration('a').should == 0.2
41
+ @tracker.average_duration('b').should == 0.35
42
+ end
43
+
44
+ it "should set min and max duration correctly" do
45
+ @tracker.update(request(:category => 'a', :duration => 0.2))
46
+ @tracker.update(request(:category => 'b', :duration => 0.3))
47
+ @tracker.update(request(:category => 'b', :duration => 0.4))
48
+
49
+ @tracker.min_duration('b').should == 0.3
50
+ @tracker.max_duration('b').should == 0.4
51
+ end
52
+
53
+ end
54
+
55
+ describe RequestLogAnalyzer::Tracker::Duration, 'dynamic category' do
56
+
57
+ include RequestLogAnalyzer::Spec::Helper
58
+
59
+ before(:each) do
60
+ @categorizer = Proc.new { |request| request[:duration] > 0.2 ? 'slow' : 'fast' }
61
+ @tracker = RequestLogAnalyzer::Tracker::Duration.new(:duration => :duration, :category => @categorizer)
62
+ @tracker.prepare
63
+ end
64
+
65
+ it "should use the categorizer to determine the right category" do
66
+ @tracker.update(request(:category => 'a', :duration => 0.2))
67
+ @tracker.update(request(:category => 'b', :duration => 0.3))
68
+ @tracker.update(request(:category => 'b', :duration => 0.4))
69
+
70
+ @tracker.cumulative_duration('fast').should == 0.2
71
+ @tracker.cumulative_duration('slow').should == 0.7
72
+ end
73
+
74
+ end
75
+
76
+ describe RequestLogAnalyzer::Tracker::Duration, 'reporting' do
77
+
78
+ include RequestLogAnalyzer::Spec::Helper
79
+
80
+ before(:each) do
81
+ @tracker = RequestLogAnalyzer::Tracker::Duration.new(:category => :category, :duration => :duration)
82
+ @tracker.prepare
83
+ end
84
+
85
+ it "should generate a report without errors when one category is present" do
86
+ @tracker.update(request(:category => 'a', :duration => 0.2))
87
+ lambda { @tracker.report(mock_output) }.should_not raise_error
88
+ end
89
+
90
+ it "should generate a report without errors when no category is present" do
91
+ lambda { @tracker.report(mock_output) }.should_not raise_error
92
+ end
93
+
94
+ it "should generate a report without errors when multiple categories are present" do
95
+ @tracker.update(request(:category => 'a', :duration => 0.2))
96
+ @tracker.update(request(:category => 'b', :duration => 0.2))
97
+ lambda { @tracker.report(mock_output) }.should_not raise_error
98
+ end
99
+ end
@@ -0,0 +1,83 @@
1
+ require File.dirname(__FILE__) + '/../../spec_helper'
2
+
3
+ describe RequestLogAnalyzer::Tracker::Frequency, 'static category' do
4
+
5
+ include RequestLogAnalyzer::Spec::Helper
6
+
7
+ before(:each) do
8
+ @tracker = RequestLogAnalyzer::Tracker::Frequency.new(:category => :category)
9
+ @tracker.prepare
10
+ end
11
+
12
+
13
+ it "should register a request in the right category" do
14
+ @tracker.update(request(:category => 'a', :blah => 0.2))
15
+ @tracker.frequencies.keys.should include('a')
16
+ end
17
+
18
+ it "should register a request in the right category" do
19
+ @tracker.update(request(:category => 'a', :blah => 0.2))
20
+ @tracker.update(request(:category => 'b', :blah => 0.2))
21
+ @tracker.update(request(:category => 'b', :blah => 0.2))
22
+
23
+ @tracker.frequency('a').should == 1
24
+ @tracker.frequency('b').should == 2
25
+ @tracker.overall_frequency.should == 3
26
+ end
27
+
28
+ it "should sort correctly by frequency" do
29
+ @tracker.update(request(:category => 'a', :blah => 0.2))
30
+ @tracker.update(request(:category => 'b', :blah => 0.2))
31
+ @tracker.update(request(:category => 'b', :blah => 0.2))
32
+
33
+ @tracker.sorted_by_frequency.should == [['b', 2], ['a', 1]]
34
+ end
35
+ end
36
+
37
+ describe RequestLogAnalyzer::Tracker::Frequency, 'dynamic category' do
38
+
39
+ include RequestLogAnalyzer::Spec::Helper
40
+
41
+ before(:each) do
42
+ @categorizer = Proc.new { |request| request[:duration] > 0.2 ? 'slow' : 'fast' }
43
+ @tracker = RequestLogAnalyzer::Tracker::Frequency.new(:category => @categorizer)
44
+ @tracker.prepare
45
+ end
46
+
47
+ it "should use the categorizer to determine the right category" do
48
+ @tracker.update(request(:category => 'a', :duration => 0.2))
49
+ @tracker.update(request(:category => 'b', :duration => 0.3))
50
+ @tracker.update(request(:category => 'b', :duration => 0.4))
51
+
52
+ @tracker.frequency('fast').should == 1
53
+ @tracker.frequency('slow').should == 2
54
+ @tracker.frequency('moderate').should == 0
55
+ end
56
+
57
+ end
58
+
59
+
60
+ describe RequestLogAnalyzer::Tracker::Frequency, 'reporting' do
61
+
62
+ include RequestLogAnalyzer::Spec::Helper
63
+
64
+ before(:each) do
65
+ @tracker = RequestLogAnalyzer::Tracker::Frequency.new(:category => :category)
66
+ @tracker.prepare
67
+ end
68
+
69
+ it "should generate a report without errors when one category is present" do
70
+ @tracker.update(request(:category => 'a', :blah => 0.2))
71
+ lambda { @tracker.report(mock_output) }.should_not raise_error
72
+ end
73
+
74
+ it "should generate a report without errors when no category is present" do
75
+ lambda { @tracker.report(mock_output) }.should_not raise_error
76
+ end
77
+
78
+ it "should generate a report without errors when multiple categories are present" do
79
+ @tracker.update(request(:category => 'a', :blah => 0.2))
80
+ @tracker.update(request(:category => 'b', :blah => 0.2))
81
+ lambda { @tracker.report(mock_output) }.should_not raise_error
82
+ end
83
+ end
@@ -0,0 +1,75 @@
1
+ require File.dirname(__FILE__) + '/../../spec_helper'
2
+
3
+ describe RequestLogAnalyzer::Tracker::HourlySpread do
4
+
5
+ include RequestLogAnalyzer::Spec::Helper
6
+
7
+ before(:each) do
8
+ @tracker = RequestLogAnalyzer::Tracker::HourlySpread.new
9
+ @tracker.prepare
10
+ end
11
+
12
+ it "should store timestamps correctly" do
13
+ @tracker.update(request(:timestamp => 20090102000000))
14
+ @tracker.update(request(:timestamp => 20090101000000))
15
+ @tracker.update(request(:timestamp => 20090103000000))
16
+
17
+ @tracker.request_time_graph[0].should eql(3)
18
+ end
19
+
20
+ it "should count the number of timestamps correctly" do
21
+ @tracker.update(request(:timestamp => 20090102000000))
22
+ @tracker.update(request(:timestamp => 20090101000000))
23
+ @tracker.update(request(:timestamp => 20090103000000))
24
+ @tracker.update(request(:timestamp => 20090103010000))
25
+
26
+ @tracker.total_requests.should eql(4)
27
+ end
28
+
29
+ it "should set the first request timestamp correctly" do
30
+ @tracker.update(request(:timestamp => 20090102000000))
31
+ @tracker.update(request(:timestamp => 20090101000000))
32
+ @tracker.update(request(:timestamp => 20090103000000))
33
+
34
+ @tracker.first_timestamp.should == DateTime.parse('Januari 1, 2009 00:00:00')
35
+ end
36
+
37
+ it "should set the last request timestamp correctly" do
38
+ @tracker.update(request(:timestamp => 20090102000000))
39
+ @tracker.update(request(:timestamp => 20090101000000))
40
+ @tracker.update(request(:timestamp => 20090103000000))
41
+
42
+ @tracker.last_timestamp.should == DateTime.parse('Januari 3, 2009 00:00:00')
43
+ end
44
+
45
+ it "should return the correct timespan in days when multiple requests are given" do
46
+ @tracker.update(request(:timestamp => 20090102000000))
47
+ @tracker.update(request(:timestamp => 20090101000000))
48
+ @tracker.update(request(:timestamp => 20090103000000))
49
+
50
+ @tracker.timespan.should == 2
51
+ end
52
+
53
+ end
54
+
55
+ describe RequestLogAnalyzer::Tracker::HourlySpread, 'reporting' do
56
+
57
+ include RequestLogAnalyzer::Spec::Helper
58
+
59
+ before(:each) do
60
+ @tracker = RequestLogAnalyzer::Tracker::HourlySpread.new
61
+ @tracker.prepare
62
+ end
63
+
64
+ it "should generate a report without errors when no request was tracked" do
65
+ lambda { @tracker.report(mock_output) }.should_not raise_error
66
+ end
67
+
68
+ it "should generate a report without errors when multiple requests were tracked" do
69
+ @tracker.update(request(:timestamp => 20090102000000))
70
+ @tracker.update(request(:timestamp => 20090101000000))
71
+ @tracker.update(request(:timestamp => 20090103000000))
72
+ @tracker.update(request(:timestamp => 20090103010000))
73
+ lambda { @tracker.report(mock_output) }.should_not raise_error
74
+ end
75
+ end