ralf 0.1.5 → 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
data/spec/ralf_spec.rb CHANGED
@@ -5,274 +5,342 @@ require 'ralf'
5
5
  describe Ralf do
6
6
 
7
7
  before(:all) do
8
- @key1 = {:name => 'log/access_log-2010-02-10-00-05-32-ZDRFGTCKUYVJCT', :data => 'This is content for key 1'}
9
- @key2 = {:name => 'log/access_log-2010-02-10-00-07-28-EFREUTERGRSGDH', :data => 'This is content for key 2'}
10
- @key3 = {:name => 'log/access_log-2010-02-11-00-09-32-SDHTFTFHDDDDDH', :data => 'This is content for key 3'}
8
+ # make sure we don't accidentally use actual credentials during test
9
+ ENV['AWS_ACCESS_KEY_ID'], ENV['AWS_SECRET_ACCESS_KEY'] = nil, nil
10
+
11
+ @key1 = {
12
+ :name => 'log/access_log-2010-02-10-00-05-32-ZDRFGTCKUYVJCT',
13
+ :data => 'This is content for key 1'
14
+ }
15
+ @key2 = {
16
+ :name => 'log/access_log-2010-02-10-00-07-28-EFREUTERGRSGDH',
17
+ :data => 'This is content for key 2'
18
+ }
19
+ @key3 = {
20
+ :name => 'log/access_log-2010-02-11-00-09-32-SDHTFTFHDDDDDH',
21
+ :data => 'This is content for key 3'
22
+ }
23
+
24
+ @aws_credentials = {
25
+ :aws_access_key_id => 'the_aws_access_key_id',
26
+ :aws_secret_access_key => 'the_secret_access_key',
27
+ }
28
+
29
+ @valid_options = {
30
+ :config_file => '',
31
+ :output_file => './ralf/:year/:month/:day/:bucket.log',
32
+ }.merge(@aws_credentials)
33
+
34
+ @cli_config_path = 'my_ralf.conf'
35
+ @cli_config = {
36
+ :range => '2010-02-10',
37
+ :output_file => './ralf/:year/:month/:day/:bucket.log',
38
+ :cache_dir => '/tmp/ralf_cache/:bucket',
39
+ }.merge(@aws_credentials)
40
+
41
+ @tilde_config_path = File.expand_path('~/.ralf.conf')
42
+ @tilde_config = {
43
+ :range => '2010-02-11',
44
+ :output_file => '~/ralf/:year/:month/:day/:bucket.log',
45
+ :cache_dir => '~/ralf/cache/:bucket',
46
+ }.merge(@aws_credentials)
47
+
48
+ @etc_config_path = '/etc/ralf.conf'
49
+ @etc_config = {
50
+ :range => '2010-02-12',
51
+ :output_file => '/var/log/amazon/:year/:month/:day/:bucket.log',
52
+ :cache_dir => '/var/log/amazon/ralf_cache/:year/:month/:bucket',
53
+ }.merge(@aws_credentials)
54
+
55
+ # File = mock('File')
56
+ @s3_mock = mock('s3_mock')
57
+ Ralf::Bucket.s3 = @s3_mock
58
+
59
+ @example_buckets = load_example_bucket_mocks
11
60
  end
12
61
 
13
62
  before(:each) do
14
- @default_params = {
15
- :config => File.dirname(__FILE__) + '/fixtures/config.yaml',
16
- :out_seperator => ':year/:month/:day',
17
- :date => '2010-02-10'
18
- }
63
+ RightAws::S3.should_receive(:new).any_number_of_times.and_return(@s3_mock)
19
64
  end
20
65
 
21
- it "should initialize properly" do
22
- ralf = Ralf.new(@default_params)
23
- ralf.class.should eql(Ralf)
24
- end
66
+ describe "Configuration Options" do
25
67
 
26
- describe "Preferences" do
68
+ it "should initialize properly" do
69
+ YAML.should_not_receive(:load_file)
70
+ ralf = Ralf.new({:output_file => 'here', :config_file => ''}.merge(@aws_credentials))
71
+ ralf.class.should eql(Ralf)
72
+ end
73
+
74
+ it "should read config file specified on command-line" do
75
+ YAML.should_receive(:load_file).with(@cli_config_path).and_return(@cli_config)
76
+ YAML.should_not_receive(:load_file).with(@tilde_config_path)
77
+ YAML.should_not_receive(:load_file).with(@etc_config_path)
78
+ ralf = Ralf.new(:config_file => @cli_config_path)
79
+ ralf.config.should == Ralf::Config.new(@cli_config)
80
+ end
81
+
82
+ it "should read config file from '~/.ralf.conf' if not running as root." do
83
+ Process.should_receive(:uid).and_return(1)
84
+ File.should_receive(:exist?).with(@tilde_config_path).and_return(true)
85
+ YAML.should_receive(:load_file).with(@tilde_config_path).and_return(@tilde_config)
86
+ ralf = Ralf.new
87
+ ralf.config.should == Ralf::Config.new(@tilde_config)
88
+ end
89
+
90
+ it "should read config file from '/etc/ralf.conf' if running as root." do
91
+ Process.should_receive(:uid).and_return(0)
92
+ File.should_receive(:exist?).with(@etc_config_path).and_return(true)
93
+ YAML.should_receive(:load_file).with(@etc_config_path).and_return(@etc_config)
94
+ ralf = Ralf.new
95
+ ralf.config.should == Ralf::Config.new(@etc_config)
96
+ end
27
97
 
