1 // Copyright (c) 2020 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #include "net/third_party/quiche/src/common/test_tools/quiche_test_utils.h"
6 
7 #include "net/third_party/quiche/src/common/platform/api/quiche_logging.h"
8 #include "net/third_party/quiche/src/common/platform/api/quiche_test.h"
9 
10 #include <string>
11 
12 namespace {
13 
HexDumpWithMarks(const char * data,int length,const bool * marks,int mark_length)14 std::string HexDumpWithMarks(const char* data,
15                              int length,
16                              const bool* marks,
17                              int mark_length) {
18   static const char kHexChars[] = "0123456789abcdef";
19   static const int kColumns = 4;
20 
21   const int kSizeLimit = 1024;
22   if (length > kSizeLimit || mark_length > kSizeLimit) {
23     QUICHE_LOG(ERROR) << "Only dumping first " << kSizeLimit << " bytes.";
24     length = std::min(length, kSizeLimit);
25     mark_length = std::min(mark_length, kSizeLimit);
26   }
27 
28   std::string hex;
29   for (const char* row = data; length > 0;
30        row += kColumns, length -= kColumns) {
31     for (const char* p = row; p < row + 4; ++p) {
32       if (p < row + length) {
33         const bool mark =
34             (marks && (p - data) < mark_length && marks[p - data]);
35         hex += mark ? '*' : ' ';
36         hex += kHexChars[(*p & 0xf0) >> 4];
37         hex += kHexChars[*p & 0x0f];
38         hex += mark ? '*' : ' ';
39       } else {
40         hex += "    ";
41       }
42     }
43     hex = hex + "  ";
44 
45     for (const char* p = row; p < row + 4 && p < row + length; ++p) {
46       hex += (*p >= 0x20 && *p < 0x7f) ? (*p) : '.';
47     }
48 
49     hex = hex + '\n';
50   }
51   return hex;
52 }
53 
54 }  // namespace
55 
56 namespace quiche {
57 namespace test {
58 
CompareCharArraysWithHexError(const std::string & description,const char * actual,const int actual_len,const char * expected,const int expected_len)59 void CompareCharArraysWithHexError(const std::string& description,
60                                    const char* actual,
61                                    const int actual_len,
62                                    const char* expected,
63                                    const int expected_len) {
64   EXPECT_EQ(actual_len, expected_len);
65   const int min_len = std::min(actual_len, expected_len);
66   const int max_len = std::max(actual_len, expected_len);
67   std::unique_ptr<bool[]> marks(new bool[max_len]);
68   bool identical = (actual_len == expected_len);
69   for (int i = 0; i < min_len; ++i) {
70     if (actual[i] != expected[i]) {
71       marks[i] = true;
72       identical = false;
73     } else {
74       marks[i] = false;
75     }
76   }
77   for (int i = min_len; i < max_len; ++i) {
78     marks[i] = true;
79   }
80   if (identical)
81     return;
82   ADD_FAILURE() << "Description:\n"
83                 << description << "\n\nExpected:\n"
84                 << HexDumpWithMarks(expected, expected_len, marks.get(),
85                                     max_len)
86                 << "\nActual:\n"
87                 << HexDumpWithMarks(actual, actual_len, marks.get(), max_len);
88 }
89 
90 }  // namespace test
91 }  // namespace quiche
92