Skip to content

Fix browser detection when choosing crypto impl #170

Fix browser detection when choosing crypto impl

Fix browser detection when choosing crypto impl #170

GitHub Actions / Test SSH on macOS-latest succeeded Oct 27, 2023 in 0s

Test SSH on macOS-latest ✅

Tests passed successfully

Report Passed Failed Skipped Time
out/TestResults/SSH-CS-net6.0.trx 360✅ 10⚪ 38s
out/TestResults/SSH-CS-netcoreapp3.1.trx 366✅ 10⚪ 177s

✅ out/TestResults/SSH-CS-net6.0.trx

370 tests were completed in 38s with 360 passed, 0 failed and 10 skipped.

Test suite Passed Failed Skipped Time
Microsoft.DevTunnels.Ssh.Test.ChannelTests 58✅ 5s
Microsoft.DevTunnels.Ssh.Test.CryptoTests 18✅ 1s
Microsoft.DevTunnels.Ssh.Test.InteropTests 23✅ 9s
Microsoft.DevTunnels.Ssh.Test.KeyImportExportTests 87✅ 10⚪ 326ms
Microsoft.DevTunnels.Ssh.Test.MetricsTests 8✅ 3s
Microsoft.DevTunnels.Ssh.Test.MultiChannelStreamTests 13✅ 177ms
Microsoft.DevTunnels.Ssh.Test.PipeTests 22✅ 966ms
Microsoft.DevTunnels.Ssh.Test.PortForwardingTests 58✅ 2s
Microsoft.DevTunnels.Ssh.Test.ReconnectTests 18✅ 10s
Microsoft.DevTunnels.Ssh.Test.SecureStreamTests 12✅ 561ms
Microsoft.DevTunnels.Ssh.Test.ServiceTests 7✅ 233ms
Microsoft.DevTunnels.Ssh.Test.SessionTests 23✅ 3s
Microsoft.DevTunnels.Ssh.Test.StreamTests 6✅ 166ms
Microsoft.DevTunnels.Ssh.Test.VersionTests 7✅ 2ms

✅ Microsoft.DevTunnels.Ssh.Test.ChannelTests

✅ ChannelReceiveWaitsForListener
✅ ChannelRequest(success: False)
✅ ChannelRequest(success: True)
✅ ChannelRequestEarlyCancellation
✅ ChannelRequestHandlerClosesChannel
✅ ChannelRequestHandlerException
✅ ChannelRequestLateCancellation
✅ CloseChannelWithSignal
✅ CloseChannelWithStatus
✅ CloseClientChannel
✅ CloseServerChannel
✅ CloseSessionClosesChannel
✅ CloseSessionClosesChannelWithException
✅ DisposeChannelCloses
✅ OpenAndCloseChannelFromClient(channelType: "test")
✅ OpenAndCloseChannelFromClient(channelType: null)
✅ OpenAndCloseChannelFromServer(channelType: "test")
✅ OpenAndCloseChannelFromServer(channelType: null)
✅ OpenChannelCancelByAcceptor
✅ OpenChannelCancelByOpener
✅ OpenChannelWithMultipleRequests
✅ OpenChannelWithRequest(serverExtension: False, clientExtension: False)
✅ OpenChannelWithRequest(serverExtension: False, clientExtension: True)
✅ OpenChannelWithRequest(serverExtension: True, clientExtension: False)
✅ OpenChannelWithRequest(serverExtension: True, clientExtension: True)
✅ OpenChannelWithRequestFail(serverExtension: False, clientExtension: False)
✅ OpenChannelWithRequestFail(serverExtension: False, clientExtension: True)
✅ OpenChannelWithRequestFail(serverExtension: True, clientExtension: False)
✅ OpenChannelWithRequestFail(serverExtension: True, clientExtension: True)
✅ OpenChannelWithRequestNoReply(serverExtension: False, clientExtension: False)
✅ OpenChannelWithRequestNoReply(serverExtension: False, clientExtension: True)
✅ OpenChannelWithRequestNoReply(serverExtension: True, clientExtension: False)
✅ OpenChannelWithRequestNoReply(serverExtension: True, clientExtension: True)
✅ OpenChannelWithRequestUnauthenticated
✅ SendBlocksOnClosedWindow
✅ SendChannelData(data: [[]])
✅ SendChannelData(data: [[0], []])
✅ SendChannelData(data: [[116, 101, 115, 116], []])
✅ SendChannelData(data: [[65, 65, 65, 65, 65, ...]])
✅ SendChannelDataOverMultipleChannels(data: [[]])
✅ SendChannelDataOverMultipleChannels(data: [[0], []])
✅ SendChannelDataOverMultipleChannels(data: [[116, 101, 115, 116], []])
✅ SendChannelDataOverMultipleChannels(data: [[65, 65, 65, 65, 65, ...]])
✅ SendChannelDataWithOffset
✅ SendIncreasingChannelData
✅ SendLargeChannelData(clientMaxWindowSize: 1048576, serverMaxWindowSize: 1048576)
✅ SendLargeChannelData(clientMaxWindowSize: 1048576, serverMaxWindowSize: 5242880)
✅ SendLargeChannelData(clientMaxWindowSize: 5242880, serverMaxWindowSize: 1048576)
✅ SendLargeDataWithoutAwait
✅ SendServerChannelData(data: [[]])
✅ SendServerChannelData(data: [[0], []])
✅ SendServerChannelData(data: [[116, 101, 115, 116], []])
✅ SendServerChannelData(data: [[65, 65, 65, 65, 65, ...]])
✅ SendWhileOpening
✅ TraceChannelData
✅ UnknownChannelAdjustWindowIsIgnored
✅ UnknownChannelDataIsIgnored
✅ UnknownChannelEofIsIgnored

✅ Microsoft.DevTunnels.Ssh.Test.CryptoTests

✅ EncryptDecrypt(encAlg: "aes256-cbc")
✅ EncryptDecrypt(encAlg: "aes256-ctr")
✅ EncryptDecrypt(encAlg: "aes256-gcm@openssh.com")
✅ Hmac(hmacAlg: "hmac-sha2-256-etm@openssh.com")
✅ Hmac(hmacAlg: "hmac-sha2-256")
✅ Hmac(hmacAlg: "hmac-sha2-512-etm@openssh.com")
✅ Hmac(hmacAlg: "hmac-sha2-512")
✅ KeyExchange(kexAlg: "diffie-hellman-group14-sha256")
✅ KeyExchange(kexAlg: "diffie-hellman-group16-sha512")
✅ KeyExchange(kexAlg: "ecdh-sha2-nistp256")
✅ KeyExchange(kexAlg: "ecdh-sha2-nistp384")
✅ KeyExchange(kexAlg: "ecdh-sha2-nistp521")
✅ SignVerify(pkAlg: "ecdsa-sha2-nistp256", keySize: null)
✅ SignVerify(pkAlg: "ecdsa-sha2-nistp384", keySize: null)
✅ SignVerify(pkAlg: "ecdsa-sha2-nistp521", keySize: null)
✅ SignVerify(pkAlg: "rsa-sha2-256", keySize: 1024)
✅ SignVerify(pkAlg: "rsa-sha2-512", keySize: 2048)
✅ SignVerify(pkAlg: "rsa-sha2-512", keySize: 4096)

✅ Microsoft.DevTunnels.Ssh.Test.InteropTests