98
+ it "should read config file from '~/.ralf.conf' if running as root and /etc/ralf doesn't exist." do
99
+ Process.should_receive(:uid).and_return(0)
100
+ File.should_receive(:exist?).with(@etc_config_path).and_return(true)
101
+ YAML.should_receive(:load_file).with(@etc_config_path).and_return(@etc_config)
102
+ ralf = Ralf.new
103
+ ralf.config.should == Ralf::Config.new(@etc_config)
104
+ end
105
+
106
+ it "should have only required option when :config_file is empty string" do
107
+ YAML.should_not_receive(:load_file)
108
+ File.should_not_receive(:exist?)
109
+ ralf = Ralf.new({ :config_file => ''}.merge(@aws_credentials))
110
+ ralf.config.should == Ralf::Config.new(@aws_credentials)
111
+ end
112
+
113
+ it "command-line options should override config file options" do
114
+ File.should_receive(:exist?).with(@tilde_config_path).and_return(true)
115
+ YAML.should_receive(:load_file).with(@tilde_config_path).and_return(@tilde_config)
116
+ ralf = Ralf.new(@cli_config)
117
+ ralf.config.should == Ralf::Config.new(@cli_config)
118
+ end
119
+
28
120
  it "should raise an error when an nonexistent config file is given" do
121
+ missing_file = 'the_missing_file.conf'
122
+ File.should_receive(:open).with(missing_file).and_raise(Errno::ENOENT)
29
123
  lambda {
30
- ralf = Ralf.new(:config => '~/a_non_existen_file.yaml')
31
- }.should raise_error(Ralf::NoConfigFile)
124
+ ralf = Ralf.new(:config_file => missing_file)
125
+ }.should raise_error(Errno::ENOENT)
32
126
  end
33
127
 
34
128
  it "should set the preferences" do
35
- ralf = Ralf.new(@default_params)
36
- ralf.config[:aws_access_key_id].should eql('access_key')
37
- ralf.config[:aws_secret_access_key].should eql('secret')
38
- ralf.config[:out_path].should eql('/Users/berl/S3')
39
- # ralf.config.should eql({:aws_access_key_id => 'access_key', :aws_secret_access_key => 'secret'})
129
+ YAML.should_not_receive(:load_file)
130
+ ralf = Ralf.new(@cli_config.merge(:config_file => ''))
131
+ ralf.config.should == Ralf::Config.new(@cli_config)
40
132
  end
41
-
42
- it "should look for default configurations" do
43
- File.should_receive(:expand_path).once.with('~/.ralf.yaml').and_return('/Users/berl/.ralf.yaml')
44
- File.should_receive(:expand_path).twice.with('/Users/berl/.ralf.yaml').and_return('/Users/berl/.ralf.yaml')
45
- File.should_receive(:expand_path).once.with('/etc/ralf.yaml').and_return('/etc/ralf.yaml')
46
- File.should_receive(:exists?).once.with('/etc/ralf.yaml').and_return(false)
47
- File.should_receive(:exists?).twice.with('/Users/berl/.ralf.yaml').and_return(true)
48
- YAML.should_receive(:load_file).with('/Users/berl/.ralf.yaml').and_return({
49
- :aws_access_key_id => 'access_key',
50
- :aws_secret_access_key => 'secret',
51
- :out_path => '/Users/berl/S3',
52
- :out_prefix => 's3_combined'
53
- })
54
-
55
- ralf = Ralf.new()
133
+
134
+ it "should raise Ralf::Config::ConfigurationError when --output-file not specified" do
135
+ YAML.should_not_receive(:load_file)
136
+ lambda {
137
+ Ralf.new(:output_file => nil, :config_file => '')
138
+ }.should raise_error(Ralf::Config::ConfigurationError)
56
139
  end
57
140
 
58
141
  it "should use AWS credentials provided in ENV" do
