mirror of
https://github.com/kidfromjupiter/nearby.git
synced 2026-09-16 15:36: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
|
||||
|
||||
Reference in New Issue
Block a user