When running an XCTest that executes a network operation, i get the following error:
-waitForExpectationsWithTimeout: timed out but was unable to run the timeout handler because the main thread was unresponsive (0.5 seconds is allowed after the wait times out). Conditions that may cause this include processing blocking IO on the main thread, calls to sleep(), deadlocks, and synchronous IPC. Xcode will attempt to relaunch the process and continue with the next test...
I have a test that executes a Network Command method which uses NSURLSession under the hood.
This test is part of a test class with 4 consecutive network request tests.
When run independently from other tests it succeeds every time. When running the entire Test file (4 tests in total), it succeeds every time.
But when running the entire test suite (50 tests), i get "Stall on main thread" on the first network operation test. The other 3 network operation tests go through fine.
Here is the code for the test:
- (void)test_session_001_ObtainsSessionObjectFromServer
{
XCTestExpectation *expectation = [self expectationWithDescription:[self description]];
id<IPVideoSessionProtocol> provider = [IPVideoSessionFactory getProvider];
[provider createVideoSessionWithUserID:@"SomeUserID"
withCompletionBlock:^(IPVideoSession *session) {
if ([session isKindOfClass:[IPVideoSession class]] &&
[session.sessionID isKindOfClass:[NSString class]] &&
session.sessionID.length > 0) {
// The returned session ID is populated
[expectation fulfill];
}
}];
[self waitForExpectationsWithTimeout:5.0f handler:^(NSError *error) {
if (error)
{
XCTFail(@"IPVideoSessionManagerTests Did not execute in allotted time");
}
}];
}
The code inside createVideoSession...
- (void)createVideoSessionWithUserID:(NSString*)userID
withCompletionBlock:(IPVideoSessionCompletionBlock)block
{
IPCreateVideoSessionCommand* command = [[IPCreateVideoSessionCommand alloc]
initWithUserID:userID];
[command executeWithCompletionBlock:^(IPNetworkError *error, NSString *resultJSON)
{
if (error) {
[IPAlertPresenter displayNetworkError:error];
block(nil);
return;
}
NSDictionary *dict = [resultJSON toJsonDictionary];
block([IPVideoSession getSessionFromDictionary:dict]);
}];
}
The code inside executeWithCompletionBlock:
- (void)executeWithCompletionBlock:(CommandCompletionBlock)block
{
if (!self.isConnected && ![[IPDebugManager sharedInstance] networkBypassActivated]) {
IPNetworkError* error = [[IPNetworkError alloc] initWithType:NetworkErrorTypeNotConnectedToNetwork];
block(error, nil);
return;
}
NSURLSession *session = [self composeSession];
NSURLRequest *request = [self composeRequest];
self.strongSelf = self;
__weak __typeof(self) weakSelf = self;
NSURLSessionDataTask *dataTask = [session dataTaskWithRequest:request completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) {
[IPDispatch toMainThread:^{
[weakSelf
handleCommandResponse:response
withData:data
withError:error
withCompletionBlock:block];
weakSelf.strongSelf = nil;
}];
}];
[dataTask resume];
}
NOTE: This error only happens when all tests are run. This test succeeds by itself, and also: if I run all 4 tests inside this Test Class.