59
- ENV['AWS_ACCESS_KEY_ID'] = 'access_key'
60
- ENV['AWS_SECRET_ACCESS_KEY'] = 'secret'
61
- File.should_receive(:exists?).once.with('/etc/ralf.yaml').and_return(false)
62
- File.should_receive(:exists?).once.with('/Users/berl/.ralf.yaml').and_return(false)
63
-
142
+ YAML.should_not_receive(:load_file)
64
143
  lambda {
65
- Ralf.new(:out_path => '/Users/berl/S3')
66
- }.should_not raise_error(Ralf::ConfigIncomplete)
144
+ Ralf.new(:config_file => '')
145
+ }.should raise_error(Ralf::Config::ConfigurationError, 'aws_access_key_id missing, aws_secret_access_key missing')
67
146
 
147
+ ENV['AWS_ACCESS_KEY_ID'], ENV['AWS_SECRET_ACCESS_KEY'] = 'aws_access_key', 'secret'
148
+ lambda {
149
+ Ralf.new(:config_file => '')
150
+ }.should_not raise_error(Ralf::Config::ConfigurationError)
151
+
152
+ # reset
153
+ ENV['AWS_ACCESS_KEY_ID'], ENV['AWS_SECRET_ACCESS_KEY'] = nil, nil
68
154
  end
69
155
 
70
156
  end
71
157
 
72
- describe "Date handling" do
158
+ describe "Range handling" do
159
+
160
+ it "should set range to today if unspecified" do
161
+ YAML.should_not_receive(:load_file)
162
+ now = Time.now
163
+ Time.should_receive(:now).any_number_of_times.and_return(now)
164
+ ralf = Ralf.new(@valid_options)
165
+ date = now.strftime("%Y-%m-%d")
73
166
 
74
- it "should set the date to today" do
75
- ralf = Ralf.new()
76
- date = Date.today
77
- ralf.date.should eql("%4d-%02d-%02d" % [date.year, date.month, date.day])
167
+ ralf.config.range.to_s.should eql("#{date}..#{date}")
78
168
  end
79
169
 
80
- it "should set the date to the date given" do
81
- ralf = Ralf.new(@default_params.merge(:date => '2010-02-01'))
82
- ralf.date.should eql('2010-02-01')
170
+ it "should set the range when single date given" do
171
+ YAML.should_not_receive(:load_file)
172
+ ralf = Ralf.new(@valid_options.merge(:range => '2010-02-01'))
173
+ ralf.config.range.to_s.should eql('2010-02-01..2010-02-01')
83
174
  end
84
175
 
85
176
  it "should raise error when invalid date given" do
177
+ YAML.should_not_receive(:load_file)
86
178
  lambda {
87
- ralf = Ralf.new(@default_params.merge(:date => 'someday'))
88
- ralf.date.should be_nil
89
- }.should raise_error(Ralf::InvalidDate, "someday is an invalid value.")
179
+ ralf = Ralf.new(@valid_options.merge(:range => 'someday'))
180
+ ralf.range.should be_nil
181
+ }.should raise_error(Ralf::Config::RangeError, "invalid expression 'someday'")
90
182
  end
91
183
 
92
184
  it "should accept a range of 2 dates" do
93
- ralf = Ralf.new(@default_params.merge(:date => nil, :range => ['2010-02-10', '2010-02-12']))
94
- ralf.range.to_s.should eql('2010-02-10..2010-02-12')
185
+ YAML.should_not_receive(:load_file)
186
+ ralf = Ralf.new(@valid_options.merge(:range => ['2010-02-10', '2010-02-12']))
187
+ ralf.config.range.to_s.should eql('2010-02-10..2010-02-12')
188
+ end
189
+
190
+ it "should raise error for range array with more than 2 items" do
191
+ YAML.should_not_receive(:load_file)
192
+ lambda {
193
+ ralf = Ralf.new(@valid_options.merge(:range => ['2010-02-10', '2010-02-12', '2010-02-13']))
194
+ }.should raise_error(ArgumentError, 'too many range items')
95
195
  end
96
196
 
97
- it "should accept a range starting with 1 date" do
98
- Date.should_receive(:today).any_number_of_times.and_return(Date.strptime('2010-02-17'))
99
- ralf = Ralf.new(@default_params.merge(:date => nil, :range => '2010-02-10'))
100
- ralf.range.to_s.should eql('2010-02-10..2010-02-17')
197
+ it "should treat a range with 1 date as a single date" do
198
+ YAML.should_not_receive(:load_file)
199
+ ralf = Ralf.new(@valid_options.merge(:range => '2010-02-10'))
200
+ ralf.config.range.to_s.should eql('2010-02-10..2010-02-10')
201
+ end
101
202
 
