appstats 0.0.13 → 0.0.14

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,123 @@
1
+ require 'spec_helper'
2
+
3
+ module Appstats
4
+ describe Context do
5
+
6
+ before(:each) do
7
+ @context = Appstats::Context.new
8
+ @time = Time.parse('2010-01-02 10:20:30')
9
+ end
10
+
11
+ describe "#initialize" do
12
+
13
+ it "should set context_key to nil" do
14
+ @context.context_key.should == nil
15
+ end
16
+
17
+ it "should set context_value to nil" do
18
+ @context.context_value.should == nil
19
+ end
20
+
21
+ it "should set context_int to nil" do
22
+ @context.context_int.should == nil
23
+ end
24
+
25
+ it "should set context_float to nil" do
26
+ @context.context_float.should == nil
27
+ end
28
+
29
+ it "should set on constructor" do
30
+ context = Appstats::Context.new(:context_key => 'a', :context_value => "b", :context_int => 1, :context_float => 1.3)
31
+ context.context_key.should == 'a'
32
+ context.context_value.should == 'b'
33
+ context.context_int.should == nil
34
+ context.context_float.should == nil
35
+ end
36
+
37
+ end
38
+
39
+ describe "#context_int" do
40
+
41
+ it "should be nil if not an int" do
42
+ @context.context_int.should == nil
43
+ @context.context_value = "1"
44
+ @context.context_int.should == 1
45
+
46
+ @context.context_value = "2"
47
+ @context.context_int.should == 2
48
+
49
+ @context.context_value = "c"
50
+ @context.context_int.should == nil
51
+
52
+ @context.context_value = nil
53
+ @context.context_int.should == nil
54
+
55
+ end
56
+
57
+ end
58
+
59
+ describe "#context_float" do
60
+
61
+ it "should be nil if not an int" do
62
+ @context.context_float.should == nil
63
+ @context.context_value = "1"
64
+ @context.context_float.should == 1.0
65
+
66
+ @context.context_value = "2.1"
67
+ @context.context_float.should == 2.1
68
+
69
+ @context.context_value = "c"
70
+ @context.context_float.should == nil
71
+
72
+ @context.context_value = nil
73
+ @context.context_float.should == nil
74
+
75
+ end
76
+ end
77
+
78
+ describe "#entry" do
79
+
80
+ before(:each) do
81
+ @entry = Appstats::Entry.new(:action => "a")
82
+ @entry.save.should == true
83
+ end
84
+
85
+ it "should have an entry" do
86
+ @context.entry.should == nil
87
+ @context.entry = @entry
88
+ @context.save.should == true
89
+ @context.reload
90
+ @context.entry.should == @entry
91
+
92
+ @context = Context.last
93
+ @context.entry.should == @entry
94
+ end
95
+
96
+ end
97
+
98
+ describe "#to_s" do
99
+
100
+ before(:each) do
101
+ @context = Appstats::Context.new
102
+ end
103
+
104
+ it "should return no context if no key" do
105
+ @context.to_s.should == 'No Context'
106
+ @context.context_key = ''
107
+ @context.to_s.should == 'No Context'
108
+ end
109
+
110
+ it "should return the context_key name if no date" do
111
+ @context.context_key = "Blah"
112
+ @context.to_s.should == 'Blah[]'
113
+ end
114
+
115
+ it "should return context_key and context_value if available" do
116
+ @context.context_key = "More Blah"
117
+ @context.context_value = "true"
118
+ @context.to_s.should == "More Blah[true]"
119
+ end
120
+
121
+ end
122
+ end
123
+ end
@@ -3,32 +3,62 @@ require 'spec_helper'
3
3
  module Appstats
4
4
  describe Entry do
5
5
 
6
+ before(:each) do
7
+ @time = Time.parse('2010-01-02 10:20:30')
8
+ @entry = Appstats::Entry.new
9
+ Time.stub!(:now).and_return(@time)
10
+ end
11
+
6
12
  describe "#initialize" do
7
13
 
8
- before(:each) do
9
- @entry = Appstats::Entry.new
10
- end
11
-
12
- it "should set entry_type to nil" do
13
- @entry.entry_type.should == nil
14
+ it "should set action to nil" do
15
+ @entry.action.should == nil
14
16
  end
15
17
 
