request-log-analyzer 1.0.2

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 (60) hide show
  1. data/DESIGN +14 -0
  2. data/HACKING +7 -0
  3. data/LICENSE +20 -0
  4. data/README.textile +36 -0
  5. data/Rakefile +5 -0
  6. data/bin/request-log-analyzer +123 -0
  7. data/lib/cli/bashcolorizer.rb +60 -0
  8. data/lib/cli/command_line_arguments.rb +301 -0
  9. data/lib/cli/progressbar.rb +236 -0
  10. data/lib/request_log_analyzer.rb +14 -0
  11. data/lib/request_log_analyzer/aggregator/base.rb +45 -0
  12. data/lib/request_log_analyzer/aggregator/database.rb +148 -0
  13. data/lib/request_log_analyzer/aggregator/echo.rb +25 -0
  14. data/lib/request_log_analyzer/aggregator/summarizer.rb +116 -0
  15. data/lib/request_log_analyzer/controller.rb +201 -0
  16. data/lib/request_log_analyzer/file_format.rb +81 -0
  17. data/lib/request_log_analyzer/file_format/merb.rb +33 -0
  18. data/lib/request_log_analyzer/file_format/rails.rb +90 -0
  19. data/lib/request_log_analyzer/filter/base.rb +29 -0
  20. data/lib/request_log_analyzer/filter/field.rb +36 -0
  21. data/lib/request_log_analyzer/filter/timespan.rb +32 -0
  22. data/lib/request_log_analyzer/line_definition.rb +159 -0
  23. data/lib/request_log_analyzer/log_parser.rb +173 -0
  24. data/lib/request_log_analyzer/log_processor.rb +121 -0
  25. data/lib/request_log_analyzer/request.rb +95 -0
  26. data/lib/request_log_analyzer/source/base.rb +42 -0
  27. data/lib/request_log_analyzer/source/log_file.rb +170 -0
  28. data/lib/request_log_analyzer/tracker/base.rb +54 -0
  29. data/lib/request_log_analyzer/tracker/category.rb +71 -0
  30. data/lib/request_log_analyzer/tracker/duration.rb +81 -0
  31. data/lib/request_log_analyzer/tracker/hourly_spread.rb +80 -0
  32. data/lib/request_log_analyzer/tracker/timespan.rb +54 -0
  33. data/spec/controller_spec.rb +40 -0
  34. data/spec/database_inserter_spec.rb +101 -0
  35. data/spec/file_format_spec.rb +78 -0
  36. data/spec/file_formats/spec_format.rb +26 -0
  37. data/spec/filter_spec.rb +137 -0
  38. data/spec/fixtures/merb.log +84 -0
  39. data/spec/fixtures/multiple_files_1.log +5 -0
  40. data/spec/fixtures/multiple_files_2.log +2 -0
  41. data/spec/fixtures/rails_1x.log +59 -0
  42. data/spec/fixtures/rails_22.log +12 -0
  43. data/spec/fixtures/rails_22_cached.log +10 -0
  44. data/spec/fixtures/rails_unordered.log +24 -0
  45. data/spec/fixtures/syslog_1x.log +5 -0
  46. data/spec/fixtures/test_file_format.log +13 -0
  47. data/spec/fixtures/test_language_combined.log +14 -0
  48. data/spec/fixtures/test_order.log +16 -0
  49. data/spec/line_definition_spec.rb +124 -0
  50. data/spec/log_parser_spec.rb +68 -0
  51. data/spec/log_processor_spec.rb +57 -0
  52. data/spec/merb_format_spec.rb +38 -0
  53. data/spec/rails_format_spec.rb +76 -0
  54. data/spec/request_spec.rb +72 -0
  55. data/spec/spec_helper.rb +67 -0
  56. data/spec/summarizer_spec.rb +9 -0
  57. data/tasks/github-gem.rake +177 -0
  58. data/tasks/request_log_analyzer.rake +10 -0
  59. data/tasks/rspec.rake +6 -0
  60. metadata +135 -0
