request-log-analyzer 1.1.1 → 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 (62) 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 -38
  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 +22 -16
  10. data/lib/request_log_analyzer/controller.rb +21 -5
  11. data/lib/request_log_analyzer/file_format/merb.rb +22 -9
  12. data/lib/request_log_analyzer/file_format/rails.rb +37 -23
  13. data/lib/request_log_analyzer/file_format/rails_development.rb +33 -88
  14. data/lib/request_log_analyzer/file_format.rb +50 -18
  15. data/lib/request_log_analyzer/filter/{anonimize.rb → anonymize.rb} +3 -8
  16. data/lib/request_log_analyzer/filter/field.rb +7 -6
  17. data/lib/request_log_analyzer/filter/timespan.rb +7 -3
  18. data/lib/request_log_analyzer/filter.rb +0 -4
  19. data/lib/request_log_analyzer/line_definition.rb +22 -88
  20. data/lib/request_log_analyzer/log_processor.rb +5 -25
  21. data/lib/request_log_analyzer/output/fixed_width.rb +14 -3
  22. data/lib/request_log_analyzer/output/html.rb +1 -0
  23. data/lib/request_log_analyzer/request.rb +62 -4
  24. data/lib/request_log_analyzer/source/database.rb +76 -0
  25. data/lib/request_log_analyzer/source/log_parser.rb +104 -52
  26. data/lib/request_log_analyzer/source.rb +28 -6
  27. data/lib/request_log_analyzer/tracker/duration.rb +90 -15
  28. data/lib/request_log_analyzer/tracker/{category.rb → frequency.rb} +24 -12
  29. data/lib/request_log_analyzer/tracker/hourly_spread.rb +20 -9
  30. data/lib/request_log_analyzer/tracker/timespan.rb +15 -8
  31. data/lib/request_log_analyzer.rb +29 -16
  32. data/spec/integration/command_line_usage_spec.rb +71 -0
  33. data/spec/lib/helper.rb +33 -0
  34. data/spec/lib/mocks.rb +47 -0
  35. data/spec/lib/testing_format.rb +39 -0
  36. data/spec/spec_helper.rb +5 -25
  37. data/spec/{database_inserter_spec.rb → unit/aggregator/database_inserter_spec.rb} +40 -37
  38. data/spec/unit/aggregator/summarizer_spec.rb +28 -0
  39. data/spec/unit/controller/controller_spec.rb +43 -0
  40. data/spec/unit/controller/log_processor_spec.rb +20 -0
  41. data/spec/{file_format_spec.rb → unit/file_format/file_format_api_spec.rb} +18 -6
  42. data/spec/unit/file_format/line_definition_spec.rb +64 -0
  43. data/spec/{merb_format_spec.rb → unit/file_format/merb_format_spec.rb} +3 -3
  44. data/spec/{rails_format_spec.rb → unit/file_format/rails_format_spec.rb} +24 -15
  45. data/spec/unit/filter/anonymize_filter_spec.rb +22 -0
  46. data/spec/unit/filter/field_filter_spec.rb +69 -0
  47. data/spec/unit/filter/timespan_filter_spec.rb +61 -0
  48. data/spec/{log_parser_spec.rb → unit/source/log_parser_spec.rb} +9 -10
  49. data/spec/{request_spec.rb → unit/source/request_spec.rb} +5 -5
  50. data/spec/unit/tracker/duration_tracker_spec.rb +99 -0
  51. data/spec/unit/tracker/frequency_tracker_spec.rb +83 -0
  52. data/spec/unit/tracker/hourly_spread_spec.rb +75 -0
  53. data/spec/unit/tracker/timespan_tracker_spec.rb +65 -0
  54. data/spec/unit/tracker/tracker_api_test.rb +45 -0
  55. data/tasks/rspec.rake +12 -0
  56. metadata +56 -28
  57. data/spec/controller_spec.rb +0 -45
  58. data/spec/file_formats/spec_format.rb +0 -27
  59. data/spec/filter_spec.rb +0 -157
  60. data/spec/line_definition_spec.rb +0 -124
  61. data/spec/log_processor_spec.rb +0 -57
  62. data/spec/summarizer_spec.rb +0 -9
