| // Copyright (c) 2013 The Chromium Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| #include "quic/core/quic_error_codes.h" |
| |
| #include <cstdint> |
| |
| #include "third_party/boringssl/src/include/openssl/ssl.h" |
| #include "quic/platform/api/quic_test.h" |
| |
| namespace quic { |
| namespace test { |
| namespace { |
| |
| using QuicErrorCodesTest = QuicTest; |
| |
| TEST_F(QuicErrorCodesTest, QuicErrorCodeToString) { |
| EXPECT_STREQ("QUIC_NO_ERROR", QuicErrorCodeToString(QUIC_NO_ERROR)); |
| } |
| |
| TEST_F(QuicErrorCodesTest, QuicIetfTransportErrorCodeString) { |
| EXPECT_EQ("CRYPTO_ERROR(missing extension)", |
| QuicIetfTransportErrorCodeString( |
| static_cast<quic::QuicIetfTransportErrorCodes>( |
| CRYPTO_ERROR_FIRST + SSL_AD_MISSING_EXTENSION))); |
| |
| EXPECT_EQ("NO_IETF_QUIC_ERROR", |
| QuicIetfTransportErrorCodeString(NO_IETF_QUIC_ERROR)); |
| EXPECT_EQ("INTERNAL_ERROR", QuicIetfTransportErrorCodeString(INTERNAL_ERROR)); |
| EXPECT_EQ("SERVER_BUSY_ERROR", |
| QuicIetfTransportErrorCodeString(SERVER_BUSY_ERROR)); |
| EXPECT_EQ("FLOW_CONTROL_ERROR", |
| QuicIetfTransportErrorCodeString(FLOW_CONTROL_ERROR)); |
| EXPECT_EQ("STREAM_LIMIT_ERROR", |
| QuicIetfTransportErrorCodeString(STREAM_LIMIT_ERROR)); |
| EXPECT_EQ("STREAM_STATE_ERROR", |
| QuicIetfTransportErrorCodeString(STREAM_STATE_ERROR)); |
| EXPECT_EQ("FINAL_SIZE_ERROR", |
| QuicIetfTransportErrorCodeString(FINAL_SIZE_ERROR)); |
| EXPECT_EQ("FRAME_ENCODING_ERROR", |
| QuicIetfTransportErrorCodeString(FRAME_ENCODING_ERROR)); |
| EXPECT_EQ("TRANSPORT_PARAMETER_ERROR", |
| QuicIetfTransportErrorCodeString(TRANSPORT_PARAMETER_ERROR)); |
| EXPECT_EQ("CONNECTION_ID_LIMIT_ERROR", |
| QuicIetfTransportErrorCodeString(CONNECTION_ID_LIMIT_ERROR)); |
| EXPECT_EQ("PROTOCOL_VIOLATION", |
| QuicIetfTransportErrorCodeString(PROTOCOL_VIOLATION)); |
| EXPECT_EQ("INVALID_TOKEN", QuicIetfTransportErrorCodeString(INVALID_TOKEN)); |
| EXPECT_EQ("CRYPTO_BUFFER_EXCEEDED", |
| QuicIetfTransportErrorCodeString(CRYPTO_BUFFER_EXCEEDED)); |
| EXPECT_EQ("KEY_UPDATE_ERROR", |
| QuicIetfTransportErrorCodeString(KEY_UPDATE_ERROR)); |
| EXPECT_EQ("AEAD_LIMIT_REACHED", |
| QuicIetfTransportErrorCodeString(AEAD_LIMIT_REACHED)); |
| |
| EXPECT_EQ("Unknown(1024)", |
| QuicIetfTransportErrorCodeString( |
| static_cast<quic::QuicIetfTransportErrorCodes>(0x400))); |
| } |
| |
| TEST_F(QuicErrorCodesTest, QuicErrorCodeToTransportErrorCode) { |
| for (int internal_error_code = 0; internal_error_code < QUIC_LAST_ERROR; |
| ++internal_error_code) { |
| std::string internal_error_code_string = |
| QuicErrorCodeToString(static_cast<QuicErrorCode>(internal_error_code)); |
| if (internal_error_code_string == "INVALID_ERROR_CODE") { |
| // Not a valid QuicErrorCode. |
| continue; |
| } |
| QuicErrorCodeToIetfMapping ietf_error_code = |
| QuicErrorCodeToTransportErrorCode( |
| static_cast<QuicErrorCode>(internal_error_code)); |
| if (ietf_error_code.is_transport_close) { |
| QuicIetfTransportErrorCodes transport_error_code = |
| static_cast<QuicIetfTransportErrorCodes>(ietf_error_code.error_code); |
| bool is_transport_crypto_error_code = |
| transport_error_code >= 0x100 && transport_error_code <= 0x1ff; |
| if (is_transport_crypto_error_code) { |
| // Ensure that every QuicErrorCode that maps to a CRYPTO_ERROR code has |
| // a corresponding reverse mapping in TlsAlertToQuicErrorCode: |
| EXPECT_EQ( |
| internal_error_code, |
| TlsAlertToQuicErrorCode(transport_error_code - CRYPTO_ERROR_FIRST)); |
| } |
| bool is_valid_transport_error_code = |
| transport_error_code <= 0x0f || is_transport_crypto_error_code; |
| EXPECT_TRUE(is_valid_transport_error_code) << internal_error_code_string; |
| } else { |
| // Non-transport errors are application errors, either HTTP/3 or QPACK. |
| uint64_t application_error_code = ietf_error_code.error_code; |
| bool is_valid_http3_error_code = |
| application_error_code >= 0x100 && application_error_code <= 0x110; |
| bool is_valid_qpack_error_code = |
| application_error_code >= 0x200 && application_error_code <= 0x202; |
| EXPECT_TRUE(is_valid_http3_error_code || is_valid_qpack_error_code) |
| << internal_error_code_string; |
| } |
| } |
| } |
| |
| using QuicRstErrorCodesTest = QuicTest; |
| |
| TEST_F(QuicRstErrorCodesTest, QuicRstStreamErrorCodeToString) { |
| EXPECT_STREQ("QUIC_BAD_APPLICATION_PAYLOAD", |
| QuicRstStreamErrorCodeToString(QUIC_BAD_APPLICATION_PAYLOAD)); |
| } |
| |
| // When an IETF application protocol error code (sent on the wire in |
| // RESET_STREAM and STOP_SENDING frames) is translated into a |
| // QuicRstStreamErrorCode and back, it must yield the original value. |
| TEST_F(QuicRstErrorCodesTest, |
| IetfResetStreamErrorCodeToRstStreamErrorCodeAndBack) { |
| for (uint64_t wire_code : |
| {static_cast<uint64_t>(QuicHttp3ErrorCode::HTTP3_NO_ERROR), |
| static_cast<uint64_t>(QuicHttp3ErrorCode::GENERAL_PROTOCOL_ERROR), |
| static_cast<uint64_t>(QuicHttp3ErrorCode::INTERNAL_ERROR), |
| static_cast<uint64_t>(QuicHttp3ErrorCode::STREAM_CREATION_ERROR), |
| static_cast<uint64_t>(QuicHttp3ErrorCode::CLOSED_CRITICAL_STREAM), |
| static_cast<uint64_t>(QuicHttp3ErrorCode::FRAME_UNEXPECTED), |
| static_cast<uint64_t>(QuicHttp3ErrorCode::FRAME_ERROR), |
| static_cast<uint64_t>(QuicHttp3ErrorCode::EXCESSIVE_LOAD), |
| static_cast<uint64_t>(QuicHttp3ErrorCode::ID_ERROR), |
| static_cast<uint64_t>(QuicHttp3ErrorCode::SETTINGS_ERROR), |
| static_cast<uint64_t>(QuicHttp3ErrorCode::MISSING_SETTINGS), |
| static_cast<uint64_t>(QuicHttp3ErrorCode::REQUEST_REJECTED), |
| static_cast<uint64_t>(QuicHttp3ErrorCode::REQUEST_CANCELLED), |
| static_cast<uint64_t>(QuicHttp3ErrorCode::REQUEST_INCOMPLETE), |
| static_cast<uint64_t>(QuicHttp3ErrorCode::CONNECT_ERROR), |
| static_cast<uint64_t>(QuicHttp3ErrorCode::VERSION_FALLBACK), |
| static_cast<uint64_t>(QuicHttpQpackErrorCode::DECOMPRESSION_FAILED), |
| static_cast<uint64_t>(QuicHttpQpackErrorCode::ENCODER_STREAM_ERROR), |
| static_cast<uint64_t>(QuicHttpQpackErrorCode::DECODER_STREAM_ERROR)}) { |
| QuicRstStreamErrorCode rst_stream_error_code = |
| IetfResetStreamErrorCodeToRstStreamErrorCode(wire_code); |
| EXPECT_EQ(wire_code, RstStreamErrorCodeToIetfResetStreamErrorCode( |
| rst_stream_error_code)); |
| } |
| } |
| |
| } // namespace |
| } // namespace test |
| } // namespace quic |