✅ InteropJumpHostTest
✅ InteropWithSshClientTool(kexAlg: "diffie-hellman-group14-sha256", pkAlg: "ecdsa-sha2-nistp384", hmacAlg: "hmac-sha2-512")
✅ InteropWithSshClientTool(kexAlg: "diffie-hellman-group14-sha256", pkAlg: "ecdsa-sha2-nistp521", hmacAlg: "hmac-sha2-512")
✅ InteropWithSshClientTool(kexAlg: "diffie-hellman-group14-sha256", pkAlg: "rsa-sha2-512", hmacAlg: "hmac-sha2-512")
✅ InteropWithSshClientTool(kexAlg: "diffie-hellman-group16-sha512", pkAlg: "rsa-sha2-512", hmacAlg: "hmac-sha2-512-etm@openssh.com")
✅ InteropWithSshClientTool(kexAlg: "ecdh-sha2-nistp384", pkAlg: "ecdsa-sha2-nistp384", hmacAlg: "hmac-sha2-512")
✅ InteropWithSshClientTool(kexAlg: "ecdh-sha2-nistp521", pkAlg: "ecdsa-sha2-nistp521", hmacAlg: "hmac-sha2-512-etm@openssh.com")
✅ InteropWithSshClientTSLib(kexAlg: "diffie-hellman-group14-sha256", pkAlg: "ecdsa-sha2-nistp521", hmacAlg: "hmac-sha2-512", reconnect: False)
✅ InteropWithSshClientTSLib(kexAlg: "diffie-hellman-group14-sha256", pkAlg: "rsa-sha2-512", hmacAlg: "hmac-sha2-512", reconnect: True)
✅ InteropWithSshClientTSLib(kexAlg: "diffie-hellman-group16-sha512", pkAlg: "rsa-sha2-512", hmacAlg: "hmac-sha2-512-etm@openssh.com", reconnect: False)
✅ InteropWithSshClientTSLib(kexAlg: "diffie-hellman-group16-sha512", pkAlg: "rsa-sha2-512", hmacAlg: "hmac-sha2-512-etm@openssh.com", reconnect: True)
✅ InteropWithSshServerTool(kexAlg: "diffie-hellman-group14-sha256", pkAlg: "ecdsa-sha2-nistp384", hmacAlg: "hmac-sha2-512")
✅ InteropWithSshServerTool(kexAlg: "diffie-hellman-group14-sha256", pkAlg: "ecdsa-sha2-nistp521", hmacAlg: "hmac-sha2-512")
✅ InteropWithSshServerTool(kexAlg: "diffie-hellman-group14-sha256", pkAlg: "rsa-sha2-512", hmacAlg: "hmac-sha2-512")
✅ InteropWithSshServerTool(kexAlg: "diffie-hellman-group16-sha512", pkAlg: "rsa-sha2-512", hmacAlg: "hmac-sha2-512-etm@openssh.com")
✅ InteropWithSshServerTool(kexAlg: "ecdh-sha2-nistp384", pkAlg: "ecdsa-sha2-nistp384", hmacAlg: "hmac-sha2-512")
✅ InteropWithSshServerTool(kexAlg: "ecdh-sha2-nistp521", pkAlg: "ecdsa-sha2-nistp521", hmacAlg: "hmac-sha2-512-etm@openssh.com")
✅ InteropWithSshServerTSLib(kexAlg: "diffie-hellman-group14-sha256", pkAlg: "ecdsa-sha2-nistp521", hmacAlg: "hmac-sha2-512", reconnect: False)
✅ InteropWithSshServerTSLib(kexAlg: "diffie-hellman-group14-sha256", pkAlg: "rsa-sha2-512", hmacAlg: "hmac-sha2-512", reconnect: True)
✅ InteropWithSshServerTSLib(kexAlg: "diffie-hellman-group16-sha512", pkAlg: "rsa-sha2-512", hmacAlg: "hmac-sha2-512-etm@openssh.com", reconnect: False)
✅ InteropWithSshServerTSLib(kexAlg: "diffie-hellman-group16-sha512", pkAlg: "rsa-sha2-512", hmacAlg: "hmac-sha2-512-etm@openssh.com", reconnect: True)
✅ InteropWithSshServerTSLib(kexAlg: "ecdh-sha2-nistp384", pkAlg: "ecdsa-sha2-nistp384", hmacAlg: "hmac-sha2-512", reconnect: False)
✅ InteropWithSshServerTSLib(kexAlg: "ecdh-sha2-nistp521", pkAlg: "ecdsa-sha2-nistp521", hmacAlg: "hmac-sha2-512-etm@openssh.com", reconnect: True)

✅ Microsoft.DevTunnels.Ssh.Test.KeyImportExportTests

✅ ExportImportPrivateKeyBytes(algorithm: "ecdsa384", keyFormat: OpenSsh, passphrase: "password")
✅ ExportImportPrivateKeyBytes(algorithm: "ecdsa384", keyFormat: OpenSsh, passphrase: null)
✅ ExportImportPrivateKeyBytes(algorithm: "ecdsa384", keyFormat: Pkcs8, passphrase: "password")
✅ ExportImportPrivateKeyBytes(algorithm: "ecdsa384", keyFormat: Pkcs8, passphrase: null)
✅ ExportImportPrivateKeyBytes(algorithm: "ecdsa384", keyFormat: Sec1, passphrase: null)
✅ ExportImportPrivateKeyBytes(algorithm: "rsa2048", keyFormat: OpenSsh, passphrase: "password")
✅ ExportImportPrivateKeyBytes(algorithm: "rsa2048", keyFormat: OpenSsh, passphrase: null)
✅ ExportImportPrivateKeyBytes(algorithm: "rsa2048", keyFormat: Pkcs1, passphrase: null)
✅ ExportImportPrivateKeyBytes(algorithm: "rsa2048", keyFormat: Pkcs8, passphrase: "password")
✅ ExportImportPrivateKeyBytes(algorithm: "rsa2048", keyFormat: Pkcs8, passphrase: null)
✅ ExportImportPrivateKeyBytes(algorithm: "rsa2048", keyFormat: Ssh2, passphrase: null)
✅ ExportImportPublicKeyBytes(algorithm: "ecdsa384", keyFormat: Pkcs8)
✅ ExportImportPublicKeyBytes(algorithm: "ecdsa384", keyFormat: Ssh)
✅ ExportImportPublicKeyBytes(algorithm: "rsa2048", keyFormat: Pkcs1)
✅ ExportImportPublicKeyBytes(algorithm: "rsa2048", keyFormat: Pkcs8)
✅ ExportImportPublicKeyBytes(algorithm: "rsa2048", keyFormat: Ssh)
✅ ExportImportPublicKeyBytes(algorithm: "rsa2048", keyFormat: Ssh2)
✅ ExportPrivateKey(algorithm: "ecdsa384", keyFormat: OpenSsh, passphrase: "password")
✅ ExportPrivateKey(algorithm: "ecdsa384", keyFormat: OpenSsh, passphrase: null)
✅ ExportPrivateKey(algorithm: "ecdsa384", keyFormat: Pkcs8, passphrase: "password")
✅ ExportPrivateKey(algorithm: "ecdsa384", keyFormat: Pkcs8, passphrase: null)
✅ ExportPrivateKey(algorithm: "ecdsa384", keyFormat: Sec1, passphrase: "password")
✅ ExportPrivateKey(algorithm: "ecdsa384", keyFormat: Sec1, passphrase: null)
✅ ExportPrivateKey(algorithm: "ecdsa521", keyFormat: Pkcs8, passphrase: null)
✅ ExportPrivateKey(algorithm: "ecdsa521", keyFormat: Sec1, passphrase: null)
⚪ ExportPrivateKey(algorithm: "rsa2048", keyFormat: Jwk, passphrase: null)
✅ ExportPrivateKey(algorithm: "rsa2048", keyFormat: OpenSsh, passphrase: "password")
✅ ExportPrivateKey(algorithm: "rsa2048", keyFormat: OpenSsh, passphrase: null)
✅ ExportPrivateKey(algorithm: "rsa2048", keyFormat: Pkcs1, passphrase: "password")
✅ ExportPrivateKey(algorithm: "rsa2048", keyFormat: Pkcs1, passphrase: null)
✅ ExportPrivateKey(algorithm: "rsa2048", keyFormat: Pkcs8, passphrase: "password")
✅ ExportPrivateKey(algorithm: "rsa2048", keyFormat: Pkcs8, passphrase: null)
✅ ExportPrivateKey(algorithm: "rsa2048", keyFormat: Ssh2, passphrase: "password")
✅ ExportPrivateKey(algorithm: "rsa2048", keyFormat: Ssh2, passphrase: null)
⚪ ExportPrivateKey(algorithm: "rsa4096", keyFormat: Jwk, passphrase: null)
✅ ExportPrivateKey(algorithm: "rsa4096", keyFormat: OpenSsh, passphrase: null)
✅ ExportPrivateKey(algorithm: "rsa4096", keyFormat: Pkcs1, passphrase: null)
✅ ExportPrivateKey(algorithm: "rsa4096", keyFormat: Pkcs8, passphrase: null)
✅ ExportPrivateKey(algorithm: "rsa4096", keyFormat: Ssh2, passphrase: null)
⚪ ExportPublicKey(algorithm: "ecdsa384", keyFormat: Jwk)
✅ ExportPublicKey(algorithm: "ecdsa384", keyFormat: Pkcs8)
✅ ExportPublicKey(algorithm: "ecdsa384", keyFormat: Ssh)
✅ ExportPublicKey(algorithm: "ecdsa521", keyFormat: Pkcs8)
✅ ExportPublicKey(algorithm: "ecdsa521", keyFormat: Ssh)
⚪ ExportPublicKey(algorithm: "rsa2048", keyFormat: Jwk)
✅ ExportPublicKey(algorithm: "rsa2048", keyFormat: Pkcs1)
✅ ExportPublicKey(algorithm: "rsa2048", keyFormat: Pkcs8)
✅ ExportPublicKey(algorithm: "rsa2048", keyFormat: Ssh)
✅ ExportPublicKey(algorithm: "rsa2048", keyFormat: Ssh2)
⚪ ExportPublicKey(algorithm: "rsa4096", keyFormat: Jwk)
✅ ExportPublicKey(algorithm: "rsa4096", keyFormat: Pkcs1)
✅ ExportPublicKey(algorithm: "rsa4096", keyFormat: Pkcs8)
✅ ExportPublicKey(algorithm: "rsa4096", keyFormat: Ssh)
✅ ExportPublicKey(algorithm: "rsa4096", keyFormat: Ssh2)
✅ ExportPublicKeyNotSupported(algorithm: "ecdsa384", keyFormat: Sec1)
⚪ ImportPrivateKey(algorithm: "ecdsa384", keyFormat: Jwk, passphrase: null)
✅ ImportPrivateKey(algorithm: "ecdsa384", keyFormat: OpenSsh, passphrase: "password")
✅ ImportPrivateKey(algorithm: "ecdsa384", keyFormat: OpenSsh, passphrase: null)
✅ ImportPrivateKey(algorithm: "ecdsa384", keyFormat: Pkcs8, passphrase: "password")
✅ ImportPrivateKey(algorithm: "ecdsa384", keyFormat: Pkcs8, passphrase: null)
✅ ImportPrivateKey(algorithm: "ecdsa384", keyFormat: Sec1, passphrase: "password")
✅ ImportPrivateKey(algorithm: "ecdsa384", keyFormat: Sec1, passphrase: null)
✅ ImportPrivateKey(algorithm: "ecdsa521", keyFormat: Pkcs8, passphrase: null)
✅ ImportPrivateKey(algorithm: "ecdsa521", keyFormat: Sec1, passphrase: null)
⚪ ImportPrivateKey(algorithm: "rsa2048", keyFormat: Jwk, passphrase: null)
✅ ImportPrivateKey(algorithm: "rsa2048", keyFormat: OpenSsh, passphrase: "password")
✅ ImportPrivateKey(algorithm: "rsa2048", keyFormat: OpenSsh, passphrase: null)
✅ ImportPrivateKey(algorithm: "rsa2048", keyFormat: Pkcs1, passphrase: "password")
✅ ImportPrivateKey(algorithm: "rsa2048", keyFormat: Pkcs1, passphrase: null)
✅ ImportPrivateKey(algorithm: "rsa2048", keyFormat: Pkcs8, passphrase: "password")
✅ ImportPrivateKey(algorithm: "rsa2048", keyFormat: Pkcs8, passphrase: null)
✅ ImportPrivateKey(algorithm: "rsa2048", keyFormat: Ssh2, passphrase: "password")
✅ ImportPrivateKey(algorithm: "rsa2048", keyFormat: Ssh2, passphrase: null)
⚪ ImportPrivateKey(algorithm: "rsa4096", keyFormat: Jwk, passphrase: null)
✅ ImportPrivateKey(algorithm: "rsa4096", keyFormat: OpenSsh, passphrase: null)
✅ ImportPrivateKey(algorithm: "rsa4096", keyFormat: Pkcs1, passphrase: null)
✅ ImportPrivateKey(algorithm: "rsa4096", keyFormat: Pkcs8, passphrase: null)
✅ ImportPrivateKey(algorithm: "rsa4096", keyFormat: Ssh2, passphrase: null)
✅ ImportPrivateKeyInvalidPassword(algorithm: "ecdsa384", keyFormat: OpenSsh)
✅ ImportPrivateKeyInvalidPassword(algorithm: "ecdsa384", keyFormat: Pkcs8)
✅ ImportPrivateKeyInvalidPassword(algorithm: "rsa2048", keyFormat: OpenSsh)
✅ ImportPrivateKeyInvalidPassword(algorithm: "rsa2048", keyFormat: Pkcs1)
✅ ImportPrivateKeyInvalidPassword(algorithm: "rsa2048", keyFormat: Pkcs8)
✅ ImportPrivateKeyInvalidPassword(algorithm: "rsa2048", keyFormat: Ssh2)
⚪ ImportPublicKey(algorithm: "ecdsa384", keyFormat: Jwk)
✅ ImportPublicKey(algorithm: "ecdsa384", keyFormat: Pkcs8)
✅ ImportPublicKey(algorithm: "ecdsa384", keyFormat: Ssh)
✅ ImportPublicKey(algorithm: "ecdsa521", keyFormat: Ssh)
⚪ ImportPublicKey(algorithm: "rsa2048", keyFormat: Jwk)
✅ ImportPublicKey(algorithm: "rsa2048", keyFormat: Pkcs1)
✅ ImportPublicKey(algorithm: "rsa2048", keyFormat: Pkcs8)
✅ ImportPublicKey(algorithm: "rsa2048", keyFormat: Ssh)
✅ ImportPublicKey(algorithm: "rsa2048", keyFormat: Ssh2)
✅ ImportPublicKey(algorithm: "rsa4096", keyFormat: Pkcs1)
✅ ImportPublicKey(algorithm: "rsa4096", keyFormat: Pkcs8)
✅ ImportPublicKey(algorithm: "rsa4096", keyFormat: Ssh)
✅ ImportPublicKey(algorithm: "rsa4096", keyFormat: Ssh2)