102
- ralf = Ralf.new(@default_params.merge(:date => nil, :range => ['2010-02-10']))
103
- ralf.range.to_s.should eql('2010-02-10..2010-02-17')
203
+ it "should accept a range array with 1 date" do
204
+ YAML.should_not_receive(:load_file)
205
+ ralf = Ralf.new(@valid_options.merge(:range => ['2010-02-10']))
206
+ ralf.config.range.to_s.should eql('2010-02-10..2010-02-10')
104
207
  end
105
208
 
106
209
  it "should accept a range defined by words" do
107
- Date.should_receive(:today).any_number_of_times.and_return(Date.strptime('2010-02-17'))
108
- Chronic.should_receive(:parse).once.with('2 days ago', {:guess=>false, :context=>:past}).and_return(
109
- Chronic::Span.new(Time.parse('Mon Feb 15 00:00:00 +0100 2010'),Time.parse('Tue Feb 16 00:00:00 +0100 2010'))
110
- )
111
-
112
- ralf = Ralf.new(@default_params.merge(:date => nil, :range => '2 days ago'))
113
- ralf.range.to_s.should eql('2010-02-15..2010-02-17')
210
+ YAML.should_not_receive(:load_file)
211
+ Time.should_receive(:now).any_number_of_times.and_return(Time.parse('Mon Feb 17 09:41:00 +0100 2010'))
212
+ ralf = Ralf.new(@valid_options.merge(:range => '2 days ago'))
213
+ ralf.config.range.to_s.should eql('2010-02-15..2010-02-15')
114
214
  end
115
215
 
116
216
  it "should accept a month and convert it to a range" do
117
- ralf = Ralf.new(@default_params.merge(:date => nil, :range => 'january'))
118
- ralf.range.to_s.should eql('2010-01-01..2010-01-31')
217
+ YAML.should_not_receive(:load_file)
218
+ Time.should_receive(:now).any_number_of_times.and_return(Time.parse('Mon Feb 17 09:41:00 +0100 2010'))
219
+ ralf = Ralf.new(@valid_options.merge(:range => 'january'))
220
+ ralf.config.range.to_s.should eql('2010-01-01..2010-01-31')
119
221
  end
120
-
121
- end
122
-
123
- describe "Handle Buckets" do
124
-
125
- before(:each) do
126
- @ralf = Ralf.new(@default_params)
127
- @bucket1 = {:name => 'bucket1'}
128
- @bucket1.should_receive(:logging_info).any_number_of_times.and_return({ :enabled => true, :targetprefix => "log/access_log-", :targetbucket => @bucket1[:name] })
129
- @bucket1.should_receive(:name).any_number_of_times.and_return(@bucket1[:name])
130
- @bucket2 = {:name => 'bucket2'}
131
- @bucket2.should_receive(:logging_info).any_number_of_times.and_return({ :enabled => false, :targetprefix => "log/", :targetbucket => @bucket2[:name] })
132
- @bucket2.should_receive(:name).any_number_of_times.and_return(@bucket2[:name])
222
+
223
+ it "should allow 'this month' with base 'yesterday'" do
224
+ YAML.should_not_receive(:load_file)
225
+ Time.should_receive(:now).any_number_of_times.and_return(Time.parse('Sat May 01 16:31:00 +0100 2010'))
226
+ ralf = Ralf.new(@valid_options.merge(:range => 'this month', :now => 'yesterday'))
227
+ ralf.config.range.to_s.should eql('2010-04-01..2010-04-30')
133
228
  end
134
-
135
- it "should find buckets with logging enabled" do
136
- @ralf.s3.should_receive(:buckets).once.and_return([@bucket1, @bucket2])
137
-
138
- @ralf.find_buckets_with_logging.should eql([@bucket1, @bucket2])
139
- @ralf.buckets_with_logging.should eql([@bucket1])
229
+
230
+ it "should support setting range first then change now (1st day of month)" do
231
+ YAML.should_not_receive(:load_file)
232
+ Time.should_receive(:now).any_number_of_times.and_return(Time.parse('Sat May 01 16:31:00 +0100 2010'))
233
+ ralf = Ralf.new(@valid_options.merge(:range => 'this month'))
234
+ ralf.config.range.to_s.should eql('2010-05-01..2010-05-01')
235
+ ralf.config.merge!(:now => 'yesterday')
236
+ ralf.config.range.to_s.should eql('2010-04-01..2010-04-30')
140
237
  end
141
238
 