16
- it "should set name to nil" do
17
- @entry.name.should == nil
18
+ it "should set occurred_at to nil" do
19
+ @entry.occurred_at.should == nil
18
20
  end
19
-
20
- it "should set description to nil" do
21
- @entry.description.should == nil
21
+
22
+ it "should set raw_entry to nil" do
23
+ @entry.raw_entry.should == nil
22
24
  end
23
25
 
24
26
  it "should set on constructor" do
25
- entry = Appstats::Entry.new(:entry_type => 'a', :name => 'b', :description => 'c')
26
- entry.entry_type.should == 'a'
27
- entry.name.should == 'b'
28
-
27
+ entry = Appstats::Entry.new(:action => 'a', :occurred_at => @time, :raw_entry => 'b')
28
+ entry.action.should == 'a'
29
+ entry.occurred_at.should == @time
30
+ entry.raw_entry.should == 'b'
29
31
  end
30
32
 
31
33
  end
34
+
35
+ describe "#contexts" do
36
+
37
+ it "should have none by default" do
38
+ @entry.contexts.size.should == 0
39
+ end
40
+
41
+ it "should be able add contexts" do
42
+ context = Appstats::Context.new(:context_key => 'a', :context_value => 'one')
43
+ context.save.should == true
44
+ @entry.contexts<< context
45
+ @entry.save.should == true
46
+ @entry.reload
47
+ @entry.contexts.size.should == 1
48
+ @entry.contexts[0].should == context
49
+ end
50
+
51
+ it "should alphabetize them" do
52
+ zzz = Appstats::Context.create(:context_key => 'zzz', :context_value => 'one')
53
+ aaa = Appstats::Context.create(:context_key => 'aaa', :context_value => 'one')
54
+ @entry.contexts<< zzz
55
+ @entry.contexts<< aaa
56
+ @entry.save.should == true
57
+ @entry.reload
58
+ @entry.contexts.should == [aaa,zzz]
59
+ end
60
+
61
+ end
32
62
 
33
63
  describe "#to_s" do
34
64
 
@@ -36,9 +66,124 @@ module Appstats
36
66
  @entry = Appstats::Entry.new
37
67
  end
38
68
 
39
- it "should run the test" do
40
- @entry.to_s.should == 'Entry [type],[name],[description]'
69
+ it "should return no entry if no action" do
70
+ @entry.to_s.should == 'No Entry'
71
+ @entry.action = ''
72
+ @entry.to_s.should == 'No Entry'
73
+ end
74
+
75
+ it "should return the action name if no date" do
76
+ @entry.action = "Blah"
77
+ @entry.to_s.should == 'Blah'
78
+ end
79
+
80
+ it "should return action and date if available" do
81
+ @entry.action = "More Blah"
82
+ @entry.occurred_at = @time
83
+ @entry.to_s.should == "More Blah at 2010-01-02 10:20:30"
41
84
  end
85
+
42
86
  end
