PageRenderTime 30ms CodeModel.GetById 18ms RepoModel.GetById 1ms app.codeStats 0ms

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

http://macfuse.googlecode.com/
Objective C | 165 lines | 113 code | 25 blank | 27 comment | 3 complexity | 75b119faafe97ae54a5c4c5a26e61beb MD5 | raw file
Possible License(s): Apache-2.0, BSD-3-Clause, GPL-2.0
  1. //
  2. // GTMStackTraceTest.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 <Foundation/Foundation.h>
  19. #import "GTMStackTrace.h"
  20. #import "GTMSenTestCase.h"
  21. @interface GTMStackTraceTest : GTMTestCase
  22. @end
  23. @implementation GTMStackTraceTest
  24. + (BOOL)classMethodTest {
  25. NSString *stacktrace = GTMStackTrace();
  26. NSArray *stacklines = [stacktrace componentsSeparatedByString:@"\n"];
  27. NSString *firstFrame = [stacklines objectAtIndex:0];
  28. NSRange range = [firstFrame rangeOfString:@"+"];
  29. return range.location != NSNotFound;
  30. }
  31. - (void)testStackTraceBasic {
  32. NSString *stacktrace = GTMStackTrace();
  33. NSArray *stacklines = [stacktrace componentsSeparatedByString:@"\n"];
  34. STAssertGreaterThan([stacklines count], (NSUInteger)3,
  35. @"stack trace must have > 3 lines");
  36. STAssertLessThan([stacklines count], (NSUInteger)35,
  37. @"stack trace must have < 35 lines");
  38. NSString *firstFrame = [stacklines objectAtIndex:0];
  39. NSRange range = [firstFrame rangeOfString:@"testStackTraceBasic"];
  40. STAssertNotEquals(range.location, (NSUInteger)NSNotFound,
  41. @"First frame should contain testStackTraceBasic,"
  42. " stack trace: %@", stacktrace);
  43. range = [firstFrame rangeOfString:@"#0"];
  44. STAssertNotEquals(range.location, (NSUInteger)NSNotFound,
  45. @"First frame should contain #0, stack trace: %@",
  46. stacktrace);
  47. range = [firstFrame rangeOfString:@"-"];
  48. STAssertNotEquals(range.location, (NSUInteger)NSNotFound,
  49. @"First frame should contain - since it's "
  50. @"an instance method: %@", stacktrace);
  51. STAssertTrue([[self class] classMethodTest], @"First frame should contain"
  52. @"+ since it's a class method");
  53. }
  54. -(void)testGetStackAddressDescriptors {
  55. struct GTMAddressDescriptor descs[100];
  56. size_t depth = sizeof(descs) / sizeof(struct GTMAddressDescriptor);
  57. depth = GTMGetStackAddressDescriptors(descs, depth);
  58. // Got atleast 4...
  59. STAssertGreaterThan(depth, (size_t)4, nil);
  60. // All that we got have symbols
  61. for (NSUInteger lp = 0 ; lp < depth ; ++lp) {
  62. STAssertNotNULL(descs[lp].symbol, @"didn't get a symbol at depth %lu",
  63. (unsigned long)lp);
  64. }
  65. // Do it again, but don't give it enough space (to make sure it handles that)
  66. size_t fullDepth = depth;
  67. STAssertGreaterThan(fullDepth, (size_t)4, nil);
  68. depth -= 2;
  69. depth = GTMGetStackAddressDescriptors(descs, depth);
  70. STAssertLessThan(depth, fullDepth, nil);
  71. // All that we got have symbols
  72. for (NSUInteger lp = 0 ; lp < depth ; ++lp) {
  73. STAssertNotNULL(descs[lp].symbol, @"didn't get a symbol at depth %lu",
  74. (unsigned long)lp);
  75. }
  76. }
  77. #if MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_5
  78. - (void)helperThatThrows {
  79. [NSException raise:@"TestException" format:@"TestExceptionDescription"];
  80. }
  81. - (void)testStackExceptionTrace {
  82. NSException *exception = nil;
  83. @try {
  84. [self helperThatThrows];
  85. }
  86. @catch (NSException * e) {
  87. exception = e;
  88. }
  89. STAssertNotNil(exception, nil);
  90. NSString *stacktrace = GTMStackTraceFromException(exception);
  91. NSArray *stacklines = [stacktrace componentsSeparatedByString:@"\n"];
  92. STAssertGreaterThan([stacklines count], (NSUInteger)4,
  93. @"stack trace must have > 4 lines");
  94. STAssertLessThan([stacklines count], (NSUInteger)35,
  95. @"stack trace must have < 35 lines");
  96. STAssertEquals([stacklines count],
  97. [[exception callStackReturnAddresses] count],
  98. @"stack trace should have the same number of lines as the "
  99. @" array of return addresses. stack trace: %@", stacktrace);
  100. // we can't look for it on a specific frame because NSException doesn't
  101. // really document how deep the stack will be
  102. NSRange range = [stacktrace rangeOfString:@"testStackExceptionTrace"];
  103. STAssertNotEquals(range.location, (NSUInteger)NSNotFound,
  104. @"Stack trace should contain testStackExceptionTrace,"
  105. " stack trace: %@", stacktrace);
  106. }
  107. #endif
  108. #if MAC_OS_X_VERSION_MIN_REQUIRED < MAC_OS_X_VERSION_10_5
  109. - (void)testProgramCountersBasic {
  110. void *pcs[10];
  111. NSUInteger depth = 10;
  112. depth = GTMGetStackProgramCounters(pcs, depth);
  113. STAssertGreaterThan(depth, (NSUInteger)3, @"stack trace must have > 3 lines");
  114. STAssertLessThanOrEqual(depth, (NSUInteger)10,
  115. @"stack trace must have < 10 lines");
  116. // pcs is an array of program counters from the stack. pcs[0] should match
  117. // the call into GTMGetStackProgramCounters, which is tough for us to check.
  118. // However, we can verify that pcs[1] is equal to our current return address
  119. // for our current function.
  120. void *current_pc = __builtin_return_address(0);
  121. STAssertEquals(pcs[1], current_pc, @"pcs[1] should equal the current PC");
  122. }
  123. - (void)testProgramCountersMore {
  124. void *pcs0[0];
  125. NSUInteger depth0 = 0;
  126. depth0 = GTMGetStackProgramCounters(pcs0, depth0);
  127. STAssertEquals(depth0, (NSUInteger)0, @"stack trace must have 0 lines");
  128. void *pcs1[1];
  129. NSUInteger depth1 = 1;
  130. depth1 = GTMGetStackProgramCounters(pcs1, depth1);
  131. STAssertEquals(depth1, (NSUInteger)1, @"stack trace must have 1 lines");
  132. void *pcs2[2];
  133. NSUInteger depth2 = 2;
  134. depth2 = GTMGetStackProgramCounters(pcs2, depth2);
  135. STAssertEquals(depth2, (NSUInteger)2, @"stack trace must have 2 lines");
  136. void *current_pc = __builtin_return_address(0);
  137. STAssertEquals(pcs2[1], current_pc, @"pcs[1] should equal the current PC");
  138. }
  139. #endif // MAC_OS_X_VERSION_MIN_REQUIRED < MAC_OS_X_VERSION_10_5
  140. @end