142
- it "should return the new organized path" do
143
- @key1.should_receive(:name).and_return(@key1[:name])
144
- @ralf.s3_organized_log_file(@bucket1, @key1).should eql('log/2010/02/10/access_log-2010-02-10-00-05-32-ZDRFGTCKUYVJCT')
239
+ it "should support setting range first then change now" do
240
+ YAML.should_not_receive(:load_file)
241
+ Time.should_receive(:now).any_number_of_times.and_return(Time.parse('Sat May 08 16:31:00 +0100 2010'))
242
+ ralf = Ralf.new(@valid_options.merge(:range => 'this month'))
243
+ ralf.config.range.to_s.should eql('2010-05-01..2010-05-07')
244
+ ralf.config.merge!(:now => '2010-05-06')
245
+ ralf.config.range.to_s.should eql('2010-05-01..2010-05-06')
145
246
  end
146
247
 
147
- describe "logging" do
148
-
149
- before(:each) do
150
- @key1.should_receive(:name).any_number_of_times.and_return(@key1[:name])
151
- @key2.should_receive(:name).any_number_of_times.and_return(@key2[:name])
152
- @key1.should_receive(:data).any_number_of_times.and_return(@key1[:data])
153
- @key2.should_receive(:data).any_number_of_times.and_return(@key2[:data])
154
- end
155
-
156
- it "should save logging to disk" do
157
- @bucket1.should_receive(:keys).any_number_of_times.and_return([@key1, @key2])
158
-
159
- File.should_receive(:makedirs).twice.with('/Users/berl/S3/bucket1/log/2010/02/10').and_return(true)
160
- File.should_receive(:exists?).once.with( '/Users/berl/S3/bucket1/log/2010/02/10/access_log-2010-02-10-00-07-28-EFREUTERGRSGDH').and_return(true)
161
- File.should_receive(:exists?).once.with( '/Users/berl/S3/bucket1/log/2010/02/10/access_log-2010-02-10-00-05-32-ZDRFGTCKUYVJCT').and_return(false)
162
- File.should_receive(:open).once.with( '/Users/berl/S3/bucket1/log/2010/02/10/access_log-2010-02-10-00-05-32-ZDRFGTCKUYVJCT', "w").and_return(true)
163
-
164
- @ralf.save_logging_to_local_disk(@bucket1, '2010-02-10').should eql([@key1, @key2])
165
- end
166
-
167
- it "should save logging for range to disk" do
168
- @bucket1.should_receive(:keys).any_number_of_times.and_return([@key1, @key2], [@key3], [])
169
- @key3.should_receive(:name).any_number_of_times.and_return(@key3[:name])
170
- @key3.should_receive(:data).any_number_of_times.and_return(@key3[:data])
171
-
172
- @ralf.date = nil
173
- @ralf.range = ['2010-02-10', '2010-02-12']
248
+ end
174
249
 
175
- File.should_receive(:exists?).once.with( '/Users/berl/S3/bucket1/log/2010/02/10/access_log-2010-02-10-00-05-32-ZDRFGTCKUYVJCT').and_return(false)
176
- File.should_receive(:exists?).once.with( '/Users/berl/S3/bucket1/log/2010/02/10/access_log-2010-02-10-00-07-28-EFREUTERGRSGDH').and_return(true)
177
- File.should_receive(:exists?).once.with( '/Users/berl/S3/bucket1/log/2010/02/11/access_log-2010-02-11-00-09-32-SDHTFTFHDDDDDH').and_return(false)
178
- File.should_receive(:open).once.with( '/Users/berl/S3/bucket1/log/2010/02/10/access_log-2010-02-10-00-05-32-ZDRFGTCKUYVJCT', "w").and_return(true)
179
- File.should_receive(:open).once.with( '/Users/berl/S3/bucket1/log/2010/02/11/access_log-2010-02-11-00-09-32-SDHTFTFHDDDDDH', "w").and_return(true)
250
+ describe "Handle Buckets" do
180
251
 
181
- @ralf.save_logging(@bucket1).class.should eql(Range)
252
+ it "should download, merge and convert logfiles" do
253
+ YAML.should_not_receive(:load_file)
254
+ @s3_mock.should_receive(:bucket).any_number_of_times do |name|
255
+ @example_buckets[name]
182
256
  end