@@ -0,0 +1,20 @@
1
+ require File.dirname(__FILE__) + '/../../spec_helper'
2
+
3
+ require 'request_log_analyzer/log_processor'
4
+
5
+ describe RequestLogAnalyzer::LogProcessor, 'stripping log files' do
6
+
7
+ include RequestLogAnalyzer::Spec::Helper
8
+
9
+ before(:each) do
10
+ @log_stripper = RequestLogAnalyzer::LogProcessor.new(testing_format, :strip, {})
11
+ end
12
+
13
+ it "should remove a junk line" do
14
+ @log_stripper.strip_line("junk line\n").should be_empty
15
+ end
16
+
17
+ it "should keep a teaser line intact" do
18
+ @log_stripper.strip_line("processing 1234\n").should be_empty
19
+ end
20
+ 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::FileFormat, :format_definition do
4
4
 
@@ -50,20 +50,31 @@ describe RequestLogAnalyzer::FileFormat, :format_definition do
50
50
  line.first_test :regexp => /test/, :captures => []
51
51
  end
52
52
 
53
+
53
54
  @second_file_format.format_definition do |line|
54
55
  line.second_test :regexp => /test/, :captures => []
55
56
  end
56
57
 
58
+ @first_file_format.line_definer.should_not eql(@second_file_format.line_definer)
57
59
  @first_file_format.new.should have(1).line_definitions
58
- @first_file_format.new.line_definitions[:first_test].should_not be_nil
59
- @second_file_format.new.should have(1).line_definitions
60
60
  @second_file_format.new.line_definitions[:second_test].should_not be_nil
61
61
  end
62
62
  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
@@ -0,0 +1,64 @@
1
+ require File.dirname(__FILE__) + '/../../spec_helper'
2
+
3
+ describe RequestLogAnalyzer::LineDefinition, :parsing do
4
+
5
+ before(:each) do
6
+ @line_definition = RequestLogAnalyzer::LineDefinition.new(:test, {
7
+ :teaser => /Testing /,
8
+ :regexp => /Testing (\w+), tries\: (\d+)/,
9
+ :captures => [{ :name => :what, :type => :string }, { :name => :tries, :type => :integer }]
10
+ })
11
+ end
12
+
13
+ it "should return false on an unmatching line" do
14
+ (@line_definition =~ "nonmatching").should be_false
15
+ end
16
+
17
+ it "should return false when only the teaser matches" do
18
+ (@line_definition =~ "Testing LineDefinition").should be_false
19
+ end
20
+
21
+ it "should return a hash if the line matches" do
22
+ (@line_definition =~ "Testing LineDefinition, tries: 123").should be_kind_of(Hash)
23
+ end
24
+
25
+ it "should return a hash with :captures set to an array" do
26
+ hash = @line_definition.matches("Testing LineDefinition, tries: 123")
27
+ hash[:captures][0].should == "LineDefinition"
28
+ hash[:captures][1].should == "123"
29
+ end
30
+
31
+ it "should return a hash with :line_definition set" do
32
+ @line_definition.matches("Testing LineDefinition, tries: 123")[:line_definition].should == @line_definition
33
+ end
34
+ end
35
+
36
+ describe RequestLogAnalyzer::LineDefinition, :converting do
37
+
38
+ include RequestLogAnalyzer::Spec::Helper
39
+
40
+ before(:each) do
41
+ @file_format = testing_format
42
+ @request = @file_format.request
43
+ end
44
+
45
+ it "should convert captures to a hash of converted values" do
46
+ hash = @file_format.line_definitions[:first].convert_captured_values(["456"], @request)
47
+ hash[:request_no].should == 456
48
+ end
49
+
50
+ it "should convert captures to a hash" do
51
+ hash = @file_format.line_definitions[:test].convert_captured_values(["great", nil], @request)
52
+ hash[:test_capture].should == 'Testing is great'
53
+ hash[:duration].should be_nil
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
62
+
63
+
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))
@@ -29,7 +29,7 @@ describe RequestLogAnalyzer::Source::LogParser, :merb do
29
29
  @log_parser.parse_file(log_fixture(:merb)) { |found_request| request ||= found_request }
30
30
 
31
31
  request.should be_completed
32
- #request[:timestamp].should == DateTime.parse('Fri Aug 29 11:10:23 +0200 2008') # FIX ME
32
+ request[:timestamp].should == 20080829111023 # 'Fri Aug 29 11:10:23 +0200 2008'
33
33
  request[:dispatch_time].should == 0.243424
34
34
  request[:after_filters_time].should == 6.9e-05
35
35
  request[:before_filters_time].should == 0.213213
@@ -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,55 +67,63 @@ 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)
86
+ @request = @file_format.request
83
87
  end
84
88
 
85
89
  it "should have a valid language definitions" do
86
90
  @file_format.should be_valid
87
91
  end
