PageRenderTime 38ms CodeModel.GetById 9ms RepoModel.GetById 0ms app.codeStats 0ms

/google_toolbox/Foundation/GTMLoggerRingBufferWriterTest.m

http://github.com/yfactorial/objectiveresource
Objective C | 363 lines | 234 code | 84 blank | 45 comment | 9 complexity | 7fdae748bb19e5c436e3998c389360e8 MD5 | raw file
Possible License(s): Apache-2.0
  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. #import "GTMSenTestCase.h"
  19. #import "GTMLoggerRingBufferWriter.h"
  20. #import "GTMLogger.h"
  21. #import "GTMUnitTestDevLog.h"
  22. // --------------------------------------------------
  23. // CountingWriter keeps a count of the number of times it has been
  24. // told to write something, and also keeps track of what it was
  25. // asked to log.
  26. @interface CountingWriter : NSObject<GTMLogWriter> {
  27. @private
  28. NSMutableArray *loggedContents_;
  29. }
  30. - (NSUInteger)count;
  31. - (NSArray *)loggedContents;
  32. - (void)reset;
  33. @end // CountingWriter
  34. @implementation CountingWriter
  35. - (void)logMessage:(NSString *)msg level:(GTMLoggerLevel)level {
  36. if (!loggedContents_) {
  37. loggedContents_ = [[NSMutableArray alloc] init];
  38. }
  39. [loggedContents_ addObject:msg];
  40. } // logMessage
  41. - (void)dealloc {
  42. [loggedContents_ release];
  43. [super dealloc];
  44. } // dealloc
  45. - (void)reset {
  46. [loggedContents_ release];
  47. loggedContents_ = nil;
  48. } // reset
  49. - (NSUInteger)count {
  50. return [loggedContents_ count];
  51. } // count
  52. - (NSArray *)loggedContents {
  53. return loggedContents_;
  54. } // loggedContents
  55. @end // CountingWriter
  56. @interface GTMLoggerRingBufferWriterTest : GTMTestCase {
  57. @private
  58. GTMLogger *logger_;
  59. CountingWriter *countingWriter_;
  60. }
  61. @end // GTMLoggerRingBufferWriterTest
  62. // --------------------------------------------------
  63. @implementation GTMLoggerRingBufferWriterTest
  64. // Utilty to compare the set of messages captured by a CountingWriter
  65. // with an array of expected messages. The messages are expected to
  66. // be in the same order in both places.
  67. - (void)compareWriter:(CountingWriter *)writer
  68. withExpectedLogging:(NSArray *)expected
  69. line:(int)line {
  70. NSArray *loggedContents = [writer loggedContents];
  71. STAssertEquals([expected count], [loggedContents count],
  72. @"count mismatch from line %d", line);
  73. for (unsigned int i = 0; i < [expected count]; i++) {
  74. STAssertEqualObjects([expected objectAtIndex:i],
  75. [loggedContents objectAtIndex:i],
  76. @"logging mistmatch at index %d from line %d",
  77. i, line);
  78. }
  79. } // compareWithExpectedLogging
  80. - (void)setUp {
  81. countingWriter_ = [[CountingWriter alloc] init];
  82. logger_ = [[GTMLogger alloc] init];
  83. } // setUp
  84. - (void)tearDown {
  85. [countingWriter_ release];
  86. [logger_ release];
  87. } // tearDown
  88. - (void)testCreation {
  89. // Make sure initializers work.
  90. GTMLoggerRingBufferWriter *writer =
  91. [GTMLoggerRingBufferWriter ringBufferWriterWithCapacity:32
  92. writer:countingWriter_];
  93. STAssertEquals([writer capacity], (NSUInteger)32, nil);
  94. STAssertTrue([writer writer] == countingWriter_, nil);
  95. STAssertEquals([writer count], (NSUInteger)0, nil);
  96. STAssertEquals([writer droppedLogCount], (NSUInteger)0, nil);
  97. STAssertEquals([writer totalLogged], (NSUInteger)0, nil);
  98. // Try with invalid arguments. Should always get nil back.
  99. writer =
  100. [GTMLoggerRingBufferWriter ringBufferWriterWithCapacity:0
  101. writer:countingWriter_];
  102. STAssertNil(writer, nil);
  103. writer = [GTMLoggerRingBufferWriter ringBufferWriterWithCapacity:32
  104. writer:nil];
  105. STAssertNil(writer, nil);
  106. writer = [[GTMLoggerRingBufferWriter alloc] init];
  107. STAssertNil(writer, nil);
  108. } // testCreation
  109. - (void)testLogging {
  110. GTMLoggerRingBufferWriter *writer =
  111. [GTMLoggerRingBufferWriter ringBufferWriterWithCapacity:4
  112. writer:countingWriter_];
  113. [logger_ setWriter:writer];
  114. // Shouldn't do anything if there are no contents.
  115. [writer dumpContents];
  116. STAssertEquals([writer count], (NSUInteger)0, nil);
  117. STAssertEquals([countingWriter_ count], (NSUInteger)0, nil);
  118. // Log a single item. Make sure the counts are accurate.
  119. [logger_ logDebug:@"oop"];
  120. STAssertEquals([writer count], (NSUInteger)1, nil);
  121. STAssertEquals([writer totalLogged], (NSUInteger)1, nil);
  122. STAssertEquals([writer droppedLogCount], (NSUInteger)0, nil);
  123. STAssertEquals([countingWriter_ count], (NSUInteger)0, nil);
  124. // Log a second item. Also make sure counts are accurate.
  125. [logger_ logDebug:@"ack"];
  126. STAssertEquals([writer count], (NSUInteger)2, nil);
  127. STAssertEquals([writer totalLogged], (NSUInteger)2, nil);
  128. STAssertEquals([writer droppedLogCount], (NSUInteger)0, nil);
  129. STAssertEquals([countingWriter_ count], (NSUInteger)0, nil);
  130. // Print them, and make sure the countingWriter sees the right stuff.
  131. [writer dumpContents];
  132. STAssertEquals([countingWriter_ count], (NSUInteger)2, nil);
  133. STAssertEquals([writer count], (NSUInteger)2, nil); // Should not be zeroed.
  134. STAssertEquals([writer totalLogged], (NSUInteger)2, nil);
  135. [self compareWriter:countingWriter_
  136. withExpectedLogging:[NSArray arrayWithObjects:@"oop",@"ack", nil]
  137. line:__LINE__];
  138. // Wipe the slates clean.
  139. [writer reset];
  140. [countingWriter_ reset];
  141. STAssertEquals([writer count], (NSUInteger)0, nil);
  142. STAssertEquals([writer totalLogged], (NSUInteger)0, nil);
  143. // An error log level should print the buffer and empty it.
  144. [logger_ logDebug:@"oop"];
  145. [logger_ logInfo:@"ack"];
  146. STAssertEquals([writer droppedLogCount], (NSUInteger)0, nil);
  147. STAssertEquals([writer totalLogged], (NSUInteger)2, nil);
  148. [logger_ logError:@"blargh"];
  149. STAssertEquals([countingWriter_ count], (NSUInteger)3, nil);
  150. STAssertEquals([writer droppedLogCount], (NSUInteger)0, nil);
  151. [self compareWriter:countingWriter_
  152. withExpectedLogging:[NSArray arrayWithObjects:@"oop", @"ack",
  153. @"blargh", nil]
  154. line:__LINE__];
  155. // An assert log level should do the same. This also fills the
  156. // buffer to its limit without wrapping.
  157. [countingWriter_ reset];
  158. [logger_ logDebug:@"oop"];
  159. [logger_ logInfo:@"ack"];
  160. [logger_ logDebug:@"blargh"];
  161. STAssertEquals([writer droppedLogCount], (NSUInteger)0, nil);
  162. STAssertEquals([writer count], (NSUInteger)3, nil);
  163. STAssertEquals([writer totalLogged], (NSUInteger)3, nil);
  164. [logger_ logAssert:@"ouch"];
  165. STAssertEquals([countingWriter_ count], (NSUInteger)4, nil);
  166. STAssertEquals([writer droppedLogCount], (NSUInteger)0, nil);
  167. [self compareWriter:countingWriter_
  168. withExpectedLogging:[NSArray arrayWithObjects:@"oop", @"ack",
  169. @"blargh", @"ouch", nil]
  170. line:__LINE__];
  171. // Try with exactly one wrap around.
  172. [countingWriter_ reset];
  173. [logger_ logInfo:@"ack"];
  174. [logger_ logDebug:@"oop"];
  175. [logger_ logDebug:@"blargh"];
  176. [logger_ logDebug:@"flong"]; // Fills buffer
  177. STAssertEquals([writer droppedLogCount], (NSUInteger)0, nil);
  178. STAssertEquals([writer count], (NSUInteger)4, nil);
  179. [logger_ logAssert:@"ouch"]; // should drop "ack"
  180. STAssertEquals([countingWriter_ count], (NSUInteger)4, nil);
  181. [self compareWriter:countingWriter_
  182. withExpectedLogging:[NSArray arrayWithObjects:@"oop", @"blargh",
  183. @"flong", @"ouch", nil]
  184. line:__LINE__];
  185. // Try with more than one wrap around.
  186. [countingWriter_ reset];
  187. [logger_ logInfo:@"ack"];
  188. [logger_ logDebug:@"oop"];
  189. [logger_ logDebug:@"blargh"];
  190. [logger_ logDebug:@"flong"]; // Fills buffer
  191. [logger_ logDebug:@"bloogie"]; // should drop "ack"
  192. STAssertEquals([writer droppedLogCount], (NSUInteger)1, nil);
  193. STAssertEquals([writer count], (NSUInteger)4, nil);
  194. [logger_ logAssert:@"ouch"]; // should drop "oop"
  195. STAssertEquals([countingWriter_ count], (NSUInteger)4, nil);
  196. [self compareWriter:countingWriter_
  197. withExpectedLogging:[NSArray arrayWithObjects:@"blargh",
  198. @"flong", @"bloogie", @"ouch", nil]
  199. line:__LINE__];
  200. } // testBasics
  201. - (void)testCornerCases {
  202. // make sure we work with small buffer sizes.
  203. GTMLoggerRingBufferWriter *writer =
  204. [GTMLoggerRingBufferWriter ringBufferWriterWithCapacity:1
  205. writer:countingWriter_];
  206. [logger_ setWriter:writer];
  207. [logger_ logInfo:@"ack"];
  208. STAssertEquals([countingWriter_ count], (NSUInteger)0, nil);
  209. STAssertEquals([writer count], (NSUInteger)1, nil);
  210. [writer dumpContents];
  211. STAssertEquals([countingWriter_ count], (NSUInteger)1, nil);
  212. [self compareWriter:countingWriter_
  213. withExpectedLogging:[NSArray arrayWithObjects:@"ack", nil]
  214. line:__LINE__];
  215. [logger_ logDebug:@"oop"]; // should drop "ack"
  216. STAssertEquals([writer count], (NSUInteger)1, nil);
  217. STAssertEquals([writer droppedLogCount], (NSUInteger)1, nil);
  218. [countingWriter_ reset];
  219. [logger_ logError:@"snoogy"]; // should drop "oop"
  220. STAssertEquals([countingWriter_ count], (NSUInteger)1, nil);
  221. [self compareWriter:countingWriter_
  222. withExpectedLogging:[NSArray arrayWithObjects:@"snoogy", nil]
  223. line:__LINE__];
  224. } // testCornerCases
  225. // Run 10 threads, all logging through the same logger.
  226. static volatile NSUInteger gStoppedThreads = 0; // Total number that have stopped.
  227. - (void)bangMe:(id)info {
  228. NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
  229. GTMLogger *logger = (GTMLogger *)info;
  230. // Log a string.
  231. for (int i = 0; i < 27; i++) {
  232. [logger logDebug:@"oop"];
  233. }
  234. // log another string which should push the first string out.
  235. // if we see any "oop"s in the logger output, then we know it got
  236. // confused.
  237. for (int i = 0; i < 15; i++) {
  238. [logger logDebug:@"ack"];
  239. }
  240. [pool release];
  241. @synchronized ([self class]) {
  242. gStoppedThreads++;
  243. }
  244. } // bangMe
  245. - (void)testThreading {
  246. const NSUInteger kThreadCount = 10;
  247. const NSUInteger kCapacity = 10;
  248. GTMLoggerRingBufferWriter *writer =
  249. [GTMLoggerRingBufferWriter ringBufferWriterWithCapacity:kCapacity
  250. writer:countingWriter_];
  251. [logger_ setWriter:writer];
  252. for (NSUInteger i = 0; i < kThreadCount; i++) {
  253. [NSThread detachNewThreadSelector:@selector(bangMe:)
  254. toTarget:self
  255. withObject:logger_];
  256. }
  257. // The threads are running, so wait for them all to finish.
  258. while (1) {
  259. NSDate *quick = [NSDate dateWithTimeIntervalSinceNow:0.2];
  260. [[NSRunLoop currentRunLoop] runUntilDate:quick];
  261. @synchronized ([self class]) {
  262. if (gStoppedThreads == kThreadCount) break;
  263. }
  264. }
  265. // Now make sure we get back what's expected.
  266. STAssertEquals([writer count], kThreadCount, nil);
  267. STAssertEquals([countingWriter_ count], (NSUInteger)0, nil); // Nothing should be logged
  268. STAssertEquals([writer totalLogged], (NSUInteger)420, nil);
  269. [logger_ logError:@"bork"];
  270. STAssertEquals([countingWriter_ count], kCapacity, nil);
  271. NSArray *expected = [NSArray arrayWithObjects:
  272. @"ack", @"ack", @"ack", @"ack", @"ack",
  273. @"ack", @"ack", @"ack", @"ack", @"bork",
  274. nil];
  275. [self compareWriter:countingWriter_
  276. withExpectedLogging:expected
  277. line:__LINE__];
  278. } // testThreading
  279. @end // GTMLoggerRingBufferWriterTest