appstats 0.0.13 → 0.0.14

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.
@@ -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