diff options
Diffstat (limited to 'chromium/net/spdy/hpack_round_trip_test.cc')
-rw-r--r-- | chromium/net/spdy/hpack_round_trip_test.cc | 174 |
1 files changed, 174 insertions, 0 deletions
diff --git a/chromium/net/spdy/hpack_round_trip_test.cc b/chromium/net/spdy/hpack_round_trip_test.cc new file mode 100644 index 00000000000..39be93982b6 --- /dev/null +++ b/chromium/net/spdy/hpack_round_trip_test.cc @@ -0,0 +1,174 @@ +// Copyright 2014 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include <cmath> +#include <ctime> +#include <map> +#include <string> +#include <vector> + +#include "base/rand_util.h" +#include "net/spdy/hpack_constants.h" +#include "net/spdy/hpack_decoder.h" +#include "net/spdy/hpack_encoder.h" +#include "testing/gtest/include/gtest/gtest.h" + +namespace net { + +using std::map; +using std::string; +using std::vector; + +namespace { + +class HpackRoundTripTest : public ::testing::Test { + protected: + HpackRoundTripTest() + : encoder_(ObtainHpackHuffmanTable()), + decoder_(ObtainHpackHuffmanTable()) {} + + virtual void SetUp() { + // Use a small table size to tickle eviction handling. + encoder_.ApplyHeaderTableSizeSetting(256); + decoder_.ApplyHeaderTableSizeSetting(256); + } + + bool RoundTrip(const map<string, string>& header_set) { + string encoded; + encoder_.EncodeHeaderSet(header_set, &encoded); + + bool success = decoder_.HandleControlFrameHeadersData( + 1, encoded.data(), encoded.size()); + success &= decoder_.HandleControlFrameHeadersComplete(1); + + EXPECT_EQ(header_set, decoder_.decoded_block()); + return success; + } + + size_t SampleExponential(size_t mean, size_t sanity_bound) { + return std::min<size_t>(-std::log(base::RandDouble()) * mean, + sanity_bound); + } + + HpackEncoder encoder_; + HpackDecoder decoder_; +}; + +TEST_F(HpackRoundTripTest, ResponseFixtures) { + { + map<string, string> headers; + headers[":status"] = "302"; + headers["cache-control"] = "private"; + headers["date"] = "Mon, 21 Oct 2013 20:13:21 GMT"; + headers["location"] = "https://www.example.com"; + EXPECT_TRUE(RoundTrip(headers)); + } + { + map<string, string> headers; + headers[":status"] = "200"; + headers["cache-control"] = "private"; + headers["date"] = "Mon, 21 Oct 2013 20:13:21 GMT"; + headers["location"] = "https://www.example.com"; + EXPECT_TRUE(RoundTrip(headers)); + } + { + map<string, string> headers; + headers[":status"] = "200"; + headers["cache-control"] = "private"; + headers["content-encoding"] = "gzip"; + headers["date"] = "Mon, 21 Oct 2013 20:13:22 GMT"; + headers["location"] = "https://www.example.com"; + headers["set-cookie"] = "foo=ASDJKHQKBZXOQWEOPIUAXQWEOIU;" + " max-age=3600; version=1"; + EXPECT_TRUE(RoundTrip(headers)); + } +} + +TEST_F(HpackRoundTripTest, RequestFixtures) { + { + map<string, string> headers; + headers[":authority"] = "www.example.com"; + headers[":method"] = "GET"; + headers[":path"] = "/"; + headers[":scheme"] = "http"; + headers["cookie"] = "baz=bing; foo=bar"; + EXPECT_TRUE(RoundTrip(headers)); + } + { + map<string, string> headers; + headers[":authority"] = "www.example.com"; + headers[":method"] = "GET"; + headers[":path"] = "/"; + headers[":scheme"] = "http"; + headers["cache-control"] = "no-cache"; + headers["cookie"] = "fizzle=fazzle; foo=bar"; + EXPECT_TRUE(RoundTrip(headers)); + } + { + map<string, string> headers; + headers[":authority"] = "www.example.com"; + headers[":method"] = "GET"; + headers[":path"] = "/index.html"; + headers[":scheme"] = "https"; + headers["custom-key"] = "custom-value"; + headers["cookie"] = "baz=bing; fizzle=fazzle; garbage"; + EXPECT_TRUE(RoundTrip(headers)); + } +} + +TEST_F(HpackRoundTripTest, RandomizedExamples) { + // Grow vectors of names & values, which are seeded with fixtures and then + // expanded with dynamically generated data. Samples are taken using the + // exponential distribution. + vector<string> names; + names.push_back(":authority"); + names.push_back(":path"); + names.push_back(":status"); + // TODO(jgraettinger): Enable "cookie" as a name fixture. Crumbs may be + // reconstructed in any order, which breaks the simple validation used here. + + vector<string> values; + values.push_back("/"); + values.push_back("/index.html"); + values.push_back("200"); + values.push_back("404"); + values.push_back(""); + values.push_back("baz=bing; foo=bar; garbage"); + values.push_back("baz=bing; fizzle=fazzle; garbage"); + + int seed = std::time(NULL); + LOG(INFO) << "Seeding with srand(" << seed << ")"; + srand(seed); + + for (size_t i = 0; i != 2000; ++i) { + map<string, string> headers; + + size_t header_count = 1 + SampleExponential(7, 50); + for (size_t j = 0; j != header_count; ++j) { + size_t name_index = SampleExponential(20, 200); + size_t value_index = SampleExponential(20, 200); + + string name, value; + if (name_index >= names.size()) { + names.push_back(base::RandBytesAsString(1 + SampleExponential(5, 30))); + name = names.back(); + } else { + name = names[name_index]; + } + if (value_index >= values.size()) { + values.push_back(base::RandBytesAsString( + 1 + SampleExponential(15, 75))); + value = values.back(); + } else { + value = values[value_index]; + } + headers[name] = value; + } + EXPECT_TRUE(RoundTrip(headers)); + } +} + +} // namespace + +} // namespace net |