forked from quic-go/quic-go
267 lines
8.0 KiB
Go
267 lines
8.0 KiB
Go
package qlog
|
|
|
|
import (
|
|
"go/ast"
|
|
"go/parser"
|
|
gotoken "go/token"
|
|
"path"
|
|
"runtime"
|
|
"strconv"
|
|
"testing"
|
|
|
|
"github.com/quic-go/quic-go/internal/protocol"
|
|
"github.com/quic-go/quic-go/internal/qerr"
|
|
"github.com/quic-go/quic-go/logging"
|
|
"github.com/stretchr/testify/require"
|
|
)
|
|
|
|
func TestOwnerStringRepresentation(t *testing.T) {
|
|
testCases := []struct {
|
|
owner owner
|
|
expected string
|
|
}{
|
|
{ownerLocal, "local"},
|
|
{ownerRemote, "remote"},
|
|
}
|
|
|
|
for _, tc := range testCases {
|
|
require.Equal(t, tc.expected, tc.owner.String())
|
|
}
|
|
}
|
|
|
|
func TestCategoryStringRepresentation(t *testing.T) {
|
|
testCases := []struct {
|
|
category category
|
|
expected string
|
|
}{
|
|
{categoryConnectivity, "connectivity"},
|
|
{categoryTransport, "transport"},
|
|
{categoryRecovery, "recovery"},
|
|
{categorySecurity, "security"},
|
|
}
|
|
|
|
for _, tc := range testCases {
|
|
require.Equal(t, tc.expected, tc.category.String())
|
|
}
|
|
}
|
|
|
|
func TestPacketTypeStringRepresentation(t *testing.T) {
|
|
testCases := []struct {
|
|
packetType logging.PacketType
|
|
expected string
|
|
}{
|
|
{logging.PacketTypeInitial, "initial"},
|
|
{logging.PacketTypeHandshake, "handshake"},
|
|
{logging.PacketType0RTT, "0RTT"},
|
|
{logging.PacketType1RTT, "1RTT"},
|
|
{logging.PacketTypeStatelessReset, "stateless_reset"},
|
|
{logging.PacketTypeRetry, "retry"},
|
|
{logging.PacketTypeVersionNegotiation, "version_negotiation"},
|
|
{logging.PacketTypeNotDetermined, ""},
|
|
}
|
|
|
|
for _, tc := range testCases {
|
|
require.Equal(t, tc.expected, packetType(tc.packetType).String())
|
|
}
|
|
}
|
|
|
|
func TestPacketDropReasonStringRepresentation(t *testing.T) {
|
|
testCases := []struct {
|
|
reason logging.PacketDropReason
|
|
expected string
|
|
}{
|
|
{logging.PacketDropKeyUnavailable, "key_unavailable"},
|
|
{logging.PacketDropUnknownConnectionID, "unknown_connection_id"},
|
|
{logging.PacketDropHeaderParseError, "header_parse_error"},
|
|
{logging.PacketDropPayloadDecryptError, "payload_decrypt_error"},
|
|
{logging.PacketDropProtocolViolation, "protocol_violation"},
|
|
{logging.PacketDropDOSPrevention, "dos_prevention"},
|
|
{logging.PacketDropUnsupportedVersion, "unsupported_version"},
|
|
{logging.PacketDropUnexpectedPacket, "unexpected_packet"},
|
|
{logging.PacketDropUnexpectedSourceConnectionID, "unexpected_source_connection_id"},
|
|
{logging.PacketDropUnexpectedVersion, "unexpected_version"},
|
|
}
|
|
|
|
for _, tc := range testCases {
|
|
require.Equal(t, tc.expected, packetDropReason(tc.reason).String())
|
|
}
|
|
}
|
|
|
|
func TestTimerTypeStringRepresentation(t *testing.T) {
|
|
testCases := []struct {
|
|
timerType logging.TimerType
|
|
expected string
|
|
}{
|
|
{logging.TimerTypeACK, "ack"},
|
|
{logging.TimerTypePTO, "pto"},
|
|
}
|
|
|
|
for _, tc := range testCases {
|
|
require.Equal(t, tc.expected, timerType(tc.timerType).String())
|
|
}
|
|
}
|
|
|
|
func TestKeyTypeStringRepresentation(t *testing.T) {
|
|
testCases := []struct {
|
|
encLevel protocol.EncryptionLevel
|
|
perspective protocol.Perspective
|
|
expected string
|
|
}{
|
|
{protocol.EncryptionInitial, protocol.PerspectiveClient, "client_initial_secret"},
|
|
{protocol.EncryptionInitial, protocol.PerspectiveServer, "server_initial_secret"},
|
|
{protocol.EncryptionHandshake, protocol.PerspectiveClient, "client_handshake_secret"},
|
|
{protocol.EncryptionHandshake, protocol.PerspectiveServer, "server_handshake_secret"},
|
|
{protocol.Encryption0RTT, protocol.PerspectiveClient, "client_0rtt_secret"},
|
|
{protocol.Encryption0RTT, protocol.PerspectiveServer, "server_0rtt_secret"},
|
|
{protocol.Encryption1RTT, protocol.PerspectiveClient, "client_1rtt_secret"},
|
|
{protocol.Encryption1RTT, protocol.PerspectiveServer, "server_1rtt_secret"},
|
|
}
|
|
|
|
for _, tc := range testCases {
|
|
require.Equal(t, tc.expected, encLevelToKeyType(tc.encLevel, tc.perspective).String())
|
|
}
|
|
}
|
|
|
|
func TestKeyUpdateTriggerStringRepresentation(t *testing.T) {
|
|
testCases := []struct {
|
|
trigger keyUpdateTrigger
|
|
expected string
|
|
}{
|
|
{keyUpdateTLS, "tls"},
|
|
{keyUpdateRemote, "remote_update"},
|
|
{keyUpdateLocal, "local_update"},
|
|
}
|
|
|
|
for _, tc := range testCases {
|
|
require.Equal(t, tc.expected, tc.trigger.String())
|
|
}
|
|
}
|
|
|
|
func TestPacketNumberSpaceFromEncryptionLevel(t *testing.T) {
|
|
testCases := []struct {
|
|
encLevel protocol.EncryptionLevel
|
|
expected string
|
|
}{
|
|
{protocol.EncryptionInitial, "initial"},
|
|
{protocol.EncryptionHandshake, "handshake"},
|
|
{protocol.Encryption0RTT, "application_data"},
|
|
{protocol.Encryption1RTT, "application_data"},
|
|
}
|
|
|
|
for _, tc := range testCases {
|
|
require.Equal(t, tc.expected, encLevelToPacketNumberSpace(tc.encLevel))
|
|
}
|
|
}
|
|
|
|
func TestTransportErrorStringRepresentationForEveryErrorCode(t *testing.T) {
|
|
_, thisfile, _, ok := runtime.Caller(0)
|
|
require.True(t, ok, "Failed to get current frame")
|
|
filename := path.Join(path.Dir(thisfile), "../internal/qerr/error_codes.go")
|
|
fileAst, err := parser.ParseFile(gotoken.NewFileSet(), filename, nil, 0)
|
|
require.NoError(t, err)
|
|
constSpecs := fileAst.Decls[2].(*ast.GenDecl).Specs
|
|
require.Greater(t, len(constSpecs), 4)
|
|
for _, c := range constSpecs {
|
|
valString := c.(*ast.ValueSpec).Values[0].(*ast.BasicLit).Value
|
|
val, err := strconv.ParseInt(valString, 0, 64)
|
|
require.NoError(t, err)
|
|
require.NotEmpty(t, transportError(val).String())
|
|
}
|
|
}
|
|
|
|
func TestTransportErrorStringRepresentation(t *testing.T) {
|
|
testCases := []struct {
|
|
err qerr.TransportErrorCode
|
|
expected string
|
|
}{
|
|
{qerr.NoError, "no_error"},
|
|
{qerr.InternalError, "internal_error"},
|
|
{qerr.ConnectionRefused, "connection_refused"},
|
|
{qerr.FlowControlError, "flow_control_error"},
|
|
{qerr.StreamLimitError, "stream_limit_error"},
|
|
{qerr.StreamStateError, "stream_state_error"},
|
|
{qerr.FrameEncodingError, "frame_encoding_error"},
|
|
{qerr.ConnectionIDLimitError, "connection_id_limit_error"},
|
|
{qerr.ProtocolViolation, "protocol_violation"},
|
|
{qerr.InvalidToken, "invalid_token"},
|
|
{qerr.ApplicationErrorErrorCode, "application_error"},
|
|
{qerr.CryptoBufferExceeded, "crypto_buffer_exceeded"},
|
|
{qerr.NoViablePathError, "no_viable_path"},
|
|
{1337, ""},
|
|
}
|
|
|
|
for _, tc := range testCases {
|
|
require.Equal(t, tc.expected, transportError(tc.err).String())
|
|
}
|
|
}
|
|
|
|
func TestCongestionStateUpdatesStringRepresentation(t *testing.T) {
|
|
testCases := []struct {
|
|
state logging.CongestionState
|
|
expected string
|
|
}{
|
|
{logging.CongestionStateSlowStart, "slow_start"},
|
|
{logging.CongestionStateCongestionAvoidance, "congestion_avoidance"},
|
|
{logging.CongestionStateApplicationLimited, "application_limited"},
|
|
{logging.CongestionStateRecovery, "recovery"},
|
|
}
|
|
|
|
for _, tc := range testCases {
|
|
require.Equal(t, tc.expected, congestionState(tc.state).String())
|
|
}
|
|
}
|
|
|
|
func TestECNBitsStringRepresentation(t *testing.T) {
|
|
testCases := []struct {
|
|
ecn logging.ECN
|
|
expected string
|
|
}{
|
|
{logging.ECT0, "ECT(0)"},
|
|
{logging.ECT1, "ECT(1)"},
|
|
{logging.ECNCE, "CE"},
|
|
{logging.ECTNot, "Not-ECT"},
|
|
{42, "unknown ECN"},
|
|
}
|
|
|
|
for _, tc := range testCases {
|
|
require.Equal(t, tc.expected, ecn(tc.ecn).String())
|
|
}
|
|
}
|
|
|
|
func TestECNStateStringRepresentation(t *testing.T) {
|
|
testCases := []struct {
|
|
state logging.ECNState
|
|
expected string
|
|
}{
|
|
{logging.ECNStateTesting, "testing"},
|
|
{logging.ECNStateUnknown, "unknown"},
|
|
{logging.ECNStateFailed, "failed"},
|
|
{logging.ECNStateCapable, "capable"},
|
|
{42, "unknown ECN state"},
|
|
}
|
|
|
|
for _, tc := range testCases {
|
|
require.Equal(t, tc.expected, ecnState(tc.state).String())
|
|
}
|
|
}
|
|
|
|
func TestECNStateTriggerStringRepresentation(t *testing.T) {
|
|
testCases := []struct {
|
|
trigger logging.ECNStateTrigger
|
|
expected string
|
|
}{
|
|
{logging.ECNTriggerNoTrigger, ""},
|
|
{logging.ECNFailedNoECNCounts, "ACK doesn't contain ECN marks"},
|
|
{logging.ECNFailedDecreasedECNCounts, "ACK decreases ECN counts"},
|
|
{logging.ECNFailedLostAllTestingPackets, "all ECN testing packets declared lost"},
|
|
{logging.ECNFailedMoreECNCountsThanSent, "ACK contains more ECN counts than ECN-marked packets sent"},
|
|
{logging.ECNFailedTooFewECNCounts, "ACK contains fewer new ECN counts than acknowledged ECN-marked packets"},
|
|
{logging.ECNFailedManglingDetected, "ECN mangling detected"},
|
|
{42, "unknown ECN state trigger"},
|
|
}
|
|
|
|
for _, tc := range testCases {
|
|
require.Equal(t, tc.expected, ecnStateTrigger(tc.trigger).String())
|
|
}
|
|
}
|