87
+
88
+ describe "#load_from_logger_file" do
89
+
90
+ before(:each) do
91
+ @before_count = Entry.count
92
+ Appstats::Logger.reset
93
+ Time.stub!(:now).and_return(Time.parse('2010-09-21 23:15:20'))
94
+ end
95
+
96
+ after(:each) do
97
+ File.delete(Appstats::Logger.filename) if File.exists?(Appstats::Logger.filename)
98
+ end
99
+
100
+ it "should handle nil" do
101
+ Entry.load_from_logger_file(nil).should == false
102
+ Entry.count.should == @before_count
103
+ Entry.count.should == @before_count
104
+ end
105
+
106
+ it "should handle unknown files" do
107
+ File.exists?("should_not_exist.txt").should == false
108
+ Entry.load_from_logger_file("should_not_exist.txt").should == false
109
+ Entry.count.should == @before_count
110
+ end
111
+
112
+ it "should handle appstat files" do
113
+ Appstats::Logger.entry("test_action")
114
+ Appstats::Logger.entry("another_test_action")
115
+ Entry.load_from_logger_file(Appstats::Logger.filename).should == true
116
+ Entry.count.should == @before_count + 2
117
+ Entry.last.action.should == "another_test_action"
118
+ end
119
+
120
+ end
121
+
122
+
123
+ describe "#load_from_logger_entry" do
124
+
125
+ before(:each) do
126
+ @before_count = Entry.count
127
+ end
128
+
129
+ it "should handle nil" do
130
+ Entry.load_from_logger_entry(nil).should == false
131
+ Entry.count.should == @before_count
132
+
133
+ Entry.load_from_logger_entry("").should == false
134
+ Entry.count.should == @before_count
135
+ end
136
+
137
+ it "should create an unknown for unknown entries" do
138
+ entry = Entry.load_from_logger_entry("blah")
139
+ Entry.count.should == @before_count + 1
140
+ entry.action.should == "UNKNOWN_ACTION"
141
+ entry.raw_entry.should == "blah"
142
+ entry.occurred_at.should == nil
143
+ end
144
+
145
+ it "should understand an entry without contexts" do
146
+ entry = Entry.load_from_logger_entry("0.0.14 setup[:,=,-n] 2010-09-21 23:15:20 action=address_search")
147
+ Entry.count.should == @before_count + 1
148
+ entry.action.should == "address_search"
149
+ entry.raw_entry.should == "0.0.14 setup[:,=,-n] 2010-09-21 23:15:20 action=address_search"
150
+ entry.occurred_at.should == Time.parse("2010-09-21 23:15:20")
151
+ end
152
+
153
+ it "should understand contexts" do
154
+ entry = Entry.load_from_logger_entry("0.0.14 setup[:,=,-n] 2010-09-21 23:15:20 action=address_filter : app_name=Market : server=Live")
155
+ Entry.count.should == @before_count + 1
156
+ entry.action.should == "address_filter"
157
+ entry.raw_entry.should == "0.0.14 setup[:,=,-n] 2010-09-21 23:15:20 action=address_filter : app_name=Market : server=Live"
158
+ entry.occurred_at.should == Time.parse("2010-09-21 23:15:20")
159
+ entry.contexts.size.should == 2
160
+ entry.contexts[0].context_key = "app_name"
161
+ entry.contexts[0].context_value = "Market"
162
+ entry.contexts[1].context_key = "server"
163
+ entry.contexts[1].context_value = "Live"
164
+ end
165
+
166
+ end
167
+
168
+ describe "#log_collector" do
169
+
170
+ before(:each) do
171
+ @log_collector = Appstats::LogCollector.new(:host => "a")
172
+ @log_collector.save.should == true
173
+ end
174
+
175
+ it "should have a log_collector" do
176
+ @entry.log_collector.should == nil
177
+ @entry.log_collector = @log_collector
178
+ @entry.save.should == true
179
+ @entry.reload
180
+ @entry.log_collector.should == @log_collector
181
+
182
+ @entry = Entry.last
183
+ @entry.log_collector.should == @log_collector
184
+ end
185
+
186
+ end
187
+
43
188
  end
44
189
  end
