[NC Apple coverage] Add unit tests for nearby::apple::AwdlMedium.

PiperOrigin-RevId: 802840092
This commit is contained in:
Edwin Wu
2025-09-03 21:18:51 -07:00
committed by Copybara-Service
parent f0d164fc40
commit b90f1d3719
5 changed files with 320 additions and 19 deletions
@@ -28,9 +28,9 @@
}
- (void)startAdvertisingPort:(NSInteger)port
serviceName:(NSString*)serviceName
serviceType:(NSString*)serviceType
txtRecords:(NSDictionary<NSString*, NSString*>*)txtRecords {
serviceName:(NSString *)serviceName
serviceType:(NSString *)serviceType
txtRecords:(NSDictionary<NSString *, NSString *> *)txtRecords {
self.startedAdvertisingPort = @(port);
self.startedAdvertisingServiceName = serviceName;
self.startedAdvertisingServiceType = serviceType;
@@ -40,52 +40,79 @@
self.stoppedAdvertisingPort = @(port);
}
- (BOOL)startDiscoveryForServiceType:(NSString*)serviceType
- (BOOL)startDiscoveryForServiceType:(NSString *)serviceType
serviceFoundHandler:(nonnull ServiceUpdateHandler)serviceFoundHandler
serviceLostHandler:(nonnull ServiceUpdateHandler)serviceLostHandler
includePeerToPeer:(BOOL)includePeerToPeer
error:(NSError**)error {
error:(NSError **)error {
self.startedDiscoveryServiceType = serviceType;
self.startedDiscoveryIncludePeerToPeer = includePeerToPeer;
return YES;
}
- (void)stopDiscoveryForServiceType:(NSString*)serviceType {
- (void)stopDiscoveryForServiceType:(NSString *)serviceType {
self.stoppedDiscoveryServiceType = serviceType;
}
- (GNCNWFrameworkSocket*)connectToServiceName:(NSString*)serviceName
serviceType:(NSString*)serviceType
error:(NSError**)error {
- (GNCNWFrameworkSocket *)connectToServiceName:(NSString *)serviceName
serviceType:(NSString *)serviceType
error:(NSError **)error {
self.connectedToServiceName = serviceName;
self.connectedToServiceType = serviceType;
nw_connection_t connection = (nw_connection_t) @"mock connection";
GNCFakeNWFrameworkSocket* socket =
GNCFakeNWFrameworkSocket *socket =
[[GNCFakeNWFrameworkSocket alloc] initWithConnection:connection];
[self.sockets addObject:socket];
return socket;
}
- (GNCNWFrameworkSocket*)connectToHost:(GNCIPv4Address*)host
port:(NSInteger)port
includePeerToPeer:(BOOL)includePeerToPeer
error:(NSError**)error {
- (nullable GNCNWFrameworkSocket *)connectToServiceName:(NSString *)serviceName
serviceType:(NSString *)serviceType
PSKIdentity:(NSData *)pskIdentity
PSKSharedSecret:(NSData *)pskSharedSecret
error:(NSError **)error {
self.connectedToServiceName = serviceName;
self.connectedToServiceType = serviceType;
nw_connection_t connection = (nw_connection_t) @"mock connection";
GNCFakeNWFrameworkSocket *socket =
[[GNCFakeNWFrameworkSocket alloc] initWithConnection:connection];
[self.sockets addObject:socket];
return socket;
}
- (GNCNWFrameworkSocket *)connectToHost:(GNCIPv4Address *)host
port:(NSInteger)port
includePeerToPeer:(BOOL)includePeerToPeer
error:(NSError **)error {
self.connectedToHost = host;
self.connectedToPort = port;
self.connectedToIncludePeerToPeer = includePeerToPeer;
nw_connection_t connection = (nw_connection_t) @"mock connection";
GNCFakeNWFrameworkSocket* socket =
GNCFakeNWFrameworkSocket *socket =
[[GNCFakeNWFrameworkSocket alloc] initWithConnection:connection];
[self.sockets addObject:socket];
return socket;
}
- (GNCNWFrameworkServerSocket*)listenForServiceOnPort:(NSInteger)port
includePeerToPeer:(BOOL)includePeerToPeer
error:(NSError**)error {
- (GNCNWFrameworkServerSocket *)listenForServiceOnPort:(NSInteger)port
includePeerToPeer:(BOOL)includePeerToPeer
error:(NSError **)error {
self.listenedForServiceOnPort = port;
self.listenedForServiceIncludePeerToPeer = includePeerToPeer;
GNCFakeNWFrameworkServerSocket* serverSocket =
GNCFakeNWFrameworkServerSocket *serverSocket =
[[GNCFakeNWFrameworkServerSocket alloc] initWithPort:port];
[self.serverSockets addObject:serverSocket];
return serverSocket;
}
- (nullable GNCNWFrameworkServerSocket *)listenForServiceWithPSKIdentity:(NSData *)pskIdentity
PSKSharedSecret:(NSData *)pskSharedSecret
port:(NSInteger)port
includePeerToPeer:(BOOL)includePeerToPeer
error:(NSError **)error {
self.listenedForServiceOnPort = port;
self.listenedForServiceIncludePeerToPeer = includePeerToPeer;
GNCFakeNWFrameworkServerSocket *serverSocket =
[[GNCFakeNWFrameworkServerSocket alloc] initWithPort:port];
[self.serverSockets addObject:serverSocket];
return serverSocket;
@@ -24,6 +24,7 @@ objc_library(
name = "PlatformTestslib",
testonly = True,
srcs = [
"GNCAwdlMediumTest.mm",
"GNCCryptoTest.mm",
"GNCDeviceInfoTest.mm",
"GNCMultiThreadExecutorTest.mm",
@@ -0,0 +1,269 @@
// Copyright 2025 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// https://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#include "internal/platform/implementation/apple/awdl.h"
#import <XCTest/XCTest.h>
#include <string>
#import "internal/platform/implementation/apple/Mediums/WiFiCommon/GNCIPv4Address.h"
#import "internal/platform/implementation/apple/Mediums/WiFiCommon/GNCNWFramework.h"
#import "internal/platform/implementation/apple/Mediums/WiFiCommon/Tests/GNCFakeNWFramework.h"
#import "internal/platform/implementation/apple/Mediums/WiFiCommon/Tests/GNCFakeNWFrameworkServerSocket.h"
#import "internal/platform/implementation/apple/Mediums/WiFiCommon/Tests/GNCFakeNWFrameworkSocket.h"
static NSString* const kTestServiceType = @"_my-service._tcp";
static NSString* const kTestServiceName = @"My Service";
static const int kTestPort = 1234;
@interface GNCAwdlMediumTest : XCTestCase
@end
@implementation GNCAwdlMediumTest {
GNCFakeNWFramework* _fakeNWFramework;
std::unique_ptr<nearby::apple::AwdlMedium> _awdlMedium;
}
- (void)setUp {
[super setUp];
_fakeNWFramework = [[GNCFakeNWFramework alloc] init];
_awdlMedium = std::make_unique<nearby::apple::AwdlMedium>(_fakeNWFramework);
}
- (void)tearDown {
_awdlMedium.reset();
[super tearDown];
}
- (void)testStartAdvertising {
nearby::NsdServiceInfo nsdServiceInfo;
nsdServiceInfo.SetServiceType([kTestServiceType UTF8String]);
nsdServiceInfo.SetServiceName([kTestServiceName UTF8String]);
nsdServiceInfo.SetPort(kTestPort);
XCTAssertTrue(_awdlMedium->StartAdvertising(nsdServiceInfo));
XCTAssertEqualObjects(_fakeNWFramework.startedAdvertisingPort, @(kTestPort));
XCTAssertEqualObjects(_fakeNWFramework.startedAdvertisingServiceName, kTestServiceName);
XCTAssertEqualObjects(_fakeNWFramework.startedAdvertisingServiceType, kTestServiceType);
}
- (void)testStopAdvertising {
nearby::NsdServiceInfo nsdServiceInfo;
nsdServiceInfo.SetPort(kTestPort);
XCTAssertTrue(_awdlMedium->StopAdvertising(nsdServiceInfo));
XCTAssertEqualObjects(_fakeNWFramework.stoppedAdvertisingPort, @(kTestPort));
}
- (void)testStartDiscovery {
std::string serviceType = [kTestServiceType UTF8String];
XCTAssertTrue(_awdlMedium->StartDiscovery(serviceType,
nearby::api::AwdlMedium::DiscoveredServiceCallback{}));
XCTAssertEqualObjects(_fakeNWFramework.startedDiscoveryServiceType, kTestServiceType);
XCTAssertTrue(_fakeNWFramework.startedDiscoveryIncludePeerToPeer);
}
- (void)testStopDiscovery {
std::string serviceType = [kTestServiceType UTF8String];
XCTAssertTrue(_awdlMedium->StopDiscovery(serviceType));
XCTAssertEqualObjects(_fakeNWFramework.stoppedDiscoveryServiceType, kTestServiceType);
}
- (void)testConnectToService {
nearby::NsdServiceInfo nsdServiceInfo;
nsdServiceInfo.SetServiceType([kTestServiceType UTF8String]);
nsdServiceInfo.SetServiceName([kTestServiceName UTF8String]);
nearby::CancellationFlag cancellationFlag;
_awdlMedium->ConnectToService(nsdServiceInfo, &cancellationFlag);
XCTAssertEqualObjects(_fakeNWFramework.connectedToServiceName, kTestServiceName);
XCTAssertEqualObjects(_fakeNWFramework.connectedToServiceType, kTestServiceType);
}
- (void)testConnectToServiceWithPsk {
nearby::NsdServiceInfo nsdServiceInfo;
nsdServiceInfo.SetServiceType([kTestServiceType UTF8String]);
nsdServiceInfo.SetServiceName([kTestServiceName UTF8String]);
nearby::api::PskInfo pskInfo;
nearby::CancellationFlag cancellationFlag;
_awdlMedium->ConnectToService(nsdServiceInfo, pskInfo, &cancellationFlag);
XCTAssertEqualObjects(_fakeNWFramework.connectedToServiceName, kTestServiceName);
XCTAssertEqualObjects(_fakeNWFramework.connectedToServiceType, kTestServiceType);
}
- (void)testListenForService {
std::unique_ptr<nearby::api::AwdlServerSocket> serverSocket =
_awdlMedium->ListenForService(kTestPort);
XCTAssertTrue(serverSocket != nullptr);
XCTAssertEqual(_fakeNWFramework.listenedForServiceOnPort, kTestPort);
XCTAssertTrue(_fakeNWFramework.listenedForServiceIncludePeerToPeer);
}
- (void)testListenForServiceWithPsk {
nearby::api::PskInfo pskInfo;
std::unique_ptr<nearby::api::AwdlServerSocket> serverSocket =
_awdlMedium->ListenForService(pskInfo, kTestPort);
XCTAssertTrue(serverSocket != nullptr);
XCTAssertEqual(_fakeNWFramework.listenedForServiceOnPort, kTestPort);
XCTAssertTrue(_fakeNWFramework.listenedForServiceIncludePeerToPeer);
}
- (void)testSocketAndStream {
// Create a server socket.
std::unique_ptr<nearby::api::AwdlServerSocket> serverSocket =
_awdlMedium->ListenForService(kTestPort);
XCTAssertTrue(serverSocket != nullptr);
GNCFakeNWFrameworkServerSocket* fakeServerSocket =
(GNCFakeNWFrameworkServerSocket*)_fakeNWFramework.serverSockets[0];
nw_connection_t connection = (nw_connection_t) @"mock connection";
GNCFakeNWFrameworkSocket* fakeSocket =
[[GNCFakeNWFrameworkSocket alloc] initWithConnection:connection];
fakeServerSocket.socketToReturnOnAccept = fakeSocket;
// Accept a client socket.
std::unique_ptr<nearby::api::AwdlSocket> clientSocket = serverSocket->Accept();
XCTAssertTrue(clientSocket != nullptr);
// Test input stream.
nearby::InputStream& inputStream = clientSocket->GetInputStream();
fakeSocket.dataToRead = [@"test data" dataUsingEncoding:NSUTF8StringEncoding];
nearby::ExceptionOr<nearby::ByteArray> readData = inputStream.Read(9);
XCTAssertTrue(readData.ok());
XCTAssertEqual(std::string(readData.result()), "test data");
// Test output stream.
nearby::OutputStream& outputStream = clientSocket->GetOutputStream();
nearby::ByteArray writeData("write data");
XCTAssertTrue(outputStream.Write(writeData).Ok());
XCTAssertEqualObjects(fakeSocket.writtenData,
[@"write data" dataUsingEncoding:NSUTF8StringEncoding]);
// Test closing the socket.
XCTAssertTrue(clientSocket->Close().Ok());
XCTAssertTrue(fakeSocket.isClosed);
// Test closing the server socket.
XCTAssertTrue(serverSocket->Close().Ok());
XCTAssertTrue(fakeServerSocket.isClosed);
}
- (void)testServerSocketGetIPAddress {
// Create a server socket.
std::unique_ptr<nearby::api::AwdlServerSocket> serverSocket =
_awdlMedium->ListenForService(kTestPort);
XCTAssertTrue(serverSocket != nullptr);
// IP address is hardcoded in GNCFakeNWFrameworkServerSocket to 192.168.1.1
GNCIPv4Address* ipAddress = [GNCIPv4Address addressWithDottedRepresentation:@"192.168.1.1"];
NSData* ipAddressData = ipAddress.binaryRepresentation;
XCTAssertEqual(serverSocket->GetIPAddress(),
std::string((char*)ipAddressData.bytes, ipAddressData.length));
// Test closing the server socket.
XCTAssertTrue(serverSocket->Close().Ok());
}
- (void)testServerSocketGetPort {
// Create a server socket.
std::unique_ptr<nearby::api::AwdlServerSocket> serverSocket =
_awdlMedium->ListenForService(kTestPort);
XCTAssertTrue(serverSocket != nullptr);
XCTAssertEqual(serverSocket->GetPort(), kTestPort);
// Test closing the server socket.
XCTAssertTrue(serverSocket->Close().Ok());
}
- (void)testOutputStreamClose {
// Create a server socket and accept a client.
std::unique_ptr<nearby::api::AwdlServerSocket> serverSocket =
_awdlMedium->ListenForService(kTestPort);
GNCFakeNWFrameworkServerSocket* fakeServerSocket =
(GNCFakeNWFrameworkServerSocket*)_fakeNWFramework.serverSockets[0];
nw_connection_t connection = (nw_connection_t) @"mock connection";
GNCFakeNWFrameworkSocket* fakeSocket =
[[GNCFakeNWFrameworkSocket alloc] initWithConnection:connection];
fakeServerSocket.socketToReturnOnAccept = fakeSocket;
std::unique_ptr<nearby::api::AwdlSocket> clientSocket = serverSocket->Accept();
XCTAssertTrue(clientSocket != nullptr);
// Get the output stream.
nearby::OutputStream& outputStream = clientSocket->GetOutputStream();
// Close the output stream.
XCTAssertTrue(outputStream.Close().Ok());
XCTAssertFalse(fakeSocket.isClosed);
// Close the server socket.
XCTAssertTrue(serverSocket->Close().Ok());
}
- (void)testOutputStreamFlush {
// Create a server socket and accept a client.
std::unique_ptr<nearby::api::AwdlServerSocket> serverSocket =
_awdlMedium->ListenForService(kTestPort);
GNCFakeNWFrameworkServerSocket* fakeServerSocket =
(GNCFakeNWFrameworkServerSocket*)_fakeNWFramework.serverSockets[0];
nw_connection_t connection = (nw_connection_t) @"mock connection";
GNCFakeNWFrameworkSocket* fakeSocket =
[[GNCFakeNWFrameworkSocket alloc] initWithConnection:connection];
fakeServerSocket.socketToReturnOnAccept = fakeSocket;
std::unique_ptr<nearby::api::AwdlSocket> clientSocket = serverSocket->Accept();
XCTAssertTrue(clientSocket != nullptr);
// Get the output stream.
nearby::OutputStream& outputStream = clientSocket->GetOutputStream();
// Flush the output stream.
XCTAssertTrue(outputStream.Flush().Ok());
// Close the socket and server socket.
XCTAssertTrue(clientSocket->Close().Ok());
XCTAssertTrue(serverSocket->Close().Ok());
}
- (void)testInputStreamClose {
// Create a server socket and accept a client.
std::unique_ptr<nearby::api::AwdlServerSocket> serverSocket =
_awdlMedium->ListenForService(kTestPort);
GNCFakeNWFrameworkServerSocket* fakeServerSocket =
(GNCFakeNWFrameworkServerSocket*)_fakeNWFramework.serverSockets[0];
nw_connection_t connection = (nw_connection_t) @"mock connection";
GNCFakeNWFrameworkSocket* fakeSocket =
[[GNCFakeNWFrameworkSocket alloc] initWithConnection:connection];
fakeServerSocket.socketToReturnOnAccept = fakeSocket;
std::unique_ptr<nearby::api::AwdlSocket> clientSocket = serverSocket->Accept();
XCTAssertTrue(clientSocket != nullptr);
// Get the input stream.
nearby::InputStream& inputStream = clientSocket->GetInputStream();
// Close the input stream.
XCTAssertTrue(inputStream.Close().Ok());
XCTAssertFalse(fakeSocket.isClosed);
// Close the server socket.
XCTAssertTrue(serverSocket->Close().Ok());
}
@end
@@ -100,6 +100,8 @@ class AwdlServerSocket : public api::AwdlServerSocket {
class AwdlMedium : public api::AwdlMedium {
public:
AwdlMedium();
// For testing only.
explicit AwdlMedium(GNCNWFramework* medium);
~AwdlMedium() override = default;
AwdlMedium(const AwdlMedium&) = delete;
@@ -124,6 +124,8 @@ Exception AwdlServerSocket::Close() {
AwdlMedium::AwdlMedium() { medium_ = [[GNCNWFramework alloc] init]; }
AwdlMedium::AwdlMedium(GNCNWFramework* medium) : medium_(medium) {}
bool AwdlMedium::StartAdvertising(const NsdServiceInfo& nsd_service_info) {
return network_utils::StartAdvertising(medium_, nsd_service_info);
}