* Enhance and rename AsyncEmbeddedEventLoop
Motivation
AsyncEmbeddedEventLoop is an important part of our ongoing testing story
for NIO. However, it suffers from two problems.
The first is a usability one. As we discovered during the original
implementation, following EmbeddedEventLoop's pattern of not having any
EventLoop "Tasks" execute until run() meant that simple constructs like
`EventLoopFuture.wait` and `EventLoopFuture.get` didn't work at all,
forcing us to add an annoying `awaitFuture` method.
When playing with implementing EmbeddedChannel, this got worse, as I/O
methods also don't run immediately if called from the testing thread. We
couldn't easily work around this issue, and it meant that common
patterns (like calling `channel.writeAndFlush`) would deadlock!
This is unacceptable, so a change had to be made.
While we're here, we received feedback that the name is unclear to
users. Given that this particular event loop is in no sense "embedded",
we no longer need the name, so we can take this opportunity to use a
better one.
Modifications
Changed `func execute` to immediately execute its task body, and to
dequeue all pending tasks at this time. Essentially, it's the equivalent
to run(). This is a major change in its behaviour.
Renamed the loop to `NIOAsyncTestingEventLoop`.
Result
Better names, easier to use.
* Make soundness happy
* Remove awaitFuture
Workaround for https://github.com/apple/swift/issues/59911
```swift
/src/Tests/NIOHTTP1Tests/HTTPTest.swift:148:21: warning: 'buf' mutated after capture by sendable closure
buf.writeString("\(c)")
```
The variable `buf` is mutated but only before being capture by the sendable closure.
All other warnings/errors are fixed with the latest Swift 5.7 toolchain
We would previously attempt to convert an error to a description without
consideration for the provenance on Windows. This would result in a
failure if the error code was not from `errno`. Account for the source
of the error and translate it appropriately. We can not retrieve
descriptions on errors that may originate from Windows or WinSock as
well as the C library.
* Adopt `Sendable` for closures in `HTTPPipelineSetup.swift`
* make `UnsafeTransfer` and `UnsafeMutableTransferBox` available in Swift 5.4 too
* fix code duplication
* Copy `UnsafeTransfer` to `NIOHTTP1Tests` to be able to remove `@testable` from `NIOCore` import
* Adopt `Sendable` for closures in `HTTPServerUpgradeHandler.swift`
* Adopt `Sendable` for closures in `HTTPClientUpgradeHandler.swift`
* Adopt `Sendable` for closures in `HTTPPipelineSetup.swift`
* make `UnsafeTransfer` and `UnsafeMutableTransferBox` available in Swift 5.4 too
* fix code duplication
* Copy `UnsafeTransfer` to `NIOHTTP1Tests` to be able to remove `@testable` from `NIOCore` import
* Adopting `Sendable` in `NIOTestUtils`
The parameter `decoderFactory` of the static methods `ByteToMessageDecoderVerifier.verifyDecoder` do not need to be `@escaping`. I have made them non-escaping as part of `Sendable` adoption because we would otherwise need to think about if they should be `@Sendable` too.
`VerificationError` is interesting, see the code comment for more information.
* Adopting `Sendable` in `NIOTestUtils`
The parameter `decoderFactory` of the static methods `ByteToMessageDecoderVerifier.verifyDecoder` do not need to be `@escaping`. I have made them non-escaping as part of `Sendable` adoption because we would otherwise need to think about if they should be `@Sendable` too.
`VerificationError` is interesting, see the code comment for more information.
* Clarify the reason `VerificationError` already conforms to `Sendable`
`EmbeddedChannel` and `EmbeddedEventLoop` should not be `Sendable`. However, they inherit from `Channel` and `EventLoop` respectively. Therfore, they need to be `Sendable` (and are already implcitily `Sendable`. Given these constraints, we can’t mark `EmbeddedChannel` and `EmbeddedEventLoop` as non-Sendable.
This extension does not port cleanly to Windows as the time structures
on Windows are different. This happens to be unused, so simply remove
the extension on Windows.
* Provide conversion APIs between TimeAmount and Swift.Duration
Signed-off-by: Si Beaumont <beaumont@apple.com>
* fixup: Remove unnecessary overflow check
Signed-off-by: Si Beaumont <beaumont@apple.com>
* fixup: Move into new _NIOBeta57 module
Signed-off-by: Si Beaumont <beaumont@apple.com>
* fixup: Rename _NIOBeta57 module to _NIOBeta and move tests to own target
Signed-off-by: Si Beaumont <beaumont@apple.com>
* soundness: copyright years for some reason
Signed-off-by: Si Beaumont <beaumont@apple.com>
* Throw fatalError when scheduling on shutdown EL if SWIFTNIO_STRICT is set
Signed-off-by: Si Beaumont <beaumont@apple.com>
* Add CrashTest for SWIFTNIO_STRICT crash
Signed-off-by: Si Beaumont <beaumont@apple.com>
* fixup: Extract env var parsing to static let
Signed-off-by: Si Beaumont <beaumont@apple.com>
Co-authored-by: Cory Benfield <lukasa@apple.com>
Add an import of `NIOCore` on Windows which mirrors the other platforms.
This greatly reduces the noise in the error list.
Co-authored-by: Cory Benfield <lukasa@apple.com>
* implement the _failEarlyRangeCheck methods as no-ops
* mark _failEarlyRangeCheck with @inlinable
* add a comment on why the _failEarlyRangeCheck methods are implemented as no-ops
Co-authored-by: Cory Benfield <lukasa@apple.com>
The member names are not identical across platforms. Add a case to
handle the name difference on Windows.
Co-authored-by: Cory Benfield <lukasa@apple.com>
Use Win32 APIs to properly validate if a file is a pipe on Windows.
This enables providing the same semantics without leaking additional
Windows specifics.
Co-authored-by: Cory Benfield <lukasa@apple.com>
Reorganise the ECN constants to colocate the definitions for the
different platforms. Define the constants for Windows as the platform
does not provide them in the system headers.
Replace the use of raw constants with the internal enumeration. This
ensures that the constant names are uniform and don't leak structural
information from the underlying information.
Create a wrapper over `strerror` which is considered deprecated due to
the use of a shared global buffer. Use `strerror_s` which requires a
buffer and size to prevent shared state or a buffer overrun. This is
documented by Microsoft as requiring at most 94 characters, so we use a
buffer of size 95.
This cleans up a reference to `freeifaddrs` as that is no longer
referenced in the code base. This avoids an error on Windows as
a side-effect.
Co-authored-by: Cory Benfield <lukasa@apple.com>
Use the wrapper function for duplicating the file descriptor. This
allows us to swap out the implementation for different targets making
the code more portable. It additionally adds additional error handling
and checking as the wrappers are intended to perform error handling.
Co-authored-by: Cory Benfield <lukasa@apple.com>
Reduce unnecessary noise in the files after previous refactoring
shuffled the use of the imported interfaces. We can centralise most of
the imports and internal typealiases which avoids cluttering the shared
interfaces with compatibility handling for Windows.
Extend more of the internal interfaces for the BSD API coverage on
Windows to get the same API surface when possible.
Co-authored-by: Cory Benfield <lukasa@apple.com>
Windows does not provide a definition for `socklen_t`. Create an
internal typealias for it to provide source stability to the internal
interfaces.
Co-authored-by: George Barnett <gbarnett@apple.com>
Co-authored-by: Cory Benfield <lukasa@apple.com>
Windows does not provide a 3 parameter `open` and needs to be passed all
the parameters as `_open` is a variadic function (as per the
specification). This provides a Windows specific path for `open` and
`read` as on Darwin and Linux, `read` uses a non-standard return type
(`ssize_t`). As it happens, the `size` parameter on Windows also uses
`unsigned int` rather than `size_t` which would break on different
bitnesses.
Co-authored-by: Cory Benfield <lukasa@apple.com>
Windows does not have the same set of POSIX flag constants. In
particular, there is no equivalent to group permissions as the ACL model
on Windows is far richer and requires the full specification of the
DACLs. Additionally, isolate `O_CLOEXEC` to aid Windows which does not
have this flag.
Co-authored-by: Cory Benfield <lukasa@apple.com>
`errno` is a thread local variable, and as such on many platforms is
accessed indirectly. This is implemented as macro, but is considered
complex by the clang importer and cannot be directly used. Resolve this
by using the accessor for the value on Windows.
Co-authored-by: Cory Benfield <lukasa@apple.com>
Motivation:
On Windows we have a need to transform a subnet prefix into a subnet
mask when enumerating devices. This is a straightforward transformation
that we can easily do in pure-Swift, so let's do that. Additionally, the
functions have small enough domains that we can just exhaustively test
them.
Modifications:
- Added functions to create SocketAddress objects from subnet prefixes.
- Added exhaustive tests for those functions.
- Use these functions in Windows code.
Result:
Correct transformations of prefixes into masks on Windows.