@@ -0,0 +1,284 @@
1
+ require 'spec_helper'
2
+
3
+ module Appstats
4
+ describe LogCollector do
5
+
6
+ before(:each) do
7
+ LogCollector.delete_all
8
+ @log_collector = Appstats::LogCollector.new
9
+ @login = { :host => "myhost.localnet", :user => "deployer", :password => "pass" }
10
+ @login2 = { :host => "yourhost.localnet", :user => "deployer", :password => "ssap" }
11
+ @logins = [@login2, @login]
12
+ end
13
+
14
+ after(:each) do
15
+ LogCollector.all.each do |log_collector|
16
+ File.delete(log_collector.local_filename) if File.exists?(log_collector.local_filename)
17
+ end
18
+ end
19
+
20
+ def simple_path(local_path_to_filename)
21
+ File.expand_path("#{File.dirname(__FILE__)}/#{local_path_to_filename}")
22
+ end
23
+
24
+ describe "#initialize" do
25
+
26
+ it "should set host to nil" do
27
+ @log_collector.host.should == nil
28
+ end
29
+
30
+ it "should set filename to nil" do
31
+ @log_collector.filename.should == nil
32
+ end
33
+
34
+ it "should set status to unprocessed" do
35
+ @log_collector.status.should == nil
36
+ end
37
+
38
+ it "should set on constructor" do
39
+ log_collector = Appstats::LogCollector.new(:host => 'a', :filename => 'b', :status => 'c')
40
+ log_collector.host.should == 'a'
41
+ log_collector.filename.should == 'b'
42
+ log_collector.status.should == 'c'
43
+ end
44
+
45
+ end
46
+
47
+ describe "#find_remote_files" do
48
+
49
+ before(:each) do
50
+ @before_count = LogCollector.count
51
+ end
52
+
53
+ it "should log all transactions" do
54
+ ssh = mock(Net::SSH)
55
+ Net::SSH.should_receive(:start).with("myhost.localnet","deployer",{ :password => "pass"}).and_yield(ssh)
56
+ ssh.should_receive(:exec!).with("cd /my/path/log && ls | grep mystats").and_return("mystats1\nmystats2")
57
+
58
+ Appstats.should_receive(:log).with(:info, "Looking for logs in [deployer@myhost.localnet:/my/path/log] labelled [mystats]")
59
+ Appstats.should_receive(:log).with(:info, "About to analyze 2 file(s).")
60
+ Appstats.should_receive(:log).with(:info, " - deployer@myhost.localnet:/my/path/log/mystats1")
61
+ Appstats.should_receive(:log).with(:info, " - deployer@myhost.localnet:/my/path/log/mystats2")
62
+ Appstats.should_receive(:log).with(:info, "Loaded 2 file(s).")
63
+ LogCollector.find_remote_files(@login,"/my/path/log","mystats").should == 2
64
+ end
65
+
66
+ it "should talk to remote server" do
67
+ ssh = mock(Net::SSH)
68
+ Net::SSH.should_receive(:start).with("myhost.localnet","deployer",{ :password => "pass"}).and_yield(ssh)
69
+ ssh.should_receive(:exec!).with("cd /my/path/log && ls | grep mystats").and_return("mystats1\nmystats2")
70
+
71
+ LogCollector.find_remote_files(@login,"/my/path/log","mystats").should == 2
72
+ LogCollector.count.should == @before_count + 2
73
+
74
+ log_collector = LogCollector.last
75
+ log_collector.host.should == "myhost.localnet"
76
+ log_collector.filename.should == "/my/path/log/mystats2"
77
+ log_collector.status.should == "unprocessed"
78
+ end
79
+
80
+ it "should fail silently for bad connections" do
81
+ Net::SSH.should_receive(:start).with("myhost.localnet","deployer",{ :password => "pass"}).and_raise("Some bad message")
82
+ Appstats.should_receive(:log).with(:info, "Looking for logs in [deployer@myhost.localnet:/my/path/log] labelled [mystats]")
83
+ Appstats.should_receive(:log).with(:error,"Something bad occurred during Appstats::LogCollector#find_remote_files")
84
+ Appstats.should_receive(:log).with(:error,"Some bad message")
85
+ LogCollector.find_remote_files(@login,"/my/path/log","mystats").should == 0
86
+ end
87
+
88
+ end
89
+
90
+ describe "#load_remote_files" do
91
+
92
+ before(:each) do
93
+ @before_count = LogCollector.count
94
+ end
95
+
96
+ it "should log if nothing to load" do
97
+ log = LogCollector.create(:status => "not_unprocessed")
98
+ Appstats.should_receive(:log).with(:info,"No remote logs to load.")
99
+ LogCollector.load_remote_files(@login,"/my/path/log",[]).should == 0
100
+ end
101
+
102
+
103
+ it "should log the files loaded" do
104
+ LogCollector.load_remote_files(@login,"/my/path/log",["app2"]).should == 1
105
+
106
+ Appstats.should_receive(:log).with(:info, "About to analyze 3 file(s).")
107
+ Appstats.should_receive(:log).with(:info, " - deployer@myhost.localnet:/my/path/log/app1")
108
+ Appstats.should_receive(:log).with(:info, " - ALREADY LOADED deployer@myhost.localnet:/my/path/log/app2")
109
+ Appstats.should_receive(:log).with(:info, " - deployer@myhost.localnet:/my/path/log/app3")
110
+ Appstats.should_receive(:log).with(:info, "Loaded 2 file(s).")
111
+ LogCollector.load_remote_files(@login,"/my/path/log",["app1","app2","app3"]).should == 2
112
+ end
113
+
114
+ it "should create an unprocessed record per file" do
115
+ LogCollector.load_remote_files(@login,"/my/path/log",["app1","app2","app3"]).should == 3
116
+ LogCollector.count.should == @before_count + 3
117
+ log_collector = LogCollector.last
118
+
119
+ log_collector.host.should == "myhost.localnet"
120
+ log_collector.filename.should == "/my/path/log/app3"
121
+ log_collector.status.should == "unprocessed"
122
+ end
123
+
124
+ it "should ignore the same file" do
125
+ LogCollector.load_remote_files(@login,"/my/path/log",["app1","app3"]).should == 2
126
+ LogCollector.load_remote_files(@login,"/my/path/log",["app1","app2","app3"]).should == 1
127
+ LogCollector.count.should == @before_count + 3
128
+ log_collector = LogCollector.last
129
+
130
+ log_collector.host.should == "myhost.localnet"
131
+ log_collector.filename.should == "/my/path/log/app2"
132
+ log_collector.status.should == "unprocessed"
133
+ end
134
+
135
+ end
136
+
137
+ describe "#local_filename" do
138
+
139
+ it "should return a standardized name with the log collector id" do
140
+ log = LogCollector.create
141
+ log.local_filename.should == simple_path("../log/appstats_remote_log_#{log.id}.log")
142
+ end
143
+
144
+ end
145
+
146
+ describe "#download_remote_files" do
147
+
148
+ before(:each) do
149
+ @before_count = LogCollector.count
150
+ end
151
+
152
+ it "should only process unprocessed files" do
153
+ log = LogCollector.create(:status => "not_unprocessed")
154
+ Appstats.should_receive(:log).with(:info,"No remote logs to download.")
155
+ LogCollector.download_remote_files(@logins).should == 0
156
+ end
157
+
158
+ it "should log exceptions" do
159
+ LogCollector.load_remote_files(@login,"/my/path/log",["app1"]).should == 1
160
+ log1 = LogCollector.find_by_filename("/my/path/log/app1")
161
+
162
+ scp = mock(Net::SCP)
163
+ Net::SCP.should_receive(:start).with("myhost.localnet","deployer",{ :password => "pass"}).and_yield(scp)
164
+ scp.should_receive(:download!).with("/my/path/log/app1",simple_path("../log/appstats_remote_log_#{log1.id}.log")).and_raise("Something bad happened again")
165
+
166
+ Appstats.should_receive(:log).with(:info,"About to download 1 file(s).")
167
+ Appstats.should_receive(:log).with(:error,"Something bad occurred during Appstats::LogCollector#download_remote_files")
168
+ Appstats.should_receive(:log).with(:error,"Something bad happened again")
169
+ Appstats.should_receive(:log).with(:error, "File #{simple_path("../log/appstats_remote_log_#{log1.id}.log")} did not download.")
170
+ Appstats.should_receive(:log).with(:info,"Downloaded 0 file(s).")
171
+ LogCollector.download_remote_files(@logins).should == 0
172
+ end
173
+
174
+ it "should ignore if file not downloaded" do
175
+ LogCollector.load_remote_files(@login,"/my/path/log",["app1"]).should == 1
176
+ log1 = LogCollector.find_by_filename("/my/path/log/app1")
177
+
178
+ scp = mock(Net::SCP)
179
+ Net::SCP.should_receive(:start).with("myhost.localnet","deployer",{ :password => "pass"}).and_yield(scp)
180
+ scp.should_receive(:download!).with("/my/path/log/app1",simple_path("../log/appstats_remote_log_#{log1.id}.log"))
181
+
182
+ Appstats.should_receive(:log).with(:info,"About to download 1 file(s).")
183
+ Appstats.should_receive(:log).with(:error, "File #{simple_path("../log/appstats_remote_log_#{log1.id}.log")} did not download.")
184
+ Appstats.should_receive(:log).with(:info,"Downloaded 0 file(s).")
185
+ LogCollector.download_remote_files(@logins).should == 0
186
+ log1.reload
187
+ log1.status.should == "failed_download"
188
+ end
189
+
190
+ it "should copy the file based on the log_collector id" do
191
+ LogCollector.load_remote_files(@login,"/my/path/log",["app1","app2"]).should == 2
192
+
193
+ log1 = LogCollector.find_by_filename("/my/path/log/app1")
194
+ log2 = LogCollector.find_by_filename("/my/path/log/app2")
195
+
196
+ File.open(log1.local_filename, 'w') {|f| f.write("testfile - delete") }
197
+ File.open(log2.local_filename, 'w') {|f| f.write("testfile - delete") }
198
+
199
+
200
+ scp = mock(Net::SCP)
201
+ 1.upto(3) do
202
+ Net::SCP.should_receive(:start).with("myhost.localnet","deployer",{ :password => "pass"}).and_yield(scp)
203
+ end
204
+ scp.should_receive(:download!).with("/my/path/log/app1",simple_path("../log/appstats_remote_log_#{log1.id}.log"))
205
+ scp.should_receive(:download!).with("/my/path/log/app2",simple_path("../log/appstats_remote_log_#{log2.id}.log"))
206
+
207
+ LogCollector.download_remote_files(@logins).should == 2
208
+
209
+ log1.reload and log2.reload
210
+ log1.status.should == "downloaded"
211
+ log2.status.should == "downloaded"
212
+
213
+ LogCollector.load_remote_files(@login,"/my/path/log",["app3"]).should == 1
214
+ log3 = LogCollector.find_by_filename("/my/path/log/app3")
215
+ File.open(log3.local_filename, 'w') {|f| f.write("testfile - delete") }
216
+
217
+ localfile = simple_path("../log/appstats_remote_log_#{log3.id}.log")
218
+ scp.should_receive(:download!).with("/my/path/log/app3",localfile)
219
+
220
+ Appstats.should_receive(:log).with(:info,"About to download 1 file(s).")
221
+ Appstats.should_receive(:log).with(:info, " - deployer@myhost.localnet:/my/path/log/app3 > #{localfile}")
222
+ Appstats.should_receive(:log).with(:info,"Downloaded 1 file(s).")
223
+ LogCollector.download_remote_files(@logins).should == 1
224
+ log3.reload and log3.reload
225
+ log3.status.should == "downloaded"
226
+ end
227
+
228
+ end
229
+
230
+ describe "#process_local_files" do
231
+
232
+ before(:each) do
233
+ @entry_count = Entry.count
234
+ end
235
+
236
+ it "should only process downloaded files" do
237
+ log = LogCollector.create(:status => "not_downloaded")
238
+ Appstats.should_receive(:log).with(:info,"No local logs to process.")
239
+ LogCollector.process_local_files.should == 0
240
+ end
241
+
242
+ it "should process downloaded files into entries" do
243
+ LogCollector.load_remote_files(@login,"/my/path/log",["appstats1"]).should == 1
244
+ log3 = LogCollector.find_by_filename("/my/path/log/appstats1")
245
+ log3.status = "downloaded" and log3.save.should == true
246
+ File.open(log3.local_filename, 'w') {|f| f.write(Appstats::Logger.entry_to_s("test_action1") + "\n" + Appstats::Logger.entry_to_s("test_action2")) }
247
+
248
+ Appstats.should_receive(:log).with(:info,"About to process 1 file(s).")
249
+ Appstats.should_receive(:log).with(:info," - 2 entr(ies) in #{log3.local_filename}.")
250
+ Appstats.should_receive(:log).with(:info,"Processed 1 file(s) with 2 entr(ies).")
251
+ LogCollector.process_local_files.should == 1
252
+
253
+ log3.reload
254
+ log3.status.should == "processed"
255
+ Entry.count.should == @entry_count + 2
256
+ entry = Entry.last
257
+ entry.log_collector.should == log3
258
+ entry.action.should == "test_action2"
259
+ end
260
+
261
+ it "should deal with exceptions" do
262
+ LogCollector.load_remote_files(@login,"/my/path/log",["appstats1"]).should == 1
263
+ log3 = LogCollector.find_by_filename("/my/path/log/appstats1")
264
+ log3.status = "downloaded" and log3.save.should == true
265
+ File.open(log3.local_filename, 'w') {|f| f.write(Appstats::Logger.entry_to_s("test_action1") + "\n" + Appstats::Logger.entry_to_s("test_action2")) }
266
+
267
+ File.stub!(:open).and_raise("bad error")
268
+
269
+ Appstats.should_receive(:log).with(:info,"About to process 1 file(s).")
270
+ Appstats.should_receive(:log).with(:error,"Something bad occurred during Appstats::LogCollector#process_local_files")
271
+ Appstats.should_receive(:log).with(:error,"bad error")
272
+ Appstats.should_receive(:log).with(:info,"Processed 0 file(s) with 0 entr(ies).")
273
+ LogCollector.process_local_files.should == 0
274
+
275
+ log3.reload
276
+ log3.status.should == "downloaded"
277
+ Entry.count.should == @entry_count
278
+ end
279
+
280
+ end
281
+
282
+
283
+ end
284
+ end