Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(183)

Side by Side Diff: net/tools/transport_security_state_generator/huffman/huffman_builder_unittest.cc

Issue 2660793002: Add transport security state generator tests. (Closed)
Patch Set: export method for tests Created 3 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
1 // Copyright 2017 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 <math.h>
6
7 #include <cmath>
8
9 #include "net/tools/transport_security_state_generator/huffman/huffman_builder.h "
10 #include "testing/gmock/include/gmock/gmock.h"
11 #include "testing/gtest/include/gtest/gtest.h"
12
13 namespace net {
14
15 namespace transport_security_state {
16
17 // Test that there are no Huffman representations that are a prefix for another.
18 TEST(HuffmanBuilderTest, NoPrefixCollision) {
19 HuffmanBuilder builder;
20 HuffmanRepresentationTable encoding;
21 for (uint8_t i = 0; i <= 127; i++) {
22 // Make sure some values have identical counts.
23 for (uint8_t j = 0; j <= i % 32; j++) {
24 builder.RecordUsage(i);
25 }
26 }
27
28 encoding = builder.ToTable();
29 for (uint8_t i = 0; i <= 127; i++) {
30 // There should never exist a representation that is a prefix for, or
31 // identical to, another.
32 uint32_t mask = 0;
33 for (uint32_t k = 0; k <= encoding[i].number_of_bits; k++) {
34 mask = (mask << 1) | 1;
35 }
36 mask = mask << (32 - encoding[i].number_of_bits);
37
38 for (uint8_t j = 0; j <= 127; j++) {
39 if (i == j) {
40 continue;
41 }
42
43 uint32_t aligned_i = encoding[i].bits
44 << (32 - encoding[i].number_of_bits);
45 uint32_t aligned_j = encoding[j].bits
46 << (32 - encoding[j].number_of_bits);
47 EXPECT_NE(aligned_i, aligned_j & mask);
48 }
49 }
50 }
51
52 // Test that all recorded characters get a representation and that no other
53 // representations are created.
54 // Note: There is an exception for encodings with less than 2 unique inputs.
55 TEST(HuffmanBuilderTest, NoMissingInputs) {
56 HuffmanBuilder builder;
57 HuffmanRepresentationTable encoding;
58 for (uint8_t i = 0; i <= 63; i++) {
59 for (uint8_t j = 0; j <= i % 5; j++) {
60 builder.RecordUsage(i * 2);
61 }
62 }
63
64 encoding = builder.ToTable();
65 for (uint8_t i = 0; i <= 126; i++) {
66 if (i % 2) {
67 EXPECT_EQ(encoding.find(i), encoding.cend());
68 } else {
69 EXPECT_NE(encoding.find(i), encoding.cend());
70 }
71 }
72 }
73
74 // Test that the representations have optimal order by checking that characters
75 // with higher counts get shorter (or equal length) representations than those
76 // with lower counts.
77 TEST(HuffmanBuilderTest, OptimalCodeOrder) {
78 HuffmanBuilder builder;
79 HuffmanRepresentationTable encoding;
80 for (uint8_t i = 0; i <= 127; i++) {
81 for (uint8_t j = 0; j <= (i + 1); j++) {
82 builder.RecordUsage(i);
83 }
84 }
85
86 encoding = builder.ToTable();
87 for (uint8_t i = 0; i <= 127; i++) {
88 // The representation for |i| should be longer or have the same length as
89 // all following representations because they have a higher frequency and
90 // therefor should never get a longer representation.
91 for (uint8_t j = i; j <= 127; j++) {
92 // A representation for the values should exist in the table.
93 ASSERT_NE(encoding.find(i), encoding.cend());
94 ASSERT_NE(encoding.find(j), encoding.cend());
95
96 EXPECT_GE(encoding[i].number_of_bits, encoding[j].number_of_bits);
97 }
98 }
99 }
100
101 // Test that the ToVector() creates a byte vector that represents the expected
102 // Huffman Tree.
103 TEST(HuffmanBuilderTest, ToVector) {
104 // Build a small tree.
105 HuffmanBuilder builder;
106 builder.RecordUsage('a');
107 builder.RecordUsage('b');
108 builder.RecordUsage('b');
109 builder.RecordUsage('c');
110 builder.RecordUsage('c');
111 builder.RecordUsage('d');
112 builder.RecordUsage('d');
113 builder.RecordUsage('d');
114 builder.RecordUsage('e');
115 builder.RecordUsage('e');
116 builder.RecordUsage('e');
117
118 std::vector<uint8_t> output = builder.ToVector();
119
120 // This represents 4 elements (4 groups of 2 uint8_t's) which, when decoded,
121 // yields the expected Huffman Tree:
122 // root (element 3)
123 // / \
124 // element 1 element 2
125 // / \ / \
126 // 0xE3 (c) element 0 0xE4 (e) 0xE5 (f)
127 // / \
128 // 0xE1 (a) 0xE2 (b)
129 EXPECT_THAT(output, testing::ElementsAre(0xE1, 0xE2, 0xE3, 0x0, 0xE4, 0xE5,
130 0x1, 0x2));
131 }
132
133 // The ToVector() logic requires at least 2 unique inputs to construct the
134 // vector. Test that nodes are appended when there are less than 2 unique
135 // inputs.
136 TEST(HuffmanBuilderTest, ToVectorSingle) {
137 // Build a single element tree. Another element should be added automatically.
138 HuffmanBuilder builder;
139 builder.RecordUsage('a');
140
141 std::vector<uint8_t> output = builder.ToVector();
142
143 // This represents 1 elements (1 group of 2 uint8_t's) which, when decoded,
144 // yields the expected Huffman Tree:
145 // root (element 1)
146 // / \
147 // 0x80 (\0) 0xE1 (a)
148 //
149 // Note: the node \0 node was appended to the tree.
150 EXPECT_THAT(output, testing::ElementsAre(0x80, 0xE1));
151 }
152
153 } // transport_security_state
154
155 } // namespace net
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698