✅ Microsoft.DevTunnels.Ssh.Test.MetricsTests

✅ ClosedSessionHasNoLatency
✅ ExpandContourIntervals
✅ ExportImportContour
✅ MeasureChannelBytes
✅ MeasureSessionBytes
✅ MeasureSessionLatency
✅ MeasureSessionMessages
✅ RecordSessionContour

✅ Microsoft.DevTunnels.Ssh.Test.MultiChannelStreamTests

✅ ConnectAndRunUntilClosedAsync_Cancelled
✅ Dispose_DisposesTransportStream(disposeAsync: False)
✅ Dispose_DisposesTransportStream(disposeAsync: True)
✅ Dispose_FiresCloseEvent(isConnected: False, disposeAsync: False)
✅ Dispose_FiresCloseEvent(isConnected: False, disposeAsync: True)
✅ Dispose_FiresCloseEvent(isConnected: True, disposeAsync: False)
✅ Dispose_FiresCloseEvent(isConnected: True, disposeAsync: True)
✅ MultiChannelConnect
✅ MultiChannelReadWrite
✅ OpenChannelEvent_FiresWhenChannelOpened
✅ SequentialChannelOpenAccept
✅ SingleChannelConnect
✅ SingleChannelReadWrite

✅ Microsoft.DevTunnels.Ssh.Test.PipeTests

✅ PipeChannelClose(closeTarget: False)
✅ PipeChannelClose(closeTarget: True)
✅ PipeChannelPendingRequest
✅ PipeChannelSend(fromTarget: False)
✅ PipeChannelSend(fromTarget: True)
✅ PipeChannelSendLargeData(fromTarget: False)
✅ PipeChannelSendLargeData(fromTarget: True)
✅ PipeChannelSendSequence(fromTarget: False)
✅ PipeChannelSendSequence(fromTarget: True)
✅ PipeExtensibleChannelOpen
✅ PipeExtensibleChannelRequest(withChannelIdMapping: False)
✅ PipeExtensibleChannelRequest(withChannelIdMapping: True)
✅ PipeExtensibleSessionRequest
✅ PipeSessionChannelOpen(fromTarget: False)
✅ PipeSessionChannelOpen(fromTarget: True)
✅ PipeSessionChannelOpenAndClose(fromTarget: False)
✅ PipeSessionChannelOpenAndClose(fromTarget: True)
✅ PipeSessionChannelSend(fromTarget: False)
✅ PipeSessionChannelSend(fromTarget: True)
✅ PipeSessionClose(closeTarget: False)
✅ PipeSessionClose(closeTarget: True)
✅ PipeSessionPendingRequest

✅ Microsoft.DevTunnels.Ssh.Test.PortForwardingTests

