mirror of
https://github.com/kidfromjupiter/nearby.git
synced 2026-09-14 14:46:12 -04:00
[NC Apple coverage] Test implementation for Wifi LAN medium.
PiperOrigin-RevId: 802829901
This commit is contained in:
committed by
Copybara-Service
parent
6e1fd931b7
commit
f0d164fc40
@@ -35,10 +35,15 @@
|
||||
byte3:(uint8_t)byte3
|
||||
byte4:(uint8_t)byte4 NS_DESIGNATED_INITIALIZER;
|
||||
|
||||
/** Creates an IPv4 address from a 4 byte integer. */
|
||||
+ (nonnull instancetype)addressFromFourByteInt:(uint32_t)address;
|
||||
|
||||
/** Creates an IPv4 address from a 4 byte data object. */
|
||||
+ (nonnull instancetype)addressFromData:(nonnull NSData *)address;
|
||||
|
||||
/** Creates an IPv4 address from a human readable dotted representation. */
|
||||
+ (nullable instancetype)addressWithDottedRepresentation:(nonnull NSString *)address;
|
||||
|
||||
/** The first byte of the IP address. */
|
||||
@property(nonatomic, readonly) uint8_t byte1;
|
||||
|
||||
|
||||
@@ -47,6 +47,33 @@
|
||||
byte4:bytes[3]];
|
||||
}
|
||||
|
||||
+ (nullable instancetype)addressWithDottedRepresentation:(NSString *)address {
|
||||
NSArray<NSString *> *components = [address componentsSeparatedByString:@"."];
|
||||
if (components.count != 4) {
|
||||
return nil;
|
||||
}
|
||||
|
||||
uint8_t bytes[4];
|
||||
for (int i = 0; i < 4; ++i) {
|
||||
NSScanner *scanner = [NSScanner scannerWithString:components[i]];
|
||||
int value;
|
||||
// The string must be a valid integer and must not contain any other characters.
|
||||
if (![scanner scanInt:&value] || ![scanner isAtEnd]) {
|
||||
return nil;
|
||||
}
|
||||
|
||||
if (value < 0 || value > 255) {
|
||||
return nil;
|
||||
}
|
||||
bytes[i] = (uint8_t)value;
|
||||
}
|
||||
|
||||
return [[GNCIPv4Address alloc] initWithByte1:bytes[0]
|
||||
byte2:bytes[1]
|
||||
byte3:bytes[2]
|
||||
byte4:bytes[3]];
|
||||
}
|
||||
|
||||
- (NSData *)binaryRepresentation {
|
||||
const uint8_t bytes[] = {_byte1, _byte2, _byte3, _byte4};
|
||||
return [NSData dataWithBytes:bytes length:4];
|
||||
|
||||
@@ -20,6 +20,25 @@ licenses(["notice"])
|
||||
|
||||
package(default_visibility = ["//:__subpackages__"])
|
||||
|
||||
objc_library(
|
||||
name = "FakeNWFramework",
|
||||
testonly = True,
|
||||
srcs = [
|
||||
"GNCFakeNWFramework.m",
|
||||
"GNCFakeNWFrameworkServerSocket.m",
|
||||
"GNCFakeNWFrameworkSocket.m",
|
||||
],
|
||||
hdrs = [
|
||||
"GNCFakeNWFramework.h",
|
||||
"GNCFakeNWFrameworkServerSocket.h",
|
||||
"GNCFakeNWFrameworkSocket.h",
|
||||
],
|
||||
deps = [
|
||||
"//internal/platform/implementation/apple/Mediums/WiFiCommon",
|
||||
"//third_party/apple_frameworks:Foundation",
|
||||
],
|
||||
)
|
||||
|
||||
objc_library(
|
||||
name = "WiFiCommonTestsLib",
|
||||
testonly = True,
|
||||
|
||||
@@ -0,0 +1,46 @@
|
||||
// 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.
|
||||
|
||||
#import "internal/platform/implementation/apple/Mediums/WiFiCommon/GNCNWFramework.h"
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
@class GNCFakeNWFrameworkSocket;
|
||||
@class GNCFakeNWFrameworkServerSocket;
|
||||
|
||||
/** A fake implementation of @c GNCNWFramework to inject for testing. */
|
||||
@interface GNCFakeNWFramework : GNCNWFramework
|
||||
|
||||
@property(nonatomic, nullable) NSNumber* startedAdvertisingPort;
|
||||
@property(nonatomic, nullable) NSString* startedAdvertisingServiceName;
|
||||
@property(nonatomic, nullable) NSString* startedAdvertisingServiceType;
|
||||
@property(nonatomic, nullable) NSNumber* stoppedAdvertisingPort;
|
||||
@property(nonatomic, nullable) NSString* startedDiscoveryServiceType;
|
||||
@property(nonatomic) BOOL startedDiscoveryIncludePeerToPeer;
|
||||
@property(nonatomic, nullable) NSString* stoppedDiscoveryServiceType;
|
||||
@property(nonatomic, nullable) NSString* connectedToServiceName;
|
||||
@property(nonatomic, nullable) NSString* connectedToServiceType;
|
||||
@property(nonatomic, nullable) GNCIPv4Address* connectedToHost;
|
||||
@property(nonatomic) NSInteger connectedToPort;
|
||||
@property(nonatomic) BOOL connectedToIncludePeerToPeer;
|
||||
@property(nonatomic) NSInteger listenedForServiceOnPort;
|
||||
@property(nonatomic) BOOL listenedForServiceIncludePeerToPeer;
|
||||
@property(nonatomic, readonly) NSMutableArray<GNCFakeNWFrameworkSocket *>* sockets;
|
||||
@property(nonatomic, readonly) NSMutableArray<GNCFakeNWFrameworkServerSocket *>* serverSockets;
|
||||
|
||||
@end
|
||||
|
||||
NS_ASSUME_NONNULL_END
|
||||
@@ -0,0 +1,94 @@
|
||||
// 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.
|
||||
|
||||
#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"
|
||||
|
||||
@implementation GNCFakeNWFramework
|
||||
|
||||
- (instancetype)init {
|
||||
self = [super init];
|
||||
if (self) {
|
||||
_sockets = [NSMutableArray array];
|
||||
_serverSockets = [NSMutableArray array];
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
- (void)startAdvertisingPort:(NSInteger)port
|
||||
serviceName:(NSString*)serviceName
|
||||
serviceType:(NSString*)serviceType
|
||||
txtRecords:(NSDictionary<NSString*, NSString*>*)txtRecords {
|
||||
self.startedAdvertisingPort = @(port);
|
||||
self.startedAdvertisingServiceName = serviceName;
|
||||
self.startedAdvertisingServiceType = serviceType;
|
||||
}
|
||||
|
||||
- (void)stopAdvertisingPort:(NSInteger)port {
|
||||
self.stoppedAdvertisingPort = @(port);
|
||||
}
|
||||
|
||||
- (BOOL)startDiscoveryForServiceType:(NSString*)serviceType
|
||||
serviceFoundHandler:(nonnull ServiceUpdateHandler)serviceFoundHandler
|
||||
serviceLostHandler:(nonnull ServiceUpdateHandler)serviceLostHandler
|
||||
includePeerToPeer:(BOOL)includePeerToPeer
|
||||
error:(NSError**)error {
|
||||
self.startedDiscoveryServiceType = serviceType;
|
||||
self.startedDiscoveryIncludePeerToPeer = includePeerToPeer;
|
||||
return YES;
|
||||
}
|
||||
|
||||
- (void)stopDiscoveryForServiceType:(NSString*)serviceType {
|
||||
self.stoppedDiscoveryServiceType = serviceType;
|
||||
}
|
||||
|
||||
- (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 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 alloc] initWithConnection:connection];
|
||||
[self.sockets addObject:socket];
|
||||
return socket;
|
||||
}
|
||||
|
||||
- (GNCNWFrameworkServerSocket*)listenForServiceOnPort:(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;
|
||||
}
|
||||
|
||||
@end
|
||||
+32
@@ -0,0 +1,32 @@
|
||||
// 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.
|
||||
|
||||
#import "internal/platform/implementation/apple/Mediums/WiFiCommon/GNCNWFrameworkServerSocket.h"
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
@class GNCFakeNWFrameworkSocket;
|
||||
|
||||
/** A fake implementation of @c GNCNWFrameworkServerSocket to inject for testing. */
|
||||
@interface GNCFakeNWFrameworkServerSocket : GNCNWFrameworkServerSocket
|
||||
|
||||
@property(nonatomic) BOOL isClosed;
|
||||
@property(nonatomic, nullable) NSError* acceptError;
|
||||
@property(nonatomic, nullable) GNCFakeNWFrameworkSocket* socketToReturnOnAccept;
|
||||
|
||||
@end
|
||||
|
||||
NS_ASSUME_NONNULL_END
|
||||
+54
@@ -0,0 +1,54 @@
|
||||
// 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.
|
||||
|
||||
#import "internal/platform/implementation/apple/Mediums/WiFiCommon/Tests/GNCFakeNWFrameworkServerSocket.h"
|
||||
|
||||
#import "internal/platform/implementation/apple/Mediums/WiFiCommon/GNCIPv4Address.h"
|
||||
#import "internal/platform/implementation/apple/Mediums/WiFiCommon/Tests/GNCFakeNWFrameworkSocket.h"
|
||||
|
||||
@implementation GNCFakeNWFrameworkServerSocket {
|
||||
GNCIPv4Address *_ipAddress;
|
||||
}
|
||||
|
||||
- (instancetype)initWithPort:(NSInteger)port {
|
||||
self = [super initWithPort:port];
|
||||
if (self) {
|
||||
_ipAddress = [[GNCIPv4Address alloc] initWithByte1:192 byte2:168 byte3:1 byte4:1];
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
- (GNCIPv4Address *)ipAddress {
|
||||
return _ipAddress;
|
||||
}
|
||||
|
||||
- (nullable GNCNWFrameworkSocket *)acceptWithError:(NSError **)error {
|
||||
if (self.acceptError) {
|
||||
if (error) {
|
||||
*error = self.acceptError;
|
||||
}
|
||||
return nil;
|
||||
}
|
||||
if (self.socketToReturnOnAccept) {
|
||||
return self.socketToReturnOnAccept;
|
||||
}
|
||||
nw_connection_t connection = (nw_connection_t) @"mock connection";
|
||||
return [[GNCFakeNWFrameworkSocket alloc] initWithConnection:connection];
|
||||
}
|
||||
|
||||
- (void)close {
|
||||
self.isClosed = YES;
|
||||
}
|
||||
|
||||
@end
|
||||
+32
@@ -0,0 +1,32 @@
|
||||
// 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.
|
||||
|
||||
#import "internal/platform/implementation/apple/Mediums/WiFiCommon/GNCNWFrameworkSocket.h"
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
/** A fake implementation of @c GNCNWFrameworkSocket to inject for testing. */
|
||||
@interface GNCFakeNWFrameworkSocket : GNCNWFrameworkSocket
|
||||
|
||||
@property(nonatomic, nullable) NSData* dataToRead;
|
||||
@property(nonatomic, readonly) NSMutableData* writtenData;
|
||||
@property(nonatomic) BOOL isClosed;
|
||||
@property(nonatomic, nullable) NSError* readError;
|
||||
@property(nonatomic, nullable) NSError* writeError;
|
||||
|
||||
@end
|
||||
|
||||
NS_ASSUME_NONNULL_END
|
||||
+57
@@ -0,0 +1,57 @@
|
||||
// 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.
|
||||
|
||||
#import "internal/platform/implementation/apple/Mediums/WiFiCommon/Tests/GNCFakeNWFrameworkSocket.h"
|
||||
|
||||
@implementation GNCFakeNWFrameworkSocket
|
||||
|
||||
- (instancetype)initWithConnection:(nw_connection_t)connection {
|
||||
self = [super initWithConnection:connection];
|
||||
if (self) {
|
||||
_writtenData = [NSMutableData data];
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
- (nullable NSData *)readMaxLength:(NSUInteger)length error:(NSError **)error {
|
||||
if (self.readError) {
|
||||
if (error) {
|
||||
*error = self.readError;
|
||||
}
|
||||
return nil;
|
||||
}
|
||||
if (self.dataToRead) {
|
||||
NSData *data = self.dataToRead;
|
||||
self.dataToRead = nil;
|
||||
return data;
|
||||
}
|
||||
return [NSData data];
|
||||
}
|
||||
|
||||
- (BOOL)write:(NSData *)data error:(NSError **)error {
|
||||
if (self.writeError) {
|
||||
if (error) {
|
||||
*error = self.writeError;
|
||||
}
|
||||
return NO;
|
||||
}
|
||||
[self.writtenData appendData:data];
|
||||
return YES;
|
||||
}
|
||||
|
||||
- (void)close {
|
||||
self.isClosed = YES;
|
||||
}
|
||||
|
||||
@end
|
||||
@@ -111,4 +111,32 @@
|
||||
XCTAssertEqual(bytes[3], 171);
|
||||
}
|
||||
|
||||
- (void)testAddressWithDottedRepresentationWithValidAddress {
|
||||
GNCIPv4Address *address =
|
||||
[GNCIPv4Address addressWithDottedRepresentation:@"192.168.1.1"];
|
||||
XCTAssertNotNil(address);
|
||||
XCTAssertEqual(address.byte1, 192);
|
||||
XCTAssertEqual(address.byte2, 168);
|
||||
XCTAssertEqual(address.byte3, 1);
|
||||
XCTAssertEqual(address.byte4, 1);
|
||||
}
|
||||
|
||||
- (void)testAddressWithDottedRepresentationWithOutOfRangeAddress {
|
||||
XCTAssertNil([GNCIPv4Address addressWithDottedRepresentation:@"256.1.1.1"]);
|
||||
XCTAssertNil([GNCIPv4Address addressWithDottedRepresentation:@"-1.1.1.1"]);
|
||||
}
|
||||
|
||||
- (void)testAddressWithDottedRepresentationWithNonNumericAddress {
|
||||
XCTAssertNil([GNCIPv4Address addressWithDottedRepresentation:@"foo.1.1.1"]);
|
||||
XCTAssertNil([GNCIPv4Address addressWithDottedRepresentation:@"1.foo.1.1"]);
|
||||
XCTAssertNil([GNCIPv4Address addressWithDottedRepresentation:@"1.1.foo.1"]);
|
||||
XCTAssertNil([GNCIPv4Address addressWithDottedRepresentation:@"1.1.1.foo"]);
|
||||
}
|
||||
|
||||
- (void)testAddressWithDottedRepresentationWithInvalidFormatAddress {
|
||||
XCTAssertNil([GNCIPv4Address addressWithDottedRepresentation:@"1.1.1"]);
|
||||
XCTAssertNil([GNCIPv4Address addressWithDottedRepresentation:@"1.1.1.1.1"]);
|
||||
XCTAssertNil([GNCIPv4Address addressWithDottedRepresentation:@""]);
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
@@ -31,6 +31,7 @@ objc_library(
|
||||
"GNCScheduledExecutorTest.mm",
|
||||
"GNCSingleThreadExecutorTest.mm",
|
||||
"GNCUtilsTest.m",
|
||||
"GNCWifiLanMediumTest.mm",
|
||||
"UtilsTest.mm",
|
||||
],
|
||||
deps = [
|
||||
@@ -40,6 +41,8 @@ objc_library(
|
||||
"//internal/platform/implementation/apple", # buildcleaner: keep
|
||||
"//internal/platform/implementation/apple:Shared",
|
||||
"//internal/platform/implementation/apple:ble_v2",
|
||||
"//internal/platform/implementation/apple/Mediums/WiFiCommon",
|
||||
"//internal/platform/implementation/apple/Mediums/WiFiCommon/Tests:FakeNWFramework",
|
||||
"//third_party/apple_frameworks:CommonCrypto",
|
||||
"//third_party/apple_frameworks:Foundation",
|
||||
"//third_party/apple_frameworks:XCTest",
|
||||
|
||||
@@ -0,0 +1,257 @@
|
||||
// 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.
|
||||
|
||||
#import <XCTest/XCTest.h>
|
||||
|
||||
#include "internal/platform/implementation/apple/wifi_lan.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"
|
||||
|
||||
@interface GNCWifiLanMediumTest : XCTestCase
|
||||
@end
|
||||
|
||||
@implementation GNCWifiLanMediumTest {
|
||||
GNCFakeNWFramework* _fakeNWFramework;
|
||||
std::unique_ptr<nearby::apple::WifiLanMedium> _wifiLanMedium;
|
||||
}
|
||||
|
||||
- (void)setUp {
|
||||
[super setUp];
|
||||
_fakeNWFramework = [[GNCFakeNWFramework alloc] init];
|
||||
_wifiLanMedium = std::make_unique<nearby::apple::WifiLanMedium>(_fakeNWFramework);
|
||||
}
|
||||
|
||||
- (void)tearDown {
|
||||
_wifiLanMedium.reset();
|
||||
_fakeNWFramework = nil;
|
||||
[super tearDown];
|
||||
}
|
||||
|
||||
- (void)testStartAdvertising {
|
||||
nearby::NsdServiceInfo nsdServiceInfo;
|
||||
nsdServiceInfo.SetServiceType("_my-service._tcp");
|
||||
nsdServiceInfo.SetServiceName("My Service");
|
||||
nsdServiceInfo.SetPort(1234);
|
||||
|
||||
XCTAssertTrue(_wifiLanMedium->StartAdvertising(nsdServiceInfo));
|
||||
XCTAssertEqualObjects(_fakeNWFramework.startedAdvertisingPort, @(1234));
|
||||
XCTAssertEqualObjects(_fakeNWFramework.startedAdvertisingServiceName, @"My Service");
|
||||
XCTAssertEqualObjects(_fakeNWFramework.startedAdvertisingServiceType, @"_my-service._tcp");
|
||||
}
|
||||
|
||||
- (void)testStopAdvertising {
|
||||
nearby::NsdServiceInfo nsdServiceInfo;
|
||||
nsdServiceInfo.SetPort(1234);
|
||||
|
||||
XCTAssertTrue(_wifiLanMedium->StopAdvertising(nsdServiceInfo));
|
||||
XCTAssertEqualObjects(_fakeNWFramework.stoppedAdvertisingPort, @(1234));
|
||||
}
|
||||
|
||||
- (void)testStartDiscovery {
|
||||
std::string serviceType = "_my-service._tcp";
|
||||
|
||||
XCTAssertTrue(_wifiLanMedium->StartDiscovery(
|
||||
serviceType, nearby::api::WifiLanMedium::DiscoveredServiceCallback{}));
|
||||
XCTAssertEqualObjects(_fakeNWFramework.startedDiscoveryServiceType, @"_my-service._tcp");
|
||||
XCTAssertFalse(_fakeNWFramework.startedDiscoveryIncludePeerToPeer);
|
||||
}
|
||||
|
||||
- (void)testStopDiscovery {
|
||||
std::string serviceType = "_my-service._tcp";
|
||||
|
||||
XCTAssertTrue(_wifiLanMedium->StopDiscovery(serviceType));
|
||||
XCTAssertEqualObjects(_fakeNWFramework.stoppedDiscoveryServiceType, @"_my-service._tcp");
|
||||
}
|
||||
|
||||
- (void)testConnectToServiceWithNsdServiceInfo {
|
||||
nearby::NsdServiceInfo nsdServiceInfo;
|
||||
nsdServiceInfo.SetServiceType("_my-service._tcp");
|
||||
nsdServiceInfo.SetServiceName("My Service");
|
||||
|
||||
nearby::CancellationFlag cancellationFlag;
|
||||
_wifiLanMedium->ConnectToService(nsdServiceInfo, &cancellationFlag);
|
||||
XCTAssertEqualObjects(_fakeNWFramework.connectedToServiceName, @"My Service");
|
||||
XCTAssertEqualObjects(_fakeNWFramework.connectedToServiceType, @"_my-service._tcp");
|
||||
}
|
||||
|
||||
- (void)testConnectToServiceWithIpAddressAndPort {
|
||||
std::string ipAddress = "\xC0\xA8\x01\x01"; // 192.168.1.1
|
||||
int port = 1234;
|
||||
|
||||
nearby::CancellationFlag cancellationFlag;
|
||||
_wifiLanMedium->ConnectToService(ipAddress, port, &cancellationFlag);
|
||||
|
||||
XCTAssertEqualObjects([_fakeNWFramework.connectedToHost dottedRepresentation], @"192.168.1.1");
|
||||
XCTAssertEqual(_fakeNWFramework.connectedToPort, 1234);
|
||||
XCTAssertFalse(_fakeNWFramework.connectedToIncludePeerToPeer);
|
||||
}
|
||||
|
||||
- (void)testListenForService {
|
||||
int port = 1234;
|
||||
|
||||
std::unique_ptr<nearby::api::WifiLanServerSocket> serverSocket =
|
||||
_wifiLanMedium->ListenForService(port);
|
||||
|
||||
XCTAssertTrue(serverSocket != nullptr);
|
||||
XCTAssertEqual(_fakeNWFramework.listenedForServiceOnPort, 1234);
|
||||
XCTAssertFalse(_fakeNWFramework.listenedForServiceIncludePeerToPeer);
|
||||
}
|
||||
|
||||
- (void)testSocketAndStream {
|
||||
// Create a server socket.
|
||||
std::unique_ptr<nearby::api::WifiLanServerSocket> serverSocket =
|
||||
_wifiLanMedium->ListenForService(1234);
|
||||
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::WifiLanSocket> 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::WifiLanServerSocket> serverSocket =
|
||||
_wifiLanMedium->ListenForService(1234);
|
||||
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::WifiLanServerSocket> serverSocket =
|
||||
_wifiLanMedium->ListenForService(1234);
|
||||
XCTAssertTrue(serverSocket != nullptr);
|
||||
|
||||
XCTAssertEqual(serverSocket->GetPort(), 1234);
|
||||
|
||||
// Test closing the server socket.
|
||||
XCTAssertTrue(serverSocket->Close().Ok());
|
||||
}
|
||||
|
||||
- (void)testOutputStreamClose {
|
||||
// Create a server socket and accept a client.
|
||||
std::unique_ptr<nearby::api::WifiLanServerSocket> serverSocket =
|
||||
_wifiLanMedium->ListenForService(1234);
|
||||
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::WifiLanSocket> 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::WifiLanServerSocket> serverSocket =
|
||||
_wifiLanMedium->ListenForService(1234);
|
||||
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::WifiLanSocket> 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::WifiLanServerSocket> serverSocket =
|
||||
_wifiLanMedium->ListenForService(1234);
|
||||
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::WifiLanSocket> 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
|
||||
@@ -103,6 +103,8 @@ class WifiLanServerSocket : public api::WifiLanServerSocket {
|
||||
class WifiLanMedium : public api::WifiLanMedium {
|
||||
public:
|
||||
WifiLanMedium();
|
||||
// For testing only.
|
||||
explicit WifiLanMedium(GNCNWFramework* medium);
|
||||
~WifiLanMedium() override = default;
|
||||
|
||||
WifiLanMedium(const WifiLanMedium&) = delete;
|
||||
|
||||
@@ -124,6 +124,8 @@ Exception WifiLanServerSocket::Close() {
|
||||
|
||||
WifiLanMedium::WifiLanMedium() { medium_ = [[GNCNWFramework alloc] init]; }
|
||||
|
||||
WifiLanMedium::WifiLanMedium(GNCNWFramework* medium) : medium_(medium) {}
|
||||
|
||||
bool WifiLanMedium::StartAdvertising(const NsdServiceInfo& nsd_service_info) {
|
||||
return network_utils::StartAdvertising(medium_, nsd_service_info);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user