1/* 2 * Copyright (C) 2010 Google Inc. All rights reserved. 3 * 4 * Redistribution and use in source and binary forms, with or without 5 * modification, are permitted provided that the following conditions are 6 * met: 7 * 8 * * Redistributions of source code must retain the above copyright 9 * notice, this list of conditions and the following disclaimer. 10 * * Redistributions in binary form must reproduce the above 11 * copyright notice, this list of conditions and the following disclaimer 12 * in the documentation and/or other materials provided with the 13 * distribution. 14 * * Neither the name of Google Inc. nor the names of its 15 * contributors may be used to endorse or promote products derived from 16 * this software without specific prior written permission. 17 * 18 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 19 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 20 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 21 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 22 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 23 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 24 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 25 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 26 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 27 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 28 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 */ 30 31#include "config.h" 32 33#include "TestShell.h" 34#include "WebThemeEngineDRTMac.h" 35#include "webkit/support/webkit_support.h" 36#import <AppKit/AppKit.h> 37 38static WebThemeEngineDRTMac themeEngine; 39 40// A class to be the target/selector of the "watchdog" thread that ensures 41// pages timeout if they take too long and tells the test harness via stdout. 42@interface WatchDogTarget : NSObject { 43@private 44 NSTimeInterval _timeout; 45} 46// |timeout| is in seconds 47- (id)initWithTimeout:(NSTimeInterval)timeout; 48// serves as the "run" method of a NSThread. 49- (void)run:(id)sender; 50@end 51 52@implementation WatchDogTarget 53 54- (id)initWithTimeout:(NSTimeInterval)timeout 55{ 56 if ((self = [super init])) 57 _timeout = timeout; 58 return self; 59} 60 61- (void)run:(id)ignore 62{ 63 NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init]; 64 65 // check for debugger, just bail if so. We don't want the timeouts hitting 66 // when we're trying to track down an issue. 67 if (webkit_support::BeingDebugged()) 68 return; 69 70 NSThread* currentThread = [NSThread currentThread]; 71 72 // Wait to be cancelled. If we are that means the test finished. If it hasn't, 73 // then we need to tell the layout script we timed out and start again. 74 NSDate* limitDate = [NSDate dateWithTimeIntervalSinceNow:_timeout]; 75 while ([(NSDate*)[NSDate date] compare:limitDate] == NSOrderedAscending && 76 ![currentThread isCancelled]) { 77 // sleep for a small increment then check again 78 NSDate* incrementDate = [NSDate dateWithTimeIntervalSinceNow:1.0]; 79 [NSThread sleepUntilDate:incrementDate]; 80 } 81 if (![currentThread isCancelled]) { 82 // Print a warning to be caught by the layout-test script. 83 // Note: the layout test driver may or may not recognize 84 // this as a timeout. 85 puts("#TEST_TIMED_OUT\n"); 86 puts("#EOF\n"); 87 fflush(stdout); 88 exit(0); 89 } 90 91 [pool release]; 92} 93 94@end 95 96void TestShell::waitTestFinished() 97{ 98 ASSERT(!m_testIsPending); 99 100 m_testIsPending = true; 101 102 // Create a watchdog thread which just sets a timer and 103 // kills the process if it times out. This catches really 104 // bad hangs where the shell isn't coming back to the 105 // message loop. If the watchdog is what catches a 106 // timeout, it can't do anything except terminate the test 107 // shell, which is unfortunate. 108 // Windows multiplies by 2.5, but that causes us to run for far, far too 109 // long. We use the passed value and let the scripts flag override 110 // the value as needed. 111 NSTimeInterval timeoutSeconds = layoutTestTimeoutForWatchDog() / 1000; 112 WatchDogTarget* watchdog = [[[WatchDogTarget alloc] 113 initWithTimeout:timeoutSeconds] autorelease]; 114 NSThread* thread = [[NSThread alloc] initWithTarget:watchdog 115 selector:@selector(run:) 116 object:nil]; 117 [thread start]; 118 119 // TestFinished() will post a quit message to break this loop when the page 120 // finishes loading. 121 while (m_testIsPending) 122 webkit_support::RunMessageLoop(); 123 124 // Tell the watchdog that we're finished. No point waiting to re-join, it'll 125 // die on its own. 126 [thread cancel]; 127 [thread release]; 128} 129 130void platformInit(int*, char***) 131{ 132 webkit_support::SetThemeEngine(&themeEngine); 133} 134 135void openStartupDialog() 136{ 137 // FIXME: This code doesn't work. Need NSApplication event loop? 138 NSAlert* alert = [[[NSAlert alloc] init] autorelease]; 139 alert.messageText = @"Attach to me?"; 140 alert.informativeText = @"This would probably be a good time to attach your debugger."; 141 [alert addButtonWithTitle:@"OK"]; 142 [alert runModal]; 143} 144 145bool checkLayoutTestSystemDependencies() 146{ 147 return true; 148} 149 150