Index: new_tests/Makefile ================================================================== --- new_tests/Makefile +++ new_tests/Makefile @@ -51,12 +51,13 @@ OFSocketTests.m \ OFTCPSocketTests.m \ OFUDPSocketTests.m \ ${USE_SRCS_IPX} \ ${USE_SRCS_UNIX_SOCKETS} -SRCS_IPX = OFIPXSocketTests.m \ - OFSPXSocketTests.m +SRCS_IPX = OFIPXSocketTests.m \ + OFSPXSocketTests.m \ + OFSPXStreamSocketTests.m SRCS_UNIX_SOCKETS = OFUNIXDatagramSocketTests.m \ OFUNIXStreamSocketTests.m SRCS_SUBPROCESSES = OFSubprocessTests.m SRCS_THREADS = OFThreadTests.m ADDED new_tests/OFSPXStreamSocketTests.m Index: new_tests/OFSPXStreamSocketTests.m ================================================================== --- new_tests/OFSPXStreamSocketTests.m +++ new_tests/OFSPXStreamSocketTests.m @@ -0,0 +1,236 @@ +/* + * Copyright (c) 2008-2024 Jonathan Schleifer + * + * All rights reserved. + * + * This file is part of ObjFW. It may be distributed under the terms of the + * Q Public License 1.0, which can be found in the file LICENSE.QPL included in + * the packaging of this file. + * + * Alternatively, it may be distributed under the terms of the GNU General + * Public License, either version 2 or 3, which can be found in the file + * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this + * file. + */ + +#include "config.h" + +#include +#include + +#import "ObjFW.h" +#import "ObjFWTest.h" + +@interface OFSPXStreamSocketTests: OTTestCase +{ + OFSPXStreamSocket *_sockServer; + OFSocketAddress _addrServer; +} +@end + +@interface SPXStreamSocketDelegate: OFObject +{ +@public + OFStreamSocket *_expectedServerSocket; + OFSPXStreamSocket *_expectedClientSocket; + uint32_t _expectedNetwork; + unsigned char _expectedNode[IPX_NODE_LEN]; + uint16_t _expectedPort; + bool _accepted; + bool _connected; +} +@end + +@implementation OFSPXStreamSocketTests +- (void)setUp +{ + const unsigned char zeroNode[IPX_NODE_LEN] = { 0 }; + + _sockServer = [[OFSPXStreamSocket alloc] init]; + + @try { + _addrServer = [_sockServer bindToNetwork: 0 + node: zeroNode + port: 0]; + } @catch (OFBindSocketFailedException *e) { + switch (e.errNo) { + case EAFNOSUPPORT: + OTSkip(@"IPX unsupported"); + case ESOCKTNOSUPPORT: + case EPROTONOSUPPORT: + OTSkip(@"SPX unsupported"); + case EADDRNOTAVAIL: + OTSkip(@"IPX not configured"); + default: + @throw e; + } + } +} + +- (void)dealloc +{ + [_sockServer release]; + + [super dealloc]; +} + +- (void)testSPXStreamSocket +{ + OFSPXStreamSocket *sockClient, *sockAccepted; + const OFSocketAddress *addrAccepted; + uint32_t network; + unsigned char node[IPX_NODE_LEN], node2[IPX_NODE_LEN]; + uint16_t port; + OFDictionary *networkInterfaces; + char buffer[5]; + + sockClient = [OFSPXStreamSocket socket]; + + network = OFSocketAddressIPXNetwork(&_addrServer); + OFSocketAddressGetIPXNode(&_addrServer, node); + port = OFSocketAddressIPXPort(&_addrServer); + + [_sockServer listen]; + + /* + * Find any network interface with IPX and send to it. Any should be + * fine since we bound to 0.0. + */ + networkInterfaces = [OFSystemInfo networkInterfaces]; + for (OFString *name in networkInterfaces) { + OFNetworkInterface interface = [networkInterfaces + objectForKey: name]; + OFData *addresses = [interface + objectForKey: OFNetworkInterfaceIPXAddresses]; + + if (addresses.count == 0) + continue; + + network = OFSocketAddressIPXNetwork([addresses itemAtIndex: 0]); + OFSocketAddressGetIPXNode([addresses itemAtIndex: 0], node); + } + + [sockClient connectToNetwork: network node: node port: port]; + + sockAccepted = [_sockServer accept]; + [sockAccepted writeBuffer: "Hello" length: 5]; + + /* Test reassembly (this would not work with OFSPXSocket) */ + OTAssertEqual([sockClient readIntoBuffer: buffer length: 2], 2); + OTAssertEqual([sockClient readIntoBuffer: buffer + 2 length: 3], 3); + OTAssertEqual(memcmp(buffer, "Hello", 5), 0); + + addrAccepted = sockAccepted.remoteAddress; + OFSocketAddressGetIPXNode(addrAccepted, node2); + OTAssertEqual(memcmp(node, node2, IPX_NODE_LEN), 0); +} + +- (void)testAsyncSPXStreamSocket +{ + SPXStreamSocketDelegate *delegate = + [[[SPXStreamSocketDelegate alloc] init] autorelease]; + uint32_t network; + unsigned char node[IPX_NODE_LEN]; + uint16_t port; + OFDictionary *networkInterfaces; + OFSPXStreamSocket *sockClient; + + delegate->_expectedServerSocket = _sockServer; + _sockServer.delegate = delegate; + + sockClient = [OFSPXStreamSocket socket]; + delegate->_expectedClientSocket = sockClient; + sockClient.delegate = delegate; + + [_sockServer listen]; + [_sockServer asyncAccept]; + + network = OFSocketAddressIPXNetwork(&_addrServer); + OFSocketAddressGetIPXNode(&_addrServer, node); + port = OFSocketAddressIPXPort(&_addrServer); + + /* + * Find any network interface with IPX and send to it. Any should be + * fine since we bound to 0.0. + */ + networkInterfaces = [OFSystemInfo networkInterfaces]; + for (OFString *name in networkInterfaces) { + OFNetworkInterface interface = [networkInterfaces + objectForKey: name]; + OFData *addresses = [interface + objectForKey: OFNetworkInterfaceIPXAddresses]; + + if (addresses.count == 0) + continue; + + network = OFSocketAddressIPXNetwork([addresses itemAtIndex: 0]); + OFSocketAddressGetIPXNode([addresses itemAtIndex: 0], node); + } + + delegate->_expectedNetwork = network = + OFSocketAddressIPXNetwork(&_addrServer); + OFSocketAddressGetIPXNode(&_addrServer, node); + memcpy(delegate->_expectedNode, node, IPX_NODE_LEN); + delegate->_expectedPort = port = OFSocketAddressIPXPort(&_addrServer); + + @try { + [sockClient asyncConnectToNetwork: network + node: node + port: port]; + + [[OFRunLoop mainRunLoop] runUntilDate: + [OFDate dateWithTimeIntervalSinceNow: 2]]; + + OTAssertTrue(delegate->_accepted); + OTAssertTrue(delegate->_connected); + } @catch (OFObserveKernelEventsFailedException *e) { + /* + * Make sure it doesn't stay in the run loop and throws again + * next time we run the run loop. + */ + [sockClient cancelAsyncRequests]; + [_sockServer cancelAsyncRequests]; + + switch (e.errNo) { + case ENOTSOCK: + OTSkip(@"select() not supported for SPX"); + default: + @throw e; + } + } +} +@end + +@implementation SPXStreamSocketDelegate +- (bool)socket: (OFStreamSocket *)sock + didAcceptSocket: (OFStreamSocket *)accepted + exception: (id)exception +{ + OFEnsure(!_accepted); + + _accepted = (sock == _expectedServerSocket && accepted != nil && + exception == nil); + + if (_accepted && _connected) + [[OFRunLoop mainRunLoop] stop]; + + return false; +} + +- (void)socket: (OFSPXStreamSocket *)sock + didConnectToNetwork: (uint32_t)network + node: (const unsigned char [IPX_NODE_LEN])node + port: (uint16_t)port + exception: (id)exception +{ + OFEnsure(!_connected); + + _connected = (sock == _expectedClientSocket && + network == _expectedNetwork && + memcmp(node, _expectedNode, IPX_NODE_LEN) == 0 && + port == _expectedPort && exception == nil); + + if (_accepted && _connected) + [[OFRunLoop mainRunLoop] stop]; +} +@end Index: tests/Makefile ================================================================== --- tests/Makefile +++ tests/Makefile @@ -32,14 +32,12 @@ ${USE_SRCS_WINDOWS} SRCS_SOCKETS = ${OF_HTTP_CLIENT_TESTS_M} \ OFHTTPCookieTests.m \ OFHTTPCookieManagerTests.m \ OFKernelEventObserverTests.m \ - ${USE_SRCS_APPLETALK} \ - ${USE_SRCS_IPX} + ${USE_SRCS_APPLETALK} SRCS_APPLETALK = OFDDPSocketTests.m -SRCS_IPX = OFSPXStreamSocketTests.m SRCS_WINDOWS = OFWindowsRegistryKeyTests.m IOS_USER ?= mobile IOS_TMP ?= /tmp/objfw-test DELETED tests/OFSPXStreamSocketTests.m Index: tests/OFSPXStreamSocketTests.m ================================================================== --- tests/OFSPXStreamSocketTests.m +++ tests/OFSPXStreamSocketTests.m @@ -1,220 +0,0 @@ -/* - * Copyright (c) 2008-2024 Jonathan Schleifer - * - * All rights reserved. - * - * This file is part of ObjFW. It may be distributed under the terms of the - * Q Public License 1.0, which can be found in the file LICENSE.QPL included in - * the packaging of this file. - * - * Alternatively, it may be distributed under the terms of the GNU General - * Public License, either version 2 or 3, which can be found in the file - * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this - * file. - */ - -#include "config.h" - -#include - -#import "TestsAppDelegate.h" - -static OFString *const module = @"OFSPXStreamSocket"; - -@interface SPXStreamSocketDelegate: OFObject -{ -@public - OFStreamSocket *_expectedServerSocket; - OFSPXStreamSocket *_expectedClientSocket; - uint32_t _expectedNetwork; - unsigned char _expectedNode[IPX_NODE_LEN]; - uint16_t _expectedPort; - bool _accepted; - bool _connected; -} -@end - -@implementation SPXStreamSocketDelegate -- (bool)socket: (OFStreamSocket *)sock - didAcceptSocket: (OFStreamSocket *)accepted - exception: (id)exception -{ - OFEnsure(!_accepted); - - _accepted = (sock == _expectedServerSocket && accepted != nil && - exception == nil); - - if (_accepted && _connected) - [[OFRunLoop mainRunLoop] stop]; - - return false; -} - -- (void)socket: (OFSPXStreamSocket *)sock - didConnectToNetwork: (uint32_t)network - node: (const unsigned char [IPX_NODE_LEN])node - port: (uint16_t)port - exception: (id)exception -{ - OFEnsure(!_connected); - - _connected = (sock == _expectedClientSocket && - network == _expectedNetwork && - memcmp(node, _expectedNode, IPX_NODE_LEN) == 0 && - port == _expectedPort && exception == nil); - - if (_accepted && _connected) - [[OFRunLoop mainRunLoop] stop]; -} -@end - -@implementation TestsAppDelegate (OFSPXStreamSocketTests) -- (void)SPXStreamSocketTests -{ - const unsigned char zeroNode[IPX_NODE_LEN] = { 0 }; - void *pool = objc_autoreleasePoolPush(); - OFSPXStreamSocket *sockClient, *sockServer = nil, *sockAccepted; - OFSocketAddress address1; - const OFSocketAddress *address2; - uint32_t network; - unsigned char node[IPX_NODE_LEN], node2[IPX_NODE_LEN]; - uint16_t port; - OFDictionary *networkInterfaces; - char buffer[5]; - SPXStreamSocketDelegate *delegate; - - TEST(@"+[socket]", (sockClient = [OFSPXStreamSocket socket]) && - (sockServer = [OFSPXStreamSocket socket])) - - @try { - TEST(@"-[bindToNetwork:node:port:]", - R(address1 = [sockServer bindToNetwork: 0 - node: zeroNode - port: 0])) - } @catch (OFBindSocketFailedException *e) { - switch (e.errNo) { - case EAFNOSUPPORT: - [OFStdOut setForegroundColor: [OFColor lime]]; - [OFStdOut writeLine: - @"\r[OFSPXStreamSocket] -[bindToNetwork:node:" - @"port:]: IPX unsupported, skipping tests"]; - break; - case ESOCKTNOSUPPORT: - case EPROTONOSUPPORT: - [OFStdOut setForegroundColor: [OFColor lime]]; - [OFStdOut writeLine: - @"\r[OFSPXStreamSocket] -[bindToNetwork:node:" - @"port:]: SPX unsupported, skipping tests"]; - break; - case EADDRNOTAVAIL: - [OFStdOut setForegroundColor: [OFColor lime]]; - [OFStdOut writeLine: - @"\r[OFSPXStreamSocket] -[bindToNetwork:node:" - @"port:]: IPX not configured, skipping tests"]; - break; - default: - @throw e; - } - - objc_autoreleasePoolPop(pool); - return; - } - - network = OFSocketAddressIPXNetwork(&address1); - OFSocketAddressGetIPXNode(&address1, node); - port = OFSocketAddressIPXPort(&address1); - - TEST(@"-[listen]", R([sockServer listen])) - - /* - * Find any network interface with IPX and send to it. Any should be - * fine since we bound to 0.0. - */ - networkInterfaces = [OFSystemInfo networkInterfaces]; - for (OFString *name in networkInterfaces) { - OFNetworkInterface interface = [networkInterfaces - objectForKey: name]; - OFData *addresses = [interface - objectForKey: OFNetworkInterfaceIPXAddresses]; - - if (addresses.count == 0) - continue; - - network = OFSocketAddressIPXNetwork([addresses itemAtIndex: 0]); - OFSocketAddressGetIPXNode([addresses itemAtIndex: 0], node); - } - - TEST(@"-[connectToNetwork:node:port:]", - R([sockClient connectToNetwork: network node: node port: port])) - - TEST(@"-[accept]", (sockAccepted = [sockServer accept])) - - /* Test reassembly (this would not work with OFSPXSocket) */ - TEST(@"-[writeBuffer:length:]", - R([sockAccepted writeBuffer: "Hello" length: 5])) - - TEST(@"-[readIntoBuffer:length:]", - [sockClient readIntoBuffer: buffer length: 2] == 2 && - memcmp(buffer, "He", 2) == 0 && - [sockClient readIntoBuffer: buffer length: 3] == 3 && - memcmp(buffer, "llo", 3) == 0) - - TEST(@"-[remoteAddress]", - (address2 = sockAccepted.remoteAddress) && - R(OFSocketAddressGetIPXNode(address2, node2)) && - memcmp(node, node2, IPX_NODE_LEN) == 0) - - delegate = [[[SPXStreamSocketDelegate alloc] init] autorelease]; - - sockServer = [OFSPXStreamSocket socket]; - delegate->_expectedServerSocket = sockServer; - sockServer.delegate = delegate; - - sockClient = [OFSPXStreamSocket socket]; - delegate->_expectedClientSocket = sockClient; - sockClient.delegate = delegate; - - address1 = [sockServer bindToNetwork: 0 node: zeroNode port: 0]; - [sockServer listen]; - [sockServer asyncAccept]; - - delegate->_expectedNetwork = network = - OFSocketAddressIPXNetwork(&address1); - OFSocketAddressGetIPXNode(&address1, node); - memcpy(delegate->_expectedNode, node, IPX_NODE_LEN); - delegate->_expectedPort = port = OFSocketAddressIPXPort(&address1); - - @try { - [sockClient asyncConnectToNetwork: network - node: node - port: port]; - - [[OFRunLoop mainRunLoop] runUntilDate: - [OFDate dateWithTimeIntervalSinceNow: 2]]; - - TEST(@"-[asyncAccept] & -[asyncConnectToNetwork:node:port:]", - delegate->_accepted && delegate->_connected) - } @catch (OFObserveKernelEventsFailedException *e) { - /* - * Make sure it doesn't stay in the run loop and throws again - * next time we run the run loop. - */ - [sockClient cancelAsyncRequests]; - [sockServer cancelAsyncRequests]; - - switch (e.errNo) { - case ENOTSOCK: - [OFStdOut setForegroundColor: [OFColor lime]]; - [OFStdOut writeLine: - @"\r[OFSPXStreamSocket] -[asyncAccept] & " - @"-[asyncConnectToNetwork:node:port:]: select() " - @"not supported for SPX, skipping test"]; - break; - default: - @throw e; - } - } - - objc_autoreleasePoolPop(pool); -} -@end Index: tests/TestsAppDelegate.h ================================================================== --- tests/TestsAppDelegate.h +++ tests/TestsAppDelegate.h @@ -105,14 +105,10 @@ @interface TestsAppDelegate (RuntimeARCTests) - (void)runtimeARCTests; @end -@interface TestsAppDelegate (OFSPXStreamSocketTests) -- (void)SPXStreamSocketTests; -@end - @interface TestsAppDelegate (OFStreamTests) - (void)streamTests; @end @interface TestsAppDelegate (OFStringTests) Index: tests/TestsAppDelegate.m ================================================================== --- tests/TestsAppDelegate.m +++ tests/TestsAppDelegate.m @@ -381,13 +381,10 @@ [self valueTests]; [self streamTests]; [self memoryStreamTests]; [self notificationCenterTests]; #ifdef OF_HAVE_SOCKETS -# ifdef OF_HAVE_IPX - [self SPXStreamSocketTests]; -# endif # ifdef OF_HAVE_APPLETALK [self DDPSocketTests]; # endif [self kernelEventObserverTests]; #endif