apachecrunch 0.4 → 0.5
Sign up to get free protection for your applications and to get access to all the features.
- data/bin/apachecrunch +1 -1
- data/lib/apachecrunch.rb +5 -15
- data/lib/cast.rb +21 -0
- data/lib/derivation.rb +113 -0
- data/lib/element.rb +16 -0
- data/lib/element_value_fetcher.rb +72 -0
- data/lib/entry.rb +64 -54
- data/lib/format.rb +21 -63
- data/lib/format_token.rb +114 -0
- data/lib/format_token_definition.rb +183 -0
- data/lib/log_parser.rb +39 -31
- data/lib/procedure_dsl.rb +254 -244
- data/lib/progress.rb +1 -1
- data/test/mock.rb +37 -0
- data/test/runner.rb +13 -1
- data/test/stub.rb +66 -36
- data/test/test_derived_value_fetcher.rb +36 -0
- data/test/test_element.rb +18 -0
- data/test/test_element_value_fetcher.rb +45 -0
- data/test/test_entry_parser.rb +39 -0
- data/test/test_format.rb +13 -51
- data/test/test_format_parser.rb +22 -13
- data/test/test_log_parser.rb +88 -0
- data/test/test_raw_value_fetcher.rb +36 -0
- data/test/test_regex_token.rb +17 -0
- data/test/test_req_firstline_derivation_rule.rb +41 -0
- data/test/test_reqheader_token.rb +26 -0
- data/test/test_string_token.rb +27 -0
- data/test/test_time_derivation_rule.rb +29 -0
- metadata +23 -18
- data/lib/log_element.rb +0 -351
- data/test/test_entry.rb +0 -28
data/lib/progress.rb
CHANGED
data/test/mock.rb
ADDED
@@ -0,0 +1,37 @@
|
|
1
|
+
require 'test/stub'
|
2
|
+
|
3
|
+
class MockFile
|
4
|
+
attr_accessor :gets, :path, :close_count, :lines
|
5
|
+
def initialize
|
6
|
+
@close_count = 0
|
7
|
+
end
|
8
|
+
def close
|
9
|
+
@close_count += 1
|
10
|
+
end
|
11
|
+
def gets
|
12
|
+
@lines.shift
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
# Pretends to be Ruby's File class but just logs what it's asked to do
|
17
|
+
class MockFileClass
|
18
|
+
attr_accessor :rename_calls, :open_calls
|
19
|
+
def initialize
|
20
|
+
@rename_calls = []
|
21
|
+
@open_calls = []
|
22
|
+
end
|
23
|
+
def rename(*args); @rename_calls << args; end
|
24
|
+
def open(*args); @open_calls << args; end
|
25
|
+
end
|
26
|
+
|
27
|
+
# Pretends to be a FormatTokenFactory class but just logs what it's asked to do
|
28
|
+
class MockFormatTokenFactoryClass
|
29
|
+
attr_accessor :from_abbrev_calls
|
30
|
+
def initialize
|
31
|
+
@from_abbrev_calls = []
|
32
|
+
end
|
33
|
+
def from_abbrev(*args)
|
34
|
+
@from_abbrev_calls << args
|
35
|
+
StubAlphanumericFormatToken.new
|
36
|
+
end
|
37
|
+
end
|
data/test/runner.rb
CHANGED
@@ -5,6 +5,14 @@ $: << ".."
|
|
5
5
|
$: << "./lib"
|
6
6
|
require 'apachecrunch'
|
7
7
|
|
8
|
+
class ParticularTests
|
9
|
+
def self.run(tests)
|
10
|
+
tests.each do |test_file|
|
11
|
+
require test_file
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
8
16
|
class AllTests
|
9
17
|
def self.run
|
10
18
|
Dir.glob("test/test_*.rb").each do |test_file|
|
@@ -13,4 +21,8 @@ class AllTests
|
|
13
21
|
end
|
14
22
|
end
|
15
23
|
|
16
|
-
|
24
|
+
if ARGV.length > 0
|
25
|
+
ParticularTests.run(ARGV)
|
26
|
+
else
|
27
|
+
AllTests.run
|
28
|
+
end
|
data/test/stub.rb
CHANGED
@@ -1,56 +1,86 @@
|
|
1
|
-
class
|
2
|
-
|
3
|
-
|
4
|
-
|
1
|
+
class StubAlphanumericFormatToken < ApacheCrunch::FormatToken
|
2
|
+
def name; :alnum; end
|
3
|
+
def regex; %q![A-Za-z0-9]+!; end
|
4
|
+
def captured?; true; end
|
5
|
+
def derivation_rule; ApacheCrunch::NullDerivationRule.new; end
|
5
6
|
end
|
6
7
|
|
7
|
-
class
|
8
|
-
|
9
|
-
|
10
|
-
|
8
|
+
class StubNumericFormatToken < ApacheCrunch::FormatToken
|
9
|
+
def name; :num; end
|
10
|
+
def regex; %q!\d+!; end
|
11
|
+
def captured?; true; end
|
12
|
+
def derivation_rule; ApacheCrunch::NullDerivationRule.new; end
|
11
13
|
end
|
12
14
|
|
13
|
-
class
|
14
|
-
@
|
15
|
-
@
|
16
|
-
|
15
|
+
class StubStringFormatToken < ApacheCrunch::FormatToken
|
16
|
+
def initialize(s); @_s = s; end
|
17
|
+
def regex; @_s; end
|
18
|
+
def captured?; false; end
|
19
|
+
def derivation_rule; ApacheCrunch::NullDerivationRule.new; end
|
17
20
|
end
|
18
21
|
|
19
|
-
class
|
20
|
-
|
21
|
-
def
|
22
|
-
|
22
|
+
class StubDerivedToken < ApacheCrunch::FormatToken
|
23
|
+
@name = :derived
|
24
|
+
def derivation_rule; ApacheCrunch::NullDerivationRule.new; end
|
25
|
+
end
|
26
|
+
|
27
|
+
class StubDerivationRule
|
28
|
+
def source_name; :derivation_source; end
|
29
|
+
def target_names; [:derived]; end
|
30
|
+
def derive(name, source_value)
|
31
|
+
"derived from #{source_value}"
|
23
32
|
end
|
24
33
|
end
|
25
34
|
|
26
|
-
class
|
27
|
-
|
28
|
-
|
29
|
-
@
|
35
|
+
# Pretends to be the DerivationRuleFinder class, but find() always returns the value it was
|
36
|
+
# initialized with
|
37
|
+
class StubDerivationRuleFinder
|
38
|
+
def initialize(rule); @_rule = rule; end
|
39
|
+
def find(element_name); return @_rule; end
|
30
40
|
end
|
31
41
|
|
32
|
-
class
|
33
|
-
|
42
|
+
class StubDerivationSourceToken
|
43
|
+
def derivation_rule; StubDerivationRule.new; end
|
44
|
+
def name; :derivation_source; end
|
45
|
+
def captured?; true; end
|
46
|
+
end
|
34
47
|
|
35
|
-
|
36
|
-
|
48
|
+
class StubFormat
|
49
|
+
attr_accessor :tokens, :captured_tokens
|
50
|
+
end
|
51
|
+
|
52
|
+
class StubEntry
|
53
|
+
attr_accessor :captured_elements
|
54
|
+
def initialize; @captured_elements = {}; end
|
55
|
+
end
|
56
|
+
|
57
|
+
class StubElement
|
58
|
+
attr_accessor :token, :value, :name, :derivation_rule
|
59
|
+
def populate!(token, value)
|
60
|
+
@token = token
|
61
|
+
@value = value
|
62
|
+
@name = token.name
|
63
|
+
@derivation_rule = @token.derivation_rule
|
37
64
|
end
|
65
|
+
end
|
38
66
|
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
67
|
+
class StubValueFetcher
|
68
|
+
def initialize(fetch_result); @fetch = fetch_result; end
|
69
|
+
def fetch(*args); @fetch; end
|
70
|
+
end
|
43
71
|
|
44
|
-
|
72
|
+
# Pretends to be a Raw- or DerivedValueFetcher class, but StubValueFetcher instance returned by
|
73
|
+
# new() just fetches whatever you set fetch_result to.
|
74
|
+
class StubValueFetcherClass
|
75
|
+
attr_accessor :fetch_result
|
76
|
+
def new(*args)
|
77
|
+
StubValueFetcher.new(@fetch_result)
|
45
78
|
end
|
46
79
|
end
|
47
80
|
|
48
|
-
class
|
49
|
-
def
|
50
|
-
|
51
|
-
return StubFormatElement.new
|
52
|
-
else
|
53
|
-
return StubFormatString.new
|
54
|
-
end
|
81
|
+
class StubEntryParser
|
82
|
+
def parse_return_values=(value_list)
|
83
|
+
@_parse_return_values = value_list.clone
|
55
84
|
end
|
85
|
+
def parse(format, log_text); @_parse_return_values.shift; end
|
56
86
|
end
|
@@ -0,0 +1,36 @@
|
|
1
|
+
require 'test/stub'
|
2
|
+
|
3
|
+
class TestDerivedValueFetcher < Test::Unit::TestCase
|
4
|
+
def setup
|
5
|
+
@inst = ApacheCrunch::DerivedValueFetcher.new
|
6
|
+
end
|
7
|
+
|
8
|
+
def teardown
|
9
|
+
@inst = nil
|
10
|
+
end
|
11
|
+
|
12
|
+
# Tests a successful fetch call
|
13
|
+
def test_fetch
|
14
|
+
entry = StubEntry.new
|
15
|
+
alnum_element = StubElement.new
|
16
|
+
alnum_element.populate!(StubAlphanumericFormatToken.new, "foo123")
|
17
|
+
ds_element = StubElement.new
|
18
|
+
ds_element.populate!(StubDerivationSourceToken.new, "herpaderp")
|
19
|
+
|
20
|
+
@inst.dep_inject!(StubDerivationRuleFinder.new(StubDerivationRule.new))
|
21
|
+
entry.captured_elements = {:alnum => alnum_element, :derivation_source => ds_element}
|
22
|
+
assert_equal("derived from herpaderp", @inst.fetch(entry, :derived))
|
23
|
+
end
|
24
|
+
|
25
|
+
# Tests a fetch call for an element that's not derivable
|
26
|
+
def test_fetch_missing
|
27
|
+
entry = StubEntry.new
|
28
|
+
alnum_element = StubElement.new
|
29
|
+
alnum_element.populate!(StubAlphanumericFormatToken.new, "foo123")
|
30
|
+
ds_element = StubElement.new
|
31
|
+
ds_element.populate!(StubDerivationSourceToken.new, "herpaderp")
|
32
|
+
|
33
|
+
entry.captured_elements = [alnum_element, ds_element]
|
34
|
+
assert_nil(@inst.fetch(entry, :missing_element))
|
35
|
+
end
|
36
|
+
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
require 'test/stub'
|
2
|
+
|
3
|
+
class TestElement < Test::Unit::TestCase
|
4
|
+
def setup
|
5
|
+
@inst = ApacheCrunch::Element.new
|
6
|
+
end
|
7
|
+
|
8
|
+
def teardown
|
9
|
+
@inst = nil
|
10
|
+
end
|
11
|
+
|
12
|
+
# Tests a successful derivation_rule call
|
13
|
+
def test_derivation_rule
|
14
|
+
@inst.populate!(StubDerivationSourceToken.new, "bar456")
|
15
|
+
assert_instance_of(StubDerivationRule, @inst.derivation_rule,
|
16
|
+
"#{@inst.class}#derivation_rule returned wrong type of thing")
|
17
|
+
end
|
18
|
+
end
|
@@ -0,0 +1,45 @@
|
|
1
|
+
require 'test/stub'
|
2
|
+
|
3
|
+
class TestElementValueFetcher < Test::Unit::TestCase
|
4
|
+
def setup
|
5
|
+
@inst = ApacheCrunch::ElementValueFetcher.new
|
6
|
+
@_raw_fetcher = StubValueFetcherClass.new
|
7
|
+
@_derived_fetcher = StubValueFetcherClass.new
|
8
|
+
end
|
9
|
+
|
10
|
+
def teardown
|
11
|
+
@inst = nil
|
12
|
+
@_raw_fetcher = nil
|
13
|
+
@_derived_fetcher = nil
|
14
|
+
end
|
15
|
+
|
16
|
+
# Tests a successful fetch call that hits a raw element
|
17
|
+
def test_fetch_raw
|
18
|
+
@_raw_fetcher.fetch_result = "raw value"
|
19
|
+
@_derived_fetcher.fetch_result = nil
|
20
|
+
@inst.dep_inject!(@_raw_fetcher, @_derived_fetcher)
|
21
|
+
|
22
|
+
entry = StubEntry.new
|
23
|
+
assert_equal("raw value", @inst.fetch(entry, :irrelevant))
|
24
|
+
end
|
25
|
+
|
26
|
+
# Tests a successful fetch call that hits a derived element
|
27
|
+
def test_fetch_derived
|
28
|
+
@_raw_fetcher.fetch_result = nil
|
29
|
+
@_derived_fetcher.fetch_result = "derived value"
|
30
|
+
@inst.dep_inject!(@_raw_fetcher, @_derived_fetcher)
|
31
|
+
|
32
|
+
entry = StubEntry.new
|
33
|
+
assert_equal("derived value", @inst.fetch(entry, :irrelevant))
|
34
|
+
end
|
35
|
+
|
36
|
+
# Tests a fetch call for an element that's not there
|
37
|
+
def test_fetch_missing
|
38
|
+
@_raw_fetcher.fetch_result = nil
|
39
|
+
@_derived_fetcher.fetch_result = nil
|
40
|
+
@inst.dep_inject!(@_raw_fetcher, @_derived_fetcher)
|
41
|
+
|
42
|
+
entry = StubEntry.new
|
43
|
+
assert_nil(@inst.fetch(entry, :missing_element))
|
44
|
+
end
|
45
|
+
end
|
@@ -0,0 +1,39 @@
|
|
1
|
+
require 'test/stub'
|
2
|
+
|
3
|
+
class TestEntryParser < Test::Unit::TestCase
|
4
|
+
def setup
|
5
|
+
@inst = ApacheCrunch::EntryParser.new
|
6
|
+
|
7
|
+
@format = StubFormat.new
|
8
|
+
alnum_token = StubAlphanumericFormatToken.new
|
9
|
+
string_token = StubStringFormatToken.new(" stuff ")
|
10
|
+
num_token = StubNumericFormatToken.new
|
11
|
+
@format.tokens = [alnum_token, string_token, num_token]
|
12
|
+
@format.captured_tokens = [alnum_token, num_token]
|
13
|
+
end
|
14
|
+
|
15
|
+
def teardown
|
16
|
+
@inst = nil
|
17
|
+
end
|
18
|
+
|
19
|
+
# Tests a successful parse call
|
20
|
+
def test_parse
|
21
|
+
line_text = "hurrdurr stuff 01560"
|
22
|
+
@inst.dep_inject!(StubEntry, StubElement)
|
23
|
+
|
24
|
+
result = @inst.parse(@format, line_text)
|
25
|
+
assert_instance_of(StubEntry, result,
|
26
|
+
"#{@inst.class}#parse returned wrong type of thing")
|
27
|
+
end
|
28
|
+
|
29
|
+
# Tests a parse call on a malformatted line
|
30
|
+
def test_parse_fail
|
31
|
+
line_text = "slammadamma doesn't match"
|
32
|
+
@inst.dep_inject!(StubEntry, StubElement)
|
33
|
+
|
34
|
+
$VERBOSE = nil
|
35
|
+
result = @inst.parse(@format, line_text)
|
36
|
+
$VERBOSE = true
|
37
|
+
assert_nil(result, "#{@inst.class}#parse returned non-nil for malformmated line")
|
38
|
+
end
|
39
|
+
end
|
data/test/test_format.rb
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
require 'test/
|
1
|
+
require 'test/mock'
|
2
2
|
|
3
3
|
class TestFormat < Test::Unit::TestCase
|
4
4
|
def setup
|
@@ -9,55 +9,17 @@ class TestFormat < Test::Unit::TestCase
|
|
9
9
|
@inst = nil
|
10
10
|
end
|
11
11
|
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
@inst.
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
"!abc123\n" =~ @inst.regex
|
26
|
-
assert_nil($1)
|
27
|
-
end
|
28
|
-
|
29
|
-
# Tests regex compilation for a more complex format
|
30
|
-
def test_regex_complex
|
31
|
-
@inst.append(StubNumericFormatElement.new)
|
32
|
-
@inst.append(StubFormatString.new(' \(some stuff\) '))
|
33
|
-
@inst.append(StubAlphanumericFormatElement.new)
|
34
|
-
|
35
|
-
"54321 (some stuff) alphaNumericStuff" =~ @inst.regex
|
36
|
-
assert_equal([Regexp.last_match(1), Regexp.last_match(2)],
|
37
|
-
["54321", "alphaNumericStuff"])
|
38
|
-
|
39
|
-
"54321 (doesn't match) alphaNumericStuff" =~ @inst.regex
|
40
|
-
assert_equal([Regexp.last_match(1), Regexp.last_match(2)],
|
41
|
-
[nil, nil])
|
42
|
-
end
|
43
|
-
|
44
|
-
# Tests the list of matchable elements
|
45
|
-
def test_elements
|
46
|
-
num_element = StubNumericFormatElement.new
|
47
|
-
alnum_element = StubAlphanumericFormatElement.new
|
48
|
-
@inst.append(num_element)
|
49
|
-
@inst.append(StubFormatString.new(' \(some stuff\) '))
|
50
|
-
@inst.append(alnum_element)
|
51
|
-
|
52
|
-
assert_equal(@inst.elements, [num_element, alnum_element])
|
53
|
-
end
|
54
|
-
|
55
|
-
# Tests the derivation map
|
56
|
-
def test_derivation_map
|
57
|
-
@inst.append(StubNumericFormatElement.new)
|
58
|
-
@inst.append(StubFormatString.new(' \(some stuff\) '))
|
59
|
-
@inst.append(StubDerivationSourceElement.new)
|
60
|
-
|
61
|
-
assert(@inst.derivation_map, {:derived => StubDerivationSourceElement})
|
12
|
+
def test_captured_tokens
|
13
|
+
tokens = [
|
14
|
+
StubAlphanumericFormatToken.new,
|
15
|
+
StubStringFormatToken.new("foo"),
|
16
|
+
StubNumericFormatToken.new,
|
17
|
+
StubStringFormatToken.new("bar"),
|
18
|
+
StubAlphanumericFormatToken.new
|
19
|
+
]
|
20
|
+
|
21
|
+
@inst.tokens = tokens
|
22
|
+
assert_equal([tokens[0], tokens[2], tokens[4]], @inst.captured_tokens,
|
23
|
+
"#{@inst.class}#captured_tokens returned the wrong list of captured tokens")
|
62
24
|
end
|
63
25
|
end
|
data/test/test_format_parser.rb
CHANGED
@@ -1,26 +1,35 @@
|
|
1
|
-
require 'test/
|
1
|
+
require 'test/mock'
|
2
2
|
|
3
3
|
class TestFormatParser < Test::Unit::TestCase
|
4
4
|
def setup
|
5
|
-
@inst = ApacheCrunch::FormatParser.new
|
6
|
-
StubFormatString)
|
5
|
+
@inst = ApacheCrunch::FormatParser.new
|
7
6
|
end
|
8
7
|
|
9
8
|
def teardown
|
10
9
|
@inst = nil
|
11
10
|
end
|
12
11
|
|
13
|
-
def
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
12
|
+
def test_parse
|
13
|
+
datasets = [
|
14
|
+
["%a %b", [["%a"], [" "], ["%b"]]],
|
15
|
+
["%a bare string %{Request-Header}i",
|
16
|
+
[["%a"], [" bare string "], ["%{Request-Header}i"]]],
|
17
|
+
["%{foo:[A-Za-z0-9]}r %% %a %b",
|
18
|
+
[["%{foo:[A-Za-z0-9]}r"], [" "], ["%%"], [" "], ["%a"], [" "], ["%b"]]]
|
19
|
+
]
|
20
|
+
|
21
|
+
datasets.each do |dataset|
|
22
|
+
format_def = dataset[0]
|
23
|
+
from_abbrev_calls = dataset[1]
|
24
|
+
|
25
|
+
mock_format_token_factory = MockFormatTokenFactoryClass.new
|
26
|
+
@inst.dep_inject!(mock_format_token_factory)
|
19
27
|
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
28
|
+
result = @inst.parse_def(format_def).length
|
29
|
+
assert_equal(from_abbrev_calls, mock_format_token_factory.from_abbrev_calls,
|
30
|
+
"#{@inst.class}#parse_def didn't call FormatTokenFactory with right parameters")
|
31
|
+
assert_equal(from_abbrev_calls.length, result,
|
32
|
+
"#{@inst.class}#parse_def didn't return right number of tokens")
|
24
33
|
end
|
25
34
|
end
|
26
35
|
end
|