OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #import <UIKit/UIKit.h> | 5 #import <UIKit/UIKit.h> |
6 | 6 |
7 #include "base/debug/debugger.h" | 7 #include "base/debug/debugger.h" |
8 #include "base/logging.h" | 8 #include "base/logging.h" |
9 #include "base/mac/scoped_nsautorelease_pool.h" | 9 #include "base/mac/scoped_nsautorelease_pool.h" |
10 #include "base/memory/scoped_nsobject.h" | 10 #include "base/memory/scoped_nsobject.h" |
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
51 // Yes, this is leaked, it's just to make what's running visible. | 51 // Yes, this is leaked, it's just to make what's running visible. |
52 window_.reset([[UIWindow alloc] initWithFrame:bounds]); | 52 window_.reset([[UIWindow alloc] initWithFrame:bounds]); |
53 [window_ makeKeyAndVisible]; | 53 [window_ makeKeyAndVisible]; |
54 | 54 |
55 // Add a label with the app name. | 55 // Add a label with the app name. |
56 UILabel* label = [[[UILabel alloc] initWithFrame:bounds] autorelease]; | 56 UILabel* label = [[[UILabel alloc] initWithFrame:bounds] autorelease]; |
57 label.text = [[NSProcessInfo processInfo] processName]; | 57 label.text = [[NSProcessInfo processInfo] processName]; |
58 label.textAlignment = UITextAlignmentCenter; | 58 label.textAlignment = UITextAlignmentCenter; |
59 [window_ addSubview:label]; | 59 [window_ addSubview:label]; |
60 | 60 |
| 61 if ([self shouldRedirectOutputToFile]) |
| 62 [self redirectOutput]; |
| 63 |
61 // Queue up the test run. | 64 // Queue up the test run. |
62 [self performSelector:@selector(runTests) | 65 [self performSelector:@selector(runTests) |
63 withObject:nil | 66 withObject:nil |
64 afterDelay:0.1]; | 67 afterDelay:0.1]; |
65 return YES; | 68 return YES; |
66 } | 69 } |
67 | 70 |
| 71 // Returns true if the gtest output should be redirected to a file, then sent |
| 72 // to NSLog when compleete. This redirection is used because gtest only writes |
| 73 // output to stdout, but results must be written to NSLog in order to show up in |
| 74 // the device log that is retrieved from the device by the host. |
| 75 - (BOOL)shouldRedirectOutputToFile { |
| 76 #if !TARGET_IPHONE_SIMULATOR |
| 77 return !base::debug::BeingDebugged(); |
| 78 #endif // TARGET_IPHONE_SIMULATOR |
| 79 return NO; |
| 80 } |
| 81 |
| 82 // Returns the path to the directory to store gtest output files. |
| 83 - (NSString*)outputPath { |
| 84 NSArray* searchPath = |
| 85 NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, |
| 86 NSUserDomainMask, |
| 87 YES); |
| 88 CHECK([searchPath count] > 0) << "Failed to get the Documents folder"; |
| 89 return [searchPath objectAtIndex:0]; |
| 90 } |
| 91 |
| 92 // Returns the path to file that stdout is redirected to. |
| 93 - (NSString*)stdoutPath { |
| 94 return [[self outputPath] stringByAppendingPathComponent:@"stdout.log"]; |
| 95 } |
| 96 |
| 97 // Returns the path to file that stderr is redirected to. |
| 98 - (NSString*)stderrPath { |
| 99 return [[self outputPath] stringByAppendingPathComponent:@"stderr.log"]; |
| 100 } |
| 101 |
| 102 // Redirects stdout and stderr to files in the Documents folder in the app's |
| 103 // sandbox. |
| 104 - (void)redirectOutput { |
| 105 freopen([[self stdoutPath] UTF8String], "w+", stdout); |
| 106 freopen([[self stderrPath] UTF8String], "w+", stderr); |
| 107 } |
| 108 |
| 109 // Reads the redirected gtest output from a file and writes it to NSLog. |
| 110 - (void)writeOutputToNSLog { |
| 111 for (NSString* path in @[ [self stdoutPath], [self stderrPath]]) { |
| 112 NSString* content = [NSString stringWithContentsOfFile:path |
| 113 encoding:NSUTF8StringEncoding |
| 114 error:NULL]; |
| 115 NSArray* lines = [content componentsSeparatedByCharactersInSet: |
| 116 [NSCharacterSet newlineCharacterSet]]; |
| 117 |
| 118 NSLog(@"Writing contents of %@ to NSLog", path); |
| 119 for (NSString* line in lines) { |
| 120 NSLog(@"%@", line); |
| 121 } |
| 122 } |
| 123 } |
| 124 |
68 - (void)runTests { | 125 - (void)runTests { |
69 int exitStatus = g_test_suite->Run(); | 126 int exitStatus = g_test_suite->Run(); |
70 | 127 |
| 128 if ([self shouldRedirectOutputToFile]) |
| 129 [self writeOutputToNSLog]; |
| 130 |
71 // If a test app is too fast, it will exit before Instruments has has a | 131 // If a test app is too fast, it will exit before Instruments has has a |
72 // a chance to initialize and no test results will be seen. | 132 // a chance to initialize and no test results will be seen. |
73 // TODO(ios): crbug.com/137010 Figure out how much time is actually needed, | 133 // TODO(ios): crbug.com/137010 Figure out how much time is actually needed, |
74 // and sleep only to make sure that much time has elapsed since launch. | 134 // and sleep only to make sure that much time has elapsed since launch. |
75 [NSThread sleepUntilDate:[NSDate dateWithTimeIntervalSinceNow:2.0]]; | 135 [NSThread sleepUntilDate:[NSDate dateWithTimeIntervalSinceNow:2.0]]; |
76 window_.reset(); | 136 window_.reset(); |
77 | 137 |
78 // Use the hidden selector to try and cleanly take down the app (otherwise | 138 // Use the hidden selector to try and cleanly take down the app (otherwise |
79 // things can think the app crashed even on a zero exit status). | 139 // things can think the app crashed even on a zero exit status). |
80 UIApplication* application = [UIApplication sharedApplication]; | 140 UIApplication* application = [UIApplication sharedApplication]; |
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
119 if (!ran_hook) { | 179 if (!ran_hook) { |
120 ran_hook = true; | 180 ran_hook = true; |
121 mac::ScopedNSAutoreleasePool pool; | 181 mac::ScopedNSAutoreleasePool pool; |
122 int exit_status = UIApplicationMain(g_argc, g_argv, nil, | 182 int exit_status = UIApplicationMain(g_argc, g_argv, nil, |
123 @"ChromeUnitTestDelegate"); | 183 @"ChromeUnitTestDelegate"); |
124 exit(exit_status); | 184 exit(exit_status); |
125 } | 185 } |
126 } | 186 } |
127 | 187 |
128 } // namespace base | 188 } // namespace base |
OLD | NEW |