blob_encoding_unittest.cc (4422B)
1 /* 2 * Copyright (c) 2018 The WebRTC project authors. All Rights Reserved. 3 * 4 * Use of this source code is governed by a BSD-style license 5 * that can be found in the LICENSE file in the root of the source 6 * tree. An additional intellectual property rights grant can be found 7 * in the file PATENTS. All contributing project authors may 8 * be found in the AUTHORS file in the root of the source tree. 9 */ 10 11 #include "logging/rtc_event_log/encoder/blob_encoding.h" 12 13 #include <cstddef> 14 #include <string> 15 #include <vector> 16 17 #include "absl/strings/string_view.h" 18 #include "logging/rtc_event_log/encoder/var_int.h" 19 #include "rtc_base/checks.h" 20 #include "test/gtest.h" 21 22 using CharT = std::string::value_type; 23 24 namespace webrtc { 25 26 namespace { 27 28 void TestEncodingAndDecoding(const std::vector<std::string>& blobs) { 29 RTC_DCHECK(!blobs.empty()); 30 31 const std::string encoded = EncodeBlobs(blobs); 32 ASSERT_FALSE(encoded.empty()); 33 34 const std::vector<absl::string_view> decoded = 35 DecodeBlobs(encoded, blobs.size()); 36 37 ASSERT_EQ(decoded.size(), blobs.size()); 38 for (size_t i = 0; i < decoded.size(); ++i) { 39 ASSERT_EQ(decoded[i], blobs[i]); 40 } 41 } 42 43 void TestGracefulErrorHandling(absl::string_view encoded_blobs, 44 size_t num_of_blobs) { 45 const std::vector<absl::string_view> decoded = 46 DecodeBlobs(encoded_blobs, num_of_blobs); 47 EXPECT_TRUE(decoded.empty()); 48 } 49 50 } // namespace 51 52 TEST(BlobEncoding, EmptyBlob) { 53 TestEncodingAndDecoding({""}); 54 } 55 56 TEST(BlobEncoding, SingleCharacterBlob) { 57 TestEncodingAndDecoding({"a"}); 58 } 59 60 TEST(BlobEncoding, LongBlob) { 61 std::string blob = ""; 62 for (size_t i = 0; i < 100000; ++i) { 63 blob += std::to_string(i + 1) + " Mississippi\n"; 64 } 65 TestEncodingAndDecoding({blob}); 66 } 67 68 TEST(BlobEncoding, BlobsOfVariousLengths) { 69 constexpr size_t kJump = 0xf032d; // Arbitrary. 70 constexpr size_t kMax = 0xffffff; // Arbitrary. 71 72 std::string blob; 73 blob.reserve(kMax); 74 75 for (size_t i = 0; i < kMax; i += kJump) { 76 blob.append(kJump, 'x'); 77 TestEncodingAndDecoding({blob}); 78 } 79 } 80 81 TEST(BlobEncoding, MultipleBlobs) { 82 std::vector<std::string> blobs; 83 for (size_t i = 0; i < 100000; ++i) { 84 blobs.push_back(std::to_string(i + 1) + " Mississippi\n"); 85 } 86 TestEncodingAndDecoding(blobs); 87 } 88 89 TEST(BlobEncoding, DecodeBlobsHandlesErrorsGracefullyEmptyInput) { 90 TestGracefulErrorHandling("", 1); 91 } 92 93 TEST(BlobEncoding, DecodeBlobsHandlesErrorsGracefullyZeroBlobs) { 94 const std::string encoded = EncodeBlobs({"a"}); 95 ASSERT_FALSE(encoded.empty()); 96 TestGracefulErrorHandling(encoded, 0); 97 } 98 99 TEST(BlobEncoding, DecodeBlobsHandlesErrorsGracefullyBlobLengthTooSmall) { 100 std::string encoded = EncodeBlobs({"ab"}); 101 ASSERT_FALSE(encoded.empty()); 102 ASSERT_EQ(encoded[0], 0x02); 103 encoded[0] = 0x01; 104 TestGracefulErrorHandling(encoded, 1); 105 } 106 107 TEST(BlobEncoding, DecodeBlobsHandlesErrorsGracefullyBlobLengthTooLarge) { 108 std::string encoded = EncodeBlobs({"a"}); 109 ASSERT_FALSE(encoded.empty()); 110 ASSERT_EQ(encoded[0], 0x01); 111 encoded[0] = 0x02; 112 TestGracefulErrorHandling(encoded, 1); 113 } 114 115 TEST(BlobEncoding, 116 DecodeBlobsHandlesErrorsGracefullyNumberOfBlobsIncorrectlyHigh) { 117 const std::vector<std::string> blobs = {"a", "b"}; 118 const std::string encoded = EncodeBlobs(blobs); 119 // Test focus - two empty strings encoded, but DecodeBlobs() told way more 120 // blobs are in the strings than could be expected. 121 TestGracefulErrorHandling(encoded, 1000); 122 123 // Test sanity - show that DecodeBlobs() would have worked if it got the 124 // correct input. 125 TestEncodingAndDecoding(blobs); 126 } 127 128 TEST(BlobEncoding, DecodeBlobsHandlesErrorsGracefullyDefectiveVarInt) { 129 std::string defective_varint; 130 for (size_t i = 0; i < kMaxVarIntLengthBytes; ++i) { 131 ASSERT_LE(kMaxVarIntLengthBytes, 0xffu); 132 defective_varint += static_cast<CharT>(static_cast<size_t>(0x80u) | i); 133 } 134 defective_varint += 0x01u; 135 136 const std::string defective_encoded = defective_varint + "whatever"; 137 138 TestGracefulErrorHandling(defective_encoded, 1); 139 } 140 141 TEST(BlobEncoding, DecodeBlobsHandlesErrorsGracefullyLengthSumWrapAround) { 142 std::string max_size_varint; 143 for (size_t i = 0; i < kMaxVarIntLengthBytes - 1; ++i) { 144 max_size_varint += 0xffu; 145 } 146 max_size_varint += 0x7fu; 147 148 const std::string defective_encoded = 149 max_size_varint + max_size_varint + "whatever"; 150 151 TestGracefulErrorHandling(defective_encoded, 2); 152 } 153 154 } // namespace webrtc