183
-
184
- it "should save logging if a different targetbucket is given" do
185
- @ralf.s3.should_receive(:bucket).and_return(@bucket1)
186
- @bucket3 = {:name => 'bucket3'}
187
- @bucket3.should_receive(:logging_info).any_number_of_times.and_return({ :enabled => false, :targetprefix => "log/", :targetbucket => 'bucket1' })
188
- @bucket3.should_receive(:name).any_number_of_times.and_return(@bucket3[:name])
189
- @bucket1.should_receive(:keys).any_number_of_times.and_return([@key1, @key2])
190
-
191
- @ralf.save_logging_to_local_disk(@bucket3, '2010-02-10').should eql([@key1, @key2])
257
+
258
+ File.stub(:makedirs)
259
+ ralf = Ralf.new(@valid_options.merge(:cache_dir => '/var/log/s3/cache/:bucket',
260
+ :output_file => '/var/log/s3/:bucket.log',
261
+ :buckets => 'test1',
262
+ :range => ['2010-02-01', '2010-02-12']))
263
+
264
+ alfio = StringIO.new
265
+ File.should_receive(:open).with('/var/log/s3/test1.log.alf', 'w').and_yield(alfio)
266
+
267
+ Ralf.should_receive(:download_logs).any_number_of_times do |bucket, date, dir|
268
+ expected_bucket = Ralf::Bucket.new(@example_buckets['test1'])
269
+ [ :name, :logging_enabled?, :targetbucket, :targetprefix ].each do |attr|
270
+ bucket.send(attr).should eql(expected_bucket.send(attr))
271
+ end
272
+ ralf.config.range.should include(date)
273
+ dir.should eql("/var/log/s3/cache/test1")
274
+
275
+ log_files = []
276
+ case date
277
+ when Date.new(2010,02,10)
278
+ log_files << '/var/log/s3/cache/test1/2010-02-10-00-05-32-ZDRFGTCKUYVJCT'
279
+ when Date.new(2010,02,11)
280
+ log_files << '/var/log/s3/cache/test1/2010-02-11-00-05-32-ZDRFGTCKUYVJCT'
281
+ end
282
+ log_files
192
283
  end
193
284
 
285
+ Ralf.should_receive(:convert_to_common_log_format).with(
286
+ "/var/log/s3/test1.log.alf", "/var/log/s3/test1.log")
287
+
288
+ LogMerge::Merger.should_receive(:merge).with(alfio,
289
+ *@example_buckets['test1'].keys.map{|k| "/var/log/s3/cache/test1/#{k.name.gsub('logs/', '')}"})
290
+
291
+ ralf.run()
194
292
  end
195
-
196
- it "should merge all logs" do
197
- out_string = StringIO.new
198
-
199
- Dir.should_receive(:glob).with('/Users/berl/S3/bucket1/log/2010/02/10/access_log-2010-02-10*').and_return(
200
- ['/Users/berl/S3/bucket1/log/2010/02/10/access_log-2010-02-10-00-05-32-ZDRFGTCKUYVJCT',
201
- '/Users/berl/S3/bucket1/log/2010/02/10/access_log-2010-02-10-00-07-28-EFREUTERGRSGDH'])
202
-
203
- File.should_receive(:open).with('/Users/berl/S3/s3_combined_bucket1_2010-02-10.alf', "w").and_yield(out_string)
204
-
205
- LogMerge::Merger.should_receive(:merge).with(
206
- out_string,
207
- '/Users/berl/S3/bucket1/log/2010/02/10/access_log-2010-02-10-00-05-32-ZDRFGTCKUYVJCT',
208
- '/Users/berl/S3/bucket1/log/2010/02/10/access_log-2010-02-10-00-07-28-EFREUTERGRSGDH'
209
- )
210
-
211
- @ralf.merge_to_combined(@bucket1)
212
-
213
- out_string.string.should eql('')
214
- end
215
-
216
- it "should save logs which have a targetprefix containing a '/'" do
217
- @ralf.local_log_dirname(@bucket1).should eql('/Users/berl/S3/bucket1/log/2010/02/10')
218
- @ralf.local_log_dirname(@bucket2).should eql('/Users/berl/S3/bucket2/log/2010/02/10')
219
- end
220
-
221
- it "should save to a subdir when a out_seperator is given" do
222
- @ralf.local_log_dirname(@bucket1).should eql('/Users/berl/S3/bucket1/log/2010/02/10')
223
-
224
- @ralf.out_seperator = ':year/w:week'
225
- @ralf.local_log_dirname(@bucket1).should eql('/Users/berl/S3/bucket1/log/2010/w06')
293
+
294
+ it "should raise error when output_file option is missing" do
295
+ YAML.should_not_receive(:load_file)
296
+ ralf = Ralf.new(@aws_credentials.merge(:config_file => ''))
297
+ lambda {
298
+ ralf.run
299
+ }.should raise_error(ArgumentError, "--output-file required")
226
300
  end
227
-
228
- it "should get the proper directories" do
229
- @key1.should_receive(:name).and_return('log/access_log-2010-02-10-00-05-32-ZDRFGTCKUYVJCT')
230
- @ralf.local_log_file_basename_prefix(@bucket1).should eql('access_log-')
231
- @ralf.local_log_file_basename(@bucket1, @key1).should eql('access_log-2010-02-10-00-05-32-ZDRFGTCKUYVJCT')
232
- @ralf.local_log_dirname(@bucket1).should eql('/Users/berl/S3/bucket1/log/2010/02/10')
233
-
234
- @key1.should_receive(:name).and_return('log/2010-02-10-00-05-32-ZDRFGTCKUYVJCT')
235
- @ralf.local_log_file_basename_prefix(@bucket2).should eql('')
236
- @ralf.local_log_file_basename(@bucket2, @key1).should eql('2010-02-10-00-05-32-ZDRFGTCKUYVJCT')
237
- @ralf.local_log_dirname(@bucket2).should eql('/Users/berl/S3/bucket2/log/2010/02/10')
301
+
302
+ it "should raise error when output_file option requires :bucket variable" do
303
+ YAML.should_not_receive(:load_file)
304
+ ralf = Ralf.new(@aws_credentials.merge(:output_file => '/tmp/ralf/ralf.log', :config_file => ''))
305
+ lambda {
306
+ ralf.run
307
+ }.should raise_error(ArgumentError, "--output-file requires ':bucket' variable")
238
308
  end
239
309
 
240
310
  end
241
311
 
242
- describe "Conversion" do
243
-
244
- before(:each) do
245
- @ralf = Ralf.new(@default_params)
246
- @bucket1 = {:name => 'bucket1'}
247
- @bucket1.should_receive(:name).any_number_of_times.and_return('bucket1')
248
- end
249
-
250
- it "should convert the alf to clf" do
251
- File.should_receive(:open).once.with("/Users/berl/S3/s3_combined_bucket1_2010-02-10.log", "w").and_return(File)
252
- File.should_receive(:open).once.with("/Users/berl/S3/s3_combined_bucket1_2010-02-10.alf", "r").and_return(File)
253
- File.should_receive(:close).once.and_return(true)
254
- @ralf.convert_alt_to_clf(@bucket1).should eql(true)
255
- end
256
-
257
- it "should find the proper values in a line" do
258
- [ [
259
- '2cf7e6b06335c0689c6d29163df5bb001c96870cd78609e3845f1ed76a632621 assets.staging.kerkdienstgemist.nl [10/Feb/2010:07:17:01 +0000] 10.32.219.38 3272ee65a908a7677109fedda345db8d9554ba26398b2ca10581de88777e2b61 784FD457838EFF42 REST.GET.ACL - "GET /?acl HTTP/1.1" 200 - 1384 - 399 - "-" "Jakarta Commons-HttpClient/3.0" - ',
260
- '10.32.219.38 - 3272ee65a908a7677109fedda345db8d9554ba26398b2ca10581de88777e2b61 [10/Feb/2010:07:17:01 +0000] "GET /?acl HTTP/1.1" 200 1384 "-" "Jakarta Commons-HttpClient/3.0"'
261
- ],[
262
- '2cf7e6b06335c0689c6d29163df5bb001c96870cd78609e3845f1ed76a632621 assets.staging.kerkdienstgemist.nl [10/Feb/2010:07:17:02 +0000] 10.32.219.38 3272ee65a908a7677109fedda345db8d9554ba26398b2ca10581de88777e2b61 6E239BC5A4AC757C SOAP.PUT.OBJECT logs/2010-02-10-07-17-02-F6EFD00DAB9A08B6 "POST /soap/ HTTP/1.1" 200 - 797 686 63 31 "-" "Axis/1.3" -',
263
- '10.32.219.38 - 3272ee65a908a7677109fedda345db8d9554ba26398b2ca10581de88777e2b61 [10/Feb/2010:07:17:02 +0000] "POST /soap/ HTTP/1.1" 200 797 "-" "Axis/1.3"'
264
- ],[
265
- '2cf7e6b06335c0689c6d29163df5bb001c96870cd78609e3845f1ed76a632621 assets.staging.kerkdienstgemist.nl [10/Feb/2010:07:24:40 +0000] 10.217.37.15 - 0B76C90B3634290B REST.GET.ACL - "GET /?acl HTTP/1.1" 307 TemporaryRedirect 488 - 7 - "-" "Jakarta Commons-HttpClient/3.0" - ',
266
- '10.217.37.15 - - [10/Feb/2010:07:24:40 +0000] "GET /?acl HTTP/1.1" 307 488 "-" "Jakarta Commons-HttpClient/3.0"'
267
- ] ].each do |alf,clf|
268
- @ralf.translate_to_clf(alf).should eql(clf)
269
- end
312
+ describe "Conversion of Amazon Log Format to Common Log Format" do
313
+
314
+ it "should convert output files to common_log_format" do
315
+ input_log = StringIO.new
316
+ input_log.string = <<EOF_INPUT
317
+ 2cf7e6b06335c0689c6d29163df5bb001c96870cd78609e3845f1ed76a632621 assets.staging.kerkdienstgemist.nl [10/Feb/2010:07:17:01 +0000] 10.32.219.38 3272ee65a908a7677109fedda345db8d9554ba26398b2ca10581de88777e2b61 784FD457838EFF42 REST.GET.ACL - "GET /?acl HTTP/1.1" 200 - 1384 - 399 - "-" "Jakarta Commons-HttpClient/3.0" -
318
+ 2cf7e6b06335c0689c6d29163df5bb001c96870cd78609e3845f1ed76a632621 assets.staging.kerkdienstgemist.nl [10/Feb/2010:07:17:02 +0000] 10.32.219.38 3272ee65a908a7677109fedda345db8d9554ba26398b2ca10581de88777e2b61 6E239BC5A4AC757C SOAP.PUT.OBJECT logs/2010-02-10-07-17-02-F6EFD00DAB9A08B6 "POST /soap/ HTTP/1.1" 200 - 797 686 63 31 "-" "Axis/1.3" -
319
+ 2cf7e6b06335c0689c6d29163df5bb001c96870cd78609e3845f1ed76a632621 assets.staging.kerkdienstgemist.nl [10/Feb/2010:07:24:40 +0000] 10.217.37.15 - 0B76C90B3634290B REST.GET.ACL - "GET /?acl HTTP/1.1" 307 TemporaryRedirect 488 - 7 - "-" "Jakarta Commons-HttpClient/3.0" -
320
+ EOF_INPUT
321
+
322
+ clf_log =<<EOF_OUTPUT
323
+ 10.32.219.38 - 3272ee65a908a7677109fedda345db8d9554ba26398b2ca10581de88777e2b61 [10/Feb/2010:07:17:01 +0000] "GET /?acl HTTP/1.1" 200 1384 "-" "Jakarta Commons-HttpClient/3.0"
324
+ 10.32.219.38 - 3272ee65a908a7677109fedda345db8d9554ba26398b2ca10581de88777e2b61 [10/Feb/2010:07:17:02 +0000] "POST /soap/ HTTP/1.1" 200 797 "-" "Axis/1.3"
325
+ 10.217.37.15 - - [10/Feb/2010:07:24:40 +0000] "GET /?acl HTTP/1.1" 307 488 "-" "Jakarta Commons-HttpClient/3.0"
326
+ EOF_OUTPUT
327
+
328
+ output_log = StringIO.new
329
+
330
+ File.should_receive(:open).with('input_file', 'r').and_yield(input_log)
331
+ File.should_receive(:open).with('output_file', 'w').and_return(output_log)
332
+
333
+ Ralf.convert_to_common_log_format('input_file', 'output_file')
334
+ output_log.string.should eql(clf_log)
270
335
  end
271
336
 
272
337
  it "should mark invalid lines with '# ERROR: '" do
273
- @ralf.translate_to_clf('An invalid line in the logfile').should match(/^# ERROR/)
338
+ $stderr = StringIO.new
339
+ invalid_line = "this is an invalid log line"
340
+ Ralf.translate_to_clf(invalid_line)
341
+ $stderr.string.should eql("# ERROR: #{invalid_line}\n")
274
342
  end
275
343
 
276
344
  end
277
-
345
+
278
346
  end
data/spec/spec.opts ADDED
@@ -0,0 +1,5 @@
1
+ --colour
2
+ --format specdoc
3
+ --loadby mtime
4
+ --drb
5
+ --backtrace
@@ -0,0 +1,24 @@
1
+ require 'rubygems'
2
+ require 'right_aws' # load RightHttpConnection before FakeWeb otherwise we get buggy
3
+ require 'fakeweb'
4
+
5
+ require 'spec/autorun'
6
+
7
+ Spec::Runner.configure do |config|
8
+ # == Notes
9
+ #
10
+ # For more information take a look at Spec::Runner::Configuration and Spec::Runner
11
+
12
+ def load_example_bucket_mocks
13
+ buckets = YAML.load(File.open(File.join(File.dirname(__FILE__), 'fixtures', 'example_buckets.yaml')))
14
+ buckets = buckets.inject({}) do |memo, info|
15
+ info[:keys].map! do |key|
16
+ mock(key[:name], key)
17
+ end
18
+ memo.merge!(info[:name] => mock(info[:name], info))
19
+ memo
20
+ end
21
+ buckets
22
+ end
23
+ end
24
+
@@ -0,0 +1,4 @@
1
+
2
+ FakeWeb.allow_net_connect = false
3
+
4
+ FakeWeb.register_uri(:any, 'https://s3.amazonaws.com:443', :body => '')