✅ BlockConnectToNonForwardedPort
✅ BlockForwardAlreadyForwardedPort
✅ ConnectToForwardedPort
✅ ConnectToForwardedPortWithoutForwardingConnectionToLocalPort
✅ ConnectToForwardedPortWithTransform
✅ ForwardAndConnectTwoPorts
✅ ForwardFromRemotePortAutoChoose
✅ ForwardFromRemotePortCancel
✅ ForwardFromRemotePortClose(remoteClose: False)
✅ ForwardFromRemotePortClose(remoteClose: True)
✅ ForwardFromRemotePortEndSession(remoteEnd: False)
✅ ForwardFromRemotePortEndSession(remoteEnd: True)
✅ ForwardFromRemotePortError(remoteError: False)
✅ ForwardFromRemotePortError(remoteError: True)
✅ ForwardFromRemotePortInUse
✅ ForwardFromRemotePortRace(acceptLocalConnections: False)
✅ ForwardFromRemotePortRace(acceptLocalConnections: True)
✅ ForwardFromRemotePortReadWrite(remoteServerIPAddress: "::", remoteClientIPAddress: "::1", localForwardHost: "::1", localServerIPAddress: "::1")
✅ ForwardFromRemotePortReadWrite(remoteServerIPAddress: "::1", remoteClientIPAddress: "::1", localForwardHost: "::1", localServerIPAddress: "::1")
✅ ForwardFromRemotePortReadWrite(remoteServerIPAddress: "0.0.0.0", remoteClientIPAddress: "::1", localForwardHost: "::1", localServerIPAddress: "::1")
✅ ForwardFromRemotePortReadWrite(remoteServerIPAddress: "0.0.0.0", remoteClientIPAddress: "127.0.0.1", localForwardHost: "localhost", localServerIPAddress: "127.0.0.1")
✅ ForwardFromRemotePortReadWrite(remoteServerIPAddress: "127.0.0.1", remoteClientIPAddress: "::1", localForwardHost: "::1", localServerIPAddress: "::1")
✅ ForwardFromRemotePortReadWrite(remoteServerIPAddress: "127.0.0.1", remoteClientIPAddress: "::1", localForwardHost: "localhost", localServerIPAddress: "::1")
✅ ForwardFromRemotePortReadWrite(remoteServerIPAddress: "127.0.0.1", remoteClientIPAddress: "127.0.0.1", localForwardHost: "127.0.0.1", localServerIPAddress: "127.0.0.1")
✅ ForwardFromRemotePortReadWrite(remoteServerIPAddress: "127.0.0.1", remoteClientIPAddress: "127.0.0.1", localForwardHost: "localhost", localServerIPAddress: "::1")
✅ ForwardFromRemotePortReadWrite(remoteServerIPAddress: "127.0.0.1", remoteClientIPAddress: "127.0.0.1", localForwardHost: "localhost", localServerIPAddress: "127.0.0.1")
✅ ForwardFromRemotePortRequest(isRegistered: False, isAuthorized: False)
✅ ForwardFromRemotePortRequest(isRegistered: True, isAuthorized: False)
✅ ForwardFromRemotePortRequest(isRegistered: True, isAuthorized: True)
✅ ForwardFromRemotePortWithListenerFactory
✅ ForwardThroughPipe(fromRemote: False)
✅ ForwardThroughPipe(fromRemote: True)
✅ ForwardToRemotePortAutoChoose
✅ ForwardToRemotePortCancel
✅ ForwardToRemotePortClose(remoteClose: False)
✅ ForwardToRemotePortClose(remoteClose: True)
✅ ForwardToRemotePortEndSession(remoteEnd: False)
✅ ForwardToRemotePortEndSession(remoteEnd: True)
✅ ForwardToRemotePortError(remoteError: False)
✅ ForwardToRemotePortError(remoteError: True)
✅ ForwardToRemotePortInUse
✅ ForwardToRemotePortReadWrite(localServerIPAddress: "::", localClientIPAddress: "::1", remoteForwardHost: "::1", remoteServerIPAddress: "::1")
✅ ForwardToRemotePortReadWrite(localServerIPAddress: "::1", localClientIPAddress: "::1", remoteForwardHost: "::1", remoteServerIPAddress: "::1")
✅ ForwardToRemotePortReadWrite(localServerIPAddress: "0.0.0.0", localClientIPAddress: "::1", remoteForwardHost: "::1", remoteServerIPAddress: "::1")
✅ ForwardToRemotePortReadWrite(localServerIPAddress: "0.0.0.0", localClientIPAddress: "127.0.0.1", remoteForwardHost: "localhost", remoteServerIPAddress: "127.0.0.1")
✅ ForwardToRemotePortReadWrite(localServerIPAddress: "127.0.0.1", localClientIPAddress: "::1", remoteForwardHost: "::1", remoteServerIPAddress: "::1")
✅ ForwardToRemotePortReadWrite(localServerIPAddress: "127.0.0.1", localClientIPAddress: "::1", remoteForwardHost: "localhost", remoteServerIPAddress: "::1")
✅ ForwardToRemotePortReadWrite(localServerIPAddress: "127.0.0.1", localClientIPAddress: "127.0.0.1", remoteForwardHost: "127.0.0.1", remoteServerIPAddress: "127.0.0.1")
✅ ForwardToRemotePortReadWrite(localServerIPAddress: "127.0.0.1", localClientIPAddress: "127.0.0.1", remoteForwardHost: "localhost", remoteServerIPAddress: "::1")
✅ ForwardToRemotePortReadWrite(localServerIPAddress: "127.0.0.1", localClientIPAddress: "127.0.0.1", remoteForwardHost: "localhost", remoteServerIPAddress: "127.0.0.1")
✅ ForwardToRemotePortRequest
✅ ForwardToRemotePortUnauthorized
✅ RaiseForwardedPortEvents
✅ ReforwardingTheSamePortWhenNotAcceptLocalConnectionsForForwardedPorts
✅ StreamFromRemotePort(autoChoose: False)
✅ StreamFromRemotePort(autoChoose: True)
✅ StreamToRemotePort
✅ StreamToRemotePortError

✅ Microsoft.DevTunnels.Ssh.Test.ReconnectTests

✅ AcceptChannelOnServerReconnect
✅ DisconnectViaClientSessionClose
✅ DisconnectViaServerSessionClose
✅ DisconnectViaStreamClose
✅ DisconnectViaStreamException
✅ MultiReconnect
✅ Reconnect
✅ ReconnectAfterInterruptedReconnect
✅ ReconnectBeforeServerDisconnected
✅ ReconnectChannel
✅ ReconnectSessionNotFound
✅ ReconnectThenKeyExchange
✅ ReconnectWhileStreaming
✅ ReconnectWithRetransmittedClientData
✅ ReconnectWithRetransmittedServerData
✅ ReconnectWrongHostKey
✅ ReconnectWrongSessionId
✅ SendWhileDisconnected

✅ Microsoft.DevTunnels.Ssh.Test.SecureStreamTests

✅ AuthenticateClient(authenticateSuccess: False)
✅ AuthenticateClient(authenticateSuccess: True)
✅ AuthenticateServer(authenticateSuccess: False)
✅ AuthenticateServer(authenticateSuccess: True)
✅ DisposeClosesTransportStream(disposeAsync: False)
✅ DisposeClosesTransportStream(disposeAsync: True)
✅ DisposeRaisesCloseEvent(isConnected: False, disposeAsync: False)
✅ DisposeRaisesCloseEvent(isConnected: False, disposeAsync: True)
✅ DisposeRaisesCloseEvent(isConnected: True, disposeAsync: False)
✅ DisposeRaisesCloseEvent(isConnected: True, disposeAsync: True)
✅ ReadWrite
✅ ReconnectSecureStream

✅ Microsoft.DevTunnels.Ssh.Test.ServiceTests

✅ ActivateOnChannelRequest
✅ ActivateOnChannelType
✅ ActivateOnChannelTypeChannelRequest
✅ ActivateOnServiceRequest
✅ ActivateOnSessionRequest
✅ SendDebugMessage
✅ SendUnimplementedMessage

✅ Microsoft.DevTunnels.Ssh.Test.SessionTests

✅ AuthenticateCallbackException
✅ AuthenticateClientPublicKeyQuery(result: False)
✅ AuthenticateClientPublicKeyQuery(result: True)
✅ AuthenticateClientWithNoCredentials
✅ AuthenticateClientWithPassword
✅ AuthenticateClientWithPasswordFail
✅ AuthenticateClientWithPublicKey(pkAlgorithmName: "ecdsa-sha2-nistp256", keySize: null)
✅ AuthenticateClientWithPublicKey(pkAlgorithmName: "ecdsa-sha2-nistp384", keySize: null)
✅ AuthenticateClientWithPublicKey(pkAlgorithmName: "rsa-sha2-256", keySize: 2048)
✅ AuthenticateClientWithPublicKey(pkAlgorithmName: "rsa-sha2-512", keySize: 4096)
✅ AuthenticateClientWithPublicKeyFail
✅ AuthenticateConnectionException
✅ AuthenticateInteractive
✅ AuthenticateServerFail
✅ CloseClientSession
✅ CloseServerSession
✅ CloseSessionStream
✅ NegotiateNoKeyExchange(clientForce: False)
✅ NegotiateNoKeyExchange(clientForce: True)
✅ OpenSessionWithMultipleRequests
✅ OverlappingSessionRequests
✅ SendWhileDisconnected
✅ SessionRequestUnauthenticated

✅ Microsoft.DevTunnels.Ssh.Test.StreamTests

✅ ClosedStreamCannotReadOrWrite
✅ CloseStreamClosesChannel
✅ StreamData(data: [[]])
✅ StreamData(data: [[0], []])
✅ StreamData(data: [[116, 101, 115, 116], []])
✅ StreamData(data: [[65, 65, 65, 65, 65, ...]])

✅ Microsoft.DevTunnels.Ssh.Test.VersionTests

✅ GetLocalVersion
✅ ParseOpenSshForWindowsVersion
✅ ParseOpenSshVersion
✅ ParseOpenSshVersionWithExtraInfo
✅ ParseVsSshCSVersion
✅ ParseVsSSHTSVersion
✅ ParseWithNoSoftwareVersion

✅ out/TestResults/SSH-CS-netcoreapp3.1.trx

376 tests were completed in 177s with 366 passed, 0 failed and 10 skipped.

Test suite Passed Failed Skipped Time
Microsoft.DevTunnels.Ssh.Test.ChannelTests 58✅ 34s
Microsoft.DevTunnels.Ssh.Test.CryptoTests 18✅ 6s
Microsoft.DevTunnels.Ssh.Test.InteropTests 23✅ 29s
Microsoft.DevTunnels.Ssh.Test.KeyImportExportTests 87✅ 10⚪ 3s
Microsoft.DevTunnels.Ssh.Test.MetricsTests 8✅ 6s
Microsoft.DevTunnels.Ssh.Test.MultiChannelStreamTests 13✅ 89ms
Microsoft.DevTunnels.Ssh.Test.PipeTests 22✅ 20s
Microsoft.DevTunnels.Ssh.Test.PortForwardingTests 58✅ 24s
Microsoft.DevTunnels.Ssh.Test.ReconnectTests 18✅ 17s
Microsoft.DevTunnels.Ssh.Test.SecureStreamTests 12✅ 5s
Microsoft.DevTunnels.Ssh.Test.ServiceTests 7✅ 3s
Microsoft.DevTunnels.Ssh.Test.SessionTests 23✅ 26s
Microsoft.DevTunnels.Ssh.Test.StreamTests 6✅ 3s
Microsoft.DevTunnels.Ssh.Test.TaskExtensionsTests 6✅ 21ms
Microsoft.DevTunnels.Ssh.Test.VersionTests 7✅ 1ms

✅ Microsoft.DevTunnels.Ssh.Test.ChannelTests

✅ ChannelReceiveWaitsForListener
✅ ChannelRequest(success: False)
✅ ChannelRequest(success: True)
✅ ChannelRequestEarlyCancellation
✅ ChannelRequestHandlerClosesChannel
✅ ChannelRequestHandlerException
✅ ChannelRequestLateCancellation
✅ CloseChannelWithSignal
✅ CloseChannelWithStatus
✅ CloseClientChannel
✅ CloseServerChannel
✅ CloseSessionClosesChannel
✅ CloseSessionClosesChannelWithException
✅ DisposeChannelCloses
✅ OpenAndCloseChannelFromClient(channelType: "test")
✅ OpenAndCloseChannelFromClient(channelType: null)
✅ OpenAndCloseChannelFromServer(channelType: "test")
✅ OpenAndCloseChannelFromServer(channelType: null)
✅ OpenChannelCancelByAcceptor
✅ OpenChannelCancelByOpener
✅ OpenChannelWithMultipleRequests
✅ OpenChannelWithRequest(serverExtension: False, clientExtension: False)
✅ OpenChannelWithRequest(serverExtension: False, clientExtension: True)
✅ OpenChannelWithRequest(serverExtension: True, clientExtension: False)
✅ OpenChannelWithRequest(serverExtension: True, clientExtension: True)
✅ OpenChannelWithRequestFail(serverExtension: False, clientExtension: False)
✅ OpenChannelWithRequestFail(serverExtension: False, clientExtension: True)
✅ OpenChannelWithRequestFail(serverExtension: True, clientExtension: False)
✅ OpenChannelWithRequestFail(serverExtension: True, clientExtension: True)
✅ OpenChannelWithRequestNoReply(serverExtension: False, clientExtension: False)
✅ OpenChannelWithRequestNoReply(serverExtension: False, clientExtension: True)
✅ OpenChannelWithRequestNoReply(serverExtension: True, clientExtension: False)
✅ OpenChannelWithRequestNoReply(serverExtension: True, clientExtension: True)
✅ OpenChannelWithRequestUnauthenticated
✅ SendBlocksOnClosedWindow
✅ SendChannelData(data: [[]])
✅ SendChannelData(data: [[0], []])
✅ SendChannelData(data: [[116, 101, 115, 116], []])
✅ SendChannelData(data: [[65, 65, 65, 65, 65, ...]])
✅ SendChannelDataOverMultipleChannels(data: [[]])
✅ SendChannelDataOverMultipleChannels(data: [[0], []])
✅ SendChannelDataOverMultipleChannels(data: [[116, 101, 115, 116], []])
✅ SendChannelDataOverMultipleChannels(data: [[65, 65, 65, 65, 65, ...]])
✅ SendChannelDataWithOffset
✅ SendIncreasingChannelData
✅ SendLargeChannelData(clientMaxWindowSize: 1048576, serverMaxWindowSize: 1048576)
✅ SendLargeChannelData(clientMaxWindowSize: 1048576, serverMaxWindowSize: 5242880)
✅ SendLargeChannelData(clientMaxWindowSize: 5242880, serverMaxWindowSize: 1048576)
✅ SendLargeDataWithoutAwait
✅ SendServerChannelData(data: [[]])
✅ SendServerChannelData(data: [[0], []])
✅ SendServerChannelData(data: [[116, 101, 115, 116], []])
✅ SendServerChannelData(data: [[65, 65, 65, 65, 65, ...]])
✅ SendWhileOpening
✅ TraceChannelData
✅ UnknownChannelAdjustWindowIsIgnored
✅ UnknownChannelDataIsIgnored
✅ UnknownChannelEofIsIgnored

✅ Microsoft.DevTunnels.Ssh.Test.CryptoTests

✅ EncryptDecrypt(encAlg: "aes256-cbc")
✅ EncryptDecrypt(encAlg: "aes256-ctr")
✅ EncryptDecrypt(encAlg: "aes256-gcm@openssh.com")
✅ Hmac(hmacAlg: "hmac-sha2-256-etm@openssh.com")
✅ Hmac(hmacAlg: "hmac-sha2-256")
✅ Hmac(hmacAlg: "hmac-sha2-512-etm@openssh.com")
✅ Hmac(hmacAlg: "hmac-sha2-512")
✅ KeyExchange(kexAlg: "diffie-hellman-group14-sha256")
✅ KeyExchange(kexAlg: "diffie-hellman-group16-sha512")
✅ KeyExchange(kexAlg: "ecdh-sha2-nistp256")
✅ KeyExchange(kexAlg: "ecdh-sha2-nistp384")
✅ KeyExchange(kexAlg: "ecdh-sha2-nistp521")
✅ SignVerify(pkAlg: "ecdsa-sha2-nistp256", keySize: null)
✅ SignVerify(pkAlg: "ecdsa-sha2-nistp384", keySize: null)
✅ SignVerify(pkAlg: "ecdsa-sha2-nistp521", keySize: null)
✅ SignVerify(pkAlg: "rsa-sha2-256", keySize: 1024)
✅ SignVerify(pkAlg: "rsa-sha2-512", keySize: 2048)
✅ SignVerify(pkAlg: "rsa-sha2-512", keySize: 4096)

✅ Microsoft.DevTunnels.Ssh.Test.InteropTests

✅ InteropJumpHostTest
✅ InteropWithSshClientTool(kexAlg: "diffie-hellman-group14-sha256", pkAlg: "ecdsa-sha2-nistp384", hmacAlg: "hmac-sha2-512")
✅ InteropWithSshClientTool(kexAlg: "diffie-hellman-group14-sha256", pkAlg: "ecdsa-sha2-nistp521", hmacAlg: "hmac-sha2-512")
✅ InteropWithSshClientTool(kexAlg: "diffie-hellman-group14-sha256", pkAlg: "rsa-sha2-512", hmacAlg: "hmac-sha2-512")
✅ InteropWithSshClientTool(kexAlg: "diffie-hellman-group16-sha512", pkAlg: "rsa-sha2-512", hmacAlg: "hmac-sha2-512-etm@openssh.com")
✅ InteropWithSshClientTool(kexAlg: "ecdh-sha2-nistp384", pkAlg: "ecdsa-sha2-nistp384", hmacAlg: "hmac-sha2-512")
✅ InteropWithSshClientTool(kexAlg: "ecdh-sha2-nistp521", pkAlg: "ecdsa-sha2-nistp521", hmacAlg: "hmac-sha2-512-etm@openssh.com")
✅ InteropWithSshClientTSLib(kexAlg: "diffie-hellman-group14-sha256", pkAlg: "ecdsa-sha2-nistp521", hmacAlg: "hmac-sha2-512", reconnect: False)
✅ InteropWithSshClientTSLib(kexAlg: "diffie-hellman-group14-sha256", pkAlg: "rsa-sha2-512", hmacAlg: "hmac-sha2-512", reconnect: True)
✅ InteropWithSshClientTSLib(kexAlg: "diffie-hellman-group16-sha512", pkAlg: "rsa-sha2-512", hmacAlg: "hmac-sha2-512-etm@openssh.com", reconnect: False)
✅ InteropWithSshClientTSLib(kexAlg: "diffie-hellman-group16-sha512", pkAlg: "rsa-sha2-512", hmacAlg: "hmac-sha2-512-etm@openssh.com", reconnect: True)
✅ InteropWithSshServerTool(kexAlg: "diffie-hellman-group14-sha256", pkAlg: "ecdsa-sha2-nistp384", hmacAlg: "hmac-sha2-512")
✅ InteropWithSshServerTool(kexAlg: "diffie-hellman-group14-sha256", pkAlg: "ecdsa-sha2-nistp521", hmacAlg: "hmac-sha2-512")
✅ InteropWithSshServerTool(kexAlg: "diffie-hellman-group14-sha256", pkAlg: "rsa-sha2-512", hmacAlg: "hmac-sha2-512")
✅ InteropWithSshServerTool(kexAlg: "diffie-hellman-group16-sha512", pkAlg: "rsa-sha2-512", hmacAlg: "hmac-sha2-512-etm@openssh.com")
✅ InteropWithSshServerTool(kexAlg: "ecdh-sha2-nistp384", pkAlg: "ecdsa-sha2-nistp384", hmacAlg: "hmac-sha2-512")
✅ InteropWithSshServerTool(kexAlg: "ecdh-sha2-nistp521", pkAlg: "ecdsa-sha2-nistp521", hmacAlg: "hmac-sha2-512-etm@openssh.com")
✅ InteropWithSshServerTSLib(kexAlg: "diffie-hellman-group14-sha256", pkAlg: "ecdsa-sha2-nistp521", hmacAlg: "hmac-sha2-512", reconnect: False)
✅ InteropWithSshServerTSLib(kexAlg: "diffie-hellman-group14-sha256", pkAlg: "rsa-sha2-512", hmacAlg: "hmac-sha2-512", reconnect: True)
✅ InteropWithSshServerTSLib(kexAlg: "diffie-hellman-group16-sha512", pkAlg: "rsa-sha2-512", hmacAlg: "hmac-sha2-512-etm@openssh.com", reconnect: False)
✅ InteropWithSshServerTSLib(kexAlg: "diffie-hellman-group16-sha512", pkAlg: "rsa-sha2-512", hmacAlg: "hmac-sha2-512-etm@openssh.com", reconnect: True)
✅ InteropWithSshServerTSLib(kexAlg: "ecdh-sha2-nistp384", pkAlg: "ecdsa-sha2-nistp384", hmacAlg: "hmac-sha2-512", reconnect: False)
✅ InteropWithSshServerTSLib(kexAlg: "ecdh-sha2-nistp521", pkAlg: "ecdsa-sha2-nistp521", hmacAlg: "hmac-sha2-512-etm@openssh.com", reconnect: True)

✅ Microsoft.DevTunnels.Ssh.Test.KeyImportExportTests

✅ ExportImportPrivateKeyBytes(algorithm: "ecdsa384", keyFormat: OpenSsh, passphrase: "password")
✅ ExportImportPrivateKeyBytes(algorithm: "ecdsa384", keyFormat: OpenSsh, passphrase: null)
✅ ExportImportPrivateKeyBytes(algorithm: "ecdsa384", keyFormat: Pkcs8, passphrase: "password")
✅ ExportImportPrivateKeyBytes(algorithm: "ecdsa384", keyFormat: Pkcs8, passphrase: null)
✅ ExportImportPrivateKeyBytes(algorithm: "ecdsa384", keyFormat: Sec1, passphrase: null)
✅ ExportImportPrivateKeyBytes(algorithm: "rsa2048", keyFormat: OpenSsh, passphrase: "password")
✅ ExportImportPrivateKeyBytes(algorithm: "rsa2048", keyFormat: OpenSsh, passphrase: null)
✅ ExportImportPrivateKeyBytes(algorithm: "rsa2048", keyFormat: Pkcs1, passphrase: null)
✅ ExportImportPrivateKeyBytes(algorithm: "rsa2048", keyFormat: Pkcs8, passphrase: "password")
✅ ExportImportPrivateKeyBytes(algorithm: "rsa2048", keyFormat: Pkcs8, passphrase: null)
✅ ExportImportPrivateKeyBytes(algorithm: "rsa2048", keyFormat: Ssh2, passphrase: null)
✅ ExportImportPublicKeyBytes(algorithm: "ecdsa384", keyFormat: Pkcs8)
✅ ExportImportPublicKeyBytes(algorithm: "ecdsa384", keyFormat: Ssh)
✅ ExportImportPublicKeyBytes(algorithm: "rsa2048", keyFormat: Pkcs1)
✅ ExportImportPublicKeyBytes(algorithm: "rsa2048", keyFormat: Pkcs8)
✅ ExportImportPublicKeyBytes(algorithm: "rsa2048", keyFormat: Ssh)
✅ ExportImportPublicKeyBytes(algorithm: "rsa2048", keyFormat: Ssh2)
✅ ExportPrivateKey(algorithm: "ecdsa384", keyFormat: OpenSsh, passphrase: "password")
✅ ExportPrivateKey(algorithm: "ecdsa384", keyFormat: OpenSsh, passphrase: null)
✅ ExportPrivateKey(algorithm: "ecdsa384", keyFormat: Pkcs8, passphrase: "password")
✅ ExportPrivateKey(algorithm: "ecdsa384", keyFormat: Pkcs8, passphrase: null)
✅ ExportPrivateKey(algorithm: "ecdsa384", keyFormat: Sec1, passphrase: "password")
✅ ExportPrivateKey(algorithm: "ecdsa384", keyFormat: Sec1, passphrase: null)
✅ ExportPrivateKey(algorithm: "ecdsa521", keyFormat: Pkcs8, passphrase: null)
✅ ExportPrivateKey(algorithm: "ecdsa521", keyFormat: Sec1, passphrase: null)
⚪ ExportPrivateKey(algorithm: "rsa2048", keyFormat: Jwk, passphrase: null)
✅ ExportPrivateKey(algorithm: "rsa2048", keyFormat: OpenSsh, passphrase: "password")
✅ ExportPrivateKey(algorithm: "rsa2048", keyFormat: OpenSsh, passphrase: null)
✅ ExportPrivateKey(algorithm: "rsa2048", keyFormat: Pkcs1, passphrase: "password")
✅ ExportPrivateKey(algorithm: "rsa2048", keyFormat: Pkcs1, passphrase: null)
✅ ExportPrivateKey(algorithm: "rsa2048", keyFormat: Pkcs8, passphrase: "password")
✅ ExportPrivateKey(algorithm: "rsa2048", keyFormat: Pkcs8, passphrase: null)
✅ ExportPrivateKey(algorithm: "rsa2048", keyFormat: Ssh2, passphrase: "password")
✅ ExportPrivateKey(algorithm: "rsa2048", keyFormat: Ssh2, passphrase: null)
⚪ ExportPrivateKey(algorithm: "rsa4096", keyFormat: Jwk, passphrase: null)
✅ ExportPrivateKey(algorithm: "rsa4096", keyFormat: OpenSsh, passphrase: null)
✅ ExportPrivateKey(algorithm: "rsa4096", keyFormat: Pkcs1, passphrase: null)
✅ ExportPrivateKey(algorithm: "rsa4096", keyFormat: Pkcs8, passphrase: null)
✅ ExportPrivateKey(algorithm: "rsa4096", keyFormat: Ssh2, passphrase: null)
⚪ ExportPublicKey(algorithm: "ecdsa384", keyFormat: Jwk)
✅ ExportPublicKey(algorithm: "ecdsa384", keyFormat: Pkcs8)
✅ ExportPublicKey(algorithm: "ecdsa384", keyFormat: Ssh)
✅ ExportPublicKey(algorithm: "ecdsa521", keyFormat: Pkcs8)
✅ ExportPublicKey(algorithm: "ecdsa521", keyFormat: Ssh)
⚪ ExportPublicKey(algorithm: "rsa2048", keyFormat: Jwk)
✅ ExportPublicKey(algorithm: "rsa2048", keyFormat: Pkcs1)
✅ ExportPublicKey(algorithm: "rsa2048", keyFormat: Pkcs8)
✅ ExportPublicKey(algorithm: "rsa2048", keyFormat: Ssh)
✅ ExportPublicKey(algorithm: "rsa2048", keyFormat: Ssh2)
⚪ ExportPublicKey(algorithm: "rsa4096", keyFormat: Jwk)
✅ ExportPublicKey(algorithm: "rsa4096", keyFormat: Pkcs1)
✅ ExportPublicKey(algorithm: "rsa4096", keyFormat: Pkcs8)
✅ ExportPublicKey(algorithm: "rsa4096", keyFormat: Ssh)
✅ ExportPublicKey(algorithm: "rsa4096", keyFormat: Ssh2)
✅ ExportPublicKeyNotSupported(algorithm: "ecdsa384", keyFormat: Sec1)
⚪ ImportPrivateKey(algorithm: "ecdsa384", keyFormat: Jwk, passphrase: null)
✅ ImportPrivateKey(algorithm: "ecdsa384", keyFormat: OpenSsh, passphrase: "password")
✅ ImportPrivateKey(algorithm: "ecdsa384", keyFormat: OpenSsh, passphrase: null)
✅ ImportPrivateKey(algorithm: "ecdsa384", keyFormat: Pkcs8, passphrase: "password")
✅ ImportPrivateKey(algorithm: "ecdsa384", keyFormat: Pkcs8, passphrase: null)
✅ ImportPrivateKey(algorithm: "ecdsa384", keyFormat: Sec1, passphrase: "password")
✅ ImportPrivateKey(algorithm: "ecdsa384", keyFormat: Sec1, passphrase: null)
✅ ImportPrivateKey(algorithm: "ecdsa521", keyFormat: Pkcs8, passphrase: null)
✅ ImportPrivateKey(algorithm: "ecdsa521", keyFormat: Sec1, passphrase: null)
⚪ ImportPrivateKey(algorithm: "rsa2048", keyFormat: Jwk, passphrase: null)
✅ ImportPrivateKey(algorithm: "rsa2048", keyFormat: OpenSsh, passphrase: "password")
✅ ImportPrivateKey(algorithm: "rsa2048", keyFormat: OpenSsh, passphrase: null)
✅ ImportPrivateKey(algorithm: "rsa2048", keyFormat: Pkcs1, passphrase: "password")
✅ ImportPrivateKey(algorithm: "rsa2048", keyFormat: Pkcs1, passphrase: null)
✅ ImportPrivateKey(algorithm: "rsa2048", keyFormat: Pkcs8, passphrase: "password")
✅ ImportPrivateKey(algorithm: "rsa2048", keyFormat: Pkcs8, passphrase: null)
✅ ImportPrivateKey(algorithm: "rsa2048", keyFormat: Ssh2, passphrase: "password")
✅ ImportPrivateKey(algorithm: "rsa2048", keyFormat: Ssh2, passphrase: null)
⚪ ImportPrivateKey(algorithm: "rsa4096", keyFormat: Jwk, passphrase: null)
✅ ImportPrivateKey(algorithm: "rsa4096", keyFormat: OpenSsh, passphrase: null)
✅ ImportPrivateKey(algorithm: "rsa4096", keyFormat: Pkcs1, passphrase: null)
✅ ImportPrivateKey(algorithm: "rsa4096", keyFormat: Pkcs8, passphrase: null)
✅ ImportPrivateKey(algorithm: "rsa4096", keyFormat: Ssh2, passphrase: null)
✅ ImportPrivateKeyInvalidPassword(algorithm: "ecdsa384", keyFormat: OpenSsh)
✅ ImportPrivateKeyInvalidPassword(algorithm: "ecdsa384", keyFormat: Pkcs8)
✅ ImportPrivateKeyInvalidPassword(algorithm: "rsa2048", keyFormat: OpenSsh)
✅ ImportPrivateKeyInvalidPassword(algorithm: "rsa2048", keyFormat: Pkcs1)
✅ ImportPrivateKeyInvalidPassword(algorithm: "rsa2048", keyFormat: Pkcs8)
✅ ImportPrivateKeyInvalidPassword(algorithm: "rsa2048", keyFormat: Ssh2)
⚪ ImportPublicKey(algorithm: "ecdsa384", keyFormat: Jwk)
✅ ImportPublicKey(algorithm: "ecdsa384", keyFormat: Pkcs8)
✅ ImportPublicKey(algorithm: "ecdsa384", keyFormat: Ssh)
✅ ImportPublicKey(algorithm: "ecdsa521", keyFormat: Ssh)
⚪ ImportPublicKey(algorithm: "rsa2048", keyFormat: Jwk)
✅ ImportPublicKey(algorithm: "rsa2048", keyFormat: Pkcs1)
✅ ImportPublicKey(algorithm: "rsa2048", keyFormat: Pkcs8)
✅ ImportPublicKey(algorithm: "rsa2048", keyFormat: Ssh)
✅ ImportPublicKey(algorithm: "rsa2048", keyFormat: Ssh2)
✅ ImportPublicKey(algorithm: "rsa4096", keyFormat: Pkcs1)
✅ ImportPublicKey(algorithm: "rsa4096", keyFormat: Pkcs8)
✅ ImportPublicKey(algorithm: "rsa4096", keyFormat: Ssh)
✅ ImportPublicKey(algorithm: "rsa4096", keyFormat: Ssh2)

✅ Microsoft.DevTunnels.Ssh.Test.MetricsTests

✅ ClosedSessionHasNoLatency
✅ ExpandContourIntervals
✅ ExportImportContour
✅ MeasureChannelBytes
✅ MeasureSessionBytes
✅ MeasureSessionLatency
✅ MeasureSessionMessages
✅ RecordSessionContour

✅ Microsoft.DevTunnels.Ssh.Test.MultiChannelStreamTests

✅ ConnectAndRunUntilClosedAsync_Cancelled
✅ Dispose_DisposesTransportStream(disposeAsync: False)
✅ Dispose_DisposesTransportStream(disposeAsync: True)
✅ Dispose_FiresCloseEvent(isConnected: False, disposeAsync: False)
✅ Dispose_FiresCloseEvent(isConnected: False, disposeAsync: True)
✅ Dispose_FiresCloseEvent(isConnected: True, disposeAsync: False)
✅ Dispose_FiresCloseEvent(isConnected: True, disposeAsync: True)
✅ MultiChannelConnect
✅ MultiChannelReadWrite
✅ OpenChannelEvent_FiresWhenChannelOpened
✅ SequentialChannelOpenAccept
✅ SingleChannelConnect
✅ SingleChannelReadWrite

✅ Microsoft.DevTunnels.Ssh.Test.PipeTests

✅ PipeChannelClose(closeTarget: False)
✅ PipeChannelClose(closeTarget: True)
✅ PipeChannelPendingRequest
✅ PipeChannelSend(fromTarget: False)
✅ PipeChannelSend(fromTarget: True)
✅ PipeChannelSendLargeData(fromTarget: False)
✅ PipeChannelSendLargeData(fromTarget: True)
✅ PipeChannelSendSequence(fromTarget: False)
✅ PipeChannelSendSequence(fromTarget: True)
✅ PipeExtensibleChannelOpen
✅ PipeExtensibleChannelRequest(withChannelIdMapping: False)
✅ PipeExtensibleChannelRequest(withChannelIdMapping: True)
✅ PipeExtensibleSessionRequest
✅ PipeSessionChannelOpen(fromTarget: False)
✅ PipeSessionChannelOpen(fromTarget: True)
✅ PipeSessionChannelOpenAndClose(fromTarget: False)
✅ PipeSessionChannelOpenAndClose(fromTarget: True)
✅ PipeSessionChannelSend(fromTarget: False)
✅ PipeSessionChannelSend(fromTarget: True)
✅ PipeSessionClose(closeTarget: False)
✅ PipeSessionClose(closeTarget: True)
✅ PipeSessionPendingRequest

✅ Microsoft.DevTunnels.Ssh.Test.PortForwardingTests

✅ BlockConnectToNonForwardedPort
✅ BlockForwardAlreadyForwardedPort
✅ ConnectToForwardedPort
✅ ConnectToForwardedPortWithoutForwardingConnectionToLocalPort
✅ ConnectToForwardedPortWithTransform
✅ ForwardAndConnectTwoPorts
✅ ForwardFromRemotePortAutoChoose
✅ ForwardFromRemotePortCancel
✅ ForwardFromRemotePortClose(remoteClose: False)
✅ ForwardFromRemotePortClose(remoteClose: True)
✅ ForwardFromRemotePortEndSession(remoteEnd: False)
✅ ForwardFromRemotePortEndSession(remoteEnd: True)
✅ ForwardFromRemotePortError(remoteError: False)
✅ ForwardFromRemotePortError(remoteError: True)
✅ ForwardFromRemotePortInUse
✅ ForwardFromRemotePortRace(acceptLocalConnections: False)
✅ ForwardFromRemotePortRace(acceptLocalConnections: True)
✅ ForwardFromRemotePortReadWrite(remoteServerIPAddress: "::", remoteClientIPAddress: "::1", localForwardHost: "::1", localServerIPAddress: "::1")
✅ ForwardFromRemotePortReadWrite(remoteServerIPAddress: "::1", remoteClientIPAddress: "::1", localForwardHost: "::1", localServerIPAddress: "::1")
✅ ForwardFromRemotePortReadWrite(remoteServerIPAddress: "0.0.0.0", remoteClientIPAddress: "::1", localForwardHost: "::1", localServerIPAddress: "::1")
✅ ForwardFromRemotePortReadWrite(remoteServerIPAddress: "0.0.0.0", remoteClientIPAddress: "127.0.0.1", localForwardHost: "localhost", localServerIPAddress: "127.0.0.1")
✅ ForwardFromRemotePortReadWrite(remoteServerIPAddress: "127.0.0.1", remoteClientIPAddress: "::1", localForwardHost: "::1", localServerIPAddress: "::1")
✅ ForwardFromRemotePortReadWrite(remoteServerIPAddress: "127.0.0.1", remoteClientIPAddress: "::1", localForwardHost: "localhost", localServerIPAddress: "::1")
✅ ForwardFromRemotePortReadWrite(remoteServerIPAddress: "127.0.0.1", remoteClientIPAddress: "127.0.0.1", localForwardHost: "127.0.0.1", localServerIPAddress: "127.0.0.1")
✅ ForwardFromRemotePortReadWrite(remoteServerIPAddress: "127.0.0.1", remoteClientIPAddress: "127.0.0.1", localForwardHost: "localhost", localServerIPAddress: "::1")
✅ ForwardFromRemotePortReadWrite(remoteServerIPAddress: "127.0.0.1", remoteClientIPAddress: "127.0.0.1", localForwardHost: "localhost", localServerIPAddress: "127.0.0.1")
✅ ForwardFromRemotePortRequest(isRegistered: False, isAuthorized: False)
✅ ForwardFromRemotePortRequest(isRegistered: True, isAuthorized: False)
✅ ForwardFromRemotePortRequest(isRegistered: True, isAuthorized: True)
✅ ForwardFromRemotePortWithListenerFactory
✅ ForwardThroughPipe(fromRemote: False)
✅ ForwardThroughPipe(fromRemote: True)
✅ ForwardToRemotePortAutoChoose
✅ ForwardToRemotePortCancel
✅ ForwardToRemotePortClose(remoteClose: False)
✅ ForwardToRemotePortClose(remoteClose: True)
✅ ForwardToRemotePortEndSession(remoteEnd: False)
✅ ForwardToRemotePortEndSession(remoteEnd: True)
✅ ForwardToRemotePortError(remoteError: False)
✅ ForwardToRemotePortError(remoteError: True)
✅ ForwardToRemotePortInUse
✅ ForwardToRemotePortReadWrite(localServerIPAddress: "::", localClientIPAddress: "::1", remoteForwardHost: "::1", remoteServerIPAddress: "::1")
✅ ForwardToRemotePortReadWrite(localServerIPAddress: "::1", localClientIPAddress: "::1", remoteForwardHost: "::1", remoteServerIPAddress: "::1")
✅ ForwardToRemotePortReadWrite(localServerIPAddress: "0.0.0.0", localClientIPAddress: "::1", remoteForwardHost: "::1", remoteServerIPAddress: "::1")
✅ ForwardToRemotePortReadWrite(localServerIPAddress: "0.0.0.0", localClientIPAddress: "127.0.0.1", remoteForwardHost: "localhost", remoteServerIPAddress: "127.0.0.1")
✅ ForwardToRemotePortReadWrite(localServerIPAddress: "127.0.0.1", localClientIPAddress: "::1", remoteForwardHost: "::1", remoteServerIPAddress: "::1")
✅ ForwardToRemotePortReadWrite(localServerIPAddress: "127.0.0.1", localClientIPAddress: "::1", remoteForwardHost: "localhost", remoteServerIPAddress: "::1")
✅ ForwardToRemotePortReadWrite(localServerIPAddress: "127.0.0.1", localClientIPAddress: "127.0.0.1", remoteForwardHost: "127.0.0.1", remoteServerIPAddress: "127.0.0.1")
✅ ForwardToRemotePortReadWrite(localServerIPAddress: "127.0.0.1", localClientIPAddress: "127.0.0.1", remoteForwardHost: "localhost", remoteServerIPAddress: "::1")
✅ ForwardToRemotePortReadWrite(localServerIPAddress: "127.0.0.1", localClientIPAddress: "127.0.0.1", remoteForwardHost: "localhost", remoteServerIPAddress: "127.0.0.1")
✅ ForwardToRemotePortRequest
✅ ForwardToRemotePortUnauthorized
✅ RaiseForwardedPortEvents
✅ ReforwardingTheSamePortWhenNotAcceptLocalConnectionsForForwardedPorts
✅ StreamFromRemotePort(autoChoose: False)
✅ StreamFromRemotePort(autoChoose: True)
✅ StreamToRemotePort
✅ StreamToRemotePortError

✅ Microsoft.DevTunnels.Ssh.Test.ReconnectTests

✅ AcceptChannelOnServerReconnect
✅ DisconnectViaClientSessionClose
✅ DisconnectViaServerSessionClose
✅ DisconnectViaStreamClose
✅ DisconnectViaStreamException
✅ MultiReconnect
✅ Reconnect
✅ ReconnectAfterInterruptedReconnect
✅ ReconnectBeforeServerDisconnected
✅ ReconnectChannel
✅ ReconnectSessionNotFound
✅ ReconnectThenKeyExchange
✅ ReconnectWhileStreaming
✅ ReconnectWithRetransmittedClientData
✅ ReconnectWithRetransmittedServerData
✅ ReconnectWrongHostKey
✅ ReconnectWrongSessionId
✅ SendWhileDisconnected

✅ Microsoft.DevTunnels.Ssh.Test.SecureStreamTests

✅ AuthenticateClient(authenticateSuccess: False)
✅ AuthenticateClient(authenticateSuccess: True)
✅ AuthenticateServer(authenticateSuccess: False)
✅ AuthenticateServer(authenticateSuccess: True)
✅ DisposeClosesTransportStream(disposeAsync: False)
✅ DisposeClosesTransportStream(disposeAsync: True)
✅ DisposeRaisesCloseEvent(isConnected: False, disposeAsync: False)
✅ DisposeRaisesCloseEvent(isConnected: False, disposeAsync: True)
✅ DisposeRaisesCloseEvent(isConnected: True, disposeAsync: False)
✅ DisposeRaisesCloseEvent(isConnected: True, disposeAsync: True)
✅ ReadWrite
✅ ReconnectSecureStream

✅ Microsoft.DevTunnels.Ssh.Test.ServiceTests

✅ ActivateOnChannelRequest
✅ ActivateOnChannelType
✅ ActivateOnChannelTypeChannelRequest
✅ ActivateOnServiceRequest
✅ ActivateOnSessionRequest
✅ SendDebugMessage
✅ SendUnimplementedMessage

✅ Microsoft.DevTunnels.Ssh.Test.SessionTests

✅ AuthenticateCallbackException
✅ AuthenticateClientPublicKeyQuery(result: False)
✅ AuthenticateClientPublicKeyQuery(result: True)
✅ AuthenticateClientWithNoCredentials
✅ AuthenticateClientWithPassword
✅ AuthenticateClientWithPasswordFail
✅ AuthenticateClientWithPublicKey(pkAlgorithmName: "ecdsa-sha2-nistp256", keySize: null)
✅ AuthenticateClientWithPublicKey(pkAlgorithmName: "ecdsa-sha2-nistp384", keySize: null)
✅ AuthenticateClientWithPublicKey(pkAlgorithmName: "rsa-sha2-256", keySize: 2048)
✅ AuthenticateClientWithPublicKey(pkAlgorithmName: "rsa-sha2-512", keySize: 4096)
✅ AuthenticateClientWithPublicKeyFail
✅ AuthenticateConnectionException
✅ AuthenticateInteractive
✅ AuthenticateServerFail
✅ CloseClientSession
✅ CloseServerSession
✅ CloseSessionStream
✅ NegotiateNoKeyExchange(clientForce: False)
✅ NegotiateNoKeyExchange(clientForce: True)
✅ OpenSessionWithMultipleRequests
✅ OverlappingSessionRequests
✅ SendWhileDisconnected
✅ SessionRequestUnauthenticated

✅ Microsoft.DevTunnels.Ssh.Test.StreamTests

✅ ClosedStreamCannotReadOrWrite
✅ CloseStreamClosesChannel
✅ StreamData(data: [[]])
✅ StreamData(data: [[0], []])
✅ StreamData(data: [[116, 101, 115, 116], []])
✅ StreamData(data: [[65, 65, 65, 65, 65, ...]])

✅ Microsoft.DevTunnels.Ssh.Test.TaskExtensionsTests

✅ WaitAsync_Cancelled
✅ WaitAsync_CannotBeCancelled
✅ WaitAsync_ReturnsResult
✅ WaitAsync_ThrowsException
✅ WaitAsync_ThrowsForCancellation
✅ WaitAsync_ThrowsForNullTask

✅ Microsoft.DevTunnels.Ssh.Test.VersionTests

✅ GetLocalVersion
✅ ParseOpenSshForWindowsVersion
✅ ParseOpenSshVersion
✅ ParseOpenSshVersionWithExtraInfo
✅ ParseVsSshCSVersion
✅ ParseVsSSHTSVersion
✅ ParseWithNoSoftwareVersion