github.com/MerlinKodo/quic-go@v0.39.2/qlog/frame_test.go (about) 1 package qlog 2 3 import ( 4 "bytes" 5 "encoding/json" 6 "time" 7 8 "github.com/MerlinKodo/quic-go/internal/protocol" 9 "github.com/MerlinKodo/quic-go/internal/qerr" 10 "github.com/MerlinKodo/quic-go/logging" 11 12 "github.com/francoispqt/gojay" 13 . "github.com/onsi/ginkgo/v2" 14 . "github.com/onsi/gomega" 15 ) 16 17 var _ = Describe("Frames", func() { 18 check := func(f logging.Frame, expected map[string]interface{}) { 19 buf := &bytes.Buffer{} 20 enc := gojay.NewEncoder(buf) 21 ExpectWithOffset(1, enc.Encode(frame{Frame: f})).To(Succeed()) 22 data := buf.Bytes() 23 ExpectWithOffset(1, json.Valid(data)).To(BeTrue()) 24 checkEncoding(data, expected) 25 } 26 27 It("marshals PING frames", func() { 28 check( 29 &logging.PingFrame{}, 30 map[string]interface{}{ 31 "frame_type": "ping", 32 }, 33 ) 34 }) 35 36 It("marshals ACK frames with a range acknowledging a single packet", func() { 37 check( 38 &logging.AckFrame{ 39 DelayTime: 86 * time.Millisecond, 40 AckRanges: []logging.AckRange{{Smallest: 120, Largest: 120}}, 41 }, 42 map[string]interface{}{ 43 "frame_type": "ack", 44 "ack_delay": 86, 45 "acked_ranges": [][]float64{{120}}, 46 }, 47 ) 48 }) 49 50 It("marshals ACK frames without a delay", func() { 51 check( 52 &logging.AckFrame{ 53 AckRanges: []logging.AckRange{{Smallest: 120, Largest: 120}}, 54 }, 55 map[string]interface{}{ 56 "frame_type": "ack", 57 "acked_ranges": [][]float64{{120}}, 58 }, 59 ) 60 }) 61 62 It("marshals ACK frames with ECN counts", func() { 63 check( 64 &logging.AckFrame{ 65 AckRanges: []logging.AckRange{{Smallest: 120, Largest: 120}}, 66 ECT0: 10, 67 ECT1: 100, 68 ECNCE: 1000, 69 }, 70 map[string]interface{}{ 71 "frame_type": "ack", 72 "acked_ranges": [][]float64{{120}}, 73 "ect0": 10, 74 "ect1": 100, 75 "ce": 1000, 76 }, 77 ) 78 }) 79 80 It("marshals ACK frames with a range acknowledging ranges of packets", func() { 81 check( 82 &logging.AckFrame{ 83 DelayTime: 86 * time.Millisecond, 84 AckRanges: []logging.AckRange{ 85 {Smallest: 5, Largest: 50}, 86 {Smallest: 100, Largest: 120}, 87 }, 88 }, 89 map[string]interface{}{ 90 "frame_type": "ack", 91 "ack_delay": 86, 92 "acked_ranges": [][]float64{ 93 {5, 50}, 94 {100, 120}, 95 }, 96 }, 97 ) 98 }) 99 100 It("marshals RESET_STREAM frames", func() { 101 check( 102 &logging.ResetStreamFrame{ 103 StreamID: 987, 104 FinalSize: 1234, 105 ErrorCode: 42, 106 }, 107 map[string]interface{}{ 108 "frame_type": "reset_stream", 109 "stream_id": 987, 110 "error_code": 42, 111 "final_size": 1234, 112 }, 113 ) 114 }) 115 116 It("marshals STOP_SENDING frames", func() { 117 check( 118 &logging.StopSendingFrame{ 119 StreamID: 987, 120 ErrorCode: 42, 121 }, 122 map[string]interface{}{ 123 "frame_type": "stop_sending", 124 "stream_id": 987, 125 "error_code": 42, 126 }, 127 ) 128 }) 129 130 It("marshals CRYPTO frames", func() { 131 check( 132 &logging.CryptoFrame{ 133 Offset: 1337, 134 Length: 6, 135 }, 136 map[string]interface{}{ 137 "frame_type": "crypto", 138 "offset": 1337, 139 "length": 6, 140 }, 141 ) 142 }) 143 144 It("marshals NEW_TOKEN frames", func() { 145 check( 146 &logging.NewTokenFrame{ 147 Token: []byte{0xde, 0xad, 0xbe, 0xef}, 148 }, 149 map[string]interface{}{ 150 "frame_type": "new_token", 151 "token": map[string]interface{}{"data": "deadbeef"}, 152 }, 153 ) 154 }) 155 156 It("marshals STREAM frames with FIN", func() { 157 check( 158 &logging.StreamFrame{ 159 StreamID: 42, 160 Offset: 1337, 161 Fin: true, 162 Length: 9876, 163 }, 164 map[string]interface{}{ 165 "frame_type": "stream", 166 "stream_id": 42, 167 "offset": 1337, 168 "fin": true, 169 "length": 9876, 170 }, 171 ) 172 }) 173 174 It("marshals STREAM frames without FIN", func() { 175 check( 176 &logging.StreamFrame{ 177 StreamID: 42, 178 Offset: 1337, 179 Length: 3, 180 }, 181 map[string]interface{}{ 182 "frame_type": "stream", 183 "stream_id": 42, 184 "offset": 1337, 185 "length": 3, 186 }, 187 ) 188 }) 189 190 It("marshals MAX_DATA frames", func() { 191 check( 192 &logging.MaxDataFrame{ 193 MaximumData: 1337, 194 }, 195 map[string]interface{}{ 196 "frame_type": "max_data", 197 "maximum": 1337, 198 }, 199 ) 200 }) 201 202 It("marshals MAX_STREAM_DATA frames", func() { 203 check( 204 &logging.MaxStreamDataFrame{ 205 StreamID: 1234, 206 MaximumStreamData: 1337, 207 }, 208 map[string]interface{}{ 209 "frame_type": "max_stream_data", 210 "stream_id": 1234, 211 "maximum": 1337, 212 }, 213 ) 214 }) 215 216 It("marshals MAX_STREAMS frames", func() { 217 check( 218 &logging.MaxStreamsFrame{ 219 Type: protocol.StreamTypeBidi, 220 MaxStreamNum: 42, 221 }, 222 map[string]interface{}{ 223 "frame_type": "max_streams", 224 "stream_type": "bidirectional", 225 "maximum": 42, 226 }, 227 ) 228 }) 229 230 It("marshals DATA_BLOCKED frames", func() { 231 check( 232 &logging.DataBlockedFrame{ 233 MaximumData: 1337, 234 }, 235 map[string]interface{}{ 236 "frame_type": "data_blocked", 237 "limit": 1337, 238 }, 239 ) 240 }) 241 242 It("marshals STREAM_DATA_BLOCKED frames", func() { 243 check( 244 &logging.StreamDataBlockedFrame{ 245 StreamID: 42, 246 MaximumStreamData: 1337, 247 }, 248 map[string]interface{}{ 249 "frame_type": "stream_data_blocked", 250 "stream_id": 42, 251 "limit": 1337, 252 }, 253 ) 254 }) 255 256 It("marshals STREAMS_BLOCKED frames", func() { 257 check( 258 &logging.StreamsBlockedFrame{ 259 Type: protocol.StreamTypeUni, 260 StreamLimit: 123, 261 }, 262 map[string]interface{}{ 263 "frame_type": "streams_blocked", 264 "stream_type": "unidirectional", 265 "limit": 123, 266 }, 267 ) 268 }) 269 270 It("marshals NEW_CONNECTION_ID frames", func() { 271 check( 272 &logging.NewConnectionIDFrame{ 273 SequenceNumber: 42, 274 RetirePriorTo: 24, 275 ConnectionID: protocol.ParseConnectionID([]byte{0xde, 0xad, 0xbe, 0xef}), 276 StatelessResetToken: protocol.StatelessResetToken{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0xa, 0xb, 0xc, 0xd, 0xe, 0xf}, 277 }, 278 map[string]interface{}{ 279 "frame_type": "new_connection_id", 280 "sequence_number": 42, 281 "retire_prior_to": 24, 282 "length": 4, 283 "connection_id": "deadbeef", 284 "stateless_reset_token": "000102030405060708090a0b0c0d0e0f", 285 }, 286 ) 287 }) 288 289 It("marshals RETIRE_CONNECTION_ID frames", func() { 290 check( 291 &logging.RetireConnectionIDFrame{ 292 SequenceNumber: 1337, 293 }, 294 map[string]interface{}{ 295 "frame_type": "retire_connection_id", 296 "sequence_number": 1337, 297 }, 298 ) 299 }) 300 301 It("marshals PATH_CHALLENGE frames", func() { 302 check( 303 &logging.PathChallengeFrame{ 304 Data: [8]byte{0xde, 0xad, 0xbe, 0xef, 0xca, 0xfe, 0xc0, 0x01}, 305 }, 306 map[string]interface{}{ 307 "frame_type": "path_challenge", 308 "data": "deadbeefcafec001", 309 }, 310 ) 311 }) 312 313 It("marshals PATH_RESPONSE frames", func() { 314 check( 315 &logging.PathResponseFrame{ 316 Data: [8]byte{0xde, 0xad, 0xbe, 0xef, 0xca, 0xfe, 0xc0, 0x01}, 317 }, 318 map[string]interface{}{ 319 "frame_type": "path_response", 320 "data": "deadbeefcafec001", 321 }, 322 ) 323 }) 324 325 It("marshals CONNECTION_CLOSE frames, for application error codes", func() { 326 check( 327 &logging.ConnectionCloseFrame{ 328 IsApplicationError: true, 329 ErrorCode: 1337, 330 ReasonPhrase: "lorem ipsum", 331 }, 332 map[string]interface{}{ 333 "frame_type": "connection_close", 334 "error_space": "application", 335 "error_code": 1337, 336 "raw_error_code": 1337, 337 "reason": "lorem ipsum", 338 }, 339 ) 340 }) 341 342 It("marshals CONNECTION_CLOSE frames, for transport error codes", func() { 343 check( 344 &logging.ConnectionCloseFrame{ 345 ErrorCode: uint64(qerr.FlowControlError), 346 ReasonPhrase: "lorem ipsum", 347 }, 348 map[string]interface{}{ 349 "frame_type": "connection_close", 350 "error_space": "transport", 351 "error_code": "flow_control_error", 352 "raw_error_code": int(qerr.FlowControlError), 353 "reason": "lorem ipsum", 354 }, 355 ) 356 }) 357 358 It("marshals HANDSHAKE_DONE frames", func() { 359 check( 360 &logging.HandshakeDoneFrame{}, 361 map[string]interface{}{ 362 "frame_type": "handshake_done", 363 }, 364 ) 365 }) 366 367 It("marshals DATAGRAM frames", func() { 368 check( 369 &logging.DatagramFrame{Length: 1337}, 370 map[string]interface{}{ 371 "frame_type": "datagram", 372 "length": 1337, 373 }, 374 ) 375 }) 376 })