@@ -0,0 +1,80 @@
1
+ module RequestLogAnalyzer::Tracker
2
+
3
+ # Determines the average hourly spread of the parsed requests.
4
+ # This spread is shown in a graph form.
5
+ #
6
+ # Accepts the following options:
7
+ # * <tt>:line_type</tt> The line type that contains the duration field (determined by the category proc).
8
+ # * <tt>:if</tt> Proc that has to return !nil for a request to be passed to the tracker.
9
+ #
10
+ # Expects the following items in the update request hash
11
+ # * <tt>:timestamp</tt> in YYYYMMDDHHMMSS format.
12
+ #
13
+ # Example output:
14
+ # Requests graph - average per day per hour
15
+ # ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
16
+ # 7:00 - 330 hits : ░░░░░░░
17
+ # 8:00 - 704 hits : ░░░░░░░░░░░░░░░░░
18
+ # 9:00 - 830 hits : ░░░░░░░░░░░░░░░░░░░░
19
+ # 10:00 - 822 hits : ░░░░░░░░░░░░░░░░░░░
20
+ # 11:00 - 823 hits : ░░░░░░░░░░░░░░░░░░░
21
+ # 12:00 - 729 hits : ░░░░░░░░░░░░░░░░░
22
+ # 13:00 - 614 hits : ░░░░░░░░░░░░░░
23
+ # 14:00 - 690 hits : ░░░░░░░░░░░░░░░░
24
+ # 15:00 - 492 hits : ░░░░░░░░░░░
25
+ # 16:00 - 355 hits : ░░░░░░░░
26
+ # 17:00 - 213 hits : ░░░░░
27
+ # 18:00 - 107 hits : ░░
28
+ # ................
29
+ class HourlySpread < RequestLogAnalyzer::Tracker::Base
30
+
31
+ attr_reader :first, :last, :request_time_graph
32
+
33
+ def prepare
34
+ options[:field] ||= :timestamp
35
+ @request_time_graph = [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]
36
+ end
37
+
38
+ def update(request)
39
+ request = request.attributes
40
+ timestamp = request[options[:field]]
41
+
42
+ @request_time_graph[timestamp.to_s[8..9].to_i] +=1
43
+ @first = timestamp if @first.nil? || timestamp < @first
44
+ @last = timestamp if @last.nil? || timestamp > @last
45
+ end
46
+
47
+ def report(output = STDOUT, report_width = 80, color = false)
48
+ output << "\n"
49
+ output << "Requests graph - average per day per hour\n"
50
+ output << green("━" * report_width, color) + "\n"
51
+
52
+ if @request_time_graph == [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]
53
+ output << "None found.\n"
54
+ return
55
+ end
56
+
57
+ first_date = DateTime.parse(@first.to_s, '%Y%m%d%H%M%S')
58
+ last_date = DateTime.parse(@last.to_s, '%Y%m%d%H%M%S')
59
+ days = (@last && @first) ? (last_date - first_date).ceil : 1
60
+ deviation = @request_time_graph.max / 20
61
+ deviation = 1 if deviation == 0
62
+ color_cutoff = 15
63
+
64
+ @request_time_graph.each_with_index do |requests, index|
65
+ display_chars = requests / deviation
66
+ request_today = requests / days
67
+
68
+ if display_chars >= color_cutoff
69
+ display_chars_string = green(('░' * color_cutoff), color) + red(('░' * (display_chars - color_cutoff)), color)
70
+ else
71
+ display_chars_string = green(('░' * display_chars), color)
72
+ end
73
+
74
+ output << "#{index.to_s.rjust(3)}:00 - #{(request_today.to_s + ' hits').ljust(15)} : #{display_chars_string}\n"
75
+ end
76
+ output << "\n"
77
+
78
+ end
79
+ end
80
+ end
@@ -0,0 +1,54 @@
1
+ module RequestLogAnalyzer::Tracker
2
+
3
+ # Determines the datetime of the first request and the last request
4
+ # Also determines the amount of days inbetween these.
5
+ #
6
+ # Accepts the following options:
7
+ # * <tt>:line_type</tt> The line type that contains the duration field (determined by the category proc).
8
+ # * <tt>:if</tt> Proc that has to return !nil for a request to be passed to the tracker.
9
+ # * <tt>:field</tt> The timestamp field that is looked at. Defaults to :timestamp.
10
+ # * <tt>:title</tt> Title do be displayed above the report.
11
+ #
12
+ # Expects the following items in the update request hash
13
+ # * <tt>:timestamp</tt> in YYYYMMDDHHMMSS format.
14
+ #
15
+ # Example output:
16
+ # First request: 2008-07-13 06:25:06
17
+ # Last request: 2008-07-20 06:18:06
18
+ # Total time analyzed: 7 days
19
+ class Timespan < RequestLogAnalyzer::Tracker::Base
20
+
21
+ attr_reader :first, :last, :request_time_graph
22
+
23
+ def prepare
24
+ options[:field] ||= :timestamp
25
+ end
26
+
27
+ def update(request)
28
+ timestamp = request[options[:field]]
29
+
30
+ @first = timestamp if @first.nil? || timestamp < @first
31
+ @last = timestamp if @last.nil? || timestamp > @last
32
+ end
33
+
34
+ def report(output = STDOUT, report_width = 80, color = false)
35
+ if options[:title]
36
+ output << "\n#{options[:title]}\n"
37
+ output << green('━' * options[:title].length, color) + "\n"
38
+ end
39
+
40
+ first_date = DateTime.parse(@first.to_s, '%Y%m%d%H%M%S') rescue nil
41
+ last_date = DateTime.parse(@last.to_s, '%Y%m%d%H%M%S') rescue nil
42
+
43
+ if @last && @first
44
+ days = (@last && @first) ? (last_date - first_date).ceil : 1
45
+
46
+ output << "First request: #{first_date.strftime('%Y-%m-%d %H:%M:%I')}\n"
47
+ output << "Last request: #{last_date.strftime('%Y-%m-%d %H:%M:%I')}\n"
48
+ output << "Total time analyzed: #{days} days\n"
49
+ end
50
+ output << "\n"
51
+
52
+ end
53
+ end
54
+ end
@@ -0,0 +1,40 @@
1
+ require File.dirname(__FILE__) + '/spec_helper'
2
+
3
+ describe RequestLogAnalyzer::Controller do
4
+
5
+ include RequestLogAnalyzerSpecHelper
6
+
7
+ # it "should include the file format module" do
8
+ # controller = RequestLogAnalyzer::Controller.new(:rails)
9
+ # (class << controller; self; end).ancestors.include?(RequestLogAnalyzer::FileFormat::Rails)
10
+ # end
11
+
12
+ it "should call the aggregators when run" do
13
+ file_format = RequestLogAnalyzer::FileFormat.load(:rails)
14
+ source = RequestLogAnalyzer::Source::LogFile.new(file_format, :source_files => log_fixture(:rails_1x))
15
+ controller = RequestLogAnalyzer::Controller.new(source)
16
+
17
+ mock_aggregator = mock('aggregator')
18
+ mock_aggregator.should_receive(:prepare).once.ordered
19
+ mock_aggregator.should_receive(:aggregate).with(an_instance_of(RequestLogAnalyzer::Request)).at_least(:twice).ordered
20
+ mock_aggregator.should_receive(:finalize).once.ordered
21
+ mock_aggregator.should_receive(:report).once.ordered
22
+
23
+ another_mock_aggregator = mock('another aggregator')
24
+ another_mock_aggregator.should_receive(:prepare).once.ordered
25
+ another_mock_aggregator.should_receive(:aggregate).with(an_instance_of(RequestLogAnalyzer::Request)).at_least(:twice).ordered
26
+ another_mock_aggregator.should_receive(:finalize).once.ordered
27
+ another_mock_aggregator.should_receive(:report).once.ordered
28
+
29
+
30
+ controller.aggregators << mock_aggregator << another_mock_aggregator
31
+ controller.run!
32
+ end
33
+
34
+ it "should run well from the command line" do
35
+ temp_file = "#{File.dirname(__FILE__)}/fixtures/temp.txt"
36
+ system("#{File.dirname(__FILE__)}/../bin/request-log-analyzer #{log_fixture(:rails_1x)} > #{temp_file}").should be_true
37
+ File.unlink(temp_file)
38
+ end
39
+
40
+ end
@@ -0,0 +1,101 @@
1
+ require File.dirname(__FILE__) + '/spec_helper'
2
+ require 'request_log_analyzer/aggregator/database'
3
+
4
+
5
+ describe RequestLogAnalyzer::Aggregator::Database, "schema creation" do
6
+
7
+ TEST_DATABASE_FILE = File.dirname(__FILE__) + "/fixtures/requests.db"
8
+ include RequestLogAnalyzerSpecHelper
9
+
10
+ before(:each) do
11
+ log_parser = RequestLogAnalyzer::LogParser.new(spec_format)
12
+ @database_inserter = RequestLogAnalyzer::Aggregator::Database.new(log_parser, :database => TEST_DATABASE_FILE)
13
+ end
14
+
15
+ after(:each) do
16
+ File.unlink(TEST_DATABASE_FILE) if File.exist?(TEST_DATABASE_FILE)
17
+ end
18
+
19
+ it "should create the correct tables" do
20
+ ActiveRecord::Migration.should_receive(:create_table).with("warnings")
21
+ ActiveRecord::Migration.should_receive(:create_table).with("requests")
22
+ ActiveRecord::Migration.should_receive(:create_table).with("first_lines")
23
+ ActiveRecord::Migration.should_receive(:create_table).with("test_lines")
24
+ ActiveRecord::Migration.should_receive(:create_table).with("last_lines")
25
+ @database_inserter.prepare
26
+ end
27
+
28
+ it "should create a default Request class" do
29
+ @database_inserter.prepare
30
+ SpecFormat::Database::Request.ancestors.should include(ActiveRecord::Base)
31
+ SpecFormat::Database::Request.column_names.should include('first_lineno')
32
+ SpecFormat::Database::Request.column_names.should include('last_lineno')
33
+ end
34
+
35
+ it "should create associations for the default Request class" do
36
+ @database_inserter.prepare
37
+ @request = SpecFormat::Database::Request.new
38
+ @request.should respond_to(:test_lines)
39
+ @request.test_lines.should
40
+ end
41
+
42
+ it "should create the default table names" do
43
+ @database_inserter.prepare
44
+ @database_inserter.file_format.line_definitions.each do |name, definition|
45
+ klass = SpecFormat::Database.const_get("#{name}_line".camelize)
46
+ klass.column_names.should include('id')
47
+ klass.column_names.should include('lineno')
48
+ klass.column_names.should include('request_id')
49
+ end
50
+ end
51
+
52
+ it "should create the correct fields in the table" do
53
+ @database_inserter.prepare
54
+
55
+ SpecFormat::Database::FirstLine.column_names.should include('request_no')
56
+ SpecFormat::Database::LastLine.column_names.should include('request_no')
57
+ SpecFormat::Database::TestLine.column_names.should include('test_capture')
58
+ end
59
+
60
+ end
61
+
62
+ describe RequestLogAnalyzer::Aggregator::Database, "record insertion" do
63
+ include RequestLogAnalyzerSpecHelper
64
+
65
+ before(:each) do
66
+ log_parser = RequestLogAnalyzer::LogParser.new(spec_format)
67
+ @database_inserter = RequestLogAnalyzer::Aggregator::Database.new(log_parser, :database => TEST_DATABASE_FILE)
68
+ @database_inserter.prepare
69
+
70
+ @incomplete_request = RequestLogAnalyzer::Request.create(spec_format, {:line_type => :first, :request_no => 564})
71
+ @completed_request = RequestLogAnalyzer::Request.create(spec_format,
72
+ {:line_type => :first, :request_no => 564},
73
+ {:line_type => :test, :test_capture => "awesome"},
74
+ {:line_type => :test, :test_capture => "indeed"},
75
+ {:line_type => :last, :request_no => 564})
76
+ end
77
+
78
+ after(:each) do
79
+ File.unlink(TEST_DATABASE_FILE) if File.exist?(TEST_DATABASE_FILE)
80
+ end
81
+
82
+ it "should insert a record in the request table" do
83
+ SpecFormat::Database::Request.count.should == 0
84
+ @database_inserter.aggregate(@incomplete_request)
85
+ SpecFormat::Database::Request.count.should == 1
86
+ end
87
+
88
+ it "should insert records in all relevant line tables" do
89
+ @database_inserter.aggregate(@completed_request)
90
+ request = SpecFormat::Database::Request.first
91
+ request.should have(2).test_lines
92
+ request.should have(1).first_lines
93
+ request.should have(1).last_lines
94
+ end
95
+
96
+ it "should log a warning in the warnings table" do
97
+ SpecFormat::Database::Warning.should_receive(:create!).with(hash_including(:warning_type => 'test_warning'))
98
+ @database_inserter.warning(:test_warning, "Testing the warning system", 12)
99
+ end
100
+
101
+ end
@@ -0,0 +1,78 @@
1
+ require File.dirname(__FILE__) + '/spec_helper'
2
+
3
+ describe RequestLogAnalyzer::FileFormat, :format_definition do
4
+
5
+ before(:each) do
6
+ @first_file_format = Class.new(RequestLogAnalyzer::FileFormat)
7
+ @second_file_format = Class.new(RequestLogAnalyzer::FileFormat)
8
+ end
9
+
10
+ it "should specify lines with a hash" do
11
+
12
+ @first_file_format.new.should have(0).line_definitions
13
+
14
+ @first_file_format.format_definition do |line|
15
+ line.hash_test :regexp => /test/, :captures => []
16
+ end
17
+
18
+ @format_instance = @first_file_format.new
19
+ @format_instance.should have(1).line_definitions
20
+ @format_instance.line_definitions[:hash_test].should_not be_nil
21
+ end
22
+
23
+ it "should specift lines directly" do
24
+ @first_file_format.new.should have(0).line_definitions
25
+
26
+ @first_file_format.format_definition.direct_test do |line|
27
+ line.regexp = /test/
28
+ end
29
+
30
+ @first_file_format.new.line_definitions[:direct_test].should_not be_nil
31
+ end
32
+
33
+ it "specify lines with a block" do
34
+
35
+ @first_file_format.new.should have(0).line_definitions
36
+
37
+ @first_file_format.format_definition do |format|
38
+ format.block_test do |line|
39
+ line.regexp = /test/
40
+ line.captures = []
41
+ end
42
+ end
43
+
44
+ @first_file_format.new.line_definitions[:block_test].should_not be_nil
45
+ end
46
+
47
+ it "should define lines only for itself" do
48
+
49
+ @first_file_format.format_definition do |line|
50
+ line.first_test :regexp => /test/, :captures => []
51
+ end
52
+
53
+ @second_file_format.format_definition do |line|
54
+ line.second_test :regexp => /test/, :captures => []
55
+ end
56
+
57
+ @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
+ @second_file_format.new.line_definitions[:second_test].should_not be_nil
61
+ end
62
+ end
63
+
64
+ describe RequestLogAnalyzer::FileFormat, :load do
65
+
66
+ include RequestLogAnalyzerSpecHelper
67
+
68
+ it "should load a predefined file format from the /file_format dir" do
69
+ @file_format = RequestLogAnalyzer::FileFormat.load(:rails)
70
+ @file_format.should be_kind_of(RequestLogAnalyzer::FileFormat::Rails)
71
+ end
72
+
73
+ 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)
76
+ end
77
+
78
+ end
@@ -0,0 +1,26 @@
1
+ class SpecFormat < RequestLogAnalyzer::FileFormat
2
+
3
+ format_definition.first do |line|
4
+ line.header = true
5
+ line.teaser = /processing /
6
+ line.regexp = /processing request (\d+)/
7
+ line.captures = [{ :name => :request_no, :type => :integer, :anonymize => :slightly }]
8
+ end
9
+
10
+ format_definition.test do |line|
11
+ line.teaser = /testing /
12
+ line.regexp = /testing is (\w+)/
13
+ line.captures = [{ :name => :test_capture, :type => :string, :anonymize => true}]
14
+ end
15
+
16
+ format_definition.last do |line|
17
+ line.footer = true
18
+ line.teaser = /finishing /
19
+ line.regexp = /finishing request (\d+)/
20
+ line.captures = [{ :name => :request_no, :type => :integer}]
21
+ end
22
+
23
+ report do |analyze|
24
+ analyze.category :test_capture, :title => 'What is testing exactly?'
25
+ end
26
+ end
@@ -0,0 +1,137 @@
1
+ require File.dirname(__FILE__) + '/spec_helper'
2
+ require File.dirname(__FILE__) + '/../lib/request_log_analyzer/filter/timespan'
3
+ require File.dirname(__FILE__) + '/../lib/request_log_analyzer/filter/field'
4
+
5
+ describe RequestLogAnalyzer::Filter::Timespan, 'both before and after' do
6
+ include RequestLogAnalyzerSpecHelper
7
+
8
+ before(:each) do
9
+ @filter = RequestLogAnalyzer::Filter::Timespan.new(spec_format, :after => DateTime.parse('2009-01-01'), :before => DateTime.parse('2009-02-02'))
10
+ @filter.prepare
11
+ end
12
+
13
+ it "should reject a request before the after date" do
14
+ @filter.filter(request(:timestamp => 20081212000000)).should be_nil
15
+ end
16
+
17
+ it "should reject a request after the before date" do
18
+ @filter.filter(request(:timestamp => 20090303000000)).should be_nil
19
+ end
20
+
21
+ it "should accept a request between the after and before dates" do
22
+ @filter.filter(request(:timestamp => 20090102000000)).should_not be_nil
23
+ end
24
+ end
25
+
26
+ describe RequestLogAnalyzer::Filter::Timespan, 'only before' do
27
+ include RequestLogAnalyzerSpecHelper
28
+
29
+ before(:each) do
30
+ @filter = RequestLogAnalyzer::Filter::Timespan.new(spec_format, :before => DateTime.parse('2009-02-02'))
31
+ @filter.prepare
32
+ end
33
+
34
+ it "should accept a request before the after date" do
35
+ @filter.filter(request(:timestamp => 20081212000000)).should_not be_nil
36
+ end
37
+
38
+ it "should reject a request after the before date" do
39
+ @filter.filter(request(:timestamp => 20090303000000)).should be_nil
40
+ end
41
+
42
+ it "should accept a request between the after and before dates" do
43
+ @filter.filter(request(:timestamp => 20090102000000)).should_not be_nil
44
+ end
45
+ end
46
+
47
+ describe RequestLogAnalyzer::Filter::Timespan, 'only after' do
48
+ include RequestLogAnalyzerSpecHelper
49
+
50
+ before(:each) do
51
+ @filter = RequestLogAnalyzer::Filter::Timespan.new(spec_format, :after => DateTime.parse('2009-01-01'))
52
+ @filter.prepare
53
+ end
54
+
55
+ it "should reject a request before the after date" do
56
+ @filter.filter(request(:timestamp => 20081212000000)).should be_nil
57
+ end
58
+
59
+ it "should accept a request after the before date" do
60
+ @filter.filter(request(:timestamp => 20090303000000)).should_not be_nil
61
+ end
62
+
63
+ it "should accept a request between the after and before dates" do
64
+ @filter.filter(request(:timestamp => 20090102000000)).should_not be_nil
65
+ end
66
+ end
67
+
68
+ describe RequestLogAnalyzer::Filter::Field, 'string in accept mode' do
69
+ include RequestLogAnalyzerSpecHelper
70
+
71
+ before(:each) do
72
+ @filter = RequestLogAnalyzer::Filter::Field.new(spec_format, :field => :test, :value => 'test', :mode => :select)
73
+ @filter.prepare
74
+ end
75
+
76
+ it "should reject a request if the field value does not match" do
77
+ @filter.filter(request(:test => 'not test')).should be_nil
78
+ end
79
+
80
+ it "should reject a request if the field name does not match" do
81
+ @filter.filter(request(:testing => 'test')).should be_nil
82
+ end
83
+
84
+ it "should accept a request if the both name and value match" do
85
+ @filter.filter(request(:test => 'test')).should_not be_nil
86
+ end
87
+
88
+ it "should accept a request if the value is not the first value" do
89
+ @filter.filter(request([{:test => 'ignore'}, {:test => 'test'}])).should_not be_nil
90
+ end
91
+ end
92
+
93
+ describe RequestLogAnalyzer::Filter::Field, 'string in reject mode' do
94
+ include RequestLogAnalyzerSpecHelper
95
+
96
+ before(:each) do
97
+ @filter = RequestLogAnalyzer::Filter::Field.new(spec_format, :field => :test, :value => 'test', :mode => :reject)
98
+ @filter.prepare
99
+ end
100
+
101
+ it "should accept a request if the field value does not match" do
102
+ @filter.filter(request(:test => 'not test')).should_not be_nil
103
+ end
104
+
105
+ it "should accept a request if the field name does not match" do
106
+ @filter.filter(request(:testing => 'test')).should_not be_nil
107
+ end
108
+
109
+ it "should reject a request if the both name and value match" do
110
+ @filter.filter(request(:test => 'test')).should be_nil
111
+ end
112
+
113
+ it "should reject a request if the value is not the first value" do
114
+ @filter.filter(request([{:test => 'ignore'}, {:test => 'test'}])).should be_nil
115
+ end
116
+ end
117
+
118
+ describe RequestLogAnalyzer::Filter::Field, 'regexp in accept mode' do
119
+ include RequestLogAnalyzerSpecHelper
120
+
121
+ before(:each) do
122
+ @filter = RequestLogAnalyzer::Filter::Field.new(spec_format, :field => :test, :value => '/test/', :mode => :select)
123
+ @filter.prepare
124
+ end
125
+
126
+ it "should reject a request if the field value does not match" do
127
+ @filter.filter(request(:test => 'a working test')).should_not be_nil
128
+ end
129
+
130
+ it "should reject a request if the field name does not match" do
131
+ @filter.filter(request(:testing => 'test')).should be_nil
132
+ end
133
+
134
+ it "should accept a request if the value is not the first value" do
135
+ @filter.filter(request([{:test => 'ignore'}, {:test => 'testing 123'}])).should_not be_nil
136
+ end
137
+ end