88
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
+
89
98
  it "should parse a rendered line" do
90
- info = @file_format.line_definitions[:rendered].matches("Rendered layouts/_footer (2.9ms)")
99
+ info = @file_format.line_definitions[:rendered].match_for("Rendered layouts/_footer (2.9ms)", @request)
91
100
  info[:render_file].should == 'layouts/_footer'
92
101
  info[:render_duration].should == 0.0029
93
102
  end
94
103
 
95
104
  it "should parse a query executed line with colors" do
96
- info = @file_format.line_definitions[:query_executed].matches(" User Load (0.4ms) SELECT * FROM `users` WHERE (`users`.`id` = 18205844) ")
105
+ info = @file_format.line_definitions[:query_executed].match_for(" User Load (0.4ms) SELECT * FROM `users` WHERE (`users`.`id` = 18205844) ", @request)
97
106
  info[:query_class].should == 'User'
98
107
  info[:query_duration].should == 0.0004
99
- info[:query_sql].should == 'SELECT * FROM `users` WHERE (`users`.`id` = 18205844)'
108
+ info[:query_sql].should == 'SELECT * FROM users WHERE (users.id = :int)'
100
109
  end
101
110
 
102
111
  it "should parse a query executed line without colors" do
103
- info = @file_format.line_definitions[:query_executed].matches(" User Load (0.4ms) SELECT * FROM `users` WHERE (`users`.`id` = 18205844) ")
112
+ info = @file_format.line_definitions[:query_executed].match_for(" User Load (0.4ms) SELECT * FROM `users` WHERE (`users`.`id` = 18205844) ", @request)
104
113
  info[:query_class].should == 'User'
105
114
  info[:query_duration].should == 0.0004
106
- info[:query_sql].should == 'SELECT * FROM `users` WHERE (`users`.`id` = 18205844)'
115
+ info[:query_sql].should == 'SELECT * FROM users WHERE (users.id = :int)'
107
116
  end
108
117
 
109
118
  it "should parse a cached query line with colors" do
110
- info = @file_format.line_definitions[:query_cached].matches(' CACHE (0.0ms) SELECT * FROM `users` WHERE (`users`.`id` = 0) ')
119
+ info = @file_format.line_definitions[:query_cached].match_for(' CACHE (0.0ms) SELECT * FROM `users` WHERE (`users`.`id` = 0) ', @request)
111
120
  info[:cached_duration].should == 0.0
112
- info[:cached_sql].should == 'SELECT * FROM `users` WHERE (`users`.`id` = 0)'
121
+ info[:cached_sql].should == 'SELECT * FROM users WHERE (users.id = :int)'
113
122
  end
114
123
 
115
124
  it "should parse a cached query line without colors" do
116
- info = @file_format.line_definitions[:query_cached].matches(' CACHE (0.0ms) SELECT * FROM `users` WHERE (`users`.`id` = 0) ')
125
+ info = @file_format.line_definitions[:query_cached].match_for(' CACHE (0.0ms) SELECT * FROM `users` WHERE (`users`.`id` = 0) ', @request)
117
126
  info[:cached_duration].should == 0.0
118
- info[:cached_sql].should == 'SELECT * FROM `users` WHERE (`users`.`id` = 0)'
127
+ info[:cached_sql].should == 'SELECT * FROM users WHERE (users.id = :int)'
119
128
  end
120
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,22 +16,21 @@ 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
 
29
29
  it "should parse all request values when spanned over multiple files" do
30
30
  @log_parser.parse_files([log_fixture(:multiple_files_1), log_fixture(:multiple_files_2)]) do |request|
31
- request.lines.should have(4).items
32
-
31
+ request.lines.should have(4).items
33
32
  request[:request_no].should == 1
34
- request[:test_capture].should == "amazing"
33
+ request[:test_capture].should == "Testing is amazing" # Note the custom converter
35
34
  end
36
35
  end
37
36
 
@@ -48,10 +47,10 @@ describe RequestLogAnalyzer::Source::LogParser, :requests do
48
47
  end
49
48
 
50
49
  describe RequestLogAnalyzer::Source::LogParser, :warnings do
51
- include RequestLogAnalyzerSpecHelper
50
+ include RequestLogAnalyzer::Spec::Helper
52
51
 
53
52
  before(:each) do
54
- @log_parser = RequestLogAnalyzer::Source::LogParser.new(spec_format)
53
+ @log_parser = RequestLogAnalyzer::Source::LogParser.new(testing_format, :parse_strategy => 'cautious')
55
54
  end
56
55
 
57
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