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