| OLD | NEW | 
 | (Empty) | 
|    1 // Copyright 2016 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/http2/hpack/decoder/hpack_decoder_string_buffer.h" |  | 
|    6  |  | 
|    7 // Tests of HpackDecoderStringBuffer. |  | 
|    8  |  | 
|    9 #include <initializer_list> |  | 
|   10 #include <sstream> |  | 
|   11 #include <string> |  | 
|   12  |  | 
|   13 #include "base/logging.h" |  | 
|   14 #include "base/strings/string_piece.h" |  | 
|   15 #include "net/http2/tools/failure.h" |  | 
|   16 #include "net/spdy/spdy_test_utils.h" |  | 
|   17 #include "testing/gmock/include/gmock/gmock.h" |  | 
|   18 #include "testing/gtest/include/gtest/gtest.h" |  | 
|   19  |  | 
|   20 using ::testing::AssertionResult; |  | 
|   21 using ::testing::AssertionSuccess; |  | 
|   22 using ::testing::HasSubstr; |  | 
|   23 using base::StringPiece; |  | 
|   24 using std::string; |  | 
|   25  |  | 
|   26 namespace net { |  | 
|   27 namespace test { |  | 
|   28 namespace { |  | 
|   29  |  | 
|   30 class HpackDecoderStringBufferTest : public ::testing::Test { |  | 
|   31  protected: |  | 
|   32   typedef HpackDecoderStringBuffer::State State; |  | 
|   33   typedef HpackDecoderStringBuffer::Backing Backing; |  | 
|   34  |  | 
|   35   State state() const { return buf_.state_for_testing(); } |  | 
|   36   Backing backing() const { return buf_.backing_for_testing(); } |  | 
|   37  |  | 
|   38   // We want to know that LOG(x) << buf_ will work in production should that |  | 
|   39   // be needed, so we test that it outputs the expected values. |  | 
|   40   AssertionResult VerifyLogHasSubstrs(std::initializer_list<string> strs) { |  | 
|   41     VLOG(1) << buf_; |  | 
|   42     std::ostringstream ss; |  | 
|   43     buf_.OutputDebugStringTo(ss); |  | 
|   44     string dbg_str(ss.str()); |  | 
|   45     for (const auto& expected : strs) { |  | 
|   46       VERIFY_THAT(dbg_str, HasSubstr(expected)); |  | 
|   47     } |  | 
|   48     return AssertionSuccess(); |  | 
|   49   } |  | 
|   50  |  | 
|   51   HpackDecoderStringBuffer buf_; |  | 
|   52 }; |  | 
|   53  |  | 
|   54 TEST_F(HpackDecoderStringBufferTest, SetStatic) { |  | 
|   55   StringPiece data("static string"); |  | 
|   56  |  | 
|   57   EXPECT_EQ(state(), State::RESET); |  | 
|   58   EXPECT_TRUE(VerifyLogHasSubstrs({"state=RESET"})); |  | 
|   59  |  | 
|   60   buf_.Set(data, /*is_static*/ true); |  | 
|   61   LOG(INFO) << buf_; |  | 
|   62   EXPECT_EQ(state(), State::COMPLETE); |  | 
|   63   EXPECT_EQ(backing(), Backing::STATIC); |  | 
|   64   EXPECT_EQ(data, buf_.str()); |  | 
|   65   EXPECT_EQ(data.data(), buf_.str().data()); |  | 
|   66   EXPECT_TRUE(VerifyLogHasSubstrs( |  | 
|   67       {"state=COMPLETE", "backing=STATIC", "value: static string"})); |  | 
|   68  |  | 
|   69   // The string is static, so BufferStringIfUnbuffered won't change anything. |  | 
|   70   buf_.BufferStringIfUnbuffered(); |  | 
|   71   EXPECT_EQ(state(), State::COMPLETE); |  | 
|   72   EXPECT_EQ(backing(), Backing::STATIC); |  | 
|   73   EXPECT_EQ(data, buf_.str()); |  | 
|   74   EXPECT_EQ(data.data(), buf_.str().data()); |  | 
|   75   EXPECT_TRUE(VerifyLogHasSubstrs( |  | 
|   76       {"state=COMPLETE", "backing=STATIC", "value: static string"})); |  | 
|   77 } |  | 
|   78  |  | 
|   79 TEST_F(HpackDecoderStringBufferTest, PlainWhole) { |  | 
|   80   StringPiece data("some text."); |  | 
|   81  |  | 
|   82   LOG(INFO) << buf_; |  | 
|   83   EXPECT_EQ(state(), State::RESET); |  | 
|   84  |  | 
|   85   buf_.OnStart(/*huffman_encoded*/ false, data.size()); |  | 
|   86   EXPECT_EQ(state(), State::COLLECTING); |  | 
|   87   EXPECT_EQ(backing(), Backing::RESET); |  | 
|   88   LOG(INFO) << buf_; |  | 
|   89  |  | 
|   90   EXPECT_TRUE(buf_.OnData(data.data(), data.size())); |  | 
|   91   EXPECT_EQ(state(), State::COLLECTING); |  | 
|   92   EXPECT_EQ(backing(), Backing::UNBUFFERED); |  | 
|   93  |  | 
|   94   EXPECT_TRUE(buf_.OnEnd()); |  | 
|   95   EXPECT_EQ(state(), State::COMPLETE); |  | 
|   96   EXPECT_EQ(backing(), Backing::UNBUFFERED); |  | 
|   97   EXPECT_EQ(0u, buf_.BufferedLength()); |  | 
|   98   EXPECT_TRUE(VerifyLogHasSubstrs( |  | 
|   99       {"state=COMPLETE", "backing=UNBUFFERED", "value: some text."})); |  | 
|  100  |  | 
|  101   // We expect that the string buffer points to the passed in StringPiece's |  | 
|  102   // backing store. |  | 
|  103   EXPECT_EQ(data.data(), buf_.str().data()); |  | 
|  104  |  | 
|  105   // Now force it to buffer the string, after which it will still have the same |  | 
|  106   // string value, but the backing store will be different. |  | 
|  107   buf_.BufferStringIfUnbuffered(); |  | 
|  108   LOG(INFO) << buf_; |  | 
|  109   EXPECT_EQ(backing(), Backing::BUFFERED); |  | 
|  110   EXPECT_EQ(buf_.BufferedLength(), data.size()); |  | 
|  111   EXPECT_EQ(data, buf_.str()); |  | 
|  112   EXPECT_NE(data.data(), buf_.str().data()); |  | 
|  113   EXPECT_TRUE(VerifyLogHasSubstrs( |  | 
|  114       {"state=COMPLETE", "backing=BUFFERED", "buffer: some text."})); |  | 
|  115 } |  | 
|  116  |  | 
|  117 TEST_F(HpackDecoderStringBufferTest, PlainSplit) { |  | 
|  118   StringPiece data("some text."); |  | 
|  119   StringPiece part1 = data.substr(0, 1); |  | 
|  120   StringPiece part2 = data.substr(1); |  | 
|  121  |  | 
|  122   EXPECT_EQ(state(), State::RESET); |  | 
|  123   buf_.OnStart(/*huffman_encoded*/ false, data.size()); |  | 
|  124   EXPECT_EQ(state(), State::COLLECTING); |  | 
|  125   EXPECT_EQ(backing(), Backing::RESET); |  | 
|  126  |  | 
|  127   // OnData with only a part of the data, not the whole, so buf_ will buffer |  | 
|  128   // the data. |  | 
|  129   EXPECT_TRUE(buf_.OnData(part1.data(), part1.size())); |  | 
|  130   EXPECT_EQ(state(), State::COLLECTING); |  | 
|  131   EXPECT_EQ(backing(), Backing::BUFFERED); |  | 
|  132   EXPECT_EQ(buf_.BufferedLength(), part1.size()); |  | 
|  133   LOG(INFO) << buf_; |  | 
|  134  |  | 
|  135   EXPECT_TRUE(buf_.OnData(part2.data(), part2.size())); |  | 
|  136   EXPECT_EQ(state(), State::COLLECTING); |  | 
|  137   EXPECT_EQ(backing(), Backing::BUFFERED); |  | 
|  138   EXPECT_EQ(buf_.BufferedLength(), data.size()); |  | 
|  139  |  | 
|  140   EXPECT_TRUE(buf_.OnEnd()); |  | 
|  141   EXPECT_EQ(state(), State::COMPLETE); |  | 
|  142   EXPECT_EQ(backing(), Backing::BUFFERED); |  | 
|  143   EXPECT_EQ(buf_.BufferedLength(), data.size()); |  | 
|  144   LOG(INFO) << buf_; |  | 
|  145  |  | 
|  146   StringPiece buffered = buf_.str(); |  | 
|  147   EXPECT_EQ(data, buffered); |  | 
|  148   EXPECT_NE(data.data(), buffered.data()); |  | 
|  149  |  | 
|  150   // The string is already buffered, so BufferStringIfUnbuffered should not make |  | 
|  151   // any change. |  | 
|  152   buf_.BufferStringIfUnbuffered(); |  | 
|  153   EXPECT_EQ(backing(), Backing::BUFFERED); |  | 
|  154   EXPECT_EQ(buf_.BufferedLength(), data.size()); |  | 
|  155   EXPECT_EQ(buffered, buf_.str()); |  | 
|  156   EXPECT_EQ(buffered.data(), buf_.str().data()); |  | 
|  157 } |  | 
|  158  |  | 
|  159 TEST_F(HpackDecoderStringBufferTest, HuffmanWhole) { |  | 
|  160   string encoded = a2b_hex("f1e3c2e5f23a6ba0ab90f4ff"); |  | 
|  161   StringPiece decoded("www.example.com"); |  | 
|  162  |  | 
|  163   EXPECT_EQ(state(), State::RESET); |  | 
|  164   buf_.OnStart(/*huffman_encoded*/ true, encoded.size()); |  | 
|  165   EXPECT_EQ(state(), State::COLLECTING); |  | 
|  166  |  | 
|  167   EXPECT_TRUE(buf_.OnData(encoded.data(), encoded.size())); |  | 
|  168   EXPECT_EQ(state(), State::COLLECTING); |  | 
|  169   EXPECT_EQ(backing(), Backing::BUFFERED); |  | 
|  170  |  | 
|  171   EXPECT_TRUE(buf_.OnEnd()); |  | 
|  172   EXPECT_EQ(state(), State::COMPLETE); |  | 
|  173   EXPECT_EQ(backing(), Backing::BUFFERED); |  | 
|  174   EXPECT_EQ(buf_.BufferedLength(), decoded.size()); |  | 
|  175   EXPECT_EQ(decoded, buf_.str()); |  | 
|  176   EXPECT_TRUE(VerifyLogHasSubstrs( |  | 
|  177       {"{state=COMPLETE", "backing=BUFFERED", "buffer: www.example.com}"})); |  | 
|  178 } |  | 
|  179  |  | 
|  180 TEST_F(HpackDecoderStringBufferTest, HuffmanSplit) { |  | 
|  181   string encoded = a2b_hex("f1e3c2e5f23a6ba0ab90f4ff"); |  | 
|  182   string part1 = encoded.substr(0, 5); |  | 
|  183   string part2 = encoded.substr(5); |  | 
|  184   StringPiece decoded("www.example.com"); |  | 
|  185  |  | 
|  186   EXPECT_EQ(state(), State::RESET); |  | 
|  187   buf_.OnStart(/*huffman_encoded*/ true, encoded.size()); |  | 
|  188   EXPECT_EQ(state(), State::COLLECTING); |  | 
|  189   EXPECT_EQ(backing(), Backing::BUFFERED); |  | 
|  190   EXPECT_EQ(0u, buf_.BufferedLength()); |  | 
|  191   LOG(INFO) << buf_; |  | 
|  192  |  | 
|  193   EXPECT_TRUE(buf_.OnData(part1.data(), part1.size())); |  | 
|  194   EXPECT_EQ(state(), State::COLLECTING); |  | 
|  195   EXPECT_EQ(backing(), Backing::BUFFERED); |  | 
|  196   EXPECT_GT(buf_.BufferedLength(), 0u); |  | 
|  197   EXPECT_LT(buf_.BufferedLength(), decoded.size()); |  | 
|  198   LOG(INFO) << buf_; |  | 
|  199  |  | 
|  200   EXPECT_TRUE(buf_.OnData(part2.data(), part2.size())); |  | 
|  201   EXPECT_EQ(state(), State::COLLECTING); |  | 
|  202   EXPECT_EQ(backing(), Backing::BUFFERED); |  | 
|  203   EXPECT_EQ(buf_.BufferedLength(), decoded.size()); |  | 
|  204   LOG(INFO) << buf_; |  | 
|  205  |  | 
|  206   EXPECT_TRUE(buf_.OnEnd()); |  | 
|  207   EXPECT_EQ(state(), State::COMPLETE); |  | 
|  208   EXPECT_EQ(backing(), Backing::BUFFERED); |  | 
|  209   EXPECT_EQ(buf_.BufferedLength(), decoded.size()); |  | 
|  210   EXPECT_EQ(decoded, buf_.str()); |  | 
|  211   LOG(INFO) << buf_; |  | 
|  212 } |  | 
|  213  |  | 
|  214 TEST_F(HpackDecoderStringBufferTest, InvalidHuffmanOnData) { |  | 
|  215   // Explicitly encode the End-of-String symbol, a no-no. |  | 
|  216   string encoded = a2b_hex("ffffffff"); |  | 
|  217  |  | 
|  218   buf_.OnStart(/*huffman_encoded*/ true, encoded.size()); |  | 
|  219   EXPECT_EQ(state(), State::COLLECTING); |  | 
|  220  |  | 
|  221   EXPECT_FALSE(buf_.OnData(encoded.data(), encoded.size())); |  | 
|  222   EXPECT_EQ(state(), State::COLLECTING); |  | 
|  223   EXPECT_EQ(backing(), Backing::BUFFERED); |  | 
|  224  |  | 
|  225   LOG(INFO) << buf_; |  | 
|  226 } |  | 
|  227  |  | 
|  228 TEST_F(HpackDecoderStringBufferTest, InvalidHuffmanOnEnd) { |  | 
|  229   // Last byte of string doesn't end with prefix of End-of-String symbol. |  | 
|  230   string encoded = a2b_hex("00"); |  | 
|  231  |  | 
|  232   buf_.OnStart(/*huffman_encoded*/ true, encoded.size()); |  | 
|  233   EXPECT_EQ(state(), State::COLLECTING); |  | 
|  234  |  | 
|  235   EXPECT_TRUE(buf_.OnData(encoded.data(), encoded.size())); |  | 
|  236   EXPECT_EQ(state(), State::COLLECTING); |  | 
|  237   EXPECT_EQ(backing(), Backing::BUFFERED); |  | 
|  238  |  | 
|  239   EXPECT_FALSE(buf_.OnEnd()); |  | 
|  240   LOG(INFO) << buf_; |  | 
|  241 } |  | 
|  242  |  | 
|  243 }  // namespace |  | 
|  244 }  // namespace test |  | 
|  245 }  // namespace net |  | 
| OLD | NEW |