PageRenderTime 58ms CodeModel.GetById 1ms app.highlight 53ms RepoModel.GetById 1ms app.codeStats 0ms

/core/externals/google-toolbox-for-mac/Foundation/GTMLoggerRingBufferWriterTest.m

http://macfuse.googlecode.com/
Objective C | 363 lines | 234 code | 84 blank | 45 comment | 9 complexity | 7fdae748bb19e5c436e3998c389360e8 MD5 | raw file
  1//
  2//  GTMLoggerRingBufferWriterTest.m
  3//
  4//  Copyright 2007-2008 Google Inc.
  5//
  6//  Licensed under the Apache License, Version 2.0 (the "License"); you may not
  7//  use this file except in compliance with the License.  You may obtain a copy
  8//  of the License at
  9// 
 10//  http://www.apache.org/licenses/LICENSE-2.0
 11// 
 12//  Unless required by applicable law or agreed to in writing, software
 13//  distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
 14//  WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
 15//  License for the specific language governing permissions and limitations under
 16//  the License.
 17//
 18
 19#import "GTMSenTestCase.h"
 20#import "GTMLoggerRingBufferWriter.h"
 21#import "GTMLogger.h"
 22#import "GTMUnitTestDevLog.h"
 23
 24// --------------------------------------------------
 25// CountingWriter keeps a count of the number of times it has been
 26// told to write something, and also keeps track of what it was
 27// asked to log.
 28
 29@interface CountingWriter : NSObject<GTMLogWriter> {
 30 @private
 31  NSMutableArray *loggedContents_;
 32}
 33
 34- (NSUInteger)count;
 35- (NSArray *)loggedContents;
 36- (void)reset;
 37
 38@end  // CountingWriter
 39
 40@implementation CountingWriter
 41- (void)logMessage:(NSString *)msg level:(GTMLoggerLevel)level {
 42  if (!loggedContents_) {
 43    loggedContents_ = [[NSMutableArray alloc] init];
 44  }
 45  [loggedContents_ addObject:msg];
 46}  // logMessage
 47
 48- (void)dealloc {
 49  [loggedContents_ release];
 50  [super dealloc];
 51}  // dealloc
 52
 53- (void)reset {
 54  [loggedContents_ release];
 55  loggedContents_ = nil;
 56}  // reset
 57
 58- (NSUInteger)count {
 59  return [loggedContents_ count];
 60}  // count
 61
 62- (NSArray *)loggedContents {
 63  return loggedContents_;
 64}  // loggedContents
 65
 66@end  // CountingWriter
 67
 68
 69@interface GTMLoggerRingBufferWriterTest : GTMTestCase {
 70 @private
 71  GTMLogger *logger_;
 72  CountingWriter *countingWriter_;
 73}
 74@end  // GTMLoggerRingBufferWriterTest
 75
 76
 77// --------------------------------------------------
 78
 79@implementation GTMLoggerRingBufferWriterTest
 80
 81// Utilty to compare the set of messages captured by a CountingWriter
 82// with an array of expected messages.  The messages are expected to
 83// be in the same order in both places.
 84
 85- (void)compareWriter:(CountingWriter *)writer
 86  withExpectedLogging:(NSArray *)expected
 87                 line:(int)line {
 88  NSArray *loggedContents = [writer loggedContents];
 89
 90  STAssertEquals([expected count], [loggedContents count],
 91                 @"count mismatch from line %d", line);
 92
 93  for (unsigned int i = 0; i < [expected count]; i++) {
 94    STAssertEqualObjects([expected objectAtIndex:i],
 95                         [loggedContents objectAtIndex:i],
 96                         @"logging mistmatch at index %d from line %d",
 97                         i, line);
 98  }
 99  
100}  // compareWithExpectedLogging
101
102
103- (void)setUp {
104  countingWriter_ = [[CountingWriter alloc] init];
105  logger_ = [[GTMLogger alloc] init];
106}  // setUp
107
108
109- (void)tearDown {
110  [countingWriter_ release];
111  [logger_ release];
112}  // tearDown
113
114
115- (void)testCreation {
116
117  // Make sure initializers work.
118  GTMLoggerRingBufferWriter *writer =
119    [GTMLoggerRingBufferWriter ringBufferWriterWithCapacity:32
120                                                     writer:countingWriter_];
121  STAssertEquals([writer capacity], (NSUInteger)32, nil);
122  STAssertTrue([writer writer] == countingWriter_, nil);
123  STAssertEquals([writer count], (NSUInteger)0, nil);
124  STAssertEquals([writer droppedLogCount], (NSUInteger)0, nil);
125  STAssertEquals([writer totalLogged], (NSUInteger)0, nil);
126
127  // Try with invalid arguments.  Should always get nil back.
128  writer =
129    [GTMLoggerRingBufferWriter ringBufferWriterWithCapacity:0
130                                                     writer:countingWriter_];
131  STAssertNil(writer, nil);
132
133  writer = [GTMLoggerRingBufferWriter ringBufferWriterWithCapacity:32
134                                                             writer:nil];
135  STAssertNil(writer, nil);
136
137  writer = [[GTMLoggerRingBufferWriter alloc] init];
138  STAssertNil(writer, nil);
139
140}  // testCreation
141
142
143- (void)testLogging {
144  GTMLoggerRingBufferWriter *writer =
145    [GTMLoggerRingBufferWriter ringBufferWriterWithCapacity:4
146                                                     writer:countingWriter_];
147  [logger_ setWriter:writer];
148  
149  // Shouldn't do anything if there are no contents.
150  [writer dumpContents];
151  STAssertEquals([writer count], (NSUInteger)0, nil);
152  STAssertEquals([countingWriter_ count], (NSUInteger)0, nil);
153
154  // Log a single item.  Make sure the counts are accurate.
155  [logger_ logDebug:@"oop"];
156  STAssertEquals([writer count], (NSUInteger)1, nil);
157  STAssertEquals([writer totalLogged], (NSUInteger)1, nil);
158  STAssertEquals([writer droppedLogCount], (NSUInteger)0, nil);
159  STAssertEquals([countingWriter_ count], (NSUInteger)0, nil);
160
161  // Log a second item.  Also make sure counts are accurate.
162  [logger_ logDebug:@"ack"];
163  STAssertEquals([writer count], (NSUInteger)2, nil);
164  STAssertEquals([writer totalLogged], (NSUInteger)2, nil);
165  STAssertEquals([writer droppedLogCount], (NSUInteger)0, nil);
166  STAssertEquals([countingWriter_ count], (NSUInteger)0, nil);
167
168  // Print them, and make sure the countingWriter sees the right stuff.
169  [writer dumpContents];
170  STAssertEquals([countingWriter_ count], (NSUInteger)2, nil);
171  STAssertEquals([writer count], (NSUInteger)2, nil);  // Should not be zeroed.
172  STAssertEquals([writer totalLogged], (NSUInteger)2, nil);
173
174  [self compareWriter:countingWriter_
175        withExpectedLogging:[NSArray arrayWithObjects:@"oop",@"ack", nil]
176                 line:__LINE__];
177
178
179  // Wipe the slates clean.
180  [writer reset];
181  [countingWriter_ reset];
182  STAssertEquals([writer count], (NSUInteger)0, nil);
183  STAssertEquals([writer totalLogged], (NSUInteger)0, nil);
184
185  // An error log level should print the buffer and empty it.
186  [logger_ logDebug:@"oop"];
187  [logger_ logInfo:@"ack"];
188  STAssertEquals([writer droppedLogCount], (NSUInteger)0, nil);
189  STAssertEquals([writer totalLogged], (NSUInteger)2, nil);
190
191  [logger_ logError:@"blargh"];
192  STAssertEquals([countingWriter_ count], (NSUInteger)3, nil);
193  STAssertEquals([writer droppedLogCount], (NSUInteger)0, nil);
194
195  [self compareWriter:countingWriter_
196        withExpectedLogging:[NSArray arrayWithObjects:@"oop", @"ack",
197                                     @"blargh", nil]
198                 line:__LINE__];
199
200
201  // An assert log level should do the same.  This also fills the
202  // buffer to its limit without wrapping.
203  [countingWriter_ reset];
204  [logger_ logDebug:@"oop"];
205  [logger_ logInfo:@"ack"];
206  [logger_ logDebug:@"blargh"];
207  STAssertEquals([writer droppedLogCount], (NSUInteger)0, nil);
208  STAssertEquals([writer count], (NSUInteger)3, nil);
209  STAssertEquals([writer totalLogged], (NSUInteger)3, nil);
210
211  [logger_ logAssert:@"ouch"];
212  STAssertEquals([countingWriter_ count], (NSUInteger)4, nil);
213  STAssertEquals([writer droppedLogCount], (NSUInteger)0, nil);
214  [self compareWriter:countingWriter_
215        withExpectedLogging:[NSArray arrayWithObjects:@"oop", @"ack",
216                                     @"blargh", @"ouch", nil]
217                 line:__LINE__];
218
219
220  // Try with exactly one wrap around.
221  [countingWriter_ reset];
222  [logger_ logInfo:@"ack"];
223  [logger_ logDebug:@"oop"];
224  [logger_ logDebug:@"blargh"];
225  [logger_ logDebug:@"flong"];  // Fills buffer
226  STAssertEquals([writer droppedLogCount], (NSUInteger)0, nil);
227  STAssertEquals([writer count], (NSUInteger)4, nil);
228
229  [logger_ logAssert:@"ouch"];  // should drop "ack"
230  STAssertEquals([countingWriter_ count], (NSUInteger)4, nil);
231
232  [self compareWriter:countingWriter_
233        withExpectedLogging:[NSArray arrayWithObjects:@"oop", @"blargh",
234                                     @"flong", @"ouch", nil]
235                 line:__LINE__];
236
237
238  // Try with more than one wrap around.
239  [countingWriter_ reset];
240  [logger_ logInfo:@"ack"];
241  [logger_ logDebug:@"oop"];
242  [logger_ logDebug:@"blargh"];
243  [logger_ logDebug:@"flong"];  // Fills buffer
244  [logger_ logDebug:@"bloogie"];  // should drop "ack"
245  STAssertEquals([writer droppedLogCount], (NSUInteger)1, nil);
246  STAssertEquals([writer count], (NSUInteger)4, nil);
247
248  [logger_ logAssert:@"ouch"];  // should drop "oop"
249  STAssertEquals([countingWriter_ count], (NSUInteger)4, nil);
250
251  [self compareWriter:countingWriter_
252        withExpectedLogging:[NSArray arrayWithObjects:@"blargh",
253                                     @"flong", @"bloogie", @"ouch", nil]
254                 line:__LINE__];
255}  // testBasics
256
257
258- (void)testCornerCases {
259  // make sure we work with small buffer sizes.
260
261  GTMLoggerRingBufferWriter *writer =
262    [GTMLoggerRingBufferWriter ringBufferWriterWithCapacity:1
263                                                     writer:countingWriter_];
264  [logger_ setWriter:writer];
265
266  [logger_ logInfo:@"ack"];
267  STAssertEquals([countingWriter_ count], (NSUInteger)0, nil);  
268  STAssertEquals([writer count], (NSUInteger)1, nil);
269  [writer dumpContents];
270  STAssertEquals([countingWriter_ count], (NSUInteger)1, nil);  
271
272  [self compareWriter:countingWriter_
273        withExpectedLogging:[NSArray arrayWithObjects:@"ack", nil]
274                 line:__LINE__];
275
276  [logger_ logDebug:@"oop"];  // should drop "ack"
277  STAssertEquals([writer count], (NSUInteger)1, nil);
278  STAssertEquals([writer droppedLogCount], (NSUInteger)1, nil);
279
280  [countingWriter_ reset];
281  [logger_ logError:@"snoogy"];  // should drop "oop"
282  STAssertEquals([countingWriter_ count], (NSUInteger)1, nil);  
283
284  [self compareWriter:countingWriter_
285  withExpectedLogging:[NSArray arrayWithObjects:@"snoogy", nil]
286                 line:__LINE__];
287
288}  // testCornerCases
289
290
291
292// Run 10 threads, all logging through the same logger.  
293
294static volatile NSUInteger gStoppedThreads = 0; // Total number that have stopped.
295
296- (void)bangMe:(id)info {
297  NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
298
299  GTMLogger *logger = (GTMLogger *)info;
300
301  // Log a string.
302  for (int i = 0; i < 27; i++) {
303    [logger logDebug:@"oop"];
304  }
305
306  // log another string which should push the first string out.
307  // if we see any "oop"s in the logger output, then we know it got
308  // confused.
309  for (int i = 0; i < 15; i++) {
310    [logger logDebug:@"ack"];
311  }
312
313  [pool release];
314  @synchronized ([self class]) {
315    gStoppedThreads++;
316  }
317
318}  // bangMe
319
320
321- (void)testThreading {
322  const NSUInteger kThreadCount = 10;
323  const NSUInteger kCapacity = 10;
324
325  GTMLoggerRingBufferWriter *writer =
326    [GTMLoggerRingBufferWriter ringBufferWriterWithCapacity:kCapacity
327                                                     writer:countingWriter_];
328  [logger_ setWriter:writer];
329
330  for (NSUInteger i = 0; i < kThreadCount; i++) {
331    [NSThread detachNewThreadSelector:@selector(bangMe:)
332                             toTarget:self
333                           withObject:logger_];
334  }
335
336  // The threads are running, so wait for them all to finish.
337  while (1) {
338    NSDate *quick = [NSDate dateWithTimeIntervalSinceNow:0.2];
339    [[NSRunLoop currentRunLoop] runUntilDate:quick];
340    @synchronized ([self class]) {
341      if (gStoppedThreads == kThreadCount) break;
342    }
343  }
344
345  // Now make sure we get back what's expected.
346  STAssertEquals([writer count], kThreadCount, nil);
347  STAssertEquals([countingWriter_ count], (NSUInteger)0, nil);  // Nothing should be logged
348  STAssertEquals([writer totalLogged], (NSUInteger)420, nil);
349
350  [logger_ logError:@"bork"];
351  STAssertEquals([countingWriter_ count], kCapacity, nil);
352  
353  NSArray *expected = [NSArray arrayWithObjects:
354                       @"ack", @"ack", @"ack", @"ack", @"ack", 
355                       @"ack", @"ack", @"ack", @"ack", @"bork",
356                       nil];
357  [self compareWriter:countingWriter_
358  withExpectedLogging:expected
359                 line:__LINE__];
360
361}  // testThreading
362
363@end  // GTMLoggerRingBufferWriterTest