request-log-analyzer 1.3.4 → 1.4.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.
- data/LICENSE +3 -3
- data/README.rdoc +1 -1
- data/bin/request-log-analyzer +17 -14
- data/lib/cli/command_line_arguments.rb +51 -51
- data/lib/cli/database_console.rb +3 -3
- data/lib/cli/database_console_init.rb +4 -3
- data/lib/cli/progressbar.rb +10 -10
- data/lib/cli/tools.rb +3 -3
- data/lib/request_log_analyzer/aggregator/database_inserter.rb +19 -17
- data/lib/request_log_analyzer/aggregator/echo.rb +14 -9
- data/lib/request_log_analyzer/aggregator/summarizer.rb +26 -26
- data/lib/request_log_analyzer/aggregator.rb +11 -15
- data/lib/request_log_analyzer/controller.rb +162 -89
- data/lib/request_log_analyzer/database/base.rb +22 -21
- data/lib/request_log_analyzer/database/connection.rb +3 -3
- data/lib/request_log_analyzer/database/request.rb +22 -0
- data/lib/request_log_analyzer/database/source.rb +13 -0
- data/lib/request_log_analyzer/database/warning.rb +14 -0
- data/lib/request_log_analyzer/database.rb +28 -103
- data/lib/request_log_analyzer/file_format/amazon_s3.rb +20 -20
- data/lib/request_log_analyzer/file_format/apache.rb +37 -30
- data/lib/request_log_analyzer/file_format/merb.rb +30 -13
- data/lib/request_log_analyzer/file_format/rack.rb +11 -0
- data/lib/request_log_analyzer/file_format/rails.rb +143 -73
- data/lib/request_log_analyzer/file_format/rails_development.rb +4 -49
- data/lib/request_log_analyzer/file_format.rb +16 -28
- data/lib/request_log_analyzer/filter/anonymize.rb +8 -7
- data/lib/request_log_analyzer/filter/field.rb +9 -9
- data/lib/request_log_analyzer/filter/timespan.rb +12 -10
- data/lib/request_log_analyzer/filter.rb +12 -16
- data/lib/request_log_analyzer/line_definition.rb +15 -14
- data/lib/request_log_analyzer/log_processor.rb +27 -29
- data/lib/request_log_analyzer/mailer.rb +15 -9
- data/lib/request_log_analyzer/output/fixed_width.rb +48 -48
- data/lib/request_log_analyzer/output/html.rb +20 -20
- data/lib/request_log_analyzer/output.rb +53 -12
- data/lib/request_log_analyzer/request.rb +88 -69
- data/lib/request_log_analyzer/source/database_loader.rb +10 -14
- data/lib/request_log_analyzer/source/log_parser.rb +57 -50
- data/lib/request_log_analyzer/source.rb +10 -12
- data/lib/request_log_analyzer/tracker/duration.rb +41 -134
- data/lib/request_log_analyzer/tracker/frequency.rb +31 -32
- data/lib/request_log_analyzer/tracker/hourly_spread.rb +21 -21
- data/lib/request_log_analyzer/tracker/timespan.rb +17 -17
- data/lib/request_log_analyzer/tracker/traffic.rb +106 -0
- data/lib/request_log_analyzer/tracker.rb +139 -32
- data/lib/request_log_analyzer.rb +5 -5
- data/request-log-analyzer.gemspec +19 -15
- data/spec/database.yml +6 -0
- data/spec/fixtures/rails_22.log +1 -1
- data/spec/integration/command_line_usage_spec.rb +7 -1
- data/spec/lib/helpers.rb +7 -7
- data/spec/lib/macros.rb +3 -3
- data/spec/lib/matchers.rb +41 -27
- data/spec/lib/mocks.rb +19 -15
- data/spec/lib/testing_format.rb +9 -9
- data/spec/spec_helper.rb +6 -6
- data/spec/unit/aggregator/database_inserter_spec.rb +16 -16
- data/spec/unit/aggregator/summarizer_spec.rb +4 -4
- data/spec/unit/controller/controller_spec.rb +2 -2
- data/spec/unit/controller/log_processor_spec.rb +1 -1
- data/spec/unit/database/base_class_spec.rb +26 -33
- data/spec/unit/database/connection_spec.rb +3 -3
- data/spec/unit/database/database_spec.rb +33 -38
- data/spec/unit/file_format/amazon_s3_format_spec.rb +5 -5
- data/spec/unit/file_format/apache_format_spec.rb +48 -11
- data/spec/unit/file_format/file_format_api_spec.rb +13 -13
- data/spec/unit/file_format/line_definition_spec.rb +24 -17
- data/spec/unit/file_format/merb_format_spec.rb +41 -45
- data/spec/unit/file_format/rails_format_spec.rb +157 -117
- data/spec/unit/filter/anonymize_filter_spec.rb +2 -2
- data/spec/unit/filter/field_filter_spec.rb +13 -13
- data/spec/unit/filter/filter_spec.rb +1 -1
- data/spec/unit/filter/timespan_filter_spec.rb +15 -15
- data/spec/unit/mailer_spec.rb +30 -0
- data/spec/unit/{source/request_spec.rb → request_spec.rb} +30 -30
- data/spec/unit/source/log_parser_spec.rb +27 -27
- data/spec/unit/tracker/duration_tracker_spec.rb +115 -78
- data/spec/unit/tracker/frequency_tracker_spec.rb +74 -63
- data/spec/unit/tracker/hourly_spread_spec.rb +28 -20
- data/spec/unit/tracker/timespan_tracker_spec.rb +25 -13
- data/spec/unit/tracker/tracker_api_spec.rb +117 -42
- data/spec/unit/tracker/traffic_tracker_spec.rb +107 -0
- data/tasks/github-gem.rake +125 -75
- data/tasks/request_log_analyzer.rake +2 -2
- metadata +19 -10
|
@@ -15,6 +15,12 @@ describe RequestLogAnalyzer, 'running from command line' do
|
|
|
15
15
|
output.any? { |line| /^Parsed requests\:\s*4\s/ =~ line }.should be_true
|
|
16
16
|
end
|
|
17
17
|
|
|
18
|
+
it "should find 2 requests when parsing a compressed file" do
|
|
19
|
+
output = run("#{log_fixture(:decompression, :tgz)}")
|
|
20
|
+
output.any? { |line| /^Parsed requests\:\s*2\s/ =~ line }.should be_true
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
|
|
18
24
|
it "should skip 1 requests with a --select option" do
|
|
19
25
|
output = run("#{log_fixture(:rails_1x)} --select controller PeopleController")
|
|
20
26
|
output.any? { |line| /^Skipped requests\:\s*1\s/ =~ line }.should be_true
|
|
@@ -70,7 +76,7 @@ describe RequestLogAnalyzer, 'running from command line' do
|
|
|
70
76
|
File.exist?(temp_output_file(:dump)).should be_true
|
|
71
77
|
YAML::load(File.read(temp_output_file(:dump))).should have_at_least(1).item
|
|
72
78
|
end
|
|
73
|
-
|
|
79
|
+
|
|
74
80
|
it "should parse 4 requests from the standard input" do
|
|
75
81
|
output = run("- < #{log_fixture(:rails_1x)}")
|
|
76
82
|
output.any? { |line| /^Parsed requests\:\s*4\s/ =~ line }.should be_true
|
data/spec/lib/helpers.rb
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
module RequestLogAnalyzer::Spec::Helpers
|
|
2
|
-
|
|
2
|
+
|
|
3
3
|
# Create or return a new TestingFormat
|
|
4
4
|
def testing_format
|
|
5
5
|
@testing_format ||= TestingFormat.create
|
|
6
6
|
end
|
|
7
|
-
|
|
7
|
+
|
|
8
8
|
# Load a log file from the fixture folder
|
|
9
9
|
def log_fixture(name, extention = "log")
|
|
10
10
|
File.dirname(__FILE__) + "/../fixtures/#{name}.#{extention}"
|
|
@@ -15,7 +15,7 @@ module RequestLogAnalyzer::Spec::Helpers
|
|
|
15
15
|
if fields.kind_of?(Array)
|
|
16
16
|
format.request(*fields)
|
|
17
17
|
else
|
|
18
|
-
format.request(fields)
|
|
18
|
+
format.request(fields)
|
|
19
19
|
end
|
|
20
20
|
end
|
|
21
21
|
|
|
@@ -24,7 +24,7 @@ module RequestLogAnalyzer::Spec::Helpers
|
|
|
24
24
|
def run(arguments)
|
|
25
25
|
binary = "#{File.dirname(__FILE__)}/../../bin/request-log-analyzer"
|
|
26
26
|
arguments = arguments.join(' ') if arguments.kind_of?(Array)
|
|
27
|
-
|
|
27
|
+
|
|
28
28
|
output = []
|
|
29
29
|
IO.popen("#{binary} #{arguments}") do |pipe|
|
|
30
30
|
output = pipe.readlines
|
|
@@ -32,16 +32,16 @@ module RequestLogAnalyzer::Spec::Helpers
|
|
|
32
32
|
$?.exitstatus.should == 0
|
|
33
33
|
output
|
|
34
34
|
end
|
|
35
|
-
|
|
35
|
+
|
|
36
36
|
# Cleanup all temporary files generated by specs
|
|
37
37
|
def cleanup_temp_files!
|
|
38
38
|
Dir["#{File.dirname(__FILE__)}/../../tmp/spec.*tmp"].each do |file|
|
|
39
39
|
File.unlink(file)
|
|
40
40
|
end
|
|
41
41
|
end
|
|
42
|
-
|
|
42
|
+
|
|
43
43
|
# Return a filename that can be used as temporary file in specs
|
|
44
44
|
def temp_output_file(file_type)
|
|
45
|
-
"#{File.dirname(__FILE__)}/../../tmp/spec.#{file_type}.tmp"
|
|
45
|
+
"#{File.dirname(__FILE__)}/../../tmp/spec.#{file_type}.tmp"
|
|
46
46
|
end
|
|
47
47
|
end
|
data/spec/lib/macros.rb
CHANGED
|
@@ -1,16 +1,16 @@
|
|
|
1
1
|
module RequestLogAnalyzer::Spec::Macros
|
|
2
|
-
|
|
2
|
+
|
|
3
3
|
def test_databases
|
|
4
4
|
require 'yaml'
|
|
5
5
|
hash = YAML.load(File.read("#{File.dirname(__FILE__)}/../database.yml"))
|
|
6
6
|
hash.inject({}) { |res, (name, h)| res[name] = h.map { |(k,v)| "#{k}=#{v}" }.join(';'); res }
|
|
7
7
|
end
|
|
8
|
-
|
|
8
|
+
|
|
9
9
|
# Create or return a new TestingFormat
|
|
10
10
|
def testing_format
|
|
11
11
|
@testing_format ||= TestingFormat.create
|
|
12
12
|
end
|
|
13
|
-
|
|
13
|
+
|
|
14
14
|
def default_orm_class_names
|
|
15
15
|
['Warning', 'Request', 'Source']
|
|
16
16
|
end
|
data/spec/lib/matchers.rb
CHANGED
|
@@ -1,17 +1,17 @@
|
|
|
1
1
|
module RequestLogAnalyzer::Spec::Matchers
|
|
2
|
-
|
|
2
|
+
|
|
3
3
|
class HasLineDefinition
|
|
4
|
-
|
|
4
|
+
|
|
5
5
|
def initialize(line_type)
|
|
6
6
|
@line_type = line_type.to_sym
|
|
7
7
|
@captures = []
|
|
8
8
|
end
|
|
9
|
-
|
|
9
|
+
|
|
10
10
|
def capturing(*captures)
|
|
11
11
|
@captures += captures
|
|
12
12
|
return self
|
|
13
13
|
end
|
|
14
|
-
|
|
14
|
+
|
|
15
15
|
def matches?(file_format)
|
|
16
16
|
file_format = file_format.create if file_format.kind_of?(Class)
|
|
17
17
|
if ld = file_format.line_definitions[@line_type]
|
|
@@ -21,43 +21,57 @@ module RequestLogAnalyzer::Spec::Matchers
|
|
|
21
21
|
end
|
|
22
22
|
end
|
|
23
23
|
end
|
|
24
|
-
|
|
25
|
-
class
|
|
24
|
+
|
|
25
|
+
class ParseLine
|
|
26
|
+
|
|
26
27
|
def initialize(line)
|
|
27
|
-
@line
|
|
28
|
-
@captures
|
|
28
|
+
@line = line
|
|
29
|
+
@captures = {}
|
|
30
|
+
@line_type = nil
|
|
29
31
|
end
|
|
30
|
-
|
|
32
|
+
|
|
31
33
|
def failure_message
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
34
|
+
@failure_message
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
def as(line_type)
|
|
38
|
+
@line_type = line_type
|
|
39
|
+
return self
|
|
37
40
|
end
|
|
38
41
|
|
|
39
|
-
def
|
|
42
|
+
def and_capture(captures)
|
|
40
43
|
@captures = captures
|
|
41
44
|
return self
|
|
42
45
|
end
|
|
43
|
-
|
|
44
|
-
def
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
46
|
+
|
|
47
|
+
def fail(message)
|
|
48
|
+
@failure_message = message
|
|
49
|
+
return false
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
def matches?(file_format)
|
|
53
|
+
if @line_hash = file_format.parse_line(@line)
|
|
54
|
+
if @line_type.nil? || @line_hash[:line_definition].name == @line_type
|
|
55
|
+
@request = file_format.request(@line_hash)
|
|
56
|
+
@captures.each do |key, value|
|
|
57
|
+
return fail("Expected line #{@line.inspect}\n to capture #{key.inspect} as #{value.inspect} but was #{@request[key].inspect}.") if @request[key] != value
|
|
58
|
+
end
|
|
59
|
+
return true
|
|
60
|
+
else
|
|
61
|
+
return fail("The line should match the #{@line_type.inspect} line definition, but matched #{@line_hash[:line_definition].name.inspect} instead.")
|
|
62
|
+
end
|
|
49
63
|
else
|
|
50
|
-
return
|
|
64
|
+
return fail("The line did not match any line definition.")
|
|
51
65
|
end
|
|
52
66
|
end
|
|
53
67
|
end
|
|
54
|
-
|
|
68
|
+
|
|
55
69
|
def have_line_definition(line_type)
|
|
56
70
|
return HasLineDefinition.new(line_type)
|
|
57
71
|
end
|
|
58
|
-
|
|
59
|
-
def
|
|
60
|
-
|
|
72
|
+
|
|
73
|
+
def parse_line(line)
|
|
74
|
+
ParseLine.new(line)
|
|
61
75
|
end
|
|
62
|
-
|
|
76
|
+
|
|
63
77
|
end
|
data/spec/lib/mocks.rb
CHANGED
|
@@ -1,49 +1,53 @@
|
|
|
1
1
|
module RequestLogAnalyzer::Spec::Mocks
|
|
2
|
-
|
|
2
|
+
|
|
3
3
|
def mock_source
|
|
4
4
|
source = mock('RequestLogAnalyzer::Source::Base')
|
|
5
5
|
source.stub!(:file_format).and_return(testing_format)
|
|
6
6
|
source.stub!(:parsed_requests).and_return(2)
|
|
7
|
-
source.stub!(:skipped_requests).and_return(1)
|
|
7
|
+
source.stub!(:skipped_requests).and_return(1)
|
|
8
8
|
source.stub!(:parse_lines).and_return(10)
|
|
9
|
-
|
|
9
|
+
|
|
10
10
|
source.stub!(:warning=)
|
|
11
11
|
source.stub!(:progress=)
|
|
12
12
|
source.stub!(:source_changes=)
|
|
13
13
|
|
|
14
14
|
source.stub!(:prepare)
|
|
15
15
|
source.stub!(:finalize)
|
|
16
|
-
|
|
16
|
+
|
|
17
17
|
source.stub!(:each_request).and_return do |block|
|
|
18
18
|
block.call(testing_format.request(:field => 'value1'))
|
|
19
19
|
block.call(testing_format.request(:field => 'value2'))
|
|
20
20
|
end
|
|
21
|
-
|
|
21
|
+
|
|
22
22
|
return source
|
|
23
23
|
end
|
|
24
24
|
|
|
25
25
|
def mock_io
|
|
26
26
|
mio = mock('IO')
|
|
27
27
|
mio.stub!(:print)
|
|
28
|
-
mio.stub!(:puts)
|
|
28
|
+
mio.stub!(:puts)
|
|
29
29
|
mio.stub!(:write)
|
|
30
30
|
return mio
|
|
31
31
|
end
|
|
32
|
-
|
|
32
|
+
|
|
33
33
|
def mock_output
|
|
34
34
|
output = mock('RequestLogAnalyzer::Output::Base')
|
|
35
35
|
output.stub!(:header)
|
|
36
|
-
output.stub!(:footer)
|
|
36
|
+
output.stub!(:footer)
|
|
37
37
|
output.stub!(:puts)
|
|
38
|
-
output.stub!(:<<)
|
|
38
|
+
output.stub!(:<<)
|
|
39
|
+
output.stub!(:colorize).and_return("Fancy text")
|
|
40
|
+
output.stub!(:link)
|
|
39
41
|
output.stub!(:title)
|
|
40
42
|
output.stub!(:line)
|
|
41
|
-
output.stub!(:with_style)
|
|
43
|
+
output.stub!(:with_style)
|
|
42
44
|
output.stub!(:table).and_yield([])
|
|
43
45
|
output.stub!(:io).and_return(mock_io)
|
|
46
|
+
output.stub!(:options).and_return({})
|
|
47
|
+
output.stub!(:slice_results).and_return { |a| a }
|
|
44
48
|
return output
|
|
45
49
|
end
|
|
46
|
-
|
|
50
|
+
|
|
47
51
|
def mock_database(*stubs)
|
|
48
52
|
database = mock('RequestLogAnalyzer::Database')
|
|
49
53
|
database.stub!(:connect)
|
|
@@ -52,11 +56,11 @@ module RequestLogAnalyzer::Spec::Mocks
|
|
|
52
56
|
stubs.each { |s| database.stub!(s)}
|
|
53
57
|
return database
|
|
54
58
|
end
|
|
55
|
-
|
|
59
|
+
|
|
56
60
|
def mock_connection
|
|
57
61
|
table_creator = mock('ActiveRecord table creator')
|
|
58
62
|
table_creator.stub!(:column)
|
|
59
|
-
|
|
63
|
+
|
|
60
64
|
connection = mock('ActiveRecord::Base.connection')
|
|
61
65
|
connection.stub!(:add_index)
|
|
62
66
|
connection.stub!(:remove_index)
|
|
@@ -65,6 +69,6 @@ module RequestLogAnalyzer::Spec::Mocks
|
|
|
65
69
|
connection.stub!(:table_creator).and_return(table_creator)
|
|
66
70
|
return connection
|
|
67
71
|
end
|
|
68
|
-
|
|
69
|
-
|
|
72
|
+
|
|
73
|
+
|
|
70
74
|
end
|
data/spec/lib/testing_format.rb
CHANGED
|
@@ -5,42 +5,42 @@ class TestingFormat < RequestLogAnalyzer::FileFormat::Base
|
|
|
5
5
|
line.header = true
|
|
6
6
|
line.teaser = /processing /
|
|
7
7
|
line.regexp = /processing request (\d+)/
|
|
8
|
-
line.captures = [{ :name => :request_no, :type => :integer }]
|
|
8
|
+
line.captures = [{ :name => :request_no, :type => :integer }]
|
|
9
9
|
end
|
|
10
|
-
|
|
10
|
+
|
|
11
11
|
format_definition.test do |line|
|
|
12
12
|
line.teaser = /testing /
|
|
13
13
|
line.regexp = /testing is (\w+)(?: in (\d+\.\d+)ms)?/
|
|
14
14
|
line.captures = [{ :name => :test_capture, :type => :test_type },
|
|
15
15
|
{ :name => :duration, :type => :duration, :unit => :msec }]
|
|
16
16
|
end
|
|
17
|
-
|
|
17
|
+
|
|
18
18
|
format_definition.eval do |line|
|
|
19
19
|
line.regexp = /evaluation (\{.*\})/
|
|
20
20
|
line.captures = [{ :name => :evaluated, :type => :eval, :provides => { :greating => :string, :what => :string } }]
|
|
21
|
-
end
|
|
22
|
-
|
|
21
|
+
end
|
|
22
|
+
|
|
23
23
|
format_definition.last do |line|
|
|
24
24
|
line.footer = true
|
|
25
25
|
line.teaser = /finishing /
|
|
26
26
|
line.regexp = /finishing request (\d+)/
|
|
27
27
|
line.captures = [{ :name => :request_no, :type => :integer }]
|
|
28
28
|
end
|
|
29
|
-
|
|
29
|
+
|
|
30
30
|
format_definition.combined do |line|
|
|
31
31
|
line.header = true
|
|
32
32
|
line.footer = true
|
|
33
33
|
line.regexp = /this is a header and footer line/
|
|
34
34
|
end
|
|
35
|
-
|
|
35
|
+
|
|
36
36
|
report do |analyze|
|
|
37
37
|
analyze.frequency :test_capture, :title => 'What is testing exactly?'
|
|
38
38
|
end
|
|
39
|
-
|
|
39
|
+
|
|
40
40
|
class Request < RequestLogAnalyzer::Request
|
|
41
41
|
def convert_test_type(value, definition)
|
|
42
42
|
"Testing is #{value}"
|
|
43
43
|
end
|
|
44
44
|
end
|
|
45
|
-
|
|
45
|
+
|
|
46
46
|
end
|
data/spec/spec_helper.rb
CHANGED
|
@@ -9,16 +9,16 @@ module RequestLogAnalyzer::Spec
|
|
|
9
9
|
end
|
|
10
10
|
|
|
11
11
|
# Include all files in the spec_helper directory
|
|
12
|
-
Dir[File.dirname(__FILE__) + "/lib/**/*.rb"].each do |file|
|
|
13
|
-
require file
|
|
12
|
+
Dir[File.dirname(__FILE__) + "/lib/**/*.rb"].each do |file|
|
|
13
|
+
require file
|
|
14
14
|
end
|
|
15
15
|
|
|
16
16
|
Dir.mkdir("#{File.dirname(__FILE__)}/../tmp") unless File.exist?("#{File.dirname(__FILE__)}/../tmp")
|
|
17
17
|
|
|
18
18
|
Spec::Runner.configure do |config|
|
|
19
|
-
config.include RequestLogAnalyzer::Spec::Matchers
|
|
19
|
+
config.include RequestLogAnalyzer::Spec::Matchers
|
|
20
20
|
config.include RequestLogAnalyzer::Spec::Mocks
|
|
21
|
-
config.include RequestLogAnalyzer::Spec::Helpers
|
|
22
|
-
|
|
23
|
-
config.extend RequestLogAnalyzer::Spec::Macros
|
|
21
|
+
config.include RequestLogAnalyzer::Spec::Helpers
|
|
22
|
+
|
|
23
|
+
config.extend RequestLogAnalyzer::Spec::Macros
|
|
24
24
|
end
|
|
@@ -5,27 +5,27 @@ describe RequestLogAnalyzer::Aggregator::DatabaseInserter do
|
|
|
5
5
|
before(:all) do
|
|
6
6
|
@log_parser = RequestLogAnalyzer::Source::LogParser.new(testing_format)
|
|
7
7
|
end
|
|
8
|
-
|
|
8
|
+
|
|
9
9
|
# The prepare method is called before the parsing starts. It should establish a connection
|
|
10
10
|
# to a database that is suitable for inserting requests later on.
|
|
11
11
|
describe '#prepare' do
|
|
12
|
-
|
|
12
|
+
|
|
13
13
|
before(:each) do
|
|
14
14
|
@database = mock_database(:create_database_schema!, :drop_database_schema!, :file_format=)
|
|
15
15
|
@database_inserter = RequestLogAnalyzer::Aggregator::DatabaseInserter.new(@log_parser)
|
|
16
16
|
RequestLogAnalyzer::Database.stub!(:new).and_return(@database)
|
|
17
17
|
end
|
|
18
|
-
|
|
18
|
+
|
|
19
19
|
it 'should establish the database connection' do
|
|
20
20
|
RequestLogAnalyzer::Database.should_receive(:new).and_return(@database)
|
|
21
21
|
@database_inserter.prepare
|
|
22
22
|
end
|
|
23
|
-
|
|
23
|
+
|
|
24
24
|
it "should set the file_format" do
|
|
25
25
|
@database.should_receive(:file_format=).with(testing_format)
|
|
26
26
|
@database_inserter.prepare
|
|
27
27
|
end
|
|
28
|
-
|
|
28
|
+
|
|
29
29
|
it 'should create the database schema during preparation' do
|
|
30
30
|
@database.should_receive(:create_database_schema!)
|
|
31
31
|
@database_inserter.prepare
|
|
@@ -52,32 +52,32 @@ describe RequestLogAnalyzer::Aggregator::DatabaseInserter do
|
|
|
52
52
|
@database_inserter.prepare
|
|
53
53
|
|
|
54
54
|
@incomplete_request = testing_format.request( {:line_type => :first, :request_no => 564})
|
|
55
|
-
@completed_request = testing_format.request( {:line_type => :first, :request_no => 564},
|
|
55
|
+
@completed_request = testing_format.request( {:line_type => :first, :request_no => 564},
|
|
56
56
|
{:line_type => :test, :test_capture => "awesome"},
|
|
57
|
-
{:line_type => :test, :test_capture => "indeed"},
|
|
58
|
-
{:line_type => :eval, :evaluated => { :greating => 'howdy'}, :greating => 'howdy' },
|
|
57
|
+
{:line_type => :test, :test_capture => "indeed"},
|
|
58
|
+
{:line_type => :eval, :evaluated => { :greating => 'howdy'}, :greating => 'howdy' },
|
|
59
59
|
{:line_type => :last, :request_no => 564})
|
|
60
60
|
end
|
|
61
|
-
|
|
61
|
+
|
|
62
62
|
after(:each) do
|
|
63
63
|
@database_inserter.database.send :remove_orm_classes!
|
|
64
64
|
end
|
|
65
65
|
|
|
66
66
|
it "should insert a record in the request table" do
|
|
67
|
-
lambda {
|
|
67
|
+
lambda {
|
|
68
68
|
@database_inserter.aggregate(@incomplete_request)
|
|
69
|
-
}.should change(
|
|
69
|
+
}.should change(RequestLogAnalyzer::Database::Request, :count).from(0).to(1)
|
|
70
70
|
end
|
|
71
|
-
|
|
71
|
+
|
|
72
72
|
it "should insert a record in the first_lines table" do
|
|
73
|
-
lambda {
|
|
73
|
+
lambda {
|
|
74
74
|
@database_inserter.aggregate(@incomplete_request)
|
|
75
75
|
}.should change(@database_inserter.database.get_class(:first), :count).from(0).to(1)
|
|
76
|
-
end
|
|
76
|
+
end
|
|
77
77
|
|
|
78
78
|
it "should insert records in all relevant line tables" do
|
|
79
79
|
@database_inserter.aggregate(@completed_request)
|
|
80
|
-
request =
|
|
80
|
+
request = RequestLogAnalyzer::Database::Request.first
|
|
81
81
|
request.should have(2).test_lines
|
|
82
82
|
request.should have(1).first_lines
|
|
83
83
|
request.should have(1).eval_lines
|
|
@@ -85,7 +85,7 @@ describe RequestLogAnalyzer::Aggregator::DatabaseInserter do
|
|
|
85
85
|
end
|
|
86
86
|
|
|
87
87
|
it "should log a warning in the warnings table" do
|
|
88
|
-
|
|
88
|
+
RequestLogAnalyzer::Database::Warning.should_receive(:create!).with(hash_including(:warning_type => 'test_warning'))
|
|
89
89
|
@database_inserter.warning(:test_warning, "Testing the warning system", 12)
|
|
90
90
|
end
|
|
91
91
|
end
|
|
@@ -6,11 +6,11 @@ describe RequestLogAnalyzer::Aggregator::Summarizer do
|
|
|
6
6
|
@summarizer = RequestLogAnalyzer::Aggregator::Summarizer.new(mock_source, :output => mock_output)
|
|
7
7
|
@summarizer.prepare
|
|
8
8
|
end
|
|
9
|
-
|
|
9
|
+
|
|
10
10
|
it "not raise exception when creating a report after aggregating multiple requests" do
|
|
11
11
|
@summarizer.aggregate(request(:data => 'bluh1'))
|
|
12
|
-
@summarizer.aggregate(request(:data => 'bluh2'))
|
|
13
|
-
|
|
12
|
+
@summarizer.aggregate(request(:data => 'bluh2'))
|
|
13
|
+
|
|
14
14
|
lambda { @summarizer.report(mock_output) }.should_not raise_error
|
|
15
15
|
end
|
|
16
16
|
|
|
@@ -22,5 +22,5 @@ describe RequestLogAnalyzer::Aggregator::Summarizer do
|
|
|
22
22
|
it "not raise exception when creating a report after aggregating no requests" do
|
|
23
23
|
lambda { @summarizer.report(mock_output) }.should_not raise_error
|
|
24
24
|
end
|
|
25
|
-
|
|
25
|
+
|
|
26
26
|
end
|
|
@@ -17,7 +17,7 @@ describe RequestLogAnalyzer::Controller do
|
|
|
17
17
|
it "should call aggregators correctly when run" do
|
|
18
18
|
controller = RequestLogAnalyzer::Controller.new(mock_source, :output => mock_output)
|
|
19
19
|
|
|
20
|
-
mock_aggregator = mock('RequestLogAnalyzer::Aggregator::Base')
|
|
20
|
+
mock_aggregator = mock('RequestLogAnalyzer::Aggregator::Base')
|
|
21
21
|
mock_aggregator.should_receive(:prepare).once.ordered
|
|
22
22
|
mock_aggregator.should_receive(:aggregate).with(an_instance_of(testing_format.request_class)).twice.ordered
|
|
23
23
|
mock_aggregator.should_receive(:finalize).once.ordered
|
|
@@ -38,4 +38,4 @@ describe RequestLogAnalyzer::Controller do
|
|
|
38
38
|
controller.run!
|
|
39
39
|
end
|
|
40
40
|
|
|
41
|
-
end
|
|
41
|
+
end
|
|
@@ -7,7 +7,7 @@ describe RequestLogAnalyzer::LogProcessor, 'stripping log files' do
|
|
|
7
7
|
before(:each) do
|
|
8
8
|
@log_stripper = RequestLogAnalyzer::LogProcessor.new(testing_format, :strip, {})
|
|
9
9
|
end
|
|
10
|
-
|
|
10
|
+
|
|
11
11
|
it "should remove a junk line" do
|
|
12
12
|
@log_stripper.strip_line("junk line\n").should be_empty
|
|
13
13
|
end
|
|
@@ -1,30 +1,27 @@
|
|
|
1
1
|
require File.dirname(__FILE__) + '/../../spec_helper'
|
|
2
2
|
|
|
3
3
|
describe RequestLogAnalyzer::Database::Base do
|
|
4
|
-
|
|
4
|
+
|
|
5
5
|
describe '.subclass_from_line_definition' do
|
|
6
6
|
before(:all) do
|
|
7
7
|
@line_definition = RequestLogAnalyzer::LineDefinition.new(:test, { :regexp => /Testing (\w+), tries\: (\d+)/,
|
|
8
8
|
:captures => [{ :name => :what, :type => :string }, { :name => :tries, :type => :integer },
|
|
9
9
|
{ :name => :evaluated, :type => :hash, :provides => {:evaluated_field => :duration} }]})
|
|
10
10
|
end
|
|
11
|
-
|
|
11
|
+
|
|
12
12
|
before(:each) do
|
|
13
13
|
@orm_class = mock('Line ActiveRecord::Base class')
|
|
14
14
|
@orm_class.stub!(:set_table_name)
|
|
15
15
|
@orm_class.stub!(:belongs_to)
|
|
16
16
|
@orm_class.stub!(:serialize)
|
|
17
17
|
@orm_class.stub!(:line_definition=)
|
|
18
|
+
|
|
18
19
|
Class.stub!(:new).with(RequestLogAnalyzer::Database::Base).and_return(@orm_class)
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
@source_class.stub!(:has_many)
|
|
24
|
-
|
|
20
|
+
|
|
21
|
+
RequestLogAnalyzer::Database::Request.stub!(:has_many)
|
|
22
|
+
RequestLogAnalyzer::Database::Source.stub!(:has_many)
|
|
23
|
+
|
|
25
24
|
@database = mock_database
|
|
26
|
-
@database.stub!(:request_class).and_return(@request_class)
|
|
27
|
-
@database.stub!(:source_class).and_return(@source_class)
|
|
28
25
|
RequestLogAnalyzer::Database::Base.stub!(:database).and_return(@database)
|
|
29
26
|
end
|
|
30
27
|
|
|
@@ -32,7 +29,7 @@ describe RequestLogAnalyzer::Database::Base do
|
|
|
32
29
|
Class.should_receive(:new).with(RequestLogAnalyzer::Database::Base).and_return(@orm_class)
|
|
33
30
|
RequestLogAnalyzer::Database::Base.subclass_from_line_definition(@line_definition)
|
|
34
31
|
end
|
|
35
|
-
|
|
32
|
+
|
|
36
33
|
it "should store the LineDefinition" do
|
|
37
34
|
@orm_class.should_receive(:line_definition=).with(@line_definition)
|
|
38
35
|
RequestLogAnalyzer::Database::Base.subclass_from_line_definition(@line_definition)
|
|
@@ -49,12 +46,12 @@ describe RequestLogAnalyzer::Database::Base do
|
|
|
49
46
|
end
|
|
50
47
|
|
|
51
48
|
it "should set a :has_many relationship in the request class" do
|
|
52
|
-
|
|
49
|
+
RequestLogAnalyzer::Database::Request.should_receive(:has_many).with(:test_lines)
|
|
53
50
|
RequestLogAnalyzer::Database::Base.subclass_from_line_definition(@line_definition)
|
|
54
51
|
end
|
|
55
52
|
|
|
56
53
|
it "should set a :has_many relationship in the source class" do
|
|
57
|
-
|
|
54
|
+
RequestLogAnalyzer::Database::Source.should_receive(:has_many).with(:test_lines)
|
|
58
55
|
RequestLogAnalyzer::Database::Base.subclass_from_line_definition(@line_definition)
|
|
59
56
|
end
|
|
60
57
|
|
|
@@ -72,30 +69,26 @@ describe RequestLogAnalyzer::Database::Base do
|
|
|
72
69
|
|
|
73
70
|
describe '.subclass_from_table' do
|
|
74
71
|
before(:each) do
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
@source_class.stub!(:has_many)
|
|
80
|
-
|
|
72
|
+
|
|
73
|
+
RequestLogAnalyzer::Database::Request.stub!(:has_many)
|
|
74
|
+
RequestLogAnalyzer::Database::Source.stub!(:has_many)
|
|
75
|
+
|
|
81
76
|
@database = mock_database
|
|
82
|
-
@database.stub!(:request_class).and_return(@request_class)
|
|
83
|
-
@database.stub!(:source_class).and_return(@source_class)
|
|
84
77
|
@database.connection.stub!(:table_exists?).and_return(true)
|
|
85
78
|
RequestLogAnalyzer::Database::Base.stub!(:database).and_return(@database)
|
|
86
|
-
|
|
79
|
+
|
|
87
80
|
@klass = mock('ActiveRecord ORM class')
|
|
88
|
-
@klass.stub!(:column_names).and_return(['id', 'request_id', 'source_id', 'lineno', 'duration'])
|
|
81
|
+
@klass.stub!(:column_names).and_return(['id', 'request_id', 'source_id', 'lineno', 'duration'])
|
|
89
82
|
@klass.stub!(:set_table_name)
|
|
90
83
|
@klass.stub!(:belongs_to)
|
|
91
84
|
Class.stub!(:new).with(RequestLogAnalyzer::Database::Base).and_return(@klass)
|
|
92
85
|
end
|
|
93
|
-
|
|
86
|
+
|
|
94
87
|
it "should create a new subclass using the Base class as parent" do
|
|
95
88
|
Class.should_receive(:new).with(RequestLogAnalyzer::Database::Base).and_return(@klass)
|
|
96
89
|
RequestLogAnalyzer::Database::Base.subclass_from_table('completed_lines')
|
|
97
|
-
end
|
|
98
|
-
|
|
90
|
+
end
|
|
91
|
+
|
|
99
92
|
it "should set the table name" do
|
|
100
93
|
@klass.should_receive(:set_table_name).with('completed_lines')
|
|
101
94
|
RequestLogAnalyzer::Database::Base.subclass_from_table('completed_lines')
|
|
@@ -105,9 +98,9 @@ describe RequestLogAnalyzer::Database::Base do
|
|
|
105
98
|
@klass.should_receive(:belongs_to).with(:request)
|
|
106
99
|
RequestLogAnalyzer::Database::Base.subclass_from_table('completed_lines')
|
|
107
100
|
end
|
|
108
|
-
|
|
101
|
+
|
|
109
102
|
it "should create the :has_many relation in the request class" do
|
|
110
|
-
|
|
103
|
+
RequestLogAnalyzer::Database::Request.should_receive(:has_many).with(:completed_lines)
|
|
111
104
|
RequestLogAnalyzer::Database::Base.subclass_from_table('completed_lines')
|
|
112
105
|
end
|
|
113
106
|
|
|
@@ -115,9 +108,9 @@ describe RequestLogAnalyzer::Database::Base do
|
|
|
115
108
|
@klass.should_receive(:belongs_to).with(:source)
|
|
116
109
|
RequestLogAnalyzer::Database::Base.subclass_from_table('completed_lines')
|
|
117
110
|
end
|
|
118
|
-
|
|
111
|
+
|
|
119
112
|
it "should create the :has_many relation in the request class" do
|
|
120
|
-
|
|
113
|
+
RequestLogAnalyzer::Database::Source.should_receive(:has_many).with(:completed_lines)
|
|
121
114
|
RequestLogAnalyzer::Database::Base.subclass_from_table('completed_lines')
|
|
122
115
|
end
|
|
123
116
|
|
|
@@ -138,7 +131,7 @@ describe RequestLogAnalyzer::Database::Base do
|
|
|
138
131
|
@klass.stub!(:table_exists?).and_return(false)
|
|
139
132
|
end
|
|
140
133
|
|
|
141
|
-
after(:each) do
|
|
134
|
+
after(:each) do
|
|
142
135
|
@klass.drop_table!
|
|
143
136
|
@database.remove_orm_classes!
|
|
144
137
|
end
|
|
@@ -177,12 +170,12 @@ describe RequestLogAnalyzer::Database::Base do
|
|
|
177
170
|
it "should create a field of the correct type for every defined capture field" do
|
|
178
171
|
@database.connection.table_creator.should_receive(:column).with(:what, :string)
|
|
179
172
|
@database.connection.table_creator.should_receive(:column).with(:tries, :integer)
|
|
180
|
-
@database.connection.table_creator.should_receive(:column).with(:evaluated, :text)
|
|
173
|
+
@database.connection.table_creator.should_receive(:column).with(:evaluated, :text)
|
|
181
174
|
@klass.create_table!
|
|
182
175
|
end
|
|
183
176
|
|
|
184
177
|
it "should create a field of the correct type for every provided field" do
|
|
185
|
-
@database.connection.table_creator.should_receive(:column).with(:evaluated_field, :double)
|
|
178
|
+
@database.connection.table_creator.should_receive(:column).with(:evaluated_field, :double)
|
|
186
179
|
@klass.create_table!
|
|
187
180
|
end
|
|
188
181
|
end
|
|
@@ -15,19 +15,19 @@ describe RequestLogAnalyzer::Database::Connection do
|
|
|
15
15
|
|
|
16
16
|
it "should parse an URI-based string for MySQL" do
|
|
17
17
|
string = 'mysql://localhost.local/database'
|
|
18
|
-
RequestLogAnalyzer::Database::Connection.from_string(string).should ==
|
|
18
|
+
RequestLogAnalyzer::Database::Connection.from_string(string).should ==
|
|
19
19
|
{ :adapter => 'mysql', :database => 'database', :host => 'localhost.local' }
|
|
20
20
|
end
|
|
21
21
|
|
|
22
22
|
it "should parse an URI-based string for MySQL with only username" do
|
|
23
23
|
string = 'mysql://username@localhost.local/database'
|
|
24
|
-
RequestLogAnalyzer::Database::Connection.from_string(string).should ==
|
|
24
|
+
RequestLogAnalyzer::Database::Connection.from_string(string).should ==
|
|
25
25
|
{ :adapter => 'mysql', :database => 'database', :host => 'localhost.local', :username => 'username' }
|
|
26
26
|
end
|
|
27
27
|
|
|
28
28
|
it "should parse an URI-based string for MySQL with username and password" do
|
|
29
29
|
string = 'mysql://username:password@localhost.local/database'
|
|
30
|
-
RequestLogAnalyzer::Database::Connection.from_string(string).should ==
|
|
30
|
+
RequestLogAnalyzer::Database::Connection.from_string(string).should ==
|
|
31
31
|
{ :adapter => 'mysql', :database => 'database', :host => 'localhost.local', :username => 'username', :password => 'password' }
|
|
32
32
|
end
|
|
33
33
|
end
|