Files
quic-go/qlog/types_test.go
Marten Seemann e52027f496 qlog: migrate tests away from Ginkgo (#4640)
* qlog: migrate tests away from Ginkgo

* ci: don't run prealloc linter on test files
2024-09-11 00:28:28 -07:00

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())
}
}