PageRenderTime 41ms CodeModel.GetById 19ms RepoModel.GetById 0ms app.codeStats 0ms

/spec/unit/file_format/rails_format_spec.rb

http://github.com/wvanbergen/request-log-analyzer
Ruby | 173 lines | 136 code | 37 blank | 0 comment | 2 complexity | 2c496b1084d441b344da70cbde857f2f MD5 | raw file
  1. require 'spec_helper'
  2. describe RequestLogAnalyzer::FileFormat::Rails do
  3. describe '.create' do
  4. context 'without providing a lines argument' do
  5. subject { RequestLogAnalyzer::FileFormat::Rails.create }
  6. it { should be_well_formed }
  7. it { should satisfy { |ff| ff.report_trackers.length >= 11 } }
  8. it 'should parse the lines in the production set' do
  9. subject.line_definitions.should == RequestLogAnalyzer::FileFormat.load(:rails, 'production').line_definitions
  10. end
  11. end
  12. context 'using a comma separated list of lines as argument' do
  13. subject { RequestLogAnalyzer::FileFormat.load(:rails, 'minimal,failure') }
  14. it { should be_well_formed }
  15. it { should satisfy { |ff| ff.report_trackers.length >= 10 } }
  16. it { should have_line_definition(:processing) }
  17. it { should have_line_definition(:completed) }
  18. it { should have_line_definition(:failure) }
  19. end
  20. RequestLogAnalyzer::FileFormat::Rails::LINE_COLLECTIONS.keys.each do |constant|
  21. context "using the '#{constant}' line collection constant" do
  22. subject { RequestLogAnalyzer::FileFormat.load(:rails, constant) }
  23. it { should be_well_formed }
  24. it { should satisfy { |ff| ff.report_trackers.length >= 9 } }
  25. it { should have_line_definition(:processing) }
  26. it { should have_line_definition(:completed) }
  27. end
  28. end
  29. end
  30. subject { RequestLogAnalyzer::FileFormat.load(:rails, :all) }
  31. describe '#parse_line' do
  32. { 'with prefix' => 'LINE PREFIX: ', 'without prefix' => '' }.each do |context, prefix|
  33. context context do
  34. it 'should parse a :processing line correctly' do
  35. line = prefix + 'Processing PeopleController#index (for 1.1.1.1 at 2008-08-14 21:16:30) [GET]'
  36. subject.should parse_line(line).as(:processing).and_capture(controller: 'PeopleController', action: 'index', timestamp: 20_080_814_211_630, method: 'GET', ip: '1.1.1.1')
  37. end
  38. it 'should parse a :processing line correctly when it contains ipv6 localhost address' do
  39. line = prefix + 'Processing PeopleController#index (for ::1 at 2008-08-14 21:16:30) [GET]'
  40. subject.should parse_line(line).as(:processing).and_capture(controller: 'PeopleController', action: 'index', timestamp: 20_080_814_211_630, method: 'GET', ip: '::1')
  41. end
  42. it 'should parse a :processing line correctly when it contains ipv6 address' do
  43. line = prefix + 'Processing PeopleController#index (for 3ffe:1900:4545:3:200:f8ff:fe21:67cf at 2008-08-14 21:16:30) [GET]'
  44. subject.should parse_line(line).as(:processing).and_capture(controller: 'PeopleController', action: 'index', timestamp: 20_080_814_211_630, method: 'GET', ip: '3ffe:1900:4545:3:200:f8ff:fe21:67cf')
  45. end
  46. it 'should parse a Rails 2.1 style :completed line correctly' do
  47. line = prefix + 'Completed in 0.21665 (4 reqs/sec) | Rendering: 0.00926 (4%) | DB: 0.00000 (0%) | 200 OK [http://demo.nu/employees]'
  48. subject.should parse_line(line).as(:completed).and_capture(duration: 0.21665, db: 0.0, view: 0.00926, status: 200, url: 'http://demo.nu/employees')
  49. end
  50. it 'should parse a Rails 2.2 style :completed line correctly' do
  51. line = prefix + 'Completed in 614ms (View: 120, DB: 31) | 200 OK [http://floorplanner.local/demo]'
  52. subject.should parse_line(line).as(:completed).and_capture(duration: 0.614, db: 0.031, view: 0.120, status: 200, url: 'http://floorplanner.local/demo')
  53. end
  54. it 'should parse a Rails 2.2 style :completed line correctly when AR is disabled' do
  55. line = prefix + 'Completed in 597ms (View: 298 | 200 OK [http://shapado.com]'
  56. subject.should parse_line(line).as(:completed).and_capture(duration: 0.597, db: nil, view: 0.298, status: 200, url: 'http://shapado.com')
  57. end
  58. it 'should parse a Rails 2.2 style :completed line without view' do
  59. line = prefix + 'Completed in 148ms (DB: 0) | 302 Found [http://iwp-sod.hargray.org/login]'
  60. subject.should parse_line(line).as(:completed).and_capture(duration: 0.148, db: 0.0, view: nil, status: 302, url: 'http://iwp-sod.hargray.org/login')
  61. end
  62. it 'should parse a :failure line with exception correctly' do
  63. line = prefix + "NoMethodError (undefined method `update_domain_account' for nil:NilClass):"
  64. subject.should parse_line(line).as(:failure).and_capture(error: 'NoMethodError', message: "undefined method `update_domain_account' for nil:NilClass")
  65. end
  66. it 'should parse a :cache_hit line correctly with an filter instance reference' do
  67. line = prefix + 'Filter chain halted as [#<ActionController::Filters::AroundFilter:0x2a999ad120 @identifier=nil, @kind=:filter, @options={:only=>#<Set: {"cached"}>, :if=>:not_logged_in?, :unless=>nil}, @method=#<ActionController::Caching::Actions::ActionCacheFilter:0x2a999ad620 @check=nil, @options={:store_options=>{}, :layout=>nil, :cache_path=>#<Proc:0x0000002a999b8890@/app/controllers/cached_controller.rb:8>}>>] did_not_yield.'
  68. subject.should parse_line(line).as(:cache_hit)
  69. end
  70. it 'should parse a :cache_hit line correctly with an proc instance reference' do
  71. line = prefix + 'Filter chain halted as [#<ActionController::Filters::AroundFilter:0x2a9a923e38 @method=#<Proc:0x0000002a9818b3f8@/usr/local/lib/ruby/gems/1.8/gems/actionpack-2.3.5/lib/action_controller/caching/actions.rb:64>, @kind=:filter, @identifier=nil, @options={:unless=>nil, :if=>nil, :only=>#<Set: {"show"}>}>] did_not_yield.'
  72. subject.should parse_line(line).as(:cache_hit)
  73. end
  74. it 'should parse a :parameters line correctly' do
  75. line = prefix + ' Parameters: {"action"=>"cached", "controller"=>"cached"}'
  76. subject.should parse_line(line).as(:parameters).and_capture(params: { action: 'cached', controller: 'cached' })
  77. end
  78. it 'should parse a :rendered line correctly' do
  79. line = prefix + 'Rendered layouts/_footer (2.9ms)'
  80. subject.should parse_line(line).as(:rendered).and_capture(render_file: 'layouts/_footer', render_duration: 0.0029)
  81. end
  82. it 'should parse a :query_executed line with colors' do
  83. line = prefix + ' User Load (0.4ms) SELECT * FROM `users` WHERE (`users`.`id` = 18205844) '
  84. subject.should parse_line(line).as(:query_executed).and_capture(query_class: 'User', query_duration: 0.0004, query_sql: 'SELECT * FROM users WHERE (users.id = :int)')
  85. end
  86. it 'should parse a :query_executed line without colors' do
  87. line = prefix + ' User Load (0.4ms) SELECT * FROM `users` WHERE (`users`.`id` = 18205844) '
  88. subject.should parse_line(line).as(:query_executed).and_capture(query_class: 'User', query_duration: 0.0004, query_sql: 'SELECT * FROM users WHERE (users.id = :int)')
  89. end
  90. it 'should parse a :query_cached line with colors' do
  91. line = prefix + ' CACHE (0.0ms) SELECT * FROM `users` WHERE (`users`.`id` = 0) '
  92. subject.should parse_line(line).as(:query_cached).and_capture(cached_duration: 0.0, cached_sql: 'SELECT * FROM users WHERE (users.id = :int)')
  93. end
  94. it 'should parse a :query_cached line without colors' do
  95. line = prefix + ' CACHE (0.0ms) SELECT * FROM `users` WHERE (`users`.`id` = 0) '
  96. subject.should parse_line(line).as(:query_cached).and_capture(cached_duration: 0.0, cached_sql: 'SELECT * FROM users WHERE (users.id = :int)')
  97. end
  98. it 'should not parse an unsupported line' do
  99. line = prefix + 'nonsense line that should not be parsed as anything'
  100. subject.should_not parse_line(line)
  101. end
  102. end
  103. end
  104. end
  105. describe '#parse_io' do
  106. let(:log_parser) { RequestLogAnalyzer::Source::LogParser.new(subject, parse_strategy: 'cautious') }
  107. it 'should parse a Rails 2.1 style log and find valid Rails requests without warnings' do
  108. log_parser.should_receive(:handle_request).exactly(4).times
  109. log_parser.should_not_receive(:warn)
  110. log_parser.parse_file(log_fixture(:rails_1x))
  111. end
  112. it 'should parse a Rails 2.2 style log and find valid Rails requests without warnings' do
  113. log_parser.should_receive(:handle_request).once
  114. log_parser.should_not_receive(:warn)
  115. log_parser.parse_file(log_fixture(:rails_22))
  116. end
  117. it 'should parse a Rails SyslogLogger file with prefix and find valid requests without warnings' do
  118. log_parser.should_receive(:handle_request).once
  119. log_parser.should_not_receive(:warn)
  120. log_parser.parse_file(log_fixture(:syslog_1x))
  121. end
  122. it 'should parse cached requests' do
  123. log_parser.should_not_receive(:warn)
  124. log_parser.parse_file(log_fixture(:rails_22_cached)) do |request|
  125. request.should be_completed
  126. request =~ :cache_hit
  127. end
  128. end
  129. it 'should detect unordered requests in the logs' do
  130. log_parser.should_not_receive(:handle_request)
  131. log_parser.should_receive(:warn).with(:unclosed_request, anything).once
  132. log_parser.should_receive(:warn).with(:no_current_request, anything).at_least(:twice)
  133. log_parser.parse_file(log_fixture(:rails_unordered))
  134. end
  135. end
  136. end