Skip to content

Commit

Permalink
update coverage (#233)
Browse files Browse the repository at this point in the history
* update coverage

* update peertest

* update coverage

* update coverage

* update coverage

* update coverage

* update coverage test

* update coverage

* update coverage

* update coverage

* update coverage

* update more test

* update coverage

* update peer test

* update log
  • Loading branch information
MacOMNI authored Nov 28, 2024
1 parent 329a86f commit 958db5c
Show file tree
Hide file tree
Showing 7 changed files with 281 additions and 176 deletions.
70 changes: 0 additions & 70 deletions Networking/Sources/MsQuicSwift/QuicEventHandler.swift
Original file line number Diff line number Diff line change
Expand Up @@ -65,73 +65,3 @@ extension QuicEventHandler {

public func closed(_: QuicStream, status _: QuicStatus, code _: QuicErrorCode) {}
}

public final class MockQuicEventHandler: QuicEventHandler {
public enum EventType {
case newConnection(listener: QuicListener, connection: QuicConnection, info: ConnectionInfo)
case shouldOpen(connection: QuicConnection, certificate: Data?)
case connected(connection: QuicConnection)
case shutdownInitiated(connection: QuicConnection, reason: ConnectionCloseReason)
case shutdownComplete(connection: QuicConnection)
case streamStarted(connection: QuicConnection, stream: QuicStream)
case dataReceived(stream: QuicStream, data: Data?)
case closed(stream: QuicStream, status: QuicStatus, code: QuicErrorCode)
}

public let events: ThreadSafeContainer<[EventType]> = .init([])

public init() {}

public func newConnection(
_ listener: QuicListener, connection: QuicConnection, info: ConnectionInfo
) -> QuicStatus {
events.write { events in
events.append(.newConnection(listener: listener, connection: connection, info: info))
}

return .code(.success)
}

public func shouldOpen(_ connection: QuicConnection, certificate: Data?) -> QuicStatus {
events.write { events in
events.append(.shouldOpen(connection: connection, certificate: certificate))
}
return .code(.success)
}

public func connected(_ connection: QuicConnection) {
events.write { events in
events.append(.connected(connection: connection))
}
}

public func shutdownInitiated(_ connection: QuicConnection, reason: ConnectionCloseReason) {
events.write { events in
events.append(.shutdownInitiated(connection: connection, reason: reason))
}
}

public func shutdownComplete(_ connection: QuicConnection) {
events.write { events in
events.append(.shutdownComplete(connection: connection))
}
}

public func streamStarted(_ connect: QuicConnection, stream: QuicStream) {
events.write { events in
events.append(.streamStarted(connection: connect, stream: stream))
}
}

public func dataReceived(_ stream: QuicStream, data: Data?) {
events.write { events in
events.append(.dataReceived(stream: stream, data: data))
}
}

public func closed(_ stream: QuicStream, status: QuicStatus, code: QuicErrorCode) {
events.write { events in
events.append(.closed(stream: stream, status: status, code: code))
}
}
}
12 changes: 3 additions & 9 deletions Networking/Sources/Networking/Connection.swift
Original file line number Diff line number Diff line change
Expand Up @@ -119,16 +119,10 @@ public final class Connection<Handler: StreamHandler>: Sendable, ConnectionInfoP

public var isClosed: Bool {
state.read {
switch $0 {
case .connecting:
false
case .connected:
false
case .closed:
true
case .reconnect:
false
if case .closed = $0 {
return true
}
return false
}
}

Expand Down
37 changes: 10 additions & 27 deletions Networking/Sources/Networking/Peer.swift
Original file line number Diff line number Diff line change
Expand Up @@ -20,12 +20,7 @@ struct BackoffState {
var attempt: Int
var delay: TimeInterval

init() {
attempt = 0
delay = 1
}

init(attempt: Int = 0, delay: TimeInterval = 1) {
init(_ attempt: Int = 0, _ delay: TimeInterval = 1) {
self.attempt = attempt
self.delay = delay
}
Expand Down Expand Up @@ -479,12 +474,10 @@ private struct PeerEventHandler<Handler: StreamHandler>: QuicEventHandler {
connections.byId[connection.id]
}
guard let conn else {
logger.warning(
"Connected but connection is gone?", metadata: ["connectionId": "\(connection.id)"]
)
logger.warning("Connected but connection is gone?", metadata: ["connectionId": "\(connection.id)"])
return
}
// Check if the connection is already reconnected

impl.reconnectStates.write { reconnectStates in
reconnectStates[conn.remoteAddress] = nil
}
Expand All @@ -511,17 +504,17 @@ private struct PeerEventHandler<Handler: StreamHandler>: QuicEventHandler {
connections.byId[connection.id]
}
let needReconnect = impl.connections.write { connections in
var needReconnect = false
if let conn = connections.byId[connection.id] {
let needReconnect = conn.needReconnect
needReconnect = conn.needReconnect
if let publicKey = conn.publicKey {
connections.byPublicKey.removeValue(forKey: publicKey)
}
connections.byId.removeValue(forKey: connection.id)
connections.byAddr.removeValue(forKey: conn.remoteAddress)
conn.closed()
return needReconnect
}
return false
return needReconnect
}
if needReconnect, let address = conn?.remoteAddress, let role = conn?.role {
do {
Expand All @@ -533,10 +526,7 @@ private struct PeerEventHandler<Handler: StreamHandler>: QuicEventHandler {
}

func shutdownInitiated(_ connection: QuicConnection, reason: ConnectionCloseReason) {
logger.debug(
"Shutdown initiated",
metadata: ["connectionId": "\(connection.id)", "reason": "\(reason)"]
)
logger.debug("Shutdown initiated", metadata: ["connectionId": "\(connection.id)", "reason": "\(reason)"])
if shouldReconnect(basedOn: reason) {
impl.connections.write { connections in
if let conn = connections.byId[connection.id] {
Expand Down Expand Up @@ -609,15 +599,8 @@ private struct PeerEventHandler<Handler: StreamHandler>: QuicEventHandler {
if let connection {
connection.streamClosed(stream: stream, abort: !status.isSucceeded)
if shouldReopenStream(connection: connection, stream: stream, status: status) {
do {
if let kind = stream.kind {
// impl.reopenUpStream(connection: connection, kind: kind);
do {
try connection.createPreistentStream(kind: kind)
} catch {
logger.error("Attempt to recreate the persistent stream failed: \(error)")
}
}
if let kind = stream.kind {
impl.reopenUpStream(connection: connection, kind: kind)
}
}
} else {
Expand All @@ -642,7 +625,7 @@ private struct PeerEventHandler<Handler: StreamHandler>: QuicEventHandler {
case .connectionIdle, .badCert:
return false
default:
return !status.isSucceeded
return status.isSucceeded
}
}
}
146 changes: 146 additions & 0 deletions Networking/Tests/MsQuicSwiftTests/QuicListenerTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,152 @@ struct QuicListenerTests {
registration = try QuicRegistration()
}

final class MockQuicEventHandler: QuicEventHandler {
enum EventType {
case newConnection(listener: QuicListener, connection: QuicConnection, info: ConnectionInfo)
case shouldOpen(connection: QuicConnection, certificate: Data?)
case connected(connection: QuicConnection)
case shutdownInitiated(connection: QuicConnection, reason: ConnectionCloseReason)
case shutdownComplete(connection: QuicConnection)
case streamStarted(connection: QuicConnection, stream: QuicStream)
case dataReceived(stream: QuicStream, data: Data?)
case closed(stream: QuicStream, status: QuicStatus, code: QuicErrorCode)
}

let events: ThreadSafeContainer<[EventType]> = .init([])

init() {}

func newConnection(
_ listener: QuicListener, connection: QuicConnection, info: ConnectionInfo
) -> QuicStatus {
events.write { events in
events.append(.newConnection(listener: listener, connection: connection, info: info))
}
return .code(.success)
}

func shouldOpen(_ connection: QuicConnection, certificate: Data?) -> QuicStatus {
events.write { events in
events.append(.shouldOpen(connection: connection, certificate: certificate))
}
return .code(.success)
}

func connected(_ connection: QuicConnection) {
events.write { events in
events.append(.connected(connection: connection))
}
}

func streamStarted(_ connect: QuicConnection, stream: QuicStream) {
events.write { events in
events.append(.streamStarted(connection: connect, stream: stream))
}
}

func dataReceived(_ stream: QuicStream, data: Data?) {
events.write { events in
events.append(.dataReceived(stream: stream, data: data))
}
}
}

final class EmptyQuicEventHandler: QuicEventHandler {}

@Test
func emptyQuicEventHandler() async throws {
let serverHandler = MockQuicEventHandler()
let clientHandler = EmptyQuicEventHandler()

// create listener

let quicSettings = QuicSettings.defaultSettings
let serverConfiguration = try QuicConfiguration(
registration: registration,
pkcs12: pkcs12Data,
alpns: [Data("testalpn".utf8)],
client: false,
settings: quicSettings
)

let listener = try QuicListener(
handler: serverHandler,
registration: registration,
configuration: serverConfiguration,
listenAddress: NetAddr(ipAddress: "127.0.0.1", port: 0)!,
alpns: [Data("testalpn".utf8)]
)

let listenAddress = try listener.listenAddress()
let (ipAddress, port) = listenAddress.getAddressAndPort()
#expect(ipAddress == "127.0.0.1")
#expect(port != 0)

// create connection to listener

let clientConfiguration = try QuicConfiguration(
registration: registration,
pkcs12: pkcs12Data,
alpns: [Data("testalpn".utf8)],
client: true,
settings: quicSettings
)

let clientConnection = try QuicConnection(
handler: clientHandler,
registration: registration,
configuration: clientConfiguration
)

try clientConnection.connect(to: listenAddress)

let stream1 = try clientConnection.createStream()

try stream1.send(data: Data("test data 1".utf8))

try? await Task.sleep(for: .milliseconds(100))
let (serverConnection, info) = serverHandler.events.value.compactMap {
switch $0 {
case let .newConnection(_, connection, info):
(connection, info) as (QuicConnection, ConnectionInfo)?
default:
nil
}
}.first!

let (ipAddress2, _) = info.remoteAddress.getAddressAndPort()

#expect(info.negotiatedAlpn == Data("testalpn".utf8))
#expect(info.serverName == "127.0.0.1")
#expect(info.localAddress == listenAddress)
#expect(ipAddress2 == "127.0.0.1")

let stream2 = try serverConnection.createStream()
try stream2.send(data: Data("other test data 2".utf8))

try? await Task.sleep(for: .milliseconds(100))
let receivedData = serverHandler.events.value.compactMap {
switch $0 {
case let .dataReceived(_, data):
data
default:
nil
}
}

#expect(receivedData.count == 1)
#expect(receivedData[0] == Data("test data 1".utf8))
try clientConnection.shutdown()
try? await Task.sleep(for: .milliseconds(1000))
#expect(throws: Error.self) {
try serverConnection.connect(to: info.remoteAddress)
}
#expect(throws: Error.self) {
_ = try clientConnection.getRemoteAddress()
}
}

@Test
func connectAndSendReceive() async throws {
let serverHandler = MockQuicEventHandler()
Expand Down
Loading

0 comments on commit 958db5c

Please sign in to comment.