logbox 0.2.10
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/.bundle/config +3 -0
- data/.rvmrc +2 -0
- data/Gemfile +17 -0
- data/Gemfile.lock +30 -0
- data/README +14 -0
- data/Rakefile +74 -0
- data/VERSION +1 -0
- data/bin/download_logs +20 -0
- data/bin/obsstats +39 -0
- data/bin/rotate +17 -0
- data/bin/viewobs +198 -0
- data/lib/logbox.rb +9 -0
- data/lib/logbox/ansi_colors.rb +28 -0
- data/lib/logbox/log_parser.rb +79 -0
- data/lib/logbox/mockup_log.rb +44 -0
- data/lib/logbox/observation.rb +162 -0
- data/lib/logbox/observation_compiler.rb +311 -0
- data/lib/logbox/observation_mover.rb +142 -0
- data/lib/logbox/stream_wrapper.rb +20 -0
- data/lib/logbox/stream_wrapper/gzip_multi_file.rb +90 -0
- data/lib/logbox/stream_wrapper/observation_filter.rb +113 -0
- data/lib/logbox/stream_wrapper/order_blob_splitter.rb +96 -0
- data/lib/setup_environment.rb +15 -0
- data/logbox.gemspec +110 -0
- data/test/bin_viewobs_test.rb +42 -0
- data/test/fixtures/aws_keys_yaml.txt +3 -0
- data/test/fixtures/double-obs.log +1 -0
- data/test/fixtures/error_line.log +1 -0
- data/test/fixtures/log-for-md5.log +1 -0
- data/test/fixtures/log0.log +0 -0
- data/test/fixtures/log1.log +1 -0
- data/test/fixtures/log1.log.gz +0 -0
- data/test/fixtures/log2.log +2 -0
- data/test/fixtures/log2.log.gz +0 -0
- data/test/fixtures/log_invalid_mixed_encoding.log +1 -0
- data/test/fixtures/observation_filter.log +5 -0
- data/test/fixtures/unquoted_ugliness.log +2 -0
- data/test/log_parser_test.rb +84 -0
- data/test/observation_compiler_test.rb +216 -0
- data/test/observation_mover_test.rb +135 -0
- data/test/observation_test.rb +114 -0
- data/test/stream_wrapper/gzip_multi_file_test.rb +147 -0
- data/test/stream_wrapper/observation_filter_test.rb +171 -0
- data/test/stream_wrapper/order_blob_splitter_test.rb +129 -0
- data/test/test_helper.rb +23 -0
- metadata +177 -0
@@ -0,0 +1,135 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
require 'observation_mover'
|
3
|
+
|
4
|
+
class ObservationMoverTest < Test::Unit::TestCase
|
5
|
+
context "ObservationMover" do
|
6
|
+
setup do
|
7
|
+
setup_log_dir
|
8
|
+
@mover = ObservationMover.new(log_file_path)
|
9
|
+
end
|
10
|
+
|
11
|
+
context "#rotate" do
|
12
|
+
context "with a non-empty log file" do
|
13
|
+
should "move the log file" do
|
14
|
+
@mover.rotate_current
|
15
|
+
rotated = rotated_path!
|
16
|
+
assert_not_nil rotated
|
17
|
+
assert_equal "loggy\n", File.read(rotated)
|
18
|
+
end
|
19
|
+
should "create a new, empty log file" do
|
20
|
+
@mover.rotate_current
|
21
|
+
assert File.exists?(log_file_path)
|
22
|
+
assert ! File.size?(log_file_path)
|
23
|
+
end
|
24
|
+
should "return true" do
|
25
|
+
assert @mover.rotate_current
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
context "with an empty log file" do
|
30
|
+
setup do
|
31
|
+
File.open(log_file_path, "w").close
|
32
|
+
end
|
33
|
+
should "not rename the log file" do
|
34
|
+
@mover.rotate_current
|
35
|
+
assert_equal [log_file_path], Dir[log_file_path('*')]
|
36
|
+
end
|
37
|
+
should "return false" do
|
38
|
+
assert ! @mover.rotate_current
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
context "#prepare_rotated_for_archiving" do
|
44
|
+
setup do
|
45
|
+
@mover.rotate_current
|
46
|
+
end
|
47
|
+
should "rename a rotated file" do
|
48
|
+
rotated = rotated_path!
|
49
|
+
@mover.prepare_rotated_for_archiving
|
50
|
+
assert ! File.exists?(rotated), "#{rotated} exists!"
|
51
|
+
end
|
52
|
+
should "compress a rotated file" do
|
53
|
+
rotated = rotated_path!
|
54
|
+
@mover.prepare_rotated_for_archiving
|
55
|
+
assert ! Dir[rotated + '*.gz'].empty?
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
context '#move_prepared_to_archive' do
|
60
|
+
context "with one file with a sha" do
|
61
|
+
setup do
|
62
|
+
@shad_name = log_file_path('observer-log-2010-01-05-21-13-11-1234567890abcdef.gz')
|
63
|
+
File.open(@shad_name, 'w') { |f| f << "logline\n" }
|
64
|
+
end
|
65
|
+
should "move that file to s3" do
|
66
|
+
@mover.expects(:store_file_on_s3).with(@shad_name).returns(true)
|
67
|
+
@mover.move_prepared_to_archive
|
68
|
+
end
|
69
|
+
should "delete the file if the move succeeds" do
|
70
|
+
@mover.expects(:store_file_on_s3).with(@shad_name).returns(true)
|
71
|
+
@mover.move_prepared_to_archive
|
72
|
+
assert ! File.exists?(@shad_name)
|
73
|
+
end
|
74
|
+
should "not delete the file if the move fails" do
|
75
|
+
@mover.expects(:store_file_on_s3).with(@shad_name).returns(false)
|
76
|
+
@mover.move_prepared_to_archive
|
77
|
+
assert File.exists?(@shad_name)
|
78
|
+
end
|
79
|
+
# should "talk to s3" do
|
80
|
+
# #WebMock.disable_net_connect!
|
81
|
+
# #WebMock.allow_net_connect!
|
82
|
+
# # stub_request(:put, %r'https://rwdata-logs.s3.amazonaws.com/.*').to_return do |request|
|
83
|
+
# # raise request.inspect
|
84
|
+
# # end
|
85
|
+
# # PUT https://rwdata-logs.s3.amazonaws.com/observer-log-2010-01-05-21-13-11-1234567890abcdef with body 'logline\n' with headers {'Accept'=>'*/*', 'Authorization'=>'AWS AAAAAAAAAA:4aYODn+8Yx7nIGnGf1coqWbEjWY=', 'Content-Length'=>'8', 'Content-Md5'=>'2ee0c171dab3e30627525ff535355eba', 'Content-Type'=>'', 'Date'=>'Thu, 'User-Agent'=>'', 22 Apr 2010 12:11:09 GMT'}
|
86
|
+
# @mover.move_prepared_to_archive
|
87
|
+
# end
|
88
|
+
# should "talk to s3" do
|
89
|
+
# WebMock.disable_net_connect!
|
90
|
+
# #WebMock.allow_net_connect!
|
91
|
+
# stub_request(:any, 'https://rwdata-logs.s3.amazonaws.com/?location').to_return(:status => [500, 'Internal Server knas'])
|
92
|
+
# @mover.s3.bucket_location('rwdata-logs')
|
93
|
+
# end
|
94
|
+
end
|
95
|
+
end
|
96
|
+
|
97
|
+
context '#aws_keys' do
|
98
|
+
should "read from a yaml file and return a list" do
|
99
|
+
file = fixture_file('aws_keys_yaml.txt')
|
100
|
+
key, secret = @mover.aws_keys(file)
|
101
|
+
assert_equal 'PUBLICKEY', key
|
102
|
+
assert_equal 'SECRET/KEY', secret
|
103
|
+
end
|
104
|
+
end
|
105
|
+
|
106
|
+
context '#md5' do
|
107
|
+
should "return a Base64-coded string" do
|
108
|
+
file = fixture_file('../fixtures/log-for-md5.log')
|
109
|
+
assert_equal 'X301NTIE25GbZGzT7u7cog==', @mover.md5(file)
|
110
|
+
end
|
111
|
+
end
|
112
|
+
end
|
113
|
+
|
114
|
+
def log_file_path (file_name = 'observer.log')
|
115
|
+
File.join(log_dir, file_name)
|
116
|
+
end
|
117
|
+
|
118
|
+
def log_dir
|
119
|
+
'/tmp/test/logs'
|
120
|
+
end
|
121
|
+
|
122
|
+
def setup_log_dir
|
123
|
+
FileUtils.mkdir_p log_dir
|
124
|
+
FileUtils.rm_r log_dir
|
125
|
+
FileUtils.mkdir log_dir
|
126
|
+
File.open(log_file_path, "w") { |f| f.puts "loggy" }
|
127
|
+
end
|
128
|
+
|
129
|
+
def rotated_path!
|
130
|
+
paths = Dir[log_file_path('*')] - [log_file_path]
|
131
|
+
assert_equal 1, paths.size, "Not exactly one path in #{paths.inspect}"
|
132
|
+
paths.first
|
133
|
+
end
|
134
|
+
|
135
|
+
end
|
@@ -0,0 +1,114 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
require 'observation'
|
3
|
+
|
4
|
+
class ObservationTest < Test::Unit::TestCase
|
5
|
+
|
6
|
+
context "The Observation when initialized" do
|
7
|
+
|
8
|
+
should "copy and rename attributes" do
|
9
|
+
log_attr = {:r => "referrer", :_item_id => "id", :_user1 => "custom", :ip => "ip"}
|
10
|
+
o = Observation.new(log_attr)
|
11
|
+
assert_equal 0, o.unknown_attributes.size
|
12
|
+
assert_equal 4, o.attributes.size
|
13
|
+
assert_equal "referrer", o.attributes[:referrer]
|
14
|
+
assert_equal "id", o.attributes[:item_id]
|
15
|
+
assert_equal "custom", o.attributes[:user1]
|
16
|
+
assert_equal "ip", o.attributes[:ip]
|
17
|
+
end
|
18
|
+
|
19
|
+
should "convert local urls to absolute urls" do
|
20
|
+
log_attr = {
|
21
|
+
:_url => "../index.html",
|
22
|
+
:_thumbnail => 'http://www.test.com/te st.html#debug',
|
23
|
+
:_image => 'http://www.test.com/te%st.html#debugon',
|
24
|
+
:_basket_url => 'http://www.test.com/te%20st.html#debugoff',
|
25
|
+
:u => 'http://www.test.com/f1/f2/index.html#debugon'
|
26
|
+
}
|
27
|
+
o = Observation.new(log_attr)
|
28
|
+
assert_equal 0, o.unknown_attributes.size
|
29
|
+
assert_equal 5, o.attributes.size
|
30
|
+
assert_equal "http://www.test.com/f1/index.html", o.attributes[:url]
|
31
|
+
assert_equal "http://www.test.com/te%20st.html", o.attributes[:thumbnail]
|
32
|
+
assert_equal "http://www.test.com/te%25st.html", o.attributes[:image]
|
33
|
+
assert_equal "http://www.test.com/te%20st.html", o.attributes[:basket_url]
|
34
|
+
end
|
35
|
+
|
36
|
+
should "convert not tamper with javascript urls" do
|
37
|
+
log_attr = {
|
38
|
+
:_basket_url => "javascript:alert('basket')",
|
39
|
+
:u => 'http://www.test.com/'
|
40
|
+
}
|
41
|
+
o = Observation.new(log_attr)
|
42
|
+
assert_equal "javascript:alert('basket')", o.attributes[:basket_url]
|
43
|
+
end
|
44
|
+
|
45
|
+
should "report error for invalid urls" do
|
46
|
+
log_attr = {
|
47
|
+
:_url => "../index.html",
|
48
|
+
:u => 'index.html#anchor2'
|
49
|
+
}
|
50
|
+
o = Observation.new(log_attr)
|
51
|
+
assert o.errors.include?(:url_error_on_url)
|
52
|
+
end
|
53
|
+
|
54
|
+
should "validate that status is ok (200)" do
|
55
|
+
log_attr = { :status => '200' }
|
56
|
+
o = Observation.new(log_attr)
|
57
|
+
assert !o.errors.include?(:status_not_ok)
|
58
|
+
|
59
|
+
log_attr = { :status => '404' }
|
60
|
+
o = Observation.new(log_attr)
|
61
|
+
assert o.errors.include?(:status_not_ok)
|
62
|
+
end
|
63
|
+
|
64
|
+
should "validate type attribute" do
|
65
|
+
log_attr = { :o => "view_item", :status => "200" }
|
66
|
+
o = Observation.new(log_attr)
|
67
|
+
assert !o.errors.include?(:unknown_type)
|
68
|
+
assert_equal :view_item, o.type
|
69
|
+
|
70
|
+
log_attr = { :o => "pick_item", :status => "200" }
|
71
|
+
o = Observation.new(log_attr)
|
72
|
+
assert !o.errors.include?(:unknown_type)
|
73
|
+
assert_equal :pick_item, o.type
|
74
|
+
|
75
|
+
log_attr = { :o => "visit_page", :status => "200" }
|
76
|
+
o = Observation.new(log_attr)
|
77
|
+
assert !o.errors.include?(:unknown_type)
|
78
|
+
assert_equal :visit_page, o.type
|
79
|
+
|
80
|
+
log_attr = { :o => "apa", :status => "200" }
|
81
|
+
o = Observation.new(log_attr)
|
82
|
+
assert o.errors.include?(:unknown_type)
|
83
|
+
assert_equal :unknown, o.type
|
84
|
+
end
|
85
|
+
|
86
|
+
should "validate required attributes" do
|
87
|
+
other_names = Observation::BASIC_ATTRIBUTES_NAMES.merge(Observation::OBSERVATION_ATTRIBUTES_NAMES)
|
88
|
+
[ :uid, :sid, :aid, :_item_id ].each do |name|
|
89
|
+
error_message = "missing_#{other_names[name]}".to_sym
|
90
|
+
|
91
|
+
log_attr = { :o => "view_item", :status => "200", name => "1000" }
|
92
|
+
o = Observation.new(log_attr)
|
93
|
+
assert !o.errors.include?(error_message)
|
94
|
+
|
95
|
+
log_attr = { :o => "view_item", :status => "200" }
|
96
|
+
o = Observation.new(log_attr)
|
97
|
+
assert o.errors.include?(error_message), "'#{error_message}' not found in #{o.errors.inspect}"
|
98
|
+
end
|
99
|
+
end
|
100
|
+
|
101
|
+
should "validate visit_page with shop, account and user id" do
|
102
|
+
assert Observation.new({ :o => "visit_page", :aid => "jshop", :sid => "shirtstore", :uid => "1234", :status => "200" }).valid?
|
103
|
+
assert !Observation.new({ :o => "visit_page", :sid => "shirtstore", :uid => "1234", :status => "200" }).valid?
|
104
|
+
assert !Observation.new({ :o => "visit_page", :aid => "jshop", :uid => "1234", :status => "200" }).valid?
|
105
|
+
assert !Observation.new({ :o => "visit_page", :aid => "jshop", :sid => "shirtstore", :status => "200" }).valid?
|
106
|
+
end
|
107
|
+
should "accept visit_page without item_id as a valid observation" do
|
108
|
+
assert Observation.new({ :o => "visit_page", :status => "200", :uid => '1' * 16, :sid => 'shoop', :aid => 'act'}).valid?
|
109
|
+
end
|
110
|
+
|
111
|
+
end
|
112
|
+
|
113
|
+
end
|
114
|
+
|
@@ -0,0 +1,147 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
require 'stream_wrapper'
|
3
|
+
include StreamWrapper
|
4
|
+
|
5
|
+
class StreamWrapper::GzipMultiFileTest < Test::Unit::TestCase
|
6
|
+
context "A GzipMultiFile with one file" do
|
7
|
+
setup { @sw = GzipMultiFile.new fixture_file("log1.log") }
|
8
|
+
|
9
|
+
should "read from that file with #gets" do
|
10
|
+
assert_equal("Log 1 line 1\n", @sw.gets)
|
11
|
+
end
|
12
|
+
|
13
|
+
should "return nil from #gets after the last line" do
|
14
|
+
@sw.gets
|
15
|
+
assert_equal(nil, @sw.gets)
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
context "A GzipMultiFile with data to read" do
|
20
|
+
setup { @sw = GzipMultiFile.new fixture_file("log1.log") }
|
21
|
+
|
22
|
+
should "not be #eof?" do
|
23
|
+
assert ! @sw.eof?
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
context "A GzipMultiFile with no data left to read" do
|
28
|
+
setup do
|
29
|
+
@sw = GzipMultiFile.new fixture_file("log1.log")
|
30
|
+
@sw.gets
|
31
|
+
end
|
32
|
+
|
33
|
+
should "be #eof?" do
|
34
|
+
assert @sw.eof?
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
context "A GzipMultiFile with two files" do
|
39
|
+
setup do
|
40
|
+
@sw = GzipMultiFile.new [fixture_file("log1.log"), fixture_file("log2.log")]
|
41
|
+
end
|
42
|
+
|
43
|
+
should "read the line from file 1 first" do
|
44
|
+
assert_equal("Log 1 line 1\n", @sw.gets)
|
45
|
+
end
|
46
|
+
|
47
|
+
should "read the lines from file 2 after file 1" do
|
48
|
+
@sw.gets
|
49
|
+
assert_equal("Log 2 line 1\n", @sw.gets)
|
50
|
+
assert_equal("Log 2 line 2\n", @sw.gets)
|
51
|
+
assert_equal(nil, @sw.gets)
|
52
|
+
end
|
53
|
+
|
54
|
+
should "return nil when file 2 is empty" do
|
55
|
+
3.times { @sw.gets }
|
56
|
+
assert_equal(nil, @sw.gets)
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
context "A GzipMultiFile without files" do
|
61
|
+
setup do
|
62
|
+
@stdin = $stdin
|
63
|
+
$stdin = StringIO.new "Line 1\nLine 2\n"
|
64
|
+
@sw = GzipMultiFile.new
|
65
|
+
end
|
66
|
+
teardown do
|
67
|
+
$stdin = @stdin
|
68
|
+
end
|
69
|
+
|
70
|
+
should "read from STDIN" do
|
71
|
+
assert_equal("Line 1\n", @sw.gets)
|
72
|
+
assert_equal("Line 2\n", @sw.gets)
|
73
|
+
assert_equal(nil, @sw.gets)
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
77
|
+
context "A GzipMultiFile with one gzipped file" do
|
78
|
+
setup do
|
79
|
+
@sw = GzipMultiFile.new fixture_file("log1.log.gz")
|
80
|
+
end
|
81
|
+
|
82
|
+
should "read the unzipped data with #gets" do
|
83
|
+
assert_equal("Log 1 line 1\n", @sw.gets)
|
84
|
+
end
|
85
|
+
|
86
|
+
should "return nil from #gets after the last line" do
|
87
|
+
@sw.gets
|
88
|
+
assert_equal(nil, @sw.gets)
|
89
|
+
end
|
90
|
+
end
|
91
|
+
|
92
|
+
context "A GzipMultiFile with two gzipped files" do
|
93
|
+
setup do
|
94
|
+
@sw = GzipMultiFile.new [fixture_file("log1.log.gz"), fixture_file("log2.log.gz")]
|
95
|
+
end
|
96
|
+
|
97
|
+
should "read the line from file 1 first" do
|
98
|
+
assert_equal("Log 1 line 1\n", @sw.gets)
|
99
|
+
end
|
100
|
+
|
101
|
+
should "read the lines from file 2 after file 1" do
|
102
|
+
@sw.gets
|
103
|
+
assert_equal("Log 2 line 1\n", @sw.gets)
|
104
|
+
assert_equal("Log 2 line 2\n", @sw.gets)
|
105
|
+
assert_equal(nil, @sw.gets)
|
106
|
+
end
|
107
|
+
|
108
|
+
should "return nil when file 2 is empty" do
|
109
|
+
3.times { @sw.gets }
|
110
|
+
assert_equal(nil, @sw.gets)
|
111
|
+
end
|
112
|
+
end
|
113
|
+
|
114
|
+
context "If one of the files is empty, the GzipMultiFile" do
|
115
|
+
setup do
|
116
|
+
@sw = GzipMultiFile.new [fixture_file("log0.log"), fixture_file("log2.log")]
|
117
|
+
end
|
118
|
+
|
119
|
+
should "ignore that file without a glitch" do
|
120
|
+
assert_equal("Log 2 line 1\n", @sw.gets)
|
121
|
+
end
|
122
|
+
end
|
123
|
+
|
124
|
+
context "#shell_command" do
|
125
|
+
should "cat regular files" do
|
126
|
+
command = GzipMultiFile.new.send :shell_command, "file.log"
|
127
|
+
assert_match /^cat file.log/, command
|
128
|
+
end
|
129
|
+
should "unzip zipped files" do
|
130
|
+
command = GzipMultiFile.new.send :shell_command, "file.gz"
|
131
|
+
assert_match /^gunzip -c file.gz/, command
|
132
|
+
end
|
133
|
+
should "add filter for shop" do
|
134
|
+
command = GzipMultiFile.new("", {:shop_id => "www.24.se"}).send :shell_command, "file.gz"
|
135
|
+
assert_match /grep -F sid=www\.24\.se/, command
|
136
|
+
end
|
137
|
+
should "add filter for account" do
|
138
|
+
command = GzipMultiFile.new("", {:account_id => "jetshop"}).send :shell_command, "file.gz"
|
139
|
+
assert_match /grep -F aid=jetshop/, command
|
140
|
+
end
|
141
|
+
should "add filter for type" do
|
142
|
+
command = GzipMultiFile.new("", {:observation_type => "view_item"}).send :shell_command, "file.gz"
|
143
|
+
assert_match /grep -F o=view_item/, command
|
144
|
+
end
|
145
|
+
end
|
146
|
+
|
147
|
+
end
|
@@ -0,0 +1,171 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
require 'stream_wrapper'
|
3
|
+
include StreamWrapper
|
4
|
+
|
5
|
+
class StreamWrapper::ObservationFilterTest < Test::Unit::TestCase
|
6
|
+
|
7
|
+
context "An ObservationFilter (regardless of filter options)" do
|
8
|
+
setup do
|
9
|
+
@of = ObservationFilter.new "line 1\nline 2", {}
|
10
|
+
end
|
11
|
+
|
12
|
+
should "read from from a stream with #gets" do
|
13
|
+
assert_equal("line 1\n", @of.gets)
|
14
|
+
assert_equal("line 2", @of.gets)
|
15
|
+
end
|
16
|
+
|
17
|
+
should "return nil from #gets after the last line" do
|
18
|
+
@of.gets
|
19
|
+
@of.gets
|
20
|
+
assert_equal(nil, @of.gets)
|
21
|
+
end
|
22
|
+
|
23
|
+
should "know if the stream is eof" do
|
24
|
+
assert_equal(false, @of.eof?)
|
25
|
+
@of.gets
|
26
|
+
assert_equal(false, @of.eof?)
|
27
|
+
@of.gets
|
28
|
+
assert_equal(true, @of.eof?)
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
context "An ObservationFilter" do
|
33
|
+
should "be able to handle empty lines" do
|
34
|
+
assert_nothing_raised{ObservationFilter.new("\n", {}).to_a}
|
35
|
+
end
|
36
|
+
|
37
|
+
should "filter case insensitive" do
|
38
|
+
File.open(fixture_file("observation_filter.log")) do |file|
|
39
|
+
of = ObservationFilter.new(file, {:account_id => "xRoAdS"})
|
40
|
+
assert_not_nil(of.gets);
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
should "match escaped strings" do
|
45
|
+
file = "aid=Trygg%20Hansa\n"
|
46
|
+
of = ObservationFilter.new(file, {:account_id => "Trygg Hansa"})
|
47
|
+
assert_not_nil(of.gets);
|
48
|
+
end
|
49
|
+
|
50
|
+
should "only return rows with matching account id" do
|
51
|
+
File.open(fixture_file("observation_filter.log")) do |file|
|
52
|
+
of = ObservationFilter.new(file, {:account_id => "xroads"})
|
53
|
+
assert_not_nil(of.gets);
|
54
|
+
end
|
55
|
+
File.open(fixture_file("observation_filter.log")) do |file|
|
56
|
+
of = ObservationFilter.new(file, {:account_id => "apa"})
|
57
|
+
assert_nil(of.gets);
|
58
|
+
assert(of.eof?)
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
should "only return rows with matching shop id" do
|
63
|
+
File.open(fixture_file("observation_filter.log")) do |file|
|
64
|
+
of = ObservationFilter.new(file, {:shop_id => "Fortum"})
|
65
|
+
assert_not_nil(of.gets);
|
66
|
+
end
|
67
|
+
File.open(fixture_file("observation_filter.log")) do |file|
|
68
|
+
of = ObservationFilter.new(file, {:account_id => "apa"})
|
69
|
+
assert_nil(of.gets);
|
70
|
+
assert(of.eof?)
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
74
|
+
should "only return rows with matching account id AND shop id" do
|
75
|
+
File.open(fixture_file("observation_filter.log")) do |file|
|
76
|
+
of = ObservationFilter.new file, {:account_id => "xroads", :shop_id => "fortum"}
|
77
|
+
assert(!(of.gets =~ /fortum/));
|
78
|
+
end
|
79
|
+
File.open(fixture_file("observation_filter.log")) do |file|
|
80
|
+
of = ObservationFilter.new file, {:account_id => "apa", :shop_id => "fortum"}
|
81
|
+
assert_nil(of.gets);
|
82
|
+
end
|
83
|
+
File.open(fixture_file("observation_filter.log")) do |file|
|
84
|
+
of = ObservationFilter.new file, {:account_id => "xroads", :shop_id => "apa"}
|
85
|
+
assert_nil(of.gets);
|
86
|
+
end
|
87
|
+
end
|
88
|
+
|
89
|
+
should "skip shops" do
|
90
|
+
File.open(fixture_file("observation_filter.log")) do |file|
|
91
|
+
of = ObservationFilter.new file, {:skip_shop_id => "fortum"}
|
92
|
+
assert(!(of.gets =~ /fortum/i));
|
93
|
+
assert(!(of.gets =~ /fortum/i));
|
94
|
+
assert_nil(of.gets);
|
95
|
+
end
|
96
|
+
File.open(fixture_file("observation_filter.log")) do |file|
|
97
|
+
of = ObservationFilter.new file, {:skip_shop_id => "trygg\shansa"}
|
98
|
+
assert(!(of.gets =~ /trygg\shansa/i));
|
99
|
+
assert(!(of.gets =~ /trygg\shansa/i));
|
100
|
+
assert(!(of.gets =~ /trygg\shansa/i));
|
101
|
+
assert(!(of.gets =~ /trygg\shansa/i));
|
102
|
+
assert(!(of.gets =~ /trygg\shansa/i));
|
103
|
+
assert_nil(of.gets);
|
104
|
+
end
|
105
|
+
end
|
106
|
+
|
107
|
+
should "only return rows with matching observation type" do
|
108
|
+
File.open(fixture_file("observation_filter.log")) do |file|
|
109
|
+
of = ObservationFilter.new file, {:observation_type => "view_item"}
|
110
|
+
assert(of.gets =~ /o=view_item/);
|
111
|
+
end
|
112
|
+
File.open(fixture_file("observation_filter.log")) do |file|
|
113
|
+
of = ObservationFilter.new file, {:observation_type => "pick_item"}
|
114
|
+
assert(of.gets =~ /o=pick_item/);
|
115
|
+
end
|
116
|
+
File.open(fixture_file("observation_filter.log")) do |file|
|
117
|
+
of = ObservationFilter.new file, {:observation_type => "apa"}
|
118
|
+
assert_nil(of.gets);
|
119
|
+
end
|
120
|
+
end
|
121
|
+
|
122
|
+
should "ignore inhouse and debug rows" do
|
123
|
+
File.open(fixture_file("observation_filter.log")) do |file|
|
124
|
+
of = ObservationFilter.new file, {:skip_debug_observations => true}
|
125
|
+
assert_not_nil(of.gets);
|
126
|
+
assert_not_nil(of.gets);
|
127
|
+
assert_nil(of.gets);
|
128
|
+
end
|
129
|
+
end
|
130
|
+
|
131
|
+
if RUBY_VERSION > "1.9"
|
132
|
+
should "ignore invalide byte sequence" do
|
133
|
+
File.open(fixture_file('log_invalid_mixed_encoding.log'), :encoding => "utf-8") do |file|
|
134
|
+
of = ObservationFilter.new file, {:skip_debug_observations => true}
|
135
|
+
assert_nothing_raised{of.gets}
|
136
|
+
end
|
137
|
+
end
|
138
|
+
end
|
139
|
+
|
140
|
+
should "iterate over observations" do
|
141
|
+
File.open(fixture_file("observation_filter.log")) do |file|
|
142
|
+
of = ObservationFilter.new file, {:observation_type => "view_item"}
|
143
|
+
of.each do |o|
|
144
|
+
assert(o.kind_of?(Observation))
|
145
|
+
end
|
146
|
+
assert_equal(4, of.observation_count)
|
147
|
+
end
|
148
|
+
end
|
149
|
+
|
150
|
+
should "filter valid observations" do
|
151
|
+
file = File.open(fixture_file("observation_filter.log")).readlines.join
|
152
|
+
of = ObservationFilter.new file, {:valid => true}
|
153
|
+
assert_equal(5, of.count)
|
154
|
+
file += '81.233.91.34 - - [16/Feb/2009:08:36:36 +0100] "GET /log.gif?Intesahimlavaliddirekt& HTTP/1.1" 200 35 "http://www.xroads.se/trygghansa/Products/Product.asp?itemId=6971" "Mozilla/5.0 (Windows; U; Windows NT 5.1; sv-SE; rv:1.9.0.6) Gecko/2009011913 Firefox/3.0.6"\n'
|
155
|
+
of = ObservationFilter.new file, {:valid => true}
|
156
|
+
assert_equal(5, of.count)
|
157
|
+
of = ObservationFilter.new file, {:skip_valid => true}
|
158
|
+
assert_equal(1, of.count)
|
159
|
+
end
|
160
|
+
|
161
|
+
should "not accept false values for any options" do
|
162
|
+
File.open(fixture_file("observation_filter.log")) do |file|
|
163
|
+
assert_raise RuntimeError do
|
164
|
+
of = ObservationFilter.new file, {:valid => false}
|
165
|
+
end
|
166
|
+
end
|
167
|
+
end
|
168
|
+
|
169
|
+
end
|
170
|
+
|
171
|
+
end
|