ralf 0.1.5 → 1.0.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/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 => '')