mirror of
https://github.com/kidfromjupiter/nearby.git
synced 2026-09-14 14:46:12 -04:00
[NC Apple coverage] Refactor GNCNWFrameworkServerSocket and add more tests.
PiperOrigin-RevId: 831142947
This commit is contained in:
committed by
Copybara-Service
parent
50de2233f5
commit
a96818b409
+15
@@ -96,6 +96,21 @@ NS_ASSUME_NONNULL_BEGIN
|
||||
state:(nw_connection_state_t)state
|
||||
error:(nullable nw_error_t)error;
|
||||
|
||||
/**
|
||||
* Handles a new incoming connection from the listener.
|
||||
*
|
||||
* @param connection The new connection object.
|
||||
*/
|
||||
- (void)handleNewConnection:(nw_connection_t)connection;
|
||||
|
||||
/**
|
||||
* Configures a connection's queue and state handler, then starts it.
|
||||
* NOTE: This method should not be called directly except for testing purposes.
|
||||
*
|
||||
* @param connection The connection to configure and start.
|
||||
*/
|
||||
- (void)configureAndStartConnection:(nw_connection_t)connection;
|
||||
|
||||
@end
|
||||
|
||||
NS_ASSUME_NONNULL_END
|
||||
|
||||
+10
-5
@@ -66,6 +66,7 @@ NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
@implementation GNCNWFrameworkServerSocket {
|
||||
NSInteger _port;
|
||||
// TODO: b/434870979 - Use a dispatch_semaphore instead of a condition to simplify the logic.
|
||||
NSCondition *_condition;
|
||||
dispatch_queue_t _dispatchQueue;
|
||||
id<GNCNWListener> _listener;
|
||||
@@ -288,17 +289,18 @@ NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
// This doesn't start flaking until 0.0005 seconds, so 0.5 should be plenty of time.
|
||||
BOOL didSignal = [_condition waitUntilDate:[NSDate dateWithTimeIntervalSinceNow:0.5]];
|
||||
// We timed out waiting for the listener to transition into a state.
|
||||
if (!didSignal) {
|
||||
_listenerError = [NSError errorWithDomain:GNCNWFrameworkErrorDomain
|
||||
code:GNCNWFrameworkErrorTimedOut
|
||||
userInfo:nil];
|
||||
}
|
||||
if (error != nil) {
|
||||
*error = [_listenerError copy];
|
||||
}
|
||||
[_condition unlock];
|
||||
|
||||
// We timed out waiting for the listener to transition into a state.
|
||||
if (!didSignal) {
|
||||
[self close];
|
||||
_listenerError = [NSError errorWithDomain:GNCNWFrameworkErrorDomain
|
||||
code:GNCNWFrameworkErrorTimedOut
|
||||
userInfo:nil];
|
||||
return NO;
|
||||
}
|
||||
|
||||
@@ -322,7 +324,10 @@ NS_ASSUME_NONNULL_BEGIN
|
||||
// Keep track of any incoming connections. We must keep a reference otherwise the connection will
|
||||
// be dropped.
|
||||
[self.pendingConnections addObject:connection];
|
||||
[self configureAndStartConnection:connection];
|
||||
}
|
||||
|
||||
- (void)configureAndStartConnection:(nw_connection_t)connection {
|
||||
// Register for state changes so we can clean up any failed/canceled connections and inform Nearby
|
||||
// of any ready connections when asked.
|
||||
nw_connection_set_queue(connection, _dispatchQueue);
|
||||
|
||||
+139
@@ -25,6 +25,7 @@
|
||||
#import "internal/platform/implementation/apple/Mediums/WiFiCommon/GNCNWFrameworkSocket.h"
|
||||
#import "internal/platform/implementation/apple/Mediums/WiFiCommon/Tests/GNCFakeNWConnection.h"
|
||||
#import "internal/platform/implementation/apple/Mediums/WiFiCommon/Tests/GNCFakeNWListener.h"
|
||||
#import "third_party/objective_c/ocmock/v3/Source/OCMock/OCMock.h"
|
||||
|
||||
@interface GNCNWFrameworkServerSocketTest : XCTestCase
|
||||
@end
|
||||
@@ -90,6 +91,59 @@
|
||||
XCTAssertNil(error, @"error should be nil when accept is successful");
|
||||
}
|
||||
|
||||
- (void)testAcceptWithError_FailureWhenListenerFails API_AVAILABLE(ios(13.0)) {
|
||||
// Simulate listener entering a failed state.
|
||||
_serverSocket.listenerState = nw_listener_state_failed;
|
||||
_serverSocket.listenerError = [NSError errorWithDomain:@"Test" code:123 userInfo:nil];
|
||||
|
||||
NSError *error = nil;
|
||||
GNCNWFrameworkSocket *socket = [_serverSocket acceptWithError:&error];
|
||||
|
||||
XCTAssertNil(socket, @"acceptWithError should return nil when listener has failed");
|
||||
XCTAssertNotNil(error, @"error should be non-nil when listener has failed");
|
||||
XCTAssertEqualObjects(error.domain, @"Test");
|
||||
XCTAssertEqual(error.code, 123);
|
||||
}
|
||||
|
||||
- (void)testStartListening_Timeout API_AVAILABLE(ios(13.0)) {
|
||||
_fakeListener.simulateTimeout = YES;
|
||||
NSError *error = nil;
|
||||
XCTAssertFalse([_serverSocket startListeningWithError:&error includePeerToPeer:NO]);
|
||||
XCTAssertNotNil(error);
|
||||
XCTAssertEqualObjects(error.domain, GNCNWFrameworkErrorDomain);
|
||||
XCTAssertEqual(error.code, GNCNWFrameworkErrorTimedOut);
|
||||
}
|
||||
|
||||
- (void)testStartListening_StateInvalid API_AVAILABLE(ios(13.0)) {
|
||||
_fakeListener.stateForStart = nw_listener_state_invalid;
|
||||
_serverSocket.listenerError = [NSError errorWithDomain:@"Test" code:123 userInfo:nil];
|
||||
NSError *error = nil;
|
||||
XCTAssertFalse([_serverSocket startListeningWithError:&error includePeerToPeer:NO]);
|
||||
XCTAssertNotNil(error);
|
||||
XCTAssertEqualObjects(error.domain, @"Test");
|
||||
XCTAssertEqual(error.code, 123);
|
||||
}
|
||||
|
||||
- (void)testStartListening_StateWaiting API_AVAILABLE(ios(13.0)) {
|
||||
_fakeListener.stateForStart = nw_listener_state_waiting;
|
||||
_serverSocket.listenerError = [NSError errorWithDomain:@"Test" code:123 userInfo:nil];
|
||||
NSError *error = nil;
|
||||
XCTAssertFalse([_serverSocket startListeningWithError:&error includePeerToPeer:NO]);
|
||||
XCTAssertNotNil(error);
|
||||
XCTAssertEqualObjects(error.domain, @"Test");
|
||||
XCTAssertEqual(error.code, 123);
|
||||
}
|
||||
|
||||
- (void)testStartListening_StateCancelled API_AVAILABLE(ios(13.0)) {
|
||||
_fakeListener.stateForStart = nw_listener_state_cancelled;
|
||||
_serverSocket.listenerError = [NSError errorWithDomain:@"Test" code:123 userInfo:nil];
|
||||
NSError *error = nil;
|
||||
XCTAssertFalse([_serverSocket startListeningWithError:&error includePeerToPeer:NO]);
|
||||
XCTAssertNotNil(error);
|
||||
XCTAssertEqualObjects(error.domain, @"Test");
|
||||
XCTAssertEqual(error.code, 123);
|
||||
}
|
||||
|
||||
- (void)testStartListeningWithError_Success API_AVAILABLE(ios(13.0)) {
|
||||
// Configure the fake listener to simulate a successful start
|
||||
_fakeListener.port = 12345;
|
||||
@@ -220,4 +274,89 @@
|
||||
@"Connection should not be added to ready connections on failure.");
|
||||
}
|
||||
|
||||
- (void)testHandleNewConnectionAddsConnectionToPendingList API_AVAILABLE(ios(13.0)) {
|
||||
id partialServerSocket = OCMPartialMock(_serverSocket);
|
||||
OCMStub([partialServerSocket configureAndStartConnection:[OCMArg any]]);
|
||||
|
||||
GNCFakeNWConnection *fakeConnection = [[GNCFakeNWConnection alloc] init];
|
||||
nw_connection_t connection = (nw_connection_t)fakeConnection;
|
||||
|
||||
[partialServerSocket handleNewConnection:connection];
|
||||
|
||||
XCTAssertTrue([_serverSocket.pendingConnections containsObject:connection],
|
||||
@"handleNewConnection should add the connection to pendingConnections.");
|
||||
}
|
||||
|
||||
- (void)testHandleConnectionStateChange_Cancelled API_AVAILABLE(ios(13.0)) {
|
||||
GNCFakeNWConnection *fakeConnection = [[GNCFakeNWConnection alloc] init];
|
||||
nw_connection_t connection = (nw_connection_t)fakeConnection;
|
||||
|
||||
// Manually add to pending connections.
|
||||
[_serverSocket.pendingConnections addObject:connection];
|
||||
|
||||
// Simulate the connection failing.
|
||||
[_serverSocket handleConnectionStateChange:connection
|
||||
state:nw_connection_state_cancelled
|
||||
error:nil];
|
||||
|
||||
XCTAssertFalse([_serverSocket.pendingConnections containsObject:connection],
|
||||
@"Connection should be removed from pending connections on failure.");
|
||||
XCTAssertFalse([_serverSocket.readyConnections containsObject:connection],
|
||||
@"Connection should not be added to ready connections on failure.");
|
||||
}
|
||||
|
||||
- (void)testHandleConnectionStateChange_Invalid API_AVAILABLE(ios(13.0)) {
|
||||
GNCFakeNWConnection *fakeConnection = [[GNCFakeNWConnection alloc] init];
|
||||
nw_connection_t connection = (nw_connection_t)fakeConnection;
|
||||
|
||||
// Manually add to pending connections.
|
||||
[_serverSocket.pendingConnections addObject:connection];
|
||||
|
||||
// Simulate the connection failing.
|
||||
[_serverSocket handleConnectionStateChange:connection
|
||||
state:nw_connection_state_invalid
|
||||
error:nil];
|
||||
|
||||
XCTAssertFalse([_serverSocket.pendingConnections containsObject:connection],
|
||||
@"Connection should be removed from pending connections on failure.");
|
||||
XCTAssertFalse([_serverSocket.readyConnections containsObject:connection],
|
||||
@"Connection should not be added to ready connections on failure.");
|
||||
}
|
||||
|
||||
- (void)testHandleConnectionStateChange_Waiting API_AVAILABLE(ios(13.0)) {
|
||||
GNCFakeNWConnection *fakeConnection = [[GNCFakeNWConnection alloc] init];
|
||||
nw_connection_t connection = (nw_connection_t)fakeConnection;
|
||||
|
||||
// Manually add to pending connections.
|
||||
[_serverSocket.pendingConnections addObject:connection];
|
||||
|
||||
// Simulate the connection failing.
|
||||
[_serverSocket handleConnectionStateChange:connection
|
||||
state:nw_connection_state_waiting
|
||||
error:nil];
|
||||
|
||||
XCTAssertFalse([_serverSocket.pendingConnections containsObject:connection],
|
||||
@"Connection should be removed from pending connections on failure.");
|
||||
XCTAssertFalse([_serverSocket.readyConnections containsObject:connection],
|
||||
@"Connection should not be added to ready connections on failure.");
|
||||
}
|
||||
|
||||
- (void)testHandleConnectionStateChange_Preparing API_AVAILABLE(ios(13.0)) {
|
||||
GNCFakeNWConnection *fakeConnection = [[GNCFakeNWConnection alloc] init];
|
||||
nw_connection_t connection = (nw_connection_t)fakeConnection;
|
||||
|
||||
// Manually add to pending connections.
|
||||
[_serverSocket.pendingConnections addObject:connection];
|
||||
|
||||
// Simulate the connection failing.
|
||||
[_serverSocket handleConnectionStateChange:connection
|
||||
state:nw_connection_state_preparing
|
||||
error:nil];
|
||||
|
||||
XCTAssertTrue([_serverSocket.pendingConnections containsObject:connection],
|
||||
@"Connection should remain in pending connections when preparing.");
|
||||
XCTAssertFalse([_serverSocket.readyConnections containsObject:connection],
|
||||
@"Connection should not be added to ready connections when preparing.");
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
Reference in New Issue
Block a user