apachecrunch 0.4 → 0.5
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/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
|