PageRenderTime 47ms CodeModel.GetById 14ms app.highlight 30ms RepoModel.GetById 1ms app.codeStats 0ms

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

http://macfuse.googlecode.com/
Objective C | 182 lines | 124 code | 28 blank | 30 comment | 2 complexity | acc923ff77c16c02b34890386045467c MD5 | raw file
  1//
  2//  GTMTransientRootPortProxyTest.m
  3//
  4//  Copyright 2006-2009 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 "GTMSenTestCase.h"
 20#import "GTMTransientRootPortProxy.h"
 21
 22#define kDefaultTimeout 5.0
 23
 24enum {
 25  kGTMTransientThreadConditionStarting = 777,
 26  kGTMTransientThreadConditionStarted,
 27  kGTMTransientThreadConditionQuitting,
 28  kGTMTransientThreadConditionQuitted
 29};
 30
 31// === Start off declaring some auxillary data structures ===
 32
 33// The @protocol that we'll use for testing with.
 34@protocol DOPortTestProtocol
 35- (oneway void)doOneWayVoid;
 36- (bycopy NSString *)doReturnStringBycopy;
 37@end
 38
 39// The "server" we'll use to test the DO connection.  This server will implement
 40// our test protocol, and it will run in a separate thread from the main
 41// unit testing thread, so the DO requests can be serviced.
 42@interface DOPortTestServer : NSObject <DOPortTestProtocol> {
 43 @private
 44  NSPort *clientSendPort_;
 45  NSPort *clientReceivePort_;
 46}
 47- (void)runThread:(NSConditionLock *)lock;
 48- (NSPort *)clientSendPort;
 49- (NSPort *)clientReceivePort;
 50@end
 51
 52@implementation DOPortTestServer
 53
 54- (void)runThread:(NSConditionLock *)lock {
 55  NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
 56  NSDate *future = [NSDate dateWithTimeIntervalSinceNow:kDefaultTimeout];
 57  if(![lock lockWhenCondition:kGTMTransientThreadConditionStarting
 58                   beforeDate:future]) {
 59    _GTMDevLog(@"Unable to acquire lock in runThread! This is BAD!");
 60    [pool drain];
 61    [NSThread exit];
 62  }
 63
 64  clientSendPort_ = [NSPort port];
 65  clientReceivePort_ = [NSPort port];
 66
 67  NSConnection *conn
 68    = [[NSConnection alloc] initWithReceivePort:clientSendPort_
 69                                       sendPort:clientReceivePort_];
 70  [conn setRootObject:self];
 71  [lock unlockWithCondition:kGTMTransientThreadConditionStarted];
 72  while (![lock tryLockWhenCondition:kGTMTransientThreadConditionQuitting]) {
 73    NSDate *runUntil = [NSDate dateWithTimeIntervalSinceNow:0.1];
 74    [[NSRunLoop currentRunLoop] runUntilDate:runUntil];
 75  }
 76  [conn setRootObject:nil];
 77  [clientSendPort_ invalidate];
 78  [clientReceivePort_ invalidate];
 79  [conn release];
 80  [pool drain];
 81  [lock unlockWithCondition:kGTMTransientThreadConditionQuitted];
 82}
 83
 84- (NSPort *)clientSendPort {
 85  return clientSendPort_;
 86}
 87
 88- (NSPort *)clientReceivePort {
 89  return clientReceivePort_;
 90}
 91
 92- (oneway void)doOneWayVoid {
 93  // Do nothing
 94}
 95- (bycopy NSString *)doReturnStringBycopy {
 96  return @"TestString";
 97}
 98
 99@end
100
101// === Done with auxillary data structures, now for the main test class ===
102
103@interface GTMTransientRootPortProxyTest : GTMTestCase {
104  DOPortTestServer *server_;
105  NSConditionLock *syncLock_;
106}
107
108@end
109
110@implementation GTMTransientRootPortProxyTest
111
112- (void)testTransientRootPortProxy {
113  syncLock_ = [[[NSConditionLock alloc]
114                initWithCondition:kGTMTransientThreadConditionStarting]
115               autorelease];
116
117  // Setup our server.
118  server_ = [[[DOPortTestServer alloc] init] autorelease];
119  [NSThread detachNewThreadSelector:@selector(runThread:)
120                           toTarget:server_
121                         withObject:syncLock_];
122  NSDate *future = [NSDate dateWithTimeIntervalSinceNow:kDefaultTimeout];
123  STAssertTrue([syncLock_ lockWhenCondition:kGTMTransientThreadConditionStarted
124                                 beforeDate:future],
125               @"Unable to start thread");
126  [syncLock_ unlockWithCondition:kGTMTransientThreadConditionStarted];
127
128  NSPort *receivePort = [server_ clientReceivePort];
129  NSPort *sendPort = [server_ clientSendPort];
130
131  GTMTransientRootPortProxy<DOPortTestProtocol> *failProxy =
132    [GTMTransientRootPortProxy rootProxyWithReceivePort:nil
133                                               sendPort:nil
134                                               protocol:@protocol(DOPortTestProtocol)
135                                         requestTimeout:kDefaultTimeout
136                                           replyTimeout:kDefaultTimeout];
137  STAssertNil(failProxy, @"should have failed w/o a port");
138  failProxy =
139    [GTMTransientRootPortProxy rootProxyWithReceivePort:receivePort
140                                               sendPort:sendPort
141                                               protocol:nil
142                                         requestTimeout:kDefaultTimeout
143                                           replyTimeout:kDefaultTimeout];
144  STAssertNil(failProxy, @"should have failed w/o a protocol");
145
146  GTMTransientRootPortProxy<DOPortTestProtocol> *proxy =
147    [GTMTransientRootPortProxy rootProxyWithReceivePort:receivePort
148                                               sendPort:sendPort
149                                               protocol:@protocol(DOPortTestProtocol)
150                                         requestTimeout:kDefaultTimeout
151                                           replyTimeout:kDefaultTimeout];
152
153  STAssertEqualObjects([proxy doReturnStringBycopy],
154                       @"TestString", @"proxy should have returned "
155                       @"'TestString'");
156
157  // Redo the *exact* same test to make sure we can have multiple instances
158  // in the same app.
159  proxy =
160    [GTMTransientRootPortProxy rootProxyWithReceivePort:receivePort
161                                               sendPort:sendPort
162                                               protocol:@protocol(DOPortTestProtocol)
163                                         requestTimeout:kDefaultTimeout
164                                           replyTimeout:kDefaultTimeout];
165
166  STAssertEqualObjects([proxy doReturnStringBycopy],
167                       @"TestString", @"proxy should have returned "
168                       @"'TestString'");
169  [syncLock_ tryLockWhenCondition:kGTMTransientThreadConditionStarted];
170  [syncLock_ unlockWithCondition:kGTMTransientThreadConditionQuitting];
171
172  // Wait for the server to shutdown so we clean up nicely.
173  // The max amount of time we will wait until we abort this test.
174  NSDate *timeout = [NSDate dateWithTimeIntervalSinceNow:kDefaultTimeout];
175  // The server did not shutdown and we want to capture this as an error
176  STAssertTrue([syncLock_ lockWhenCondition:kGTMTransientThreadConditionQuitted
177                                 beforeDate:timeout],
178               @"The server did not shutdown gracefully before the timeout.");
179  [syncLock_ unlockWithCondition:kGTMTransientThreadConditionQuitted